Commit 8af0ee79 authored by Stanislav Lashmanov's avatar Stanislav Lashmanov

Refactor nextTick to use direct import from Vue package

RFC: https://gitlab.com/gitlab-org/frontend/rfcs/-/issues/47
parent b568065f
import { GlDropdown, GlDropdownItem, GlLoadingIcon, GlSearchBoxByType } from '@gitlab/ui'; import { GlDropdown, GlDropdownItem, GlLoadingIcon, GlSearchBoxByType } from '@gitlab/ui';
import { mount, shallowMount, createLocalVue } from '@vue/test-utils'; import { mount, shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import { nextTick } from 'vue';
import createMockApollo from 'helpers/mock_apollo_helper'; import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import ProjectDropdown from '~/jira_connect/branches/components/project_dropdown.vue'; import ProjectDropdown from '~/jira_connect/branches/components/project_dropdown.vue';
...@@ -101,7 +102,7 @@ describe('ProjectDropdown', () => { ...@@ -101,7 +102,7 @@ describe('ProjectDropdown', () => {
beforeEach(async () => { beforeEach(async () => {
createComponent(); createComponent();
await waitForPromises(); await waitForPromises();
await wrapper.vm.$nextTick(); await nextTick();
}); });
it('sets dropdown `loading` prop to `false`', () => { it('sets dropdown `loading` prop to `false`', () => {
......
import { GlButton } from '@gitlab/ui'; import { GlButton } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils'; import { mount, shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import * as JiraConnectApi from '~/jira_connect/subscriptions/api'; import * as JiraConnectApi from '~/jira_connect/subscriptions/api';
...@@ -63,7 +64,7 @@ describe('GroupsListItem', () => { ...@@ -63,7 +64,7 @@ describe('GroupsListItem', () => {
clickLinkButton(); clickLinkButton();
await wrapper.vm.$nextTick(); await nextTick();
expect(findLinkButton().props('loading')).toBe(true); expect(findLinkButton().props('loading')).toBe(true);
......
import { GlAlert, GlLoadingIcon, GlSearchBoxByType, GlPagination } from '@gitlab/ui'; import { GlAlert, GlLoadingIcon, GlSearchBoxByType, GlPagination } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import { fetchGroups } from '~/jira_connect/subscriptions/api'; import { fetchGroups } from '~/jira_connect/subscriptions/api';
...@@ -61,7 +62,7 @@ describe('GroupsList', () => { ...@@ -61,7 +62,7 @@ describe('GroupsList', () => {
fetchGroups.mockReturnValue(new Promise(() => {})); fetchGroups.mockReturnValue(new Promise(() => {}));
createComponent(); createComponent();
await wrapper.vm.$nextTick(); await nextTick();
expect(findGlLoadingIcon().exists()).toBe(true); expect(findGlLoadingIcon().exists()).toBe(true);
}); });
...@@ -124,7 +125,7 @@ describe('GroupsList', () => { ...@@ -124,7 +125,7 @@ describe('GroupsList', () => {
findFirstItem().vm.$emit('error', errorMessage); findFirstItem().vm.$emit('error', errorMessage);
await wrapper.vm.$nextTick(); await nextTick();
expect(findGlAlert().exists()).toBe(true); expect(findGlAlert().exists()).toBe(true);
expect(findGlAlert().text()).toContain(errorMessage); expect(findGlAlert().text()).toContain(errorMessage);
...@@ -139,7 +140,7 @@ describe('GroupsList', () => { ...@@ -139,7 +140,7 @@ describe('GroupsList', () => {
fetchGroups.mockReturnValue(new Promise(() => {})); fetchGroups.mockReturnValue(new Promise(() => {}));
findSearchBox().vm.$emit('input', mockSearchTeam); findSearchBox().vm.$emit('input', mockSearchTeam);
await wrapper.vm.$nextTick(); await nextTick();
}); });
it('calls `fetchGroups` with search term', () => { it('calls `fetchGroups` with search term', () => {
......
import { GlAlert, GlLink, GlEmptyState } from '@gitlab/ui'; import { GlAlert, GlLink, GlEmptyState } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils'; import { mount, shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import JiraConnectApp from '~/jira_connect/subscriptions/components/app.vue'; import JiraConnectApp from '~/jira_connect/subscriptions/components/app.vue';
import AddNamespaceButton from '~/jira_connect/subscriptions/components/add_namespace_button.vue'; import AddNamespaceButton from '~/jira_connect/subscriptions/components/add_namespace_button.vue';
import SignInButton from '~/jira_connect/subscriptions/components/sign_in_button.vue'; import SignInButton from '~/jira_connect/subscriptions/components/sign_in_button.vue';
...@@ -116,7 +117,7 @@ describe('JiraConnectApp', () => { ...@@ -116,7 +117,7 @@ describe('JiraConnectApp', () => {
createComponent(); createComponent();
store.commit(SET_ALERT, { message, variant }); store.commit(SET_ALERT, { message, variant });
await wrapper.vm.$nextTick(); await nextTick();
const alert = findAlert(); const alert = findAlert();
...@@ -134,10 +135,10 @@ describe('JiraConnectApp', () => { ...@@ -134,10 +135,10 @@ describe('JiraConnectApp', () => {
createComponent(); createComponent();
store.commit(SET_ALERT, { message: 'test message' }); store.commit(SET_ALERT, { message: 'test message' });
await wrapper.vm.$nextTick(); await nextTick();
findAlert().vm.$emit('dismiss'); findAlert().vm.$emit('dismiss');
await wrapper.vm.$nextTick(); await nextTick();
expect(findAlert().exists()).toBe(false); expect(findAlert().exists()).toBe(false);
}); });
...@@ -149,7 +150,7 @@ describe('JiraConnectApp', () => { ...@@ -149,7 +150,7 @@ describe('JiraConnectApp', () => {
message: __('test message %{linkStart}test link%{linkEnd}'), message: __('test message %{linkStart}test link%{linkEnd}'),
linkUrl: 'https://gitlab.com', linkUrl: 'https://gitlab.com',
}); });
await wrapper.vm.$nextTick(); await nextTick();
const alertLink = findAlertLink(); const alertLink = findAlertLink();
......
import { GlButton } from '@gitlab/ui'; import { GlButton } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import * as JiraConnectApi from '~/jira_connect/subscriptions/api'; import * as JiraConnectApi from '~/jira_connect/subscriptions/api';
...@@ -71,7 +72,7 @@ describe('SubscriptionsList', () => { ...@@ -71,7 +72,7 @@ describe('SubscriptionsList', () => {
clickUnlinkButton(); clickUnlinkButton();
await wrapper.vm.$nextTick(); await nextTick();
expect(findUnlinkButton().props('loading')).toBe(true); expect(findUnlinkButton().props('loading')).toBe(true);
......
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import Vue from 'vue'; import Vue, { nextTick } from 'vue';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import Vuex from 'vuex'; import Vuex from 'vuex';
import delayedJobFixture from 'test_fixtures/jobs/delayed.json'; import delayedJobFixture from 'test_fixtures/jobs/delayed.json';
...@@ -45,7 +45,7 @@ describe('Job App', () => { ...@@ -45,7 +45,7 @@ describe('Job App', () => {
wrapper = mount(JobApp, { propsData: { ...props }, store }); wrapper = mount(JobApp, { propsData: { ...props }, store });
}; };
const setupAndMount = ({ jobData = {}, jobLogData = {} } = {}) => { const setupAndMount = async ({ jobData = {}, jobLogData = {} } = {}) => {
mock.onGet(initSettings.endpoint).replyOnce(200, { ...job, ...jobData }); mock.onGet(initSettings.endpoint).replyOnce(200, { ...job, ...jobData });
mock.onGet(`${initSettings.pagePath}/trace.json`).reply(200, jobLogData); mock.onGet(`${initSettings.pagePath}/trace.json`).reply(200, jobLogData);
...@@ -53,12 +53,10 @@ describe('Job App', () => { ...@@ -53,12 +53,10 @@ describe('Job App', () => {
createComponent(); createComponent();
return asyncInit await asyncInit;
.then(() => { jest.runOnlyPendingTimers();
jest.runOnlyPendingTimers(); await axios.waitForAll();
}) await nextTick();
.then(() => axios.waitForAll())
.then(() => wrapper.vm.$nextTick());
}; };
const findLoadingComponent = () => wrapper.find(GlLoadingIcon); const findLoadingComponent = () => wrapper.find(GlLoadingIcon);
......
import { GlIcon, GlLink } from '@gitlab/ui'; import { GlIcon, GlLink } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import delayedJobFixture from 'test_fixtures/jobs/delayed.json'; import delayedJobFixture from 'test_fixtures/jobs/delayed.json';
import JobContainerItem from '~/jobs/components/job_container_item.vue'; import JobContainerItem from '~/jobs/components/job_container_item.vue';
import CiIcon from '~/vue_shared/components/ci_icon.vue'; import CiIcon from '~/vue_shared/components/ci_icon.vue';
...@@ -87,7 +88,7 @@ describe('JobContainerItem', () => { ...@@ -87,7 +88,7 @@ describe('JobContainerItem', () => {
}); });
it('displays remaining time in tooltip', async () => { it('displays remaining time in tooltip', async () => {
await wrapper.vm.$nextTick(); await nextTick();
const link = wrapper.findComponent(GlLink); const link = wrapper.findComponent(GlLink);
......
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import JobLogControllers from '~/jobs/components/job_log_controllers.vue'; import JobLogControllers from '~/jobs/components/job_log_controllers.vue';
describe('Job log controllers', () => { describe('Job log controllers', () => {
...@@ -111,7 +112,7 @@ describe('Job log controllers', () => { ...@@ -111,7 +112,7 @@ describe('Job log controllers', () => {
it('emits scrollJobLogTop event on click', async () => { it('emits scrollJobLogTop event on click', async () => {
findScrollTop().trigger('click'); findScrollTop().trigger('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.emitted().scrollJobLogTop).toHaveLength(1); expect(wrapper.emitted().scrollJobLogTop).toHaveLength(1);
}); });
...@@ -133,7 +134,7 @@ describe('Job log controllers', () => { ...@@ -133,7 +134,7 @@ describe('Job log controllers', () => {
it('does not emit scrollJobLogTop event on click', async () => { it('does not emit scrollJobLogTop event on click', async () => {
findScrollTop().trigger('click'); findScrollTop().trigger('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.emitted().scrollJobLogTop).toBeUndefined(); expect(wrapper.emitted().scrollJobLogTop).toBeUndefined();
}); });
...@@ -149,7 +150,7 @@ describe('Job log controllers', () => { ...@@ -149,7 +150,7 @@ describe('Job log controllers', () => {
it('emits scrollJobLogBottom event on click', async () => { it('emits scrollJobLogBottom event on click', async () => {
findScrollBottom().trigger('click'); findScrollBottom().trigger('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.emitted().scrollJobLogBottom).toHaveLength(1); expect(wrapper.emitted().scrollJobLogBottom).toHaveLength(1);
}); });
...@@ -171,7 +172,7 @@ describe('Job log controllers', () => { ...@@ -171,7 +172,7 @@ describe('Job log controllers', () => {
it('does not emit scrollJobLogBottom event on click', async () => { it('does not emit scrollJobLogBottom event on click', async () => {
findScrollBottom().trigger('click'); findScrollBottom().trigger('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.emitted().scrollJobLogBottom).toBeUndefined(); expect(wrapper.emitted().scrollJobLogBottom).toBeUndefined();
}); });
......
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import CollapsibleSection from '~/jobs/components/log/collapsible_section.vue'; import CollapsibleSection from '~/jobs/components/log/collapsible_section.vue';
import { collapsibleSectionClosed, collapsibleSectionOpened } from './mock_data'; import { collapsibleSectionClosed, collapsibleSectionOpened } from './mock_data';
...@@ -69,7 +70,7 @@ describe('Job Log Collapsible Section', () => { ...@@ -69,7 +70,7 @@ describe('Job Log Collapsible Section', () => {
}); });
}); });
it('emits onClickCollapsibleLine on click', () => { it('emits onClickCollapsibleLine on click', async () => {
createComponent({ createComponent({
section: collapsibleSectionOpened, section: collapsibleSectionOpened,
jobLogEndpoint, jobLogEndpoint,
...@@ -77,8 +78,7 @@ describe('Job Log Collapsible Section', () => { ...@@ -77,8 +78,7 @@ describe('Job Log Collapsible Section', () => {
findCollapsibleLine().trigger('click'); findCollapsibleLine().trigger('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted('onClickCollapsibleLine').length).toBe(1); expect(wrapper.emitted('onClickCollapsibleLine').length).toBe(1);
});
}); });
}); });
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DurationBadge from '~/jobs/components/log/duration_badge.vue'; import DurationBadge from '~/jobs/components/log/duration_badge.vue';
import LineHeader from '~/jobs/components/log/line_header.vue'; import LineHeader from '~/jobs/components/log/line_header.vue';
import LineNumber from '~/jobs/components/log/line_number.vue'; import LineNumber from '~/jobs/components/log/line_number.vue';
...@@ -75,12 +76,11 @@ describe('Job Log Header Line', () => { ...@@ -75,12 +76,11 @@ describe('Job Log Header Line', () => {
createComponent(data); createComponent(data);
}); });
it('emits toggleLine event', () => { it('emits toggleLine event', async () => {
wrapper.trigger('click'); wrapper.trigger('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted().toggleLine.length).toBe(1); expect(wrapper.emitted().toggleLine.length).toBe(1);
});
}); });
}); });
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import ArtifactsBlock from '~/jobs/components/artifacts_block.vue'; import ArtifactsBlock from '~/jobs/components/artifacts_block.vue';
import JobRetryForwardDeploymentModal from '~/jobs/components/job_retry_forward_deployment_modal.vue'; import JobRetryForwardDeploymentModal from '~/jobs/components/job_retry_forward_deployment_modal.vue';
...@@ -189,7 +190,7 @@ describe('Sidebar details block', () => { ...@@ -189,7 +190,7 @@ describe('Sidebar details block', () => {
locked: false, locked: false,
}; };
await wrapper.vm.$nextTick(); await nextTick();
expect(findArtifactsBlock().exists()).toBe(true); expect(findArtifactsBlock().exists()).toBe(true);
}); });
......
import { GlSkeletonLoader, GlAlert, GlEmptyState, GlPagination } from '@gitlab/ui'; import { GlSkeletonLoader, GlAlert, GlEmptyState, GlPagination } from '@gitlab/ui';
import { createLocalVue, mount, shallowMount } from '@vue/test-utils'; import { createLocalVue, mount, shallowMount } from '@vue/test-utils';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import { nextTick } from 'vue';
import createMockApollo from 'helpers/mock_apollo_helper'; import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import getJobsQuery from '~/jobs/components/table/graphql/queries/get_jobs.query.graphql'; import getJobsQuery from '~/jobs/components/table/graphql/queries/get_jobs.query.graphql';
...@@ -124,7 +125,7 @@ describe('Job table app', () => { ...@@ -124,7 +125,7 @@ describe('Job table app', () => {
}, },
}); });
await wrapper.vm.$nextTick(); await nextTick();
expect(findPrevious().exists()).toBe(true); expect(findPrevious().exists()).toBe(true);
expect(findNext().exists()).toBe(true); expect(findNext().exists()).toBe(true);
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import delayedJobFixture from 'test_fixtures/jobs/delayed.json'; import delayedJobFixture from 'test_fixtures/jobs/delayed.json';
import delayedJobMixin from '~/jobs/mixins/delayed_job_mixin'; import delayedJobMixin from '~/jobs/mixins/delayed_job_mixin';
...@@ -34,7 +35,7 @@ describe('DelayedJobMixin', () => { ...@@ -34,7 +35,7 @@ describe('DelayedJobMixin', () => {
}); });
it('does not update remaining time after mounting', async () => { it('does not update remaining time after mounting', async () => {
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.text()).toBe('00:00:00'); expect(wrapper.text()).toBe('00:00:00');
}); });
...@@ -57,7 +58,7 @@ describe('DelayedJobMixin', () => { ...@@ -57,7 +58,7 @@ describe('DelayedJobMixin', () => {
}, },
}); });
await wrapper.vm.$nextTick(); await nextTick();
}); });
it('sets remaining time', () => { it('sets remaining time', () => {
...@@ -68,7 +69,7 @@ describe('DelayedJobMixin', () => { ...@@ -68,7 +69,7 @@ describe('DelayedJobMixin', () => {
remainingTimeInMilliseconds = 41000; remainingTimeInMilliseconds = 41000;
jest.advanceTimersByTime(1000); jest.advanceTimersByTime(1000);
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.text()).toBe('00:00:41'); expect(wrapper.text()).toBe('00:00:41');
}); });
}); });
...@@ -104,7 +105,7 @@ describe('DelayedJobMixin', () => { ...@@ -104,7 +105,7 @@ describe('DelayedJobMixin', () => {
}, },
}); });
await wrapper.vm.$nextTick(); await nextTick();
}); });
it('sets remaining time', () => { it('sets remaining time', () => {
...@@ -115,7 +116,7 @@ describe('DelayedJobMixin', () => { ...@@ -115,7 +116,7 @@ describe('DelayedJobMixin', () => {
remainingTimeInMilliseconds = 41000; remainingTimeInMilliseconds = 41000;
jest.advanceTimersByTime(1000); jest.advanceTimersByTime(1000);
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.text()).toBe('00:00:41'); expect(wrapper.text()).toBe('00:00:41');
}); });
}); });
......
import { GlSprintf, GlDropdown, GlDropdownItem } from '@gitlab/ui'; import { GlSprintf, GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { scrollDown } from '~/lib/utils/scroll_utils'; import { scrollDown } from '~/lib/utils/scroll_utils';
import EnvironmentLogs from '~/logs/components/environment_logs.vue'; import EnvironmentLogs from '~/logs/components/environment_logs.vue';
...@@ -338,35 +339,32 @@ describe('EnvironmentLogs', () => { ...@@ -338,35 +339,32 @@ describe('EnvironmentLogs', () => {
expect(store.dispatch).not.toHaveBeenCalledWith(`${module}/fetchMoreLogsPrepend`, undefined); expect(store.dispatch).not.toHaveBeenCalledWith(`${module}/fetchMoreLogsPrepend`, undefined);
}); });
it('`scroll` on a scrollable target results in enabled scroll buttons', () => { it('`scroll` on a scrollable target results in enabled scroll buttons', async () => {
const target = { scrollTop: 10, clientHeight: 10, scrollHeight: 21 }; const target = { scrollTop: 10, clientHeight: 10, scrollHeight: 21 };
state.logs.isLoading = true; state.logs.isLoading = true;
findInfiniteScroll().vm.$emit('scroll', { target }); findInfiniteScroll().vm.$emit('scroll', { target });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findLogControlButtons().props('scrollDownButtonDisabled')).toEqual(false); expect(findLogControlButtons().props('scrollDownButtonDisabled')).toEqual(false);
});
}); });
it('`scroll` on a non-scrollable target in disabled scroll buttons', () => { it('`scroll` on a non-scrollable target in disabled scroll buttons', async () => {
const target = { scrollTop: 10, clientHeight: 10, scrollHeight: 20 }; const target = { scrollTop: 10, clientHeight: 10, scrollHeight: 20 };
state.logs.isLoading = true; state.logs.isLoading = true;
findInfiniteScroll().vm.$emit('scroll', { target }); findInfiniteScroll().vm.$emit('scroll', { target });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findLogControlButtons().props('scrollDownButtonDisabled')).toEqual(true); expect(findLogControlButtons().props('scrollDownButtonDisabled')).toEqual(true);
});
}); });
it('`scroll` on no target results in disabled scroll buttons', () => { it('`scroll` on no target results in disabled scroll buttons', async () => {
state.logs.isLoading = true; state.logs.isLoading = true;
findInfiniteScroll().vm.$emit('scroll', { target: undefined }); findInfiniteScroll().vm.$emit('scroll', { target: undefined });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findLogControlButtons().props('scrollDownButtonDisabled')).toEqual(true); expect(findLogControlButtons().props('scrollDownButtonDisabled')).toEqual(true);
});
}); });
}); });
}); });
import { GlButton } from '@gitlab/ui'; import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import LogControlButtons from '~/logs/components/log_control_buttons.vue'; import LogControlButtons from '~/logs/components/log_control_buttons.vue';
describe('LogControlButtons', () => { describe('LogControlButtons', () => {
...@@ -33,7 +34,7 @@ describe('LogControlButtons', () => { ...@@ -33,7 +34,7 @@ describe('LogControlButtons', () => {
expect(findRefreshBtn().is(GlButton)).toBe(true); expect(findRefreshBtn().is(GlButton)).toBe(true);
}); });
it('emits a `refresh` event on click on `refresh` button', () => { it('emits a `refresh` event on click on `refresh` button', async () => {
initWrapper(); initWrapper();
// An `undefined` value means no event was emitted // An `undefined` value means no event was emitted
...@@ -41,16 +42,15 @@ describe('LogControlButtons', () => { ...@@ -41,16 +42,15 @@ describe('LogControlButtons', () => {
findRefreshBtn().vm.$emit('click'); findRefreshBtn().vm.$emit('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted('refresh')).toHaveLength(1); expect(wrapper.emitted('refresh')).toHaveLength(1);
});
}); });
describe('when scrolling actions are enabled', () => { describe('when scrolling actions are enabled', () => {
beforeEach(() => { beforeEach(async () => {
// mock scrolled to the middle of a long page // mock scrolled to the middle of a long page
initWrapper(); initWrapper();
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('click on "scroll to top" scrolls up', () => { it('click on "scroll to top" scrolls up', () => {
...@@ -71,19 +71,18 @@ describe('LogControlButtons', () => { ...@@ -71,19 +71,18 @@ describe('LogControlButtons', () => {
}); });
describe('when scrolling actions are disabled', () => { describe('when scrolling actions are disabled', () => {
beforeEach(() => { beforeEach(async () => {
initWrapper({ listeners: {} }); initWrapper({ listeners: {} });
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('buttons are disabled', () => { it('buttons are disabled', async () => {
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findScrollToTop().exists()).toBe(false); expect(findScrollToTop().exists()).toBe(false);
expect(findScrollToBottom().exists()).toBe(false); expect(findScrollToBottom().exists()).toBe(false);
// This should be enabled when gitlab-ui contains: // This should be enabled when gitlab-ui contains:
// https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/1149 // https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/1149
// expect(findScrollToBottom().is('[disabled]')).toBe(true); // expect(findScrollToBottom().is('[disabled]')).toBe(true);
});
}); });
}); });
}); });
import { GlSprintf } from '@gitlab/ui'; import { GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import Vue from 'vue'; import Vue, { nextTick } from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import InlineConflictLines from '~/merge_conflicts/components/inline_conflict_lines.vue'; import InlineConflictLines from '~/merge_conflicts/components/inline_conflict_lines.vue';
import ParallelConflictLines from '~/merge_conflicts/components/parallel_conflict_lines.vue'; import ParallelConflictLines from '~/merge_conflicts/components/parallel_conflict_lines.vue';
...@@ -93,7 +93,7 @@ describe('Merge Conflict Resolver App', () => { ...@@ -93,7 +93,7 @@ describe('Merge Conflict Resolver App', () => {
expect(inlineButton.props('selected')).toBe(false); expect(inlineButton.props('selected')).toBe(false);
inlineButton.vm.$emit('click'); inlineButton.vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(inlineButton.props('selected')).toBe(true); expect(inlineButton.props('selected')).toBe(true);
}); });
...@@ -111,7 +111,7 @@ describe('Merge Conflict Resolver App', () => { ...@@ -111,7 +111,7 @@ describe('Merge Conflict Resolver App', () => {
mountComponent(); mountComponent();
findSideBySideButton().vm.$emit('click'); findSideBySideButton().vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
const parallelConflictLinesComponent = findParallelConflictLines(findFiles().at(0)); const parallelConflictLinesComponent = findParallelConflictLines(findFiles().at(0));
......
...@@ -2,6 +2,7 @@ import { GlStackedColumnChart, GlChartLegend } from '@gitlab/ui/dist/charts'; ...@@ -2,6 +2,7 @@ import { GlStackedColumnChart, GlChartLegend } from '@gitlab/ui/dist/charts';
import { shallowMount, mount } from '@vue/test-utils'; import { shallowMount, mount } from '@vue/test-utils';
import { cloneDeep } from 'lodash'; import { cloneDeep } from 'lodash';
import timezoneMock from 'timezone-mock'; import timezoneMock from 'timezone-mock';
import { nextTick } from 'vue';
import StackedColumnChart from '~/monitoring/components/charts/stacked_column.vue'; import StackedColumnChart from '~/monitoring/components/charts/stacked_column.vue';
import { stackedColumnGraphData } from '../../graph_data'; import { stackedColumnGraphData } from '../../graph_data';
...@@ -34,9 +35,9 @@ describe('Stacked column chart component', () => { ...@@ -34,9 +35,9 @@ describe('Stacked column chart component', () => {
}); });
describe('when graphData is present', () => { describe('when graphData is present', () => {
beforeEach(() => { beforeEach(async () => {
createWrapper(); createWrapper();
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('chart is rendered', () => { it('chart is rendered', () => {
...@@ -116,25 +117,24 @@ describe('Stacked column chart component', () => { ...@@ -116,25 +117,24 @@ describe('Stacked column chart component', () => {
expect(xAxis.axisLabel.formatter('2020-01-30T12:01:00.000Z')).toBe('4:01 AM'); expect(xAxis.axisLabel.formatter('2020-01-30T12:01:00.000Z')).toBe('4:01 AM');
}); });
it('date is shown in UTC', () => { it('date is shown in UTC', async () => {
wrapper.setProps({ timezone: 'UTC' }); wrapper.setProps({ timezone: 'UTC' });
return wrapper.vm.$nextTick().then(() => { await nextTick();
const { xAxis } = findChart().props('option'); const { xAxis } = findChart().props('option');
expect(xAxis.axisLabel.formatter('2020-01-30T12:01:00.000Z')).toBe('12:01 PM'); expect(xAxis.axisLabel.formatter('2020-01-30T12:01:00.000Z')).toBe('12:01 PM');
});
}); });
}); });
}); });
describe('when graphData has results missing', () => { describe('when graphData has results missing', () => {
beforeEach(() => { beforeEach(async () => {
const graphData = cloneDeep(stackedColumnMockedData); const graphData = cloneDeep(stackedColumnMockedData);
graphData.metrics[0].result = null; graphData.metrics[0].result = null;
createWrapper({ graphData }); createWrapper({ graphData });
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('chart is rendered', () => { it('chart is rendered', () => {
...@@ -147,7 +147,7 @@ describe('Stacked column chart component', () => { ...@@ -147,7 +147,7 @@ describe('Stacked column chart component', () => {
wrapper = createWrapper({}, mount); wrapper = createWrapper({}, mount);
}); });
it('allows user to override legend label texts using props', () => { it('allows user to override legend label texts using props', async () => {
const legendRelatedProps = { const legendRelatedProps = {
legendMinText: 'legendMinText', legendMinText: 'legendMinText',
legendMaxText: 'legendMaxText', legendMaxText: 'legendMaxText',
...@@ -158,9 +158,8 @@ describe('Stacked column chart component', () => { ...@@ -158,9 +158,8 @@ describe('Stacked column chart component', () => {
...legendRelatedProps, ...legendRelatedProps,
}); });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findChart().props()).toMatchObject(legendRelatedProps); expect(findChart().props()).toMatchObject(legendRelatedProps);
});
}); });
it('should render a tabular legend layout by default', () => { it('should render a tabular legend layout by default', () => {
......
import { GlModal } from '@gitlab/ui'; import { GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import CreateDashboardModal from '~/monitoring/components/create_dashboard_modal.vue'; import CreateDashboardModal from '~/monitoring/components/create_dashboard_modal.vue';
describe('Create dashboard modal', () => { describe('Create dashboard modal', () => {
...@@ -32,13 +33,12 @@ describe('Create dashboard modal', () => { ...@@ -32,13 +33,12 @@ describe('Create dashboard modal', () => {
wrapper.destroy(); wrapper.destroy();
}); });
it('has button that links to the project url', () => { it('has button that links to the project url', async () => {
findRepoButton().trigger('click'); findRepoButton().trigger('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findRepoButton().exists()).toBe(true); expect(findRepoButton().exists()).toBe(true);
expect(findRepoButton().attributes('href')).toBe(defaultProps.projectPath); expect(findRepoButton().attributes('href')).toBe(defaultProps.projectPath);
});
}); });
it('has button that links to the docs', () => { it('has button that links to the docs', () => {
......
import { GlDropdownItem, GlModal } from '@gitlab/ui'; import { GlDropdownItem, GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import CustomMetricsFormFields from '~/custom_metrics/components/custom_metrics_form_fields.vue'; import CustomMetricsFormFields from '~/custom_metrics/components/custom_metrics_form_fields.vue';
import { redirectTo } from '~/lib/utils/url_utility'; import { redirectTo } from '~/lib/utils/url_utility';
import ActionsMenu from '~/monitoring/components/dashboard_actions_menu.vue'; import ActionsMenu from '~/monitoring/components/dashboard_actions_menu.vue';
...@@ -60,22 +61,20 @@ describe('Actions menu', () => { ...@@ -60,22 +61,20 @@ describe('Actions menu', () => {
}); });
describe('add metric item', () => { describe('add metric item', () => {
it('is rendered when custom metrics are available', () => { it('is rendered when custom metrics are available', async () => {
createShallowWrapper(); createShallowWrapper();
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findAddMetricItem().exists()).toBe(true); expect(findAddMetricItem().exists()).toBe(true);
});
}); });
it('is not rendered when custom metrics are not available', () => { it('is not rendered when custom metrics are not available', async () => {
createShallowWrapper({ createShallowWrapper({
addingMetricsAvailable: false, addingMetricsAvailable: false,
}); });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findAddMetricItem().exists()).toBe(false); expect(findAddMetricItem().exists()).toBe(false);
});
}); });
describe('when available', () => { describe('when available', () => {
...@@ -119,30 +118,23 @@ describe('Actions menu', () => { ...@@ -119,30 +118,23 @@ describe('Actions menu', () => {
origPage = document.body.dataset.page; origPage = document.body.dataset.page;
document.body.dataset.page = 'projects:environments:metrics'; document.body.dataset.page = 'projects:environments:metrics';
wrapper.vm.$nextTick(done); nextTick(done);
}); });
afterEach(() => { afterEach(() => {
document.body.dataset.page = origPage; document.body.dataset.page = origPage;
}); });
it('is tracked', (done) => { it('is tracked', async () => {
const submitButton = findAddMetricModalSubmitButton().vm; const submitButton = findAddMetricModalSubmitButton().vm;
wrapper.vm.$nextTick(() => { await nextTick();
submitButton.$el.click(); submitButton.$el.click();
wrapper.vm.$nextTick(() => { await nextTick();
expect(Tracking.event).toHaveBeenCalledWith( expect(Tracking.event).toHaveBeenCalledWith(document.body.dataset.page, 'click_button', {
document.body.dataset.page, label: 'add_new_metric',
'click_button', property: 'modal',
{ value: undefined,
label: 'add_new_metric',
property: 'modal',
value: undefined,
},
);
done();
});
}); });
}); });
}); });
...@@ -172,14 +164,13 @@ describe('Actions menu', () => { ...@@ -172,14 +164,13 @@ describe('Actions menu', () => {
); );
}); });
it('is disabled for ootb dashboards', () => { it('is disabled for ootb dashboards', async () => {
createShallowWrapper({ createShallowWrapper({
isOotbDashboard: true, isOotbDashboard: true,
}); });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findAddPanelItemDisabled().exists()).toBe(true); expect(findAddPanelItemDisabled().exists()).toBe(true);
});
}); });
it('is visible for custom dashboards', () => { it('is visible for custom dashboards', () => {
...@@ -256,16 +247,15 @@ describe('Actions menu', () => { ...@@ -256,16 +247,15 @@ describe('Actions menu', () => {
expect(findDuplicateDashboardModal().exists()).toBe(true); expect(findDuplicateDashboardModal().exists()).toBe(true);
}); });
it('clicking on item opens up the duplicate dashboard modal', () => { it('clicking on item opens up the duplicate dashboard modal', async () => {
const modalId = 'duplicateDashboard'; const modalId = 'duplicateDashboard';
const modalTrigger = findDuplicateDashboardItem(); const modalTrigger = findDuplicateDashboardItem();
const rootEmit = jest.spyOn(wrapper.vm.$root, '$emit'); const rootEmit = jest.spyOn(wrapper.vm.$root, '$emit');
modalTrigger.trigger('click'); modalTrigger.trigger('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(rootEmit.mock.calls[0]).toContainEqual(modalId); expect(rootEmit.mock.calls[0]).toContainEqual(modalId);
});
}); });
}); });
...@@ -300,16 +290,15 @@ describe('Actions menu', () => { ...@@ -300,16 +290,15 @@ describe('Actions menu', () => {
setupAllDashboards(store, dashboardGitResponse[0].path); setupAllDashboards(store, dashboardGitResponse[0].path);
}); });
it('redirects to the newly created dashboard', () => { it('redirects to the newly created dashboard', async () => {
const newDashboard = dashboardGitResponse[1]; const newDashboard = dashboardGitResponse[1];
const newDashboardUrl = 'root/sandbox/-/metrics/dashboard.yml'; const newDashboardUrl = 'root/sandbox/-/metrics/dashboard.yml';
findDuplicateDashboardModal().vm.$emit('dashboardDuplicated', newDashboard); findDuplicateDashboardModal().vm.$emit('dashboardDuplicated', newDashboard);
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(redirectTo).toHaveBeenCalled(); expect(redirectTo).toHaveBeenCalled();
expect(redirectTo).toHaveBeenCalledWith(newDashboardUrl); expect(redirectTo).toHaveBeenCalledWith(newDashboardUrl);
});
}); });
}); });
}); });
...@@ -330,32 +319,30 @@ describe('Actions menu', () => { ...@@ -330,32 +319,30 @@ describe('Actions menu', () => {
expect(findStarDashboardItem().attributes('disabled')).toBeFalsy(); expect(findStarDashboardItem().attributes('disabled')).toBeFalsy();
}); });
it('is disabled when starring is taking place', () => { it('is disabled when starring is taking place', async () => {
store.commit(`monitoringDashboard/${types.REQUEST_DASHBOARD_STARRING}`); store.commit(`monitoringDashboard/${types.REQUEST_DASHBOARD_STARRING}`);
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findStarDashboardItem().exists()).toBe(true); expect(findStarDashboardItem().exists()).toBe(true);
expect(findStarDashboardItem().attributes('disabled')).toBe('true'); expect(findStarDashboardItem().attributes('disabled')).toBe('true');
});
}); });
it('on click it dispatches a toggle star action', () => { it('on click it dispatches a toggle star action', async () => {
findStarDashboardItem().vm.$emit('click'); findStarDashboardItem().vm.$emit('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(store.dispatch).toHaveBeenCalledWith( expect(store.dispatch).toHaveBeenCalledWith(
'monitoringDashboard/toggleStarredValue', 'monitoringDashboard/toggleStarredValue',
undefined, undefined,
); );
});
}); });
describe('when dashboard is not starred', () => { describe('when dashboard is not starred', () => {
beforeEach(() => { beforeEach(async () => {
store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, { store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, {
currentDashboard: dashboardGitResponse[0].path, currentDashboard: dashboardGitResponse[0].path,
}); });
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('item text shows "Star dashboard"', () => { it('item text shows "Star dashboard"', () => {
...@@ -364,11 +351,11 @@ describe('Actions menu', () => { ...@@ -364,11 +351,11 @@ describe('Actions menu', () => {
}); });
describe('when dashboard is starred', () => { describe('when dashboard is starred', () => {
beforeEach(() => { beforeEach(async () => {
store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, { store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, {
currentDashboard: dashboardGitResponse[1].path, currentDashboard: dashboardGitResponse[1].path,
}); });
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('item text shows "Unstar dashboard"', () => { it('item text shows "Unstar dashboard"', () => {
...@@ -403,16 +390,15 @@ describe('Actions menu', () => { ...@@ -403,16 +390,15 @@ describe('Actions menu', () => {
expect(findCreateDashboardModal().exists()).toBe(true); expect(findCreateDashboardModal().exists()).toBe(true);
}); });
it('clicking opens up the modal', () => { it('clicking opens up the modal', async () => {
const modalId = 'createDashboard'; const modalId = 'createDashboard';
const modalTrigger = findCreateDashboardItem(); const modalTrigger = findCreateDashboardItem();
const rootEmit = jest.spyOn(wrapper.vm.$root, '$emit'); const rootEmit = jest.spyOn(wrapper.vm.$root, '$emit');
modalTrigger.trigger('click'); modalTrigger.trigger('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(rootEmit.mock.calls[0]).toContainEqual(modalId); expect(rootEmit.mock.calls[0]).toContainEqual(modalId);
});
}); });
it('modal gets passed correct props', () => { it('modal gets passed correct props', () => {
......
import { GlCard, GlForm, GlFormTextarea, GlAlert } from '@gitlab/ui'; import { GlCard, GlForm, GlFormTextarea, GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DashboardPanel from '~/monitoring/components/dashboard_panel.vue'; import DashboardPanel from '~/monitoring/components/dashboard_panel.vue';
import DashboardPanelBuilder from '~/monitoring/components/dashboard_panel_builder.vue'; import DashboardPanelBuilder from '~/monitoring/components/dashboard_panel_builder.vue';
import { createStore } from '~/monitoring/stores'; import { createStore } from '~/monitoring/stores';
...@@ -90,21 +91,20 @@ describe('dashboard invalid url parameters', () => { ...@@ -90,21 +91,20 @@ describe('dashboard invalid url parameters', () => {
expect(mockShowToast).toHaveBeenCalledTimes(1); expect(mockShowToast).toHaveBeenCalledTimes(1);
}); });
it('on submit fetches a panel preview', () => { it('on submit fetches a panel preview', async () => {
findForm().vm.$emit('submit', new Event('submit')); findForm().vm.$emit('submit', new Event('submit'));
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(store.dispatch).toHaveBeenCalledWith( expect(store.dispatch).toHaveBeenCalledWith(
'monitoringDashboard/fetchPanelPreview', 'monitoringDashboard/fetchPanelPreview',
expect.stringContaining('title:'), expect.stringContaining('title:'),
); );
});
}); });
describe('when form is submitted', () => { describe('when form is submitted', () => {
beforeEach(() => { beforeEach(async () => {
store.commit(`monitoringDashboard/${types.REQUEST_PANEL_PREVIEW}`, 'mock yml content'); store.commit(`monitoringDashboard/${types.REQUEST_PANEL_PREVIEW}`, 'mock yml content');
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('submit button is disabled', () => { it('submit button is disabled', () => {
...@@ -118,23 +118,21 @@ describe('dashboard invalid url parameters', () => { ...@@ -118,23 +118,21 @@ describe('dashboard invalid url parameters', () => {
expect(findTimeRangePicker().exists()).toBe(true); expect(findTimeRangePicker().exists()).toBe(true);
}); });
it('when changed does not trigger data fetch unless preview panel button is clicked', () => { it('when changed does not trigger data fetch unless preview panel button is clicked', async () => {
// mimic initial state where SET_PANEL_PREVIEW_IS_SHOWN is set to false // mimic initial state where SET_PANEL_PREVIEW_IS_SHOWN is set to false
store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_IS_SHOWN}`, false); store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_IS_SHOWN}`, false);
return wrapper.vm.$nextTick(() => { await nextTick();
expect(store.dispatch).not.toHaveBeenCalled(); expect(store.dispatch).not.toHaveBeenCalled();
});
}); });
it('when changed triggers data fetch if preview panel button is clicked', () => { it('when changed triggers data fetch if preview panel button is clicked', async () => {
findForm().vm.$emit('submit', new Event('submit')); findForm().vm.$emit('submit', new Event('submit'));
store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_TIME_RANGE}`, mockTimeRange); store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_TIME_RANGE}`, mockTimeRange);
return wrapper.vm.$nextTick(() => { await nextTick();
expect(store.dispatch).toHaveBeenCalled(); expect(store.dispatch).toHaveBeenCalled();
});
}); });
}); });
...@@ -143,27 +141,25 @@ describe('dashboard invalid url parameters', () => { ...@@ -143,27 +141,25 @@ describe('dashboard invalid url parameters', () => {
expect(findRefreshButton().exists()).toBe(true); expect(findRefreshButton().exists()).toBe(true);
}); });
it('when clicked does not trigger data fetch unless preview panel button is clicked', () => { it('when clicked does not trigger data fetch unless preview panel button is clicked', async () => {
// mimic initial state where SET_PANEL_PREVIEW_IS_SHOWN is set to false // mimic initial state where SET_PANEL_PREVIEW_IS_SHOWN is set to false
store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_IS_SHOWN}`, false); store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_IS_SHOWN}`, false);
return wrapper.vm.$nextTick(() => { await nextTick();
expect(store.dispatch).not.toHaveBeenCalled(); expect(store.dispatch).not.toHaveBeenCalled();
});
}); });
it('when clicked triggers data fetch if preview panel button is clicked', () => { it('when clicked triggers data fetch if preview panel button is clicked', async () => {
// mimic state where preview is visible. SET_PANEL_PREVIEW_IS_SHOWN is set to true // mimic state where preview is visible. SET_PANEL_PREVIEW_IS_SHOWN is set to true
store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_IS_SHOWN}`, true); store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_IS_SHOWN}`, true);
findRefreshButton().vm.$emit('click'); findRefreshButton().vm.$emit('click');
return wrapper.vm.$nextTick(() => { await nextTick();
expect(store.dispatch).toHaveBeenCalledWith( expect(store.dispatch).toHaveBeenCalledWith(
'monitoringDashboard/fetchPanelPreviewMetrics', 'monitoringDashboard/fetchPanelPreviewMetrics',
undefined, undefined,
); );
});
}); });
}); });
...@@ -190,9 +186,9 @@ describe('dashboard invalid url parameters', () => { ...@@ -190,9 +186,9 @@ describe('dashboard invalid url parameters', () => {
describe('when there is an error', () => { describe('when there is an error', () => {
const mockError = 'an error occurred!'; const mockError = 'an error occurred!';
beforeEach(() => { beforeEach(async () => {
store.commit(`monitoringDashboard/${types.RECEIVE_PANEL_PREVIEW_FAILURE}`, mockError); store.commit(`monitoringDashboard/${types.RECEIVE_PANEL_PREVIEW_FAILURE}`, mockError);
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('displays an alert', () => { it('displays an alert', () => {
...@@ -204,19 +200,18 @@ describe('dashboard invalid url parameters', () => { ...@@ -204,19 +200,18 @@ describe('dashboard invalid url parameters', () => {
expect(findPanel().props('graphData')).toBe(null); expect(findPanel().props('graphData')).toBe(null);
}); });
it('changing time range should not refetch data', () => { it('changing time range should not refetch data', async () => {
store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_TIME_RANGE}`, mockTimeRange); store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_TIME_RANGE}`, mockTimeRange);
return wrapper.vm.$nextTick(() => { await nextTick();
expect(store.dispatch).not.toHaveBeenCalled(); expect(store.dispatch).not.toHaveBeenCalled();
});
}); });
}); });
describe('when panel data is available', () => { describe('when panel data is available', () => {
beforeEach(() => { beforeEach(async () => {
store.commit(`monitoringDashboard/${types.RECEIVE_PANEL_PREVIEW_SUCCESS}`, mockPanel); store.commit(`monitoringDashboard/${types.RECEIVE_PANEL_PREVIEW_SUCCESS}`, mockPanel);
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('displays no alert', () => { it('displays no alert', () => {
......
...@@ -2,6 +2,7 @@ import { GlDropdownItem } from '@gitlab/ui'; ...@@ -2,6 +2,7 @@ import { GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import AxiosMockAdapter from 'axios-mock-adapter'; import AxiosMockAdapter from 'axios-mock-adapter';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { nextTick } from 'vue';
import { setTestTimeout } from 'helpers/timeout'; import { setTestTimeout } from 'helpers/timeout';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import invalidUrl from '~/lib/utils/invalid_url'; import invalidUrl from '~/lib/utils/invalid_url';
...@@ -186,7 +187,7 @@ describe('Dashboard Panel', () => { ...@@ -186,7 +187,7 @@ describe('Dashboard Panel', () => {
expect(findCopyLink().exists()).toBe(false); expect(findCopyLink().exists()).toBe(false);
}); });
it('should emit `timerange` event when a zooming in/out in a chart occcurs', () => { it('should emit `timerange` event when a zooming in/out in a chart occcurs', async () => {
const timeRange = { const timeRange = {
start: '2020-01-01T00:00:00.000Z', start: '2020-01-01T00:00:00.000Z',
end: '2020-01-01T01:00:00.000Z', end: '2020-01-01T01:00:00.000Z',
...@@ -196,9 +197,8 @@ describe('Dashboard Panel', () => { ...@@ -196,9 +197,8 @@ describe('Dashboard Panel', () => {
findTimeChart().vm.$emit('datazoom', timeRange); findTimeChart().vm.$emit('datazoom', timeRange);
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.vm.$emit).toHaveBeenCalledWith('timerangezoom', timeRange); expect(wrapper.vm.$emit).toHaveBeenCalledWith('timerangezoom', timeRange);
});
}); });
it('includes a default group id', () => { it('includes a default group id', () => {
...@@ -253,16 +253,15 @@ describe('Dashboard Panel', () => { ...@@ -253,16 +253,15 @@ describe('Dashboard Panel', () => {
describe('computed', () => { describe('computed', () => {
describe('fixedCurrentTimeRange', () => { describe('fixedCurrentTimeRange', () => {
it('returns fixed time for valid time range', () => { it('returns fixed time for valid time range', async () => {
state.timeRange = mockTimeRange; state.timeRange = mockTimeRange;
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findTimeChart().props('timeRange')).toEqual( expect(findTimeChart().props('timeRange')).toEqual(
expect.objectContaining({ expect.objectContaining({
start: expect.any(String), start: expect.any(String),
end: expect.any(String), end: expect.any(String),
}), }),
); );
});
}); });
it.each` it.each`
...@@ -271,11 +270,10 @@ describe('Dashboard Panel', () => { ...@@ -271,11 +270,10 @@ describe('Dashboard Panel', () => {
${undefined} | ${{}} ${undefined} | ${{}}
${null} | ${{}} ${null} | ${{}}
${'2020-12-03'} | ${{}} ${'2020-12-03'} | ${{}}
`('returns $output for invalid input like $input', ({ input, output }) => { `('returns $output for invalid input like $input', async ({ input, output }) => {
state.timeRange = input; state.timeRange = input;
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findTimeChart().props('timeRange')).toEqual(output); expect(findTimeChart().props('timeRange')).toEqual(output);
});
}); });
}); });
}); });
...@@ -285,17 +283,16 @@ describe('Dashboard Panel', () => { ...@@ -285,17 +283,16 @@ describe('Dashboard Panel', () => {
const findEditCustomMetricLink = () => wrapper.find({ ref: 'editMetricLink' }); const findEditCustomMetricLink = () => wrapper.find({ ref: 'editMetricLink' });
const mockEditPath = '/root/kubernetes-gke-project/prometheus/metrics/23/edit'; const mockEditPath = '/root/kubernetes-gke-project/prometheus/metrics/23/edit';
beforeEach(() => { beforeEach(async () => {
createWrapper(); createWrapper();
await nextTick();
return wrapper.vm.$nextTick();
}); });
it('is not present if the panel is not a custom metric', () => { it('is not present if the panel is not a custom metric', () => {
expect(findEditCustomMetricLink().exists()).toBe(false); expect(findEditCustomMetricLink().exists()).toBe(false);
}); });
it('is present when the panel contains an edit_path property', () => { it('is present when the panel contains an edit_path property', async () => {
wrapper.setProps({ wrapper.setProps({
graphData: { graphData: {
...graphData, ...graphData,
...@@ -308,14 +305,13 @@ describe('Dashboard Panel', () => { ...@@ -308,14 +305,13 @@ describe('Dashboard Panel', () => {
}, },
}); });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findEditCustomMetricLink().exists()).toBe(true); expect(findEditCustomMetricLink().exists()).toBe(true);
expect(findEditCustomMetricLink().text()).toBe('Edit metric'); expect(findEditCustomMetricLink().text()).toBe('Edit metric');
expect(findEditCustomMetricLink().attributes('href')).toBe(mockEditPath); expect(findEditCustomMetricLink().attributes('href')).toBe(mockEditPath);
});
}); });
it('shows an "Edit metrics" link pointing to settingsPath for a panel with multiple metrics', () => { it('shows an "Edit metrics" link pointing to settingsPath for a panel with multiple metrics', async () => {
wrapper.setProps({ wrapper.setProps({
graphData: { graphData: {
...graphData, ...graphData,
...@@ -332,63 +328,58 @@ describe('Dashboard Panel', () => { ...@@ -332,63 +328,58 @@ describe('Dashboard Panel', () => {
}, },
}); });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findEditCustomMetricLink().text()).toBe('Edit metrics'); expect(findEditCustomMetricLink().text()).toBe('Edit metrics');
expect(findEditCustomMetricLink().attributes('href')).toBe(dashboardProps.settingsPath); expect(findEditCustomMetricLink().attributes('href')).toBe(dashboardProps.settingsPath);
});
}); });
}); });
describe('View Logs dropdown item', () => { describe('View Logs dropdown item', () => {
const findViewLogsLink = () => wrapper.find({ ref: 'viewLogsLink' }); const findViewLogsLink = () => wrapper.find({ ref: 'viewLogsLink' });
beforeEach(() => { beforeEach(async () => {
createWrapper(); createWrapper();
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('is not present by default', () => it('is not present by default', async () => {
wrapper.vm.$nextTick(() => { await nextTick();
expect(findViewLogsLink().exists()).toBe(false); expect(findViewLogsLink().exists()).toBe(false);
})); });
it('is not present if a time range is not set', () => { it('is not present if a time range is not set', async () => {
state.logsPath = mockLogsPath; state.logsPath = mockLogsPath;
state.timeRange = null; state.timeRange = null;
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findViewLogsLink().exists()).toBe(false); expect(findViewLogsLink().exists()).toBe(false);
});
}); });
it('is not present if the logs path is default', () => { it('is not present if the logs path is default', async () => {
state.logsPath = invalidUrl; state.logsPath = invalidUrl;
state.timeRange = mockTimeRange; state.timeRange = mockTimeRange;
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findViewLogsLink().exists()).toBe(false); expect(findViewLogsLink().exists()).toBe(false);
});
}); });
it('is not present if the logs path is not set', () => { it('is not present if the logs path is not set', async () => {
state.logsPath = null; state.logsPath = null;
state.timeRange = mockTimeRange; state.timeRange = mockTimeRange;
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findViewLogsLink().exists()).toBe(false); expect(findViewLogsLink().exists()).toBe(false);
});
}); });
it('is present when logs path and time a range is present', () => { it('is present when logs path and time a range is present', async () => {
state.logsPath = mockLogsPath; state.logsPath = mockLogsPath;
state.timeRange = mockTimeRange; state.timeRange = mockTimeRange;
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findViewLogsLink().attributes('href')).toMatch(mockLogsHref); expect(findViewLogsLink().attributes('href')).toMatch(mockLogsHref);
});
}); });
it('it is overridden when a datazoom event is received', () => { it('it is overridden when a datazoom event is received', async () => {
state.logsPath = mockLogsPath; state.logsPath = mockLogsPath;
state.timeRange = mockTimeRange; state.timeRange = mockTimeRange;
...@@ -399,13 +390,12 @@ describe('Dashboard Panel', () => { ...@@ -399,13 +390,12 @@ describe('Dashboard Panel', () => {
findTimeChart().vm.$emit('datazoom', zoomedTimeRange); findTimeChart().vm.$emit('datazoom', zoomedTimeRange);
return wrapper.vm.$nextTick(() => { await nextTick();
const start = encodeURIComponent(zoomedTimeRange.start); const start = encodeURIComponent(zoomedTimeRange.start);
const end = encodeURIComponent(zoomedTimeRange.end); const end = encodeURIComponent(zoomedTimeRange.end);
expect(findViewLogsLink().attributes('href')).toMatch( expect(findViewLogsLink().attributes('href')).toMatch(
`${mockLogsPath}?start=${start}&end=${end}`, `${mockLogsPath}?start=${start}&end=${end}`,
); );
});
}); });
}); });
...@@ -447,7 +437,7 @@ describe('Dashboard Panel', () => { ...@@ -447,7 +437,7 @@ describe('Dashboard Panel', () => {
}); });
describe('when downloading metrics data as CSV', () => { describe('when downloading metrics data as CSV', () => {
beforeEach(() => { beforeEach(async () => {
wrapper = shallowMount(DashboardPanel, { wrapper = shallowMount(DashboardPanel, {
propsData: { propsData: {
clipboardText: exampleText, clipboardText: exampleText,
...@@ -459,7 +449,7 @@ describe('Dashboard Panel', () => { ...@@ -459,7 +449,7 @@ describe('Dashboard Panel', () => {
}, },
store, store,
}); });
return wrapper.vm.$nextTick(); await nextTick();
}); });
afterEach(() => { afterEach(() => {
...@@ -509,29 +499,26 @@ describe('Dashboard Panel', () => { ...@@ -509,29 +499,26 @@ describe('Dashboard Panel', () => {
}); });
}); });
it('handles namespaced time range and logs path state', () => { it('handles namespaced time range and logs path state', async () => {
store.state[mockNamespace].timeRange = mockTimeRange; store.state[mockNamespace].timeRange = mockTimeRange;
store.state[mockNamespace].logsPath = mockLogsPath; store.state[mockNamespace].logsPath = mockLogsPath;
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.find({ ref: 'viewLogsLink' }).attributes().href).toBe(mockLogsHref); expect(wrapper.find({ ref: 'viewLogsLink' }).attributes().href).toBe(mockLogsHref);
});
}); });
it('handles namespaced deployment data state', () => { it('handles namespaced deployment data state', async () => {
store.state[mockNamespace].deploymentData = mockDeploymentData; store.state[mockNamespace].deploymentData = mockDeploymentData;
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findTimeChart().props().deploymentData).toEqual(mockDeploymentData); expect(findTimeChart().props().deploymentData).toEqual(mockDeploymentData);
});
}); });
it('handles namespaced project path state', () => { it('handles namespaced project path state', async () => {
store.state[mockNamespace].projectPath = mockProjectPath; store.state[mockNamespace].projectPath = mockProjectPath;
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findTimeChart().props().projectPath).toBe(mockProjectPath); expect(findTimeChart().props().projectPath).toBe(mockProjectPath);
});
}); });
it('it renders a time series chart with no errors', () => { it('it renders a time series chart with no errors', () => {
......
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
import createFlash from '~/flash'; import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import { import {
...@@ -51,23 +52,22 @@ describe('dashboard invalid url parameters', () => { ...@@ -51,23 +52,22 @@ describe('dashboard invalid url parameters', () => {
queryToObject.mockReset(); queryToObject.mockReset();
}); });
it('passes default url parameters to the time range picker', () => { it('passes default url parameters to the time range picker', async () => {
queryToObject.mockReturnValue({}); queryToObject.mockReturnValue({});
createMountedWrapper(); createMountedWrapper();
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findDateTimePicker().props('value')).toEqual(defaultTimeRange); expect(findDateTimePicker().props('value')).toEqual(defaultTimeRange);
expect(store.dispatch).toHaveBeenCalledWith( expect(store.dispatch).toHaveBeenCalledWith(
'monitoringDashboard/setTimeRange', 'monitoringDashboard/setTimeRange',
expect.any(Object), expect.any(Object),
); );
expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined); expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
});
}); });
it('passes a fixed time range in the URL to the time range picker', () => { it('passes a fixed time range in the URL to the time range picker', async () => {
const params = { const params = {
start: '2019-01-01T00:00:00.000Z', start: '2019-01-01T00:00:00.000Z',
end: '2019-01-10T00:00:00.000Z', end: '2019-01-10T00:00:00.000Z',
...@@ -77,37 +77,35 @@ describe('dashboard invalid url parameters', () => { ...@@ -77,37 +77,35 @@ describe('dashboard invalid url parameters', () => {
createMountedWrapper(); createMountedWrapper();
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findDateTimePicker().props('value')).toEqual(params); expect(findDateTimePicker().props('value')).toEqual(params);
expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/setTimeRange', params); expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/setTimeRange', params);
expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined); expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
});
}); });
it('passes a rolling time range in the URL to the time range picker', () => { it('passes a rolling time range in the URL to the time range picker', async () => {
queryToObject.mockReturnValue({ queryToObject.mockReturnValue({
duration_seconds: '120', duration_seconds: '120',
}); });
createMountedWrapper(); createMountedWrapper();
return wrapper.vm.$nextTick().then(() => { await nextTick();
const expectedTimeRange = { const expectedTimeRange = {
duration: { seconds: 60 * 2 }, duration: { seconds: 60 * 2 },
}; };
expect(findDateTimePicker().props('value')).toMatchObject(expectedTimeRange); expect(findDateTimePicker().props('value')).toMatchObject(expectedTimeRange);
expect(store.dispatch).toHaveBeenCalledWith( expect(store.dispatch).toHaveBeenCalledWith(
'monitoringDashboard/setTimeRange', 'monitoringDashboard/setTimeRange',
expectedTimeRange, expectedTimeRange,
); );
expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined); expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
});
}); });
it('shows an error message and loads a default time range if invalid url parameters are passed', () => { it('shows an error message and loads a default time range if invalid url parameters are passed', async () => {
queryToObject.mockReturnValue({ queryToObject.mockReturnValue({
start: '<script>alert("XSS")</script>', start: '<script>alert("XSS")</script>',
end: '<script>alert("XSS")</script>', end: '<script>alert("XSS")</script>',
...@@ -115,37 +113,35 @@ describe('dashboard invalid url parameters', () => { ...@@ -115,37 +113,35 @@ describe('dashboard invalid url parameters', () => {
createMountedWrapper(); createMountedWrapper();
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(createFlash).toHaveBeenCalled(); expect(createFlash).toHaveBeenCalled();
expect(findDateTimePicker().props('value')).toEqual(defaultTimeRange); expect(findDateTimePicker().props('value')).toEqual(defaultTimeRange);
expect(store.dispatch).toHaveBeenCalledWith( expect(store.dispatch).toHaveBeenCalledWith(
'monitoringDashboard/setTimeRange', 'monitoringDashboard/setTimeRange',
defaultTimeRange, defaultTimeRange,
); );
expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined); expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
});
}); });
it('redirects to different time range', () => { it('redirects to different time range', async () => {
const toUrl = `${mockProjectDir}/-/environments/1/metrics`; const toUrl = `${mockProjectDir}/-/environments/1/metrics`;
removeParams.mockReturnValueOnce(toUrl); removeParams.mockReturnValueOnce(toUrl);
createMountedWrapper(); createMountedWrapper();
return wrapper.vm.$nextTick().then(() => { await nextTick();
findDateTimePicker().vm.$emit('input', { findDateTimePicker().vm.$emit('input', {
duration: { seconds: 120 }, duration: { seconds: 120 },
});
// redirect to with new parameters
expect(mergeUrlParams).toHaveBeenCalledWith({ duration_seconds: '120' }, toUrl);
expect(redirectTo).toHaveBeenCalledTimes(1);
}); });
// redirect to with new parameters
expect(mergeUrlParams).toHaveBeenCalledWith({ duration_seconds: '120' }, toUrl);
expect(redirectTo).toHaveBeenCalledTimes(1);
}); });
it('changes the url when a panel moves the time slider', () => { it('changes the url when a panel moves the time slider', async () => {
const timeRange = { const timeRange = {
start: '2020-01-01T00:00:00.000Z', start: '2020-01-01T00:00:00.000Z',
end: '2020-01-01T01:00:00.000Z', end: '2020-01-01T01:00:00.000Z',
...@@ -155,12 +151,11 @@ describe('dashboard invalid url parameters', () => { ...@@ -155,12 +151,11 @@ describe('dashboard invalid url parameters', () => {
createMountedWrapper(); createMountedWrapper();
return wrapper.vm.$nextTick().then(() => { await nextTick();
wrapper.vm.onTimeRangeZoom(timeRange); wrapper.vm.onTimeRangeZoom(timeRange);
expect(updateHistory).toHaveBeenCalled(); expect(updateHistory).toHaveBeenCalled();
expect(wrapper.vm.selectedTimeRange.start.toString()).toBe(timeRange.start); expect(wrapper.vm.selectedTimeRange.start.toString()).toBe(timeRange.start);
expect(wrapper.vm.selectedTimeRange.end.toString()).toBe(timeRange.end); expect(wrapper.vm.selectedTimeRange.end.toString()).toBe(timeRange.end);
});
}); });
}); });
import { GlButton, GlCard } from '@gitlab/ui'; import { GlButton, GlCard } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils'; import { mount, shallowMount } from '@vue/test-utils';
import Vue from 'vue'; import Vue, { nextTick } from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
import EmbedGroup from '~/monitoring/components/embeds/embed_group.vue'; import EmbedGroup from '~/monitoring/components/embeds/embed_group.vue';
...@@ -75,16 +75,14 @@ describe('Embed Group', () => { ...@@ -75,16 +75,14 @@ describe('Embed Group', () => {
expect(wrapper.find('.gl-card-body').classes()).not.toContain('d-none'); expect(wrapper.find('.gl-card-body').classes()).not.toContain('d-none');
}); });
it('collapses when clicked', (done) => { it('collapses when clicked', async () => {
metricsWithDataGetter.mockReturnValue([1]); metricsWithDataGetter.mockReturnValue([1]);
mountComponent({ shallow: false, stubs: { MetricEmbed: true } }); mountComponent({ shallow: false, stubs: { MetricEmbed: true } });
wrapper.find(GlButton).trigger('click'); wrapper.find(GlButton).trigger('click');
wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.find('.gl-card-body').classes()).toContain('d-none'); expect(wrapper.find('.gl-card-body').classes()).toContain('d-none');
done();
});
}); });
}); });
......
import { GlLoadingIcon, GlIcon } from '@gitlab/ui'; import { GlLoadingIcon, GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import GraphGroup from '~/monitoring/components/graph_group.vue'; import GraphGroup from '~/monitoring/components/graph_group.vue';
describe('Graph group component', () => { describe('Graph group component', () => {
...@@ -38,13 +39,12 @@ describe('Graph group component', () => { ...@@ -38,13 +39,12 @@ describe('Graph group component', () => {
expect(findCaretIcon().props('name')).toBe('angle-down'); expect(findCaretIcon().props('name')).toBe('angle-down');
}); });
it('should show the angle-right caret icon when the user collapses the group', () => { it('should show the angle-right caret icon when the user collapses the group', async () => {
findToggleButton().trigger('click'); findToggleButton().trigger('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findContent().isVisible()).toBe(false); expect(findContent().isVisible()).toBe(false);
expect(findCaretIcon().props('name')).toBe('angle-right'); expect(findCaretIcon().props('name')).toBe('angle-right');
});
}); });
it('should contain a tab index for the collapse button', () => { it('should contain a tab index for the collapse button', () => {
...@@ -53,15 +53,14 @@ describe('Graph group component', () => { ...@@ -53,15 +53,14 @@ describe('Graph group component', () => {
expect(groupToggle.attributes('tabindex')).toBeDefined(); expect(groupToggle.attributes('tabindex')).toBeDefined();
}); });
it('should show the open the group when collapseGroup is set to true', () => { it('should show the open the group when collapseGroup is set to true', async () => {
wrapper.setProps({ wrapper.setProps({
collapseGroup: true, collapseGroup: true,
}); });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findContent().isVisible()).toBe(true); expect(findContent().isVisible()).toBe(true);
expect(findCaretIcon().props('name')).toBe('angle-down'); expect(findCaretIcon().props('name')).toBe('angle-down');
});
}); });
}); });
...@@ -77,12 +76,11 @@ describe('Graph group component', () => { ...@@ -77,12 +76,11 @@ describe('Graph group component', () => {
expect(findCaretIcon().props('name')).toBe('angle-right'); expect(findCaretIcon().props('name')).toBe('angle-right');
}); });
it('should show the angle-right caret icon when collapseGroup is false', () => { it('should show the angle-right caret icon when collapseGroup is false', async () => {
findToggleButton().trigger('click'); findToggleButton().trigger('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findCaretIcon().props('name')).toBe('angle-down'); expect(findCaretIcon().props('name')).toBe('angle-down');
});
}); });
it('should call collapse the graph group content when enter is pressed on the caret icon', () => { it('should call collapse the graph group content when enter is pressed on the caret icon', () => {
...@@ -137,15 +135,14 @@ describe('Graph group component', () => { ...@@ -137,15 +135,14 @@ describe('Graph group component', () => {
expect(findCaretIcon().exists()).toBe(false); expect(findCaretIcon().exists()).toBe(false);
}); });
it('should show the panel content when collapse is set to false', () => { it('should show the panel content when collapse is set to false', async () => {
wrapper.setProps({ wrapper.setProps({
collapseGroup: false, collapseGroup: false,
}); });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findContent().isVisible()).toBe(true); expect(findContent().isVisible()).toBe(true);
expect(findCaretIcon().exists()).toBe(false); expect(findCaretIcon().exists()).toBe(false);
});
}); });
}); });
}); });
...@@ -36,7 +36,7 @@ describe('Links Section component', () => { ...@@ -36,7 +36,7 @@ describe('Links Section component', () => {
expect(findLinks().length).toBe(0); expect(findLinks().length).toBe(0);
}); });
it('renders a link inside a section', () => { it('renders a link inside a section', async () => {
setState([ setState([
{ {
title: 'GitLab Website', title: 'GitLab Website',
...@@ -44,23 +44,21 @@ describe('Links Section component', () => { ...@@ -44,23 +44,21 @@ describe('Links Section component', () => {
}, },
]); ]);
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findLinks()).toHaveLength(1); expect(findLinks()).toHaveLength(1);
const firstLink = findLinks().at(0); const firstLink = findLinks().at(0);
expect(firstLink.attributes('href')).toBe('https://gitlab.com'); expect(firstLink.attributes('href')).toBe('https://gitlab.com');
expect(firstLink.text()).toBe('GitLab Website'); expect(firstLink.text()).toBe('GitLab Website');
});
}); });
it('renders multiple links inside a section', () => { it('renders multiple links inside a section', async () => {
const links = new Array(10) const links = new Array(10)
.fill(null) .fill(null)
.map((_, i) => ({ title: `Title ${i}`, url: `https://gitlab.com/projects/${i}` })); .map((_, i) => ({ title: `Title ${i}`, url: `https://gitlab.com/projects/${i}` }));
setState(links); setState(links);
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findLinks()).toHaveLength(10); expect(findLinks()).toHaveLength(10);
});
}); });
}); });
import { GlDropdown, GlDropdownItem, GlButton } from '@gitlab/ui'; import { GlDropdown, GlDropdownItem, GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import Visibility from 'visibilityjs'; import Visibility from 'visibilityjs';
import { nextTick } from 'vue';
import RefreshButton from '~/monitoring/components/refresh_button.vue'; import RefreshButton from '~/monitoring/components/refresh_button.vue';
import { createStore } from '~/monitoring/stores'; import { createStore } from '~/monitoring/stores';
...@@ -79,9 +80,9 @@ describe('RefreshButton', () => { ...@@ -79,9 +80,9 @@ describe('RefreshButton', () => {
describe('when a refresh rate is chosen', () => { describe('when a refresh rate is chosen', () => {
const optIndex = 2; // Other option than "Off" const optIndex = 2; // Other option than "Off"
beforeEach(() => { beforeEach(async () => {
findOptionAt(optIndex).vm.$emit('click'); findOptionAt(optIndex).vm.$emit('click');
return wrapper.vm.$nextTick; await nextTick();
}); });
it('refresh rate appears in the dropdown', () => { it('refresh rate appears in the dropdown', () => {
...@@ -101,7 +102,7 @@ describe('RefreshButton', () => { ...@@ -101,7 +102,7 @@ describe('RefreshButton', () => {
jest.runOnlyPendingTimers(); jest.runOnlyPendingTimers();
expectFetchDataToHaveBeenCalledTimes(2); expectFetchDataToHaveBeenCalledTimes(2);
await wrapper.vm.$nextTick(); await nextTick();
jest.runOnlyPendingTimers(); jest.runOnlyPendingTimers();
expectFetchDataToHaveBeenCalledTimes(3); expectFetchDataToHaveBeenCalledTimes(3);
...@@ -113,7 +114,7 @@ describe('RefreshButton', () => { ...@@ -113,7 +114,7 @@ describe('RefreshButton', () => {
jest.runOnlyPendingTimers(); jest.runOnlyPendingTimers();
expectFetchDataToHaveBeenCalledTimes(1); expectFetchDataToHaveBeenCalledTimes(1);
await wrapper.vm.$nextTick(); await nextTick();
jest.runOnlyPendingTimers(); jest.runOnlyPendingTimers();
expectFetchDataToHaveBeenCalledTimes(1); expectFetchDataToHaveBeenCalledTimes(1);
...@@ -128,9 +129,9 @@ describe('RefreshButton', () => { ...@@ -128,9 +129,9 @@ describe('RefreshButton', () => {
}); });
describe('when "Off" refresh rate is chosen', () => { describe('when "Off" refresh rate is chosen', () => {
beforeEach(() => { beforeEach(async () => {
findOptionAt(0).vm.$emit('click'); findOptionAt(0).vm.$emit('click');
return wrapper.vm.$nextTick; await nextTick();
}); });
it('refresh rate is "Off" in the dropdown', () => { it('refresh rate is "Off" in the dropdown', () => {
......
import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DropdownField from '~/monitoring/components/variables/dropdown_field.vue'; import DropdownField from '~/monitoring/components/variables/dropdown_field.vue';
describe('Custom variable component', () => { describe('Custom variable component', () => {
...@@ -53,14 +54,13 @@ describe('Custom variable component', () => { ...@@ -53,14 +54,13 @@ describe('Custom variable component', () => {
expect(findDropdown().exists()).toBe(true); expect(findDropdown().exists()).toBe(true);
}); });
it('changing dropdown items triggers update', () => { it('changing dropdown items triggers update', async () => {
createShallowWrapper(); createShallowWrapper();
jest.spyOn(wrapper.vm, '$emit'); jest.spyOn(wrapper.vm, '$emit');
findDropdownItems().at(1).vm.$emit('click'); findDropdownItems().at(1).vm.$emit('click');
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', 'canary'); expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', 'canary');
});
}); });
}); });
import { GlFormInput } from '@gitlab/ui'; import { GlFormInput } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import TextField from '~/monitoring/components/variables/text_field.vue'; import TextField from '~/monitoring/components/variables/text_field.vue';
describe('Text variable component', () => { describe('Text variable component', () => {
...@@ -23,15 +24,14 @@ describe('Text variable component', () => { ...@@ -23,15 +24,14 @@ describe('Text variable component', () => {
expect(findInput().exists()).toBe(true); expect(findInput().exists()).toBe(true);
}); });
it('always has a default value', () => { it('always has a default value', async () => {
createShallowWrapper(); createShallowWrapper();
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findInput().attributes('value')).toBe(propsData.value); expect(findInput().attributes('value')).toBe(propsData.value);
});
}); });
it('triggers keyup enter', () => { it('triggers keyup enter', async () => {
createShallowWrapper(); createShallowWrapper();
jest.spyOn(wrapper.vm, '$emit'); jest.spyOn(wrapper.vm, '$emit');
...@@ -39,12 +39,11 @@ describe('Text variable component', () => { ...@@ -39,12 +39,11 @@ describe('Text variable component', () => {
findInput().trigger('input'); findInput().trigger('input');
findInput().trigger('keyup.enter'); findInput().trigger('keyup.enter');
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', 'prod-pod'); expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', 'prod-pod');
});
}); });
it('triggers blur enter', () => { it('triggers blur enter', async () => {
createShallowWrapper(); createShallowWrapper();
jest.spyOn(wrapper.vm, '$emit'); jest.spyOn(wrapper.vm, '$emit');
...@@ -52,8 +51,7 @@ describe('Text variable component', () => { ...@@ -52,8 +51,7 @@ describe('Text variable component', () => {
findInput().trigger('input'); findInput().trigger('input');
findInput().trigger('blur'); findInput().trigger('blur');
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', 'canary-pod'); expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', 'canary-pod');
});
}); });
}); });
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { nextTick } from 'vue';
import { updateHistory, mergeUrlParams } from '~/lib/utils/url_utility'; import { updateHistory, mergeUrlParams } from '~/lib/utils/url_utility';
import DropdownField from '~/monitoring/components/variables/dropdown_field.vue'; import DropdownField from '~/monitoring/components/variables/dropdown_field.vue';
import TextField from '~/monitoring/components/variables/text_field.vue'; import TextField from '~/monitoring/components/variables/text_field.vue';
...@@ -40,11 +41,11 @@ describe('Metrics dashboard/variables section component', () => { ...@@ -40,11 +41,11 @@ describe('Metrics dashboard/variables section component', () => {
}); });
describe('when variables are set', () => { describe('when variables are set', () => {
beforeEach(() => { beforeEach(async () => {
store.state.monitoringDashboard.variables = storeVariables; store.state.monitoringDashboard.variables = storeVariables;
createShallowWrapper(); createShallowWrapper();
return wrapper.vm.$nextTick; await nextTick();
}); });
it('shows the variables section', () => { it('shows the variables section', () => {
...@@ -83,34 +84,32 @@ describe('Metrics dashboard/variables section component', () => { ...@@ -83,34 +84,32 @@ describe('Metrics dashboard/variables section component', () => {
createShallowWrapper(); createShallowWrapper();
}); });
it('merges the url params and refreshes the dashboard when a text-based variables inputs are updated', () => { it('merges the url params and refreshes the dashboard when a text-based variables inputs are updated', async () => {
const firstInput = findTextInputs().at(0); const firstInput = findTextInputs().at(0);
firstInput.vm.$emit('input', 'test'); firstInput.vm.$emit('input', 'test');
return wrapper.vm.$nextTick(() => { await nextTick();
expect(updateVariablesAndFetchData).toHaveBeenCalled(); expect(updateVariablesAndFetchData).toHaveBeenCalled();
expect(mergeUrlParams).toHaveBeenCalledWith( expect(mergeUrlParams).toHaveBeenCalledWith(
convertVariablesForURL(storeVariables), convertVariablesForURL(storeVariables),
window.location.href, window.location.href,
); );
expect(updateHistory).toHaveBeenCalled(); expect(updateHistory).toHaveBeenCalled();
});
}); });
it('merges the url params and refreshes the dashboard when a custom-based variables inputs are updated', () => { it('merges the url params and refreshes the dashboard when a custom-based variables inputs are updated', async () => {
const firstInput = findCustomInputs().at(0); const firstInput = findCustomInputs().at(0);
firstInput.vm.$emit('input', 'test'); firstInput.vm.$emit('input', 'test');
return wrapper.vm.$nextTick(() => { await nextTick();
expect(updateVariablesAndFetchData).toHaveBeenCalled(); expect(updateVariablesAndFetchData).toHaveBeenCalled();
expect(mergeUrlParams).toHaveBeenCalledWith( expect(mergeUrlParams).toHaveBeenCalledWith(
convertVariablesForURL(storeVariables), convertVariablesForURL(storeVariables),
window.location.href, window.location.href,
); );
expect(updateHistory).toHaveBeenCalled(); expect(updateHistory).toHaveBeenCalled();
});
}); });
it('does not merge the url params and refreshes the dashboard if the value entered is not different that is what currently stored', () => { it('does not merge the url params and refreshes the dashboard if the value entered is not different that is what currently stored', () => {
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import MRPopover from '~/mr_popover/components/mr_popover.vue'; import MRPopover from '~/mr_popover/components/mr_popover.vue';
import CiIcon from '~/vue_shared/components/ci_icon.vue'; import CiIcon from '~/vue_shared/components/ci_icon.vue';
...@@ -25,16 +26,15 @@ describe('MR Popover', () => { ...@@ -25,16 +26,15 @@ describe('MR Popover', () => {
}); });
}); });
it('shows skeleton-loader while apollo is loading', () => { it('shows skeleton-loader while apollo is loading', async () => {
wrapper.vm.$apollo.queries.mergeRequest.loading = true; wrapper.vm.$apollo.queries.mergeRequest.loading = true;
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.element).toMatchSnapshot(); expect(wrapper.element).toMatchSnapshot();
});
}); });
describe('loaded state', () => { describe('loaded state', () => {
it('matches the snapshot', () => { it('matches the snapshot', async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ wrapper.setData({
...@@ -51,12 +51,11 @@ describe('MR Popover', () => { ...@@ -51,12 +51,11 @@ describe('MR Popover', () => {
}, },
}); });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.element).toMatchSnapshot(); expect(wrapper.element).toMatchSnapshot();
});
}); });
it('does not show CI Icon if there is no pipeline data', () => { it('does not show CI Icon if there is no pipeline data', async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ wrapper.setData({
...@@ -69,15 +68,13 @@ describe('MR Popover', () => { ...@@ -69,15 +68,13 @@ describe('MR Popover', () => {
}, },
}); });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.find(CiIcon).exists()).toBe(false); expect(wrapper.find(CiIcon).exists()).toBe(false);
});
}); });
it('falls back to cached MR title when request fails', () => { it('falls back to cached MR title when request fails', async () => {
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.text()).toContain('MR Title'); expect(wrapper.text()).toContain('MR Title');
});
}); });
}); });
}); });
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import ResponsiveApp from '~/nav/components/responsive_app.vue'; import ResponsiveApp from '~/nav/components/responsive_app.vue';
import ResponsiveHeader from '~/nav/components/responsive_header.vue'; import ResponsiveHeader from '~/nav/components/responsive_header.vue';
import ResponsiveHome from '~/nav/components/responsive_home.vue'; import ResponsiveHome from '~/nav/components/responsive_home.vue';
...@@ -62,7 +63,7 @@ describe('~/nav/components/responsive_app.vue', () => { ...@@ -62,7 +63,7 @@ describe('~/nav/components/responsive_app.vue', () => {
wrapper.vm.$root.$emit(evt); wrapper.vm.$root.$emit(evt);
await wrapper.vm.$nextTick(); await nextTick();
}, Promise.resolve()); }, Promise.resolve());
expect(hasMobileOverlayVisible()).toBe(expectation); expect(hasMobileOverlayVisible()).toBe(expectation);
...@@ -97,7 +98,7 @@ describe('~/nav/components/responsive_app.vue', () => { ...@@ -97,7 +98,7 @@ describe('~/nav/components/responsive_app.vue', () => {
findHome().vm.$emit('menu-item-click', { view }); findHome().vm.$emit('menu-item-click', { view });
await wrapper.vm.$nextTick(); await nextTick();
}); });
it('shows header', () => { it('shows header', () => {
......
...@@ -466,8 +466,8 @@ describe('issue_comment_form component', () => { ...@@ -466,8 +466,8 @@ describe('issue_comment_form component', () => {
await findCloseReopenButton().trigger('click'); await findCloseReopenButton().trigger('click');
await wrapper.vm.$nextTick; await nextTick;
await wrapper.vm.$nextTick; await nextTick;
expect(createFlash).toHaveBeenCalledWith({ expect(createFlash).toHaveBeenCalledWith({
message: `Something went wrong while closing the ${type}. Please try again later.`, message: `Something went wrong while closing the ${type}. Please try again later.`,
...@@ -502,8 +502,8 @@ describe('issue_comment_form component', () => { ...@@ -502,8 +502,8 @@ describe('issue_comment_form component', () => {
await findCloseReopenButton().trigger('click'); await findCloseReopenButton().trigger('click');
await wrapper.vm.$nextTick; await nextTick;
await wrapper.vm.$nextTick; await nextTick;
expect(createFlash).toHaveBeenCalledWith({ expect(createFlash).toHaveBeenCalledWith({
message: `Something went wrong while reopening the ${type}. Please try again later.`, message: `Something went wrong while reopening the ${type}. Please try again later.`,
...@@ -521,7 +521,7 @@ describe('issue_comment_form component', () => { ...@@ -521,7 +521,7 @@ describe('issue_comment_form component', () => {
await findCloseReopenButton().trigger('click'); await findCloseReopenButton().trigger('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(refreshUserMergeRequestCounts).toHaveBeenCalled(); expect(refreshUserMergeRequestCounts).toHaveBeenCalled();
}); });
...@@ -581,7 +581,7 @@ describe('issue_comment_form component', () => { ...@@ -581,7 +581,7 @@ describe('issue_comment_form component', () => {
// check checkbox // check checkbox
checkbox.element.checked = shouldCheckboxBeChecked; checkbox.element.checked = shouldCheckboxBeChecked;
checkbox.trigger('change'); checkbox.trigger('change');
await wrapper.vm.$nextTick(); await nextTick();
// submit comment // submit comment
findCommentButton().trigger('click'); findCommentButton().trigger('click');
......
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import diffDiscussionHeader from '~/notes/components/diff_discussion_header.vue'; import diffDiscussionHeader from '~/notes/components/diff_discussion_header.vue';
import createStore from '~/notes/stores'; import createStore from '~/notes/stores';
...@@ -24,16 +25,15 @@ describe('diff_discussion_header component', () => { ...@@ -24,16 +25,15 @@ describe('diff_discussion_header component', () => {
wrapper.destroy(); wrapper.destroy();
}); });
it('should render user avatar', () => { it('should render user avatar', async () => {
const discussion = { ...discussionMock }; const discussion = { ...discussionMock };
discussion.diff_file = mockDiffFile; discussion.diff_file = mockDiffFile;
discussion.diff_discussion = true; discussion.diff_discussion = true;
wrapper.setProps({ discussion }); wrapper.setProps({ discussion });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.find('.user-avatar-link').exists()).toBe(true); expect(wrapper.find('.user-avatar-link').exists()).toBe(true);
});
}); });
describe('action text', () => { describe('action text', () => {
...@@ -41,7 +41,7 @@ describe('diff_discussion_header component', () => { ...@@ -41,7 +41,7 @@ describe('diff_discussion_header component', () => {
const truncatedCommitId = commitId.substr(0, 8); const truncatedCommitId = commitId.substr(0, 8);
let commitElement; let commitElement;
beforeEach((done) => { beforeEach(async () => {
store.state.diffs = { store.state.diffs = {
projectPath: 'something', projectPath: 'something',
}; };
...@@ -58,41 +58,30 @@ describe('diff_discussion_header component', () => { ...@@ -58,41 +58,30 @@ describe('diff_discussion_header component', () => {
}, },
}); });
wrapper.vm await nextTick();
.$nextTick() commitElement = wrapper.find('.commit-sha');
.then(() => {
commitElement = wrapper.find('.commit-sha');
})
.then(done)
.catch(done.fail);
}); });
describe('for diff threads without a commit id', () => { describe('for diff threads without a commit id', () => {
it('should show started a thread on the diff text', (done) => { it('should show started a thread on the diff text', async () => {
Object.assign(wrapper.vm.discussion, { Object.assign(wrapper.vm.discussion, {
for_commit: false, for_commit: false,
commit_id: null, commit_id: null,
}); });
wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.text()).toContain('started a thread on the diff'); expect(wrapper.text()).toContain('started a thread on the diff');
done();
});
}); });
it('should show thread on older version text', (done) => { it('should show thread on older version text', async () => {
Object.assign(wrapper.vm.discussion, { Object.assign(wrapper.vm.discussion, {
for_commit: false, for_commit: false,
commit_id: null, commit_id: null,
active: false, active: false,
}); });
wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.text()).toContain('started a thread on an old version of the diff'); expect(wrapper.text()).toContain('started a thread on an old version of the diff');
done();
});
}); });
}); });
...@@ -105,31 +94,25 @@ describe('diff_discussion_header component', () => { ...@@ -105,31 +94,25 @@ describe('diff_discussion_header component', () => {
}); });
describe('for diff thread with a commit id', () => { describe('for diff thread with a commit id', () => {
it('should display started thread on commit header', (done) => { it('should display started thread on commit header', async () => {
wrapper.vm.discussion.for_commit = false; wrapper.vm.discussion.for_commit = false;
wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.text()).toContain(`started a thread on commit ${truncatedCommitId}`); expect(wrapper.text()).toContain(`started a thread on commit ${truncatedCommitId}`);
expect(commitElement).not.toBe(null);
done(); expect(commitElement).not.toBe(null);
});
}); });
it('should display outdated change on commit header', (done) => { it('should display outdated change on commit header', async () => {
wrapper.vm.discussion.for_commit = false; wrapper.vm.discussion.for_commit = false;
wrapper.vm.discussion.active = false; wrapper.vm.discussion.active = false;
wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.text()).toContain( expect(wrapper.text()).toContain(
`started a thread on an outdated change in commit ${truncatedCommitId}`, `started a thread on an outdated change in commit ${truncatedCommitId}`,
); );
expect(commitElement).not.toBe(null); expect(commitElement).not.toBe(null);
done();
});
}); });
}); });
}); });
......
import { GlButton } from '@gitlab/ui'; import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import Vue from 'vue'; import Vue, { nextTick } from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import DiscussionCounter from '~/notes/components/discussion_counter.vue'; import DiscussionCounter from '~/notes/components/discussion_counter.vue';
import notesModule from '~/notes/stores/modules'; import notesModule from '~/notes/stores/modules';
...@@ -113,7 +113,7 @@ describe('DiscussionCounter component', () => { ...@@ -113,7 +113,7 @@ describe('DiscussionCounter component', () => {
expect(setExpandDiscussionsFn).toHaveBeenCalledTimes(1); expect(setExpandDiscussionsFn).toHaveBeenCalledTimes(1);
}); });
it('collapses all discussions if expanded', () => { it('collapses all discussions if expanded', async () => {
updateStoreWithExpanded(true); updateStoreWithExpanded(true);
expect(wrapper.vm.allExpanded).toBe(true); expect(wrapper.vm.allExpanded).toBe(true);
...@@ -121,13 +121,12 @@ describe('DiscussionCounter component', () => { ...@@ -121,13 +121,12 @@ describe('DiscussionCounter component', () => {
toggleAllButton.vm.$emit('click'); toggleAllButton.vm.$emit('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.vm.allExpanded).toBe(false); expect(wrapper.vm.allExpanded).toBe(false);
expect(toggleAllButton.props('icon')).toBe('angle-down'); expect(toggleAllButton.props('icon')).toBe('angle-down');
});
}); });
it('expands all discussions if collapsed', () => { it('expands all discussions if collapsed', async () => {
updateStoreWithExpanded(false); updateStoreWithExpanded(false);
expect(wrapper.vm.allExpanded).toBe(false); expect(wrapper.vm.allExpanded).toBe(false);
...@@ -135,10 +134,9 @@ describe('DiscussionCounter component', () => { ...@@ -135,10 +134,9 @@ describe('DiscussionCounter component', () => {
toggleAllButton.vm.$emit('click'); toggleAllButton.vm.$emit('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.vm.allExpanded).toBe(true); expect(wrapper.vm.allExpanded).toBe(true);
expect(toggleAllButton.props('icon')).toBe('angle-up'); expect(toggleAllButton.props('icon')).toBe('angle-up');
});
}); });
}); });
}); });
import { GlDropdown } from '@gitlab/ui'; import { GlDropdown } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import Vue from 'vue'; import Vue, { nextTick } from 'vue';
import AxiosMockAdapter from 'axios-mock-adapter'; import AxiosMockAdapter from 'axios-mock-adapter';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
...@@ -151,13 +151,11 @@ describe('DiscussionFilter component', () => { ...@@ -151,13 +151,11 @@ describe('DiscussionFilter component', () => {
window.mrTabs = undefined; window.mrTabs = undefined;
}); });
it('only renders when discussion tab is active', (done) => { it('only renders when discussion tab is active', async () => {
eventHub.$emit('MergeRequestTabChange', 'commit'); eventHub.$emit('MergeRequestTabChange', 'commit');
wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.html()).toBe(''); expect(wrapper.html()).toBe('');
done();
});
}); });
}); });
...@@ -166,58 +164,48 @@ describe('DiscussionFilter component', () => { ...@@ -166,58 +164,48 @@ describe('DiscussionFilter component', () => {
window.location.hash = ''; window.location.hash = '';
}); });
it('updates the filter when the URL links to a note', (done) => { it('updates the filter when the URL links to a note', async () => {
window.location.hash = `note_${discussionMock.notes[0].id}`; window.location.hash = `note_${discussionMock.notes[0].id}`;
wrapper.vm.currentValue = discussionFiltersMock[2].value; wrapper.vm.currentValue = discussionFiltersMock[2].value;
wrapper.vm.handleLocationHash(); wrapper.vm.handleLocationHash();
wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.vm.currentValue).toBe(DISCUSSION_FILTERS_DEFAULT_VALUE); expect(wrapper.vm.currentValue).toBe(DISCUSSION_FILTERS_DEFAULT_VALUE);
done();
});
}); });
it('does not update the filter when the current filter is "Show all activity"', (done) => { it('does not update the filter when the current filter is "Show all activity"', async () => {
window.location.hash = `note_${discussionMock.notes[0].id}`; window.location.hash = `note_${discussionMock.notes[0].id}`;
wrapper.vm.handleLocationHash(); wrapper.vm.handleLocationHash();
wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.vm.currentValue).toBe(DISCUSSION_FILTERS_DEFAULT_VALUE); expect(wrapper.vm.currentValue).toBe(DISCUSSION_FILTERS_DEFAULT_VALUE);
done();
});
}); });
it('only updates filter when the URL links to a note', (done) => { it('only updates filter when the URL links to a note', async () => {
window.location.hash = `testing123`; window.location.hash = `testing123`;
wrapper.vm.handleLocationHash(); wrapper.vm.handleLocationHash();
wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.vm.currentValue).toBe(DISCUSSION_FILTERS_DEFAULT_VALUE); expect(wrapper.vm.currentValue).toBe(DISCUSSION_FILTERS_DEFAULT_VALUE);
done();
});
}); });
it('fetches discussions when there is a hash', (done) => { it('fetches discussions when there is a hash', async () => {
window.location.hash = `note_${discussionMock.notes[0].id}`; window.location.hash = `note_${discussionMock.notes[0].id}`;
wrapper.vm.currentValue = discussionFiltersMock[2].value; wrapper.vm.currentValue = discussionFiltersMock[2].value;
jest.spyOn(wrapper.vm, 'selectFilter').mockImplementation(() => {}); jest.spyOn(wrapper.vm, 'selectFilter').mockImplementation(() => {});
wrapper.vm.handleLocationHash(); wrapper.vm.handleLocationHash();
wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.vm.selectFilter).toHaveBeenCalled(); expect(wrapper.vm.selectFilter).toHaveBeenCalled();
done();
});
}); });
it('does not fetch discussions when there is no hash', (done) => { it('does not fetch discussions when there is no hash', async () => {
window.location.hash = ''; window.location.hash = '';
jest.spyOn(wrapper.vm, 'selectFilter').mockImplementation(() => {}); jest.spyOn(wrapper.vm, 'selectFilter').mockImplementation(() => {});
wrapper.vm.handleLocationHash(); wrapper.vm.handleLocationHash();
wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.vm.selectFilter).not.toHaveBeenCalled(); expect(wrapper.vm.selectFilter).not.toHaveBeenCalled();
done();
});
}); });
}); });
}); });
import { getByRole } from '@testing-library/dom'; import { getByRole } from '@testing-library/dom';
import { shallowMount, mount } from '@vue/test-utils'; import { shallowMount, mount } from '@vue/test-utils';
import '~/behaviors/markdown/render_gfm'; import '~/behaviors/markdown/render_gfm';
import { nextTick } from 'vue';
import DiscussionNotes from '~/notes/components/discussion_notes.vue'; import DiscussionNotes from '~/notes/components/discussion_notes.vue';
import NoteableNote from '~/notes/components/noteable_note.vue'; import NoteableNote from '~/notes/components/noteable_note.vue';
import { SYSTEM_NOTE } from '~/notes/constants'; import { SYSTEM_NOTE } from '~/notes/constants';
...@@ -135,28 +136,25 @@ describe('DiscussionNotes', () => { ...@@ -135,28 +136,25 @@ describe('DiscussionNotes', () => {
createComponent({ shouldGroupReplies: true, isExpanded: true }); createComponent({ shouldGroupReplies: true, isExpanded: true });
}); });
it('emits deleteNote when first note emits handleDeleteNote', () => { it('emits deleteNote when first note emits handleDeleteNote', async () => {
findNoteAtIndex(0).vm.$emit('handleDeleteNote'); findNoteAtIndex(0).vm.$emit('handleDeleteNote');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted().deleteNote).toBeTruthy(); expect(wrapper.emitted().deleteNote).toBeTruthy();
});
}); });
it('emits startReplying when first note emits startReplying', () => { it('emits startReplying when first note emits startReplying', async () => {
findNoteAtIndex(0).vm.$emit('startReplying'); findNoteAtIndex(0).vm.$emit('startReplying');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted().startReplying).toBeTruthy(); expect(wrapper.emitted().startReplying).toBeTruthy();
});
}); });
it('emits deleteNote when second note emits handleDeleteNote', () => { it('emits deleteNote when second note emits handleDeleteNote', async () => {
findNoteAtIndex(1).vm.$emit('handleDeleteNote'); findNoteAtIndex(1).vm.$emit('handleDeleteNote');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted().deleteNote).toBeTruthy(); expect(wrapper.emitted().deleteNote).toBeTruthy();
});
}); });
}); });
...@@ -167,12 +165,11 @@ describe('DiscussionNotes', () => { ...@@ -167,12 +165,11 @@ describe('DiscussionNotes', () => {
note = wrapper.find('.notes > *'); note = wrapper.find('.notes > *');
}); });
it('emits deleteNote when first note emits handleDeleteNote', () => { it('emits deleteNote when first note emits handleDeleteNote', async () => {
note.vm.$emit('handleDeleteNote'); note.vm.$emit('handleDeleteNote');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted().deleteNote).toBeTruthy(); expect(wrapper.emitted().deleteNote).toBeTruthy();
});
}); });
}); });
}); });
......
import { GlButton } from '@gitlab/ui'; import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import resolveDiscussionButton from '~/notes/components/discussion_resolve_button.vue'; import resolveDiscussionButton from '~/notes/components/discussion_resolve_button.vue';
const buttonTitle = 'Resolve discussion'; const buttonTitle = 'Resolve discussion';
...@@ -26,15 +27,14 @@ describe('resolveDiscussionButton', () => { ...@@ -26,15 +27,14 @@ describe('resolveDiscussionButton', () => {
wrapper.destroy(); wrapper.destroy();
}); });
it('should emit a onClick event on button click', () => { it('should emit a onClick event on button click', async () => {
const button = wrapper.find(GlButton); const button = wrapper.find(GlButton);
button.vm.$emit('click'); button.vm.$emit('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted()).toEqual({ expect(wrapper.emitted()).toEqual({
onClick: [[]], onClick: [[]],
});
}); });
}); });
...@@ -57,7 +57,7 @@ describe('resolveDiscussionButton', () => { ...@@ -57,7 +57,7 @@ describe('resolveDiscussionButton', () => {
expect(button.props('loading')).toEqual(true); expect(button.props('loading')).toEqual(true);
}); });
it('should only show a loading spinner while resolving', () => { it('should only show a loading spinner while resolving', async () => {
factory({ factory({
propsData: { propsData: {
isResolving: false, isResolving: false,
...@@ -67,8 +67,7 @@ describe('resolveDiscussionButton', () => { ...@@ -67,8 +67,7 @@ describe('resolveDiscussionButton', () => {
const button = wrapper.find(GlButton); const button = wrapper.find(GlButton);
wrapper.vm.$nextTick(() => { await nextTick();
expect(button.props('loading')).toEqual(false); expect(button.props('loading')).toEqual(false);
});
}); });
}); });
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import Vue from 'vue'; import Vue, { nextTick } from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
...@@ -107,11 +107,11 @@ describe('issue_note', () => { ...@@ -107,11 +107,11 @@ describe('issue_note', () => {
line, line,
}); });
await wrapper.vm.$nextTick(); await nextTick();
expect(findMultilineComment().text()).toBe('Comment on lines 1 to 2'); expect(findMultilineComment().text()).toBe('Comment on lines 1 to 2');
}); });
it('should only render if it has everything it needs', () => { it('should only render if it has everything it needs', async () => {
const position = { const position = {
line_range: { line_range: {
start: { start: {
...@@ -140,12 +140,11 @@ describe('issue_note', () => { ...@@ -140,12 +140,11 @@ describe('issue_note', () => {
line, line,
}); });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findMultilineComment().exists()).toBe(false); expect(findMultilineComment().exists()).toBe(false);
});
}); });
it('should not render if has single line comment', () => { it('should not render if has single line comment', async () => {
const position = { const position = {
line_range: { line_range: {
start: { start: {
...@@ -174,9 +173,8 @@ describe('issue_note', () => { ...@@ -174,9 +173,8 @@ describe('issue_note', () => {
line, line,
}); });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findMultilineComment().exists()).toBe(false); expect(findMultilineComment().exists()).toBe(false);
});
}); });
it('should not render if `line_range` is unavailable', () => { it('should not render if `line_range` is unavailable', () => {
...@@ -204,7 +202,7 @@ describe('issue_note', () => { ...@@ -204,7 +202,7 @@ describe('issue_note', () => {
line, line,
}); });
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.findComponent(UserAvatarLink).props('imgSize')).toBe(24); expect(wrapper.findComponent(UserAvatarLink).props('imgSize')).toBe(24);
}); });
...@@ -318,13 +316,13 @@ describe('issue_note', () => { ...@@ -318,13 +316,13 @@ describe('issue_note', () => {
callback: () => {}, callback: () => {},
}); });
await wrapper.vm.$nextTick(); await nextTick();
let noteBodyProps = noteBody.props(); let noteBodyProps = noteBody.props();
expect(noteBodyProps.note.note_html).toBe(`<p>${updatedText}</p>\n`); expect(noteBodyProps.note.note_html).toBe(`<p>${updatedText}</p>\n`);
noteBody.vm.$emit('cancelForm', {}); noteBody.vm.$emit('cancelForm', {});
await wrapper.vm.$nextTick(); await nextTick();
noteBodyProps = noteBody.props(); noteBodyProps = noteBody.props();
......
import { GlButton } from '@gitlab/ui'; import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import Vue from 'vue'; import Vue, { nextTick } from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import TimelineToggle, { import TimelineToggle, {
timelineEnabledTooltip, timelineEnabledTooltip,
...@@ -64,7 +64,7 @@ describe('Timeline toggle', () => { ...@@ -64,7 +64,7 @@ describe('Timeline toggle', () => {
it('should set correct UI state', async () => { it('should set correct UI state', async () => {
store.state.isTimelineEnabled = true; store.state.isTimelineEnabled = true;
findGlButton().vm.$emit('click', mockEvent); findGlButton().vm.$emit('click', mockEvent);
await wrapper.vm.$nextTick(); await nextTick();
expect(findGlButton().attributes('title')).toBe(timelineEnabledTooltip); expect(findGlButton().attributes('title')).toBe(timelineEnabledTooltip);
expect(findGlButton().attributes('selected')).toBe('true'); expect(findGlButton().attributes('selected')).toBe('true');
expect(mockEvent.currentTarget.blur).toHaveBeenCalled(); expect(mockEvent.currentTarget.blur).toHaveBeenCalled();
...@@ -72,7 +72,7 @@ describe('Timeline toggle', () => { ...@@ -72,7 +72,7 @@ describe('Timeline toggle', () => {
it('should track Snowplow event', async () => { it('should track Snowplow event', async () => {
store.state.isTimelineEnabled = true; store.state.isTimelineEnabled = true;
await wrapper.vm.$nextTick(); await nextTick();
findGlButton().trigger('click'); findGlButton().trigger('click');
...@@ -97,7 +97,7 @@ describe('Timeline toggle', () => { ...@@ -97,7 +97,7 @@ describe('Timeline toggle', () => {
it('should set correct UI state', async () => { it('should set correct UI state', async () => {
store.state.isTimelineEnabled = false; store.state.isTimelineEnabled = false;
findGlButton().vm.$emit('click', mockEvent); findGlButton().vm.$emit('click', mockEvent);
await wrapper.vm.$nextTick(); await nextTick();
expect(findGlButton().attributes('title')).toBe(timelineDisabledTooltip); expect(findGlButton().attributes('title')).toBe(timelineDisabledTooltip);
expect(findGlButton().attributes('selected')).toBe(undefined); expect(findGlButton().attributes('selected')).toBe(undefined);
expect(mockEvent.currentTarget.blur).toHaveBeenCalled(); expect(mockEvent.currentTarget.blur).toHaveBeenCalled();
...@@ -105,7 +105,7 @@ describe('Timeline toggle', () => { ...@@ -105,7 +105,7 @@ describe('Timeline toggle', () => {
it('should track Snowplow event', async () => { it('should track Snowplow event', async () => {
store.state.isTimelineEnabled = false; store.state.isTimelineEnabled = false;
await wrapper.vm.$nextTick(); await nextTick();
findGlButton().trigger('click'); findGlButton().trigger('click');
......
...@@ -93,14 +93,13 @@ describe('Discussion navigation mixin', () => { ...@@ -93,14 +93,13 @@ describe('Discussion navigation mixin', () => {
expect(store.dispatch).toHaveBeenCalledWith('setCurrentDiscussionId', null); expect(store.dispatch).toHaveBeenCalledWith('setCurrentDiscussionId', null);
}); });
it('triggers the jumpToNextDiscussion action when the previous store action succeeds', () => { it('triggers the jumpToNextDiscussion action when the previous store action succeeds', async () => {
store.dispatch.mockResolvedValue(); store.dispatch.mockResolvedValue();
vm.jumpToFirstUnresolvedDiscussion(); vm.jumpToFirstUnresolvedDiscussion();
return vm.$nextTick().then(() => { await nextTick();
expect(vm.jumpToNextDiscussion).toHaveBeenCalled(); expect(vm.jumpToNextDiscussion).toHaveBeenCalled();
});
}); });
}); });
...@@ -126,11 +125,11 @@ describe('Discussion navigation mixin', () => { ...@@ -126,11 +125,11 @@ describe('Discussion navigation mixin', () => {
}); });
describe('on `show` active tab', () => { describe('on `show` active tab', () => {
beforeEach(() => { beforeEach(async () => {
window.mrTabs.currentAction = 'show'; window.mrTabs.currentAction = 'show';
wrapper.vm[fn](...args); wrapper.vm[fn](...args);
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('sets current discussion', () => { it('sets current discussion', () => {
...@@ -150,11 +149,11 @@ describe('Discussion navigation mixin', () => { ...@@ -150,11 +149,11 @@ describe('Discussion navigation mixin', () => {
}); });
describe('on `diffs` active tab', () => { describe('on `diffs` active tab', () => {
beforeEach(() => { beforeEach(async () => {
window.mrTabs.currentAction = 'diffs'; window.mrTabs.currentAction = 'diffs';
wrapper.vm[fn](...args); wrapper.vm[fn](...args);
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('sets current discussion', () => { it('sets current discussion', () => {
...@@ -178,11 +177,11 @@ describe('Discussion navigation mixin', () => { ...@@ -178,11 +177,11 @@ describe('Discussion navigation mixin', () => {
}); });
describe('on `other` active tab', () => { describe('on `other` active tab', () => {
beforeEach(() => { beforeEach(async () => {
window.mrTabs.currentAction = 'other'; window.mrTabs.currentAction = 'other';
wrapper.vm[fn](...args); wrapper.vm[fn](...args);
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('sets current discussion', () => { it('sets current discussion', () => {
......
...@@ -2,6 +2,7 @@ import { GlSprintf, GlModal, GlFormGroup, GlFormCheckbox, GlLoadingIcon } from ' ...@@ -2,6 +2,7 @@ import { GlSprintf, GlModal, GlFormGroup, GlFormCheckbox, GlLoadingIcon } from '
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import axios from 'axios'; import axios from 'axios';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import httpStatus from '~/lib/utils/http_status'; import httpStatus from '~/lib/utils/http_status';
...@@ -97,7 +98,7 @@ describe('CustomNotificationsModal', () => { ...@@ -97,7 +98,7 @@ describe('CustomNotificationsModal', () => {
], ],
}); });
await wrapper.vm.$nextTick(); await nextTick();
}); });
it.each` it.each`
...@@ -222,7 +223,7 @@ describe('CustomNotificationsModal', () => { ...@@ -222,7 +223,7 @@ describe('CustomNotificationsModal', () => {
], ],
}); });
await wrapper.vm.$nextTick(); await nextTick();
findCheckboxAt(1).vm.$emit('change', true); findCheckboxAt(1).vm.$emit('change', true);
...@@ -252,7 +253,7 @@ describe('CustomNotificationsModal', () => { ...@@ -252,7 +253,7 @@ describe('CustomNotificationsModal', () => {
], ],
}); });
await wrapper.vm.$nextTick(); await nextTick();
findCheckboxAt(1).vm.$emit('change', true); findCheckboxAt(1).vm.$emit('change', true);
......
import { GlButton, GlLink, GlFormGroup, GlFormInput, GlFormSelect } from '@gitlab/ui'; import { GlButton, GlLink, GlFormGroup, GlFormInput, GlFormSelect } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils'; import { mount, shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
import createFlash from '~/flash'; import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
...@@ -181,17 +182,18 @@ describe('operation settings external dashboard component', () => { ...@@ -181,17 +182,18 @@ describe('operation settings external dashboard component', () => {
expect(submit.text()).toBe('Save Changes'); expect(submit.text()).toBe('Save Changes');
}); });
it('submits form on click', () => { it('submits form on click', async () => {
mountComponent(false); mountComponent(false);
axios.patch.mockResolvedValue(); axios.patch.mockResolvedValue();
findSubmitButton().trigger('click'); findSubmitButton().trigger('click');
expect(axios.patch).toHaveBeenCalledWith(...endpointRequest); expect(axios.patch).toHaveBeenCalledWith(...endpointRequest);
return wrapper.vm.$nextTick().then(() => expect(refreshCurrentPage).toHaveBeenCalled()); await nextTick();
expect(refreshCurrentPage).toHaveBeenCalled();
}); });
it('creates flash banner on error', () => { it('creates flash banner on error', async () => {
mountComponent(false); mountComponent(false);
const message = 'mockErrorMessage'; const message = 'mockErrorMessage';
axios.patch.mockRejectedValue({ response: { data: { message } } }); axios.patch.mockRejectedValue({ response: { data: { message } } });
...@@ -199,14 +201,11 @@ describe('operation settings external dashboard component', () => { ...@@ -199,14 +201,11 @@ describe('operation settings external dashboard component', () => {
expect(axios.patch).toHaveBeenCalledWith(...endpointRequest); expect(axios.patch).toHaveBeenCalledWith(...endpointRequest);
return wrapper.vm await nextTick();
.$nextTick() await jest.runAllTicks();
.then(jest.runAllTicks) expect(createFlash).toHaveBeenCalledWith({
.then(() => message: `There was an error saving your changes. ${message}`,
expect(createFlash).toHaveBeenCalledWith({ });
message: `There was an error saving your changes. ${message}`,
}),
);
}); });
}); });
}); });
......
import { GlDropdownItem, GlIcon, GlDropdown } from '@gitlab/ui'; import { GlDropdownItem, GlIcon, GlDropdown } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils'; import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import { nextTick } from 'vue';
import { useFakeDate } from 'helpers/fake_date'; import { useFakeDate } from 'helpers/fake_date';
import createMockApollo from 'helpers/mock_apollo_helper'; import createMockApollo from 'helpers/mock_apollo_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
...@@ -54,8 +55,8 @@ describe('Details Header', () => { ...@@ -54,8 +55,8 @@ describe('Details Header', () => {
const waitForMetadataItems = async () => { const waitForMetadataItems = async () => {
// Metadata items are printed by a loop in the title-area and it takes two ticks for them to be available // Metadata items are printed by a loop in the title-area and it takes two ticks for them to be available
await wrapper.vm.$nextTick(); await nextTick();
await wrapper.vm.$nextTick(); await nextTick();
}; };
const mountComponent = ({ const mountComponent = ({
......
import { GlSprintf } from '@gitlab/ui'; import { GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import Component from '~/packages_and_registries/container_registry/explorer/components/list_page/registry_header.vue'; import Component from '~/packages_and_registries/container_registry/explorer/components/list_page/registry_header.vue';
import { import {
CONTAINER_REGISTRY_TITLE, CONTAINER_REGISTRY_TITLE,
...@@ -21,7 +22,7 @@ describe('registry_header', () => { ...@@ -21,7 +22,7 @@ describe('registry_header', () => {
const findImagesCountSubHeader = () => wrapper.find('[data-testid="images-count"]'); const findImagesCountSubHeader = () => wrapper.find('[data-testid="images-count"]');
const findExpirationPolicySubHeader = () => wrapper.find('[data-testid="expiration-policy"]'); const findExpirationPolicySubHeader = () => wrapper.find('[data-testid="expiration-policy"]');
const mountComponent = (propsData, slots) => { const mountComponent = async (propsData, slots) => {
wrapper = shallowMount(Component, { wrapper = shallowMount(Component, {
stubs: { stubs: {
GlSprintf, GlSprintf,
...@@ -30,7 +31,7 @@ describe('registry_header', () => { ...@@ -30,7 +31,7 @@ describe('registry_header', () => {
propsData, propsData,
slots, slots,
}); });
return wrapper.vm.$nextTick(); await nextTick();
}; };
afterEach(() => { afterEach(() => {
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import Vue from 'vue'; import Vue, { nextTick } from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import component from '~/packages_and_registries/infrastructure_registry/details/components/details_title.vue'; import component from '~/packages_and_registries/infrastructure_registry/details/components/details_title.vue';
import TitleArea from '~/vue_shared/components/registry/title_area.vue'; import TitleArea from '~/vue_shared/components/registry/title_area.vue';
...@@ -11,7 +11,10 @@ describe('PackageTitle', () => { ...@@ -11,7 +11,10 @@ describe('PackageTitle', () => {
let wrapper; let wrapper;
let store; let store;
function createComponent({ packageFiles = mavenFiles, packageEntity = terraformModule } = {}) { async function createComponent({
packageFiles = mavenFiles,
packageEntity = terraformModule,
} = {}) {
store = new Vuex.Store({ store = new Vuex.Store({
state: { state: {
packageEntity, packageEntity,
...@@ -28,7 +31,7 @@ describe('PackageTitle', () => { ...@@ -28,7 +31,7 @@ describe('PackageTitle', () => {
TitleArea, TitleArea,
}, },
}); });
return wrapper.vm.$nextTick(); await nextTick();
} }
const findTitleArea = () => wrapper.findComponent(TitleArea); const findTitleArea = () => wrapper.findComponent(TitleArea);
......
import { GlTable, GlPagination, GlModal } from '@gitlab/ui'; import { GlTable, GlPagination, GlModal } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import Vue from 'vue'; import Vue, { nextTick } from 'vue';
import { last } from 'lodash'; import { last } from 'lodash';
import Vuex from 'vuex'; import Vuex from 'vuex';
import stubChildren from 'helpers/stub_children'; import stubChildren from 'helpers/stub_children';
...@@ -120,16 +120,15 @@ describe('packages_list', () => { ...@@ -120,16 +120,15 @@ describe('packages_list', () => {
mountComponent(); mountComponent();
}); });
it('setItemToBeDeleted sets itemToBeDeleted and open the modal', () => { it('setItemToBeDeleted sets itemToBeDeleted and open the modal', async () => {
const mockModalShow = jest.spyOn(wrapper.vm.$refs.packageListDeleteModal, 'show'); const mockModalShow = jest.spyOn(wrapper.vm.$refs.packageListDeleteModal, 'show');
const item = last(wrapper.vm.list); const item = last(wrapper.vm.list);
findPackagesListRow().vm.$emit('packageToDelete', item); findPackagesListRow().vm.$emit('packageToDelete', item);
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.vm.itemToBeDeleted).toEqual(item); expect(wrapper.vm.itemToBeDeleted).toEqual(item);
expect(mockModalShow).toHaveBeenCalled(); expect(mockModalShow).toHaveBeenCalled();
});
}); });
it('deleteItemConfirmation resets itemToBeDeleted', () => { it('deleteItemConfirmation resets itemToBeDeleted', () => {
...@@ -140,15 +139,14 @@ describe('packages_list', () => { ...@@ -140,15 +139,14 @@ describe('packages_list', () => {
expect(wrapper.vm.itemToBeDeleted).toEqual(null); expect(wrapper.vm.itemToBeDeleted).toEqual(null);
}); });
it('deleteItemConfirmation emit package:delete', () => { it('deleteItemConfirmation emit package:delete', async () => {
const itemToBeDeleted = { id: 2 }; const itemToBeDeleted = { id: 2 };
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ itemToBeDeleted }); wrapper.setData({ itemToBeDeleted });
wrapper.vm.deleteItemConfirmation(); wrapper.vm.deleteItemConfirmation();
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.emitted('package:delete')[0]).toEqual([itemToBeDeleted]); expect(wrapper.emitted('package:delete')[0]).toEqual([itemToBeDeleted]);
});
}); });
it('deleteItemCanceled resets itemToBeDeleted', () => { it('deleteItemCanceled resets itemToBeDeleted', () => {
......
import { GlLink } from '@gitlab/ui'; import { GlLink } from '@gitlab/ui';
import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
...@@ -126,7 +127,7 @@ describe('packages_list_row', () => { ...@@ -126,7 +127,7 @@ describe('packages_list_row', () => {
findDeleteButton().vm.$emit('click'); findDeleteButton().vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.emitted('packageToDelete')).toBeTruthy(); expect(wrapper.emitted('packageToDelete')).toBeTruthy();
expect(wrapper.emitted('packageToDelete')[0]).toEqual([packageWithoutTags]); expect(wrapper.emitted('packageToDelete')[0]).toEqual([packageWithoutTags]);
}); });
......
import { GlIcon, GlSprintf } from '@gitlab/ui'; import { GlIcon, GlSprintf } from '@gitlab/ui';
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils'; import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
import { nextTick } from 'vue';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import PackageTags from '~/packages_and_registries/shared/components/package_tags.vue'; import PackageTags from '~/packages_and_registries/shared/components/package_tags.vue';
...@@ -24,7 +25,7 @@ const packageWithTags = { ...@@ -24,7 +25,7 @@ const packageWithTags = {
describe('PackageTitle', () => { describe('PackageTitle', () => {
let wrapper; let wrapper;
function createComponent(packageEntity = packageWithTags) { async function createComponent(packageEntity = packageWithTags) {
wrapper = shallowMountExtended(PackageTitle, { wrapper = shallowMountExtended(PackageTitle, {
propsData: { packageEntity }, propsData: { packageEntity },
stubs: { stubs: {
...@@ -35,7 +36,7 @@ describe('PackageTitle', () => { ...@@ -35,7 +36,7 @@ describe('PackageTitle', () => {
GlResizeObserver: createMockDirective(), GlResizeObserver: createMockDirective(),
}, },
}); });
return wrapper.vm.$nextTick(); await nextTick();
} }
const findTitleArea = () => wrapper.findComponent(TitleArea); const findTitleArea = () => wrapper.findComponent(TitleArea);
...@@ -71,7 +72,7 @@ describe('PackageTitle', () => { ...@@ -71,7 +72,7 @@ describe('PackageTitle', () => {
await createComponent(); await createComponent();
await wrapper.vm.$nextTick(); await nextTick();
expect(findPackageBadges()).toHaveLength(packageTags().length); expect(findPackageBadges()).toHaveLength(packageTags().length);
}); });
...@@ -85,7 +86,7 @@ describe('PackageTitle', () => { ...@@ -85,7 +86,7 @@ describe('PackageTitle', () => {
const { value } = getBinding(wrapper.element, 'gl-resize-observer'); const { value } = getBinding(wrapper.element, 'gl-resize-observer');
value(); value();
await wrapper.vm.$nextTick(); await nextTick();
expect(findPackageBadges()).toHaveLength(packageTags().length); expect(findPackageBadges()).toHaveLength(packageTags().length);
}); });
}); });
......
import { GlSprintf } from '@gitlab/ui'; import { GlSprintf } from '@gitlab/ui';
import Vue from 'vue'; import Vue, { nextTick } from 'vue';
import VueRouter from 'vue-router'; import VueRouter from 'vue-router';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
...@@ -119,7 +119,7 @@ describe('packages_list_row', () => { ...@@ -119,7 +119,7 @@ describe('packages_list_row', () => {
findDeleteButton().vm.$emit('click'); findDeleteButton().vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.emitted('packageToDelete')).toBeTruthy(); expect(wrapper.emitted('packageToDelete')).toBeTruthy();
expect(wrapper.emitted('packageToDelete')[0]).toEqual([packageWithoutTags]); expect(wrapper.emitted('packageToDelete')[0]).toEqual([packageWithoutTags]);
}); });
......
import { GlSprintf, GlLink } from '@gitlab/ui'; import { GlSprintf, GlLink } from '@gitlab/ui';
import { createLocalVue } from '@vue/test-utils'; import { createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import createMockApollo from 'helpers/mock_apollo_helper'; import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
...@@ -252,7 +253,7 @@ describe('Packages Settings', () => { ...@@ -252,7 +253,7 @@ describe('Packages Settings', () => {
emitMavenSettingsUpdate(); emitMavenSettingsUpdate();
await wrapper.vm.$nextTick(); await nextTick();
// errors are reset on mutation call // errors are reset on mutation call
expect(findMavenDuplicatedSettings().props('duplicateExceptionRegexError')).toBe(''); expect(findMavenDuplicatedSettings().props('duplicateExceptionRegexError')).toBe('');
......
import { shallowMount, createLocalVue } from '@vue/test-utils'; import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import { nextTick } from 'vue';
import createMockApollo from 'helpers/mock_apollo_helper'; import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import { GlCard, GlLoadingIcon } from 'jest/packages_and_registries/shared/stubs'; import { GlCard, GlLoadingIcon } from 'jest/packages_and_registries/shared/stubs';
...@@ -201,7 +202,7 @@ describe('Settings Form', () => { ...@@ -201,7 +202,7 @@ describe('Settings Form', () => {
finder().vm.$emit('input', 'foo'); finder().vm.$emit('input', 'foo');
expect(finder().props('error')).toEqual('bar'); expect(finder().props('error')).toEqual('bar');
await wrapper.vm.$nextTick(); await nextTick();
expect(finder().props('error')).toEqual(''); expect(finder().props('error')).toEqual('');
}); });
...@@ -213,7 +214,7 @@ describe('Settings Form', () => { ...@@ -213,7 +214,7 @@ describe('Settings Form', () => {
finder().vm.$emit('validation', false); finder().vm.$emit('validation', false);
await wrapper.vm.$nextTick(); await nextTick();
expect(findSaveButton().props('disabled')).toBe(true); expect(findSaveButton().props('disabled')).toBe(true);
}); });
...@@ -252,7 +253,7 @@ describe('Settings Form', () => { ...@@ -252,7 +253,7 @@ describe('Settings Form', () => {
findForm().trigger('reset'); findForm().trigger('reset');
await wrapper.vm.$nextTick(); await nextTick();
expect(findKeepRegexInput().props('error')).toBe(''); expect(findKeepRegexInput().props('error')).toBe('');
expect(findRemoveRegexInput().props('error')).toBe(''); expect(findRemoveRegexInput().props('error')).toBe('');
...@@ -319,7 +320,7 @@ describe('Settings Form', () => { ...@@ -319,7 +320,7 @@ describe('Settings Form', () => {
findForm().trigger('submit'); findForm().trigger('submit');
await waitForPromises(); await waitForPromises();
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_SUCCESS_MESSAGE); expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_SUCCESS_MESSAGE);
}); });
...@@ -335,7 +336,7 @@ describe('Settings Form', () => { ...@@ -335,7 +336,7 @@ describe('Settings Form', () => {
findForm().trigger('submit'); findForm().trigger('submit');
await waitForPromises(); await waitForPromises();
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.vm.$toast.show).toHaveBeenCalledWith('foo'); expect(wrapper.vm.$toast.show).toHaveBeenCalledWith('foo');
}); });
...@@ -349,7 +350,7 @@ describe('Settings Form', () => { ...@@ -349,7 +350,7 @@ describe('Settings Form', () => {
findForm().trigger('submit'); findForm().trigger('submit');
await waitForPromises(); await waitForPromises();
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_ERROR_MESSAGE); expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_ERROR_MESSAGE);
}); });
...@@ -368,7 +369,7 @@ describe('Settings Form', () => { ...@@ -368,7 +369,7 @@ describe('Settings Form', () => {
findForm().trigger('submit'); findForm().trigger('submit');
await waitForPromises(); await waitForPromises();
await wrapper.vm.$nextTick(); await nextTick();
expect(findKeepRegexInput().props('error')).toEqual('baz'); expect(findKeepRegexInput().props('error')).toEqual('baz');
}); });
......
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import Api from '~/api'; import Api from '~/api';
import NamespaceSelect from '~/pages/admin/projects/components/namespace_select.vue'; import NamespaceSelect from '~/pages/admin/projects/components/namespace_select.vue';
...@@ -55,14 +56,14 @@ describe('Dropdown select component', () => { ...@@ -55,14 +56,14 @@ describe('Dropdown select component', () => {
mountDropdown({ fieldName: 'namespace-input' }); mountDropdown({ fieldName: 'namespace-input' });
// wait for dropdown options to populate // wait for dropdown options to populate
await wrapper.vm.$nextTick(); await nextTick();
expect(findDropdownOption('user: Administrator').exists()).toBe(true); expect(findDropdownOption('user: Administrator').exists()).toBe(true);
expect(findDropdownOption('group: GitLab Org').exists()).toBe(true); expect(findDropdownOption('group: GitLab Org').exists()).toBe(true);
expect(findDropdownOption('group: Foobar').exists()).toBe(false); expect(findDropdownOption('group: Foobar').exists()).toBe(false);
findDropdownOption('user: Administrator').trigger('click'); findDropdownOption('user: Administrator').trigger('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(findNamespaceInput().attributes('value')).toBe('10'); expect(findNamespaceInput().attributes('value')).toBe('10');
expect(findDropdownToggle().text()).toBe('user: Administrator'); expect(findDropdownToggle().text()).toBe('user: Administrator');
...@@ -72,7 +73,7 @@ describe('Dropdown select component', () => { ...@@ -72,7 +73,7 @@ describe('Dropdown select component', () => {
mountDropdown(); mountDropdown();
// wait for dropdown options to populate // wait for dropdown options to populate
await wrapper.vm.$nextTick(); await nextTick();
findDropdownOption('group: GitLab Org').trigger('click'); findDropdownOption('group: GitLab Org').trigger('click');
......
import { GlModal } from '@gitlab/ui'; import { GlModal } from '@gitlab/ui';
import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { import {
I18N_PASSWORD_PROMPT_CANCEL_BUTTON, I18N_PASSWORD_PROMPT_CANCEL_BUTTON,
...@@ -62,7 +63,7 @@ describe('Password prompt modal', () => { ...@@ -62,7 +63,7 @@ describe('Password prompt modal', () => {
setPassword(mockPassword); setPassword(mockPassword);
submitModal(); submitModal();
await wrapper.vm.$nextTick(); await nextTick();
expect(handleConfirmPasswordSpy).toHaveBeenCalledTimes(1); expect(handleConfirmPasswordSpy).toHaveBeenCalledTimes(1);
expect(handleConfirmPasswordSpy).toHaveBeenCalledWith(mockPassword); expect(handleConfirmPasswordSpy).toHaveBeenCalledWith(mockPassword);
...@@ -73,7 +74,7 @@ describe('Password prompt modal', () => { ...@@ -73,7 +74,7 @@ describe('Password prompt modal', () => {
expect(findConfirmBtnDisabledState()).toBe(true); expect(findConfirmBtnDisabledState()).toBe(true);
await wrapper.vm.$nextTick(); await nextTick();
expect(findConfirmBtnDisabledState()).toBe(false); expect(findConfirmBtnDisabledState()).toBe(false);
}); });
...@@ -84,7 +85,7 @@ describe('Password prompt modal', () => { ...@@ -84,7 +85,7 @@ describe('Password prompt modal', () => {
expect(findConfirmBtnDisabledState()).toBe(true); expect(findConfirmBtnDisabledState()).toBe(true);
await wrapper.vm.$nextTick(); await nextTick();
expect(findConfirmBtnDisabledState()).toBe(true); expect(findConfirmBtnDisabledState()).toBe(true);
}); });
......
...@@ -4,6 +4,7 @@ import { mount, shallowMount } from '@vue/test-utils'; ...@@ -4,6 +4,7 @@ import { mount, shallowMount } from '@vue/test-utils';
import axios from 'axios'; import axios from 'axios';
import AxiosMockAdapter from 'axios-mock-adapter'; import AxiosMockAdapter from 'axios-mock-adapter';
import { kebabCase } from 'lodash'; import { kebabCase } from 'lodash';
import { nextTick } from 'vue';
import createFlash from '~/flash'; import createFlash from '~/flash';
import httpStatus from '~/lib/utils/http_status'; import httpStatus from '~/lib/utils/http_status';
import * as urlUtility from '~/lib/utils/url_utility'; import * as urlUtility from '~/lib/utils/url_utility';
...@@ -217,7 +218,7 @@ describe('ForkForm component', () => { ...@@ -217,7 +218,7 @@ describe('ForkForm component', () => {
it('changes to kebab case when project name changes', async () => { it('changes to kebab case when project name changes', async () => {
const newInput = `${projectPath}1`; const newInput = `${projectPath}1`;
findForkNameInput().vm.$emit('input', newInput); findForkNameInput().vm.$emit('input', newInput);
await wrapper.vm.$nextTick(); await nextTick();
expect(findForkSlugInput().attributes('value')).toBe(kebabCase(newInput)); expect(findForkSlugInput().attributes('value')).toBe(kebabCase(newInput));
}); });
...@@ -225,7 +226,7 @@ describe('ForkForm component', () => { ...@@ -225,7 +226,7 @@ describe('ForkForm component', () => {
it('does not change to kebab case when project slug is changed manually', async () => { it('does not change to kebab case when project slug is changed manually', async () => {
const newInput = `${projectPath}1`; const newInput = `${projectPath}1`;
findForkSlugInput().vm.$emit('input', newInput); findForkSlugInput().vm.$emit('input', newInput);
await wrapper.vm.$nextTick(); await nextTick();
expect(findForkSlugInput().attributes('value')).toBe(newInput); expect(findForkSlugInput().attributes('value')).toBe(newInput);
}); });
...@@ -273,7 +274,7 @@ describe('ForkForm component', () => { ...@@ -273,7 +274,7 @@ describe('ForkForm component', () => {
expect(wrapper.vm.form.fields.visibility.value).toBe('public'); expect(wrapper.vm.form.fields.visibility.value).toBe('public');
await findFormSelectOptions().at(1).setSelected(); await findFormSelectOptions().at(1).setSelected();
await wrapper.vm.$nextTick(); await nextTick();
expect(getByRole(wrapper.element, 'radio', { name: /private/i }).checked).toBe(true); expect(getByRole(wrapper.element, 'radio', { name: /private/i }).checked).toBe(true);
}); });
...@@ -283,7 +284,7 @@ describe('ForkForm component', () => { ...@@ -283,7 +284,7 @@ describe('ForkForm component', () => {
await findFormSelectOptions().at(1).setSelected(); await findFormSelectOptions().at(1).setSelected();
await wrapper.vm.$nextTick(); await nextTick();
const container = getByRole(wrapper.element, 'radiogroup', { name: /visibility/i }); const container = getByRole(wrapper.element, 'radiogroup', { name: /visibility/i });
const visibilityRadios = getAllByRole(container, 'radio'); const visibilityRadios = getAllByRole(container, 'radio');
...@@ -419,7 +420,7 @@ describe('ForkForm component', () => { ...@@ -419,7 +420,7 @@ describe('ForkForm component', () => {
const form = wrapper.find(GlForm); const form = wrapper.find(GlForm);
await form.trigger('submit'); await form.trigger('submit');
await wrapper.vm.$nextTick(); await nextTick();
}; };
describe('with invalid form', () => { describe('with invalid form', () => {
......
...@@ -3,6 +3,7 @@ import { GlAreaChart } from '@gitlab/ui/dist/charts'; ...@@ -3,6 +3,7 @@ import { GlAreaChart } from '@gitlab/ui/dist/charts';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import httpStatusCodes from '~/lib/utils/http_status'; import httpStatusCodes from '~/lib/utils/http_status';
...@@ -143,7 +144,7 @@ describe('Code Coverage', () => { ...@@ -143,7 +144,7 @@ describe('Code Coverage', () => {
it('updates the selected dropdown option with an icon', async () => { it('updates the selected dropdown option with an icon', async () => {
findSecondDropdownItem().vm.$emit('click'); findSecondDropdownItem().vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(findFirstDropdownItem().attributes('ischecked')).toBeFalsy(); expect(findFirstDropdownItem().attributes('ischecked')).toBeFalsy();
expect(findSecondDropdownItem().attributes('ischecked')).toBeTruthy(); expect(findSecondDropdownItem().attributes('ischecked')).toBeTruthy();
...@@ -155,7 +156,7 @@ describe('Code Coverage', () => { ...@@ -155,7 +156,7 @@ describe('Code Coverage', () => {
findSecondDropdownItem().vm.$emit('click'); findSecondDropdownItem().vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.vm.selectedDailyCoverage).not.toBe(originalSelectedData); expect(wrapper.vm.selectedDailyCoverage).not.toBe(originalSelectedData);
expect(wrapper.vm.selectedDailyCoverage).toBe(expectedData); expect(wrapper.vm.selectedDailyCoverage).toBe(expectedData);
......
import { GlIcon } from '@gitlab/ui'; import { GlIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { trimText } from 'helpers/text_helper'; import { trimText } from 'helpers/text_helper';
import IntervalPatternInput from '~/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue'; import IntervalPatternInput from '~/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue';
...@@ -98,7 +99,7 @@ describe('Interval Pattern Input Component', () => { ...@@ -98,7 +99,7 @@ describe('Interval Pattern Input Component', () => {
it('when a default option is selected', async () => { it('when a default option is selected', async () => {
selectEveryDayRadio(); selectEveryDayRadio();
await wrapper.vm.$nextTick(); await nextTick();
expect(findCustomInput().attributes('disabled')).toBeUndefined(); expect(findCustomInput().attributes('disabled')).toBeUndefined();
}); });
...@@ -106,7 +107,7 @@ describe('Interval Pattern Input Component', () => { ...@@ -106,7 +107,7 @@ describe('Interval Pattern Input Component', () => {
it('when the custom option is selected', async () => { it('when the custom option is selected', async () => {
selectCustomRadio(); selectCustomRadio();
await wrapper.vm.$nextTick(); await nextTick();
expect(findCustomInput().attributes('disabled')).toBeUndefined(); expect(findCustomInput().attributes('disabled')).toBeUndefined();
}); });
...@@ -150,11 +151,11 @@ describe('Interval Pattern Input Component', () => { ...@@ -150,11 +151,11 @@ describe('Interval Pattern Input Component', () => {
it('when everyday is selected, update value', async () => { it('when everyday is selected, update value', async () => {
selectEveryWeekRadio(); selectEveryWeekRadio();
await wrapper.vm.$nextTick(); await nextTick();
expect(findCustomInput().element.value).toBe(cronIntervalPresets.everyWeek); expect(findCustomInput().element.value).toBe(cronIntervalPresets.everyWeek);
selectEveryDayRadio(); selectEveryDayRadio();
await wrapper.vm.$nextTick(); await nextTick();
expect(findCustomInput().element.value).toBe(cronIntervalPresets.everyDay); expect(findCustomInput().element.value).toBe(cronIntervalPresets.everyDay);
}); });
}); });
...@@ -170,7 +171,7 @@ describe('Interval Pattern Input Component', () => { ...@@ -170,7 +171,7 @@ describe('Interval Pattern Input Component', () => {
act(); act();
await wrapper.vm.$nextTick(); await nextTick();
expect(findCustomInput().element.value).toBe(expectedValue); expect(findCustomInput().element.value).toBe(expectedValue);
}); });
...@@ -189,7 +190,7 @@ describe('Interval Pattern Input Component', () => { ...@@ -189,7 +190,7 @@ describe('Interval Pattern Input Component', () => {
findCustomInput().setValue(newValue); findCustomInput().setValue(newValue);
await wrapper.vm.$nextTick; await nextTick;
expect(findSelectedRadioKey()).toBe(customKey); expect(findSelectedRadioKey()).toBe(customKey);
}); });
......
import { GlButton } from '@gitlab/ui'; import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import { nextTick } from 'vue';
import PipelineSchedulesCallout from '~/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue'; import PipelineSchedulesCallout from '~/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue';
const cookieKey = 'pipeline_schedules_callout_dismissed'; const cookieKey = 'pipeline_schedules_callout_dismissed';
...@@ -27,7 +28,7 @@ describe('Pipeline Schedule Callout', () => { ...@@ -27,7 +28,7 @@ describe('Pipeline Schedule Callout', () => {
Cookies.set(cookieKey, true); Cookies.set(cookieKey, true);
createComponent(); createComponent();
await wrapper.vm.$nextTick(); await nextTick();
}); });
afterEach(() => { afterEach(() => {
...@@ -71,7 +72,7 @@ describe('Pipeline Schedule Callout', () => { ...@@ -71,7 +72,7 @@ describe('Pipeline Schedule Callout', () => {
findDismissCalloutBtn().vm.$emit('click'); findDismissCalloutBtn().vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(findInnerContentOfCallout().exists()).toBe(false); expect(findInnerContentOfCallout().exists()).toBe(false);
}); });
...@@ -90,7 +91,7 @@ describe('Pipeline Schedule Callout', () => { ...@@ -90,7 +91,7 @@ describe('Pipeline Schedule Callout', () => {
it('is hidden when close button is clicked', async () => { it('is hidden when close button is clicked', async () => {
findDismissCalloutBtn().vm.$emit('click'); findDismissCalloutBtn().vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(findInnerContentOfCallout().exists()).toBe(false); expect(findInnerContentOfCallout().exists()).toBe(false);
}); });
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import projectSettingRow from '~/pages/projects/shared/permissions/components/project_setting_row.vue'; import projectSettingRow from '~/pages/projects/shared/permissions/components/project_setting_row.vue';
describe('Project Setting Row', () => { describe('Project Setting Row', () => {
...@@ -18,43 +19,39 @@ describe('Project Setting Row', () => { ...@@ -18,43 +19,39 @@ describe('Project Setting Row', () => {
wrapper.destroy(); wrapper.destroy();
}); });
it('should show the label if it is set', () => { it('should show the label if it is set', async () => {
wrapper.setProps({ label: 'Test label' }); wrapper.setProps({ label: 'Test label' });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.find('label').text()).toEqual('Test label'); expect(wrapper.find('label').text()).toEqual('Test label');
});
}); });
it('should hide the label if it is not set', () => { it('should hide the label if it is not set', () => {
expect(wrapper.find('label').exists()).toBe(false); expect(wrapper.find('label').exists()).toBe(false);
}); });
it('should show the help icon with the correct help path if it is set', () => { it('should show the help icon with the correct help path if it is set', async () => {
wrapper.setProps({ label: 'Test label', helpPath: '/123' }); wrapper.setProps({ label: 'Test label', helpPath: '/123' });
return wrapper.vm.$nextTick(() => { await nextTick();
const link = wrapper.find('a'); const link = wrapper.find('a');
expect(link.exists()).toBe(true); expect(link.exists()).toBe(true);
expect(link.attributes().href).toEqual('/123'); expect(link.attributes().href).toEqual('/123');
});
}); });
it('should hide the help icon if no help path is set', () => { it('should hide the help icon if no help path is set', async () => {
wrapper.setProps({ label: 'Test label' }); wrapper.setProps({ label: 'Test label' });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.find('a').exists()).toBe(false); expect(wrapper.find('a').exists()).toBe(false);
});
}); });
it('should show the help text if it is set', () => { it('should show the help text if it is set', async () => {
wrapper.setProps({ helpText: 'Test text' }); wrapper.setProps({ helpText: 'Test text' });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.find('span').text()).toEqual('Test text'); expect(wrapper.find('span').text()).toEqual('Test text');
});
}); });
it('should hide the help text if it is set', () => { it('should hide the help text if it is set', () => {
......
...@@ -48,10 +48,10 @@ describe('WikiForm', () => { ...@@ -48,10 +48,10 @@ describe('WikiForm', () => {
return format.find(`option[value=${value}]`).setSelected(); return format.find(`option[value=${value}]`).setSelected();
}; };
const triggerFormSubmit = () => { const triggerFormSubmit = async () => {
findForm().element.dispatchEvent(new Event('submit')); findForm().element.dispatchEvent(new Event('submit'));
return nextTick(); await nextTick();
}; };
const dispatchBeforeUnload = () => { const dispatchBeforeUnload = () => {
...@@ -574,7 +574,7 @@ describe('WikiForm', () => { ...@@ -574,7 +574,7 @@ describe('WikiForm', () => {
wrapper.findComponent(GlModal).vm.$emit('primary'); wrapper.findComponent(GlModal).vm.$emit('primary');
await wrapper.vm.$nextTick(); await nextTick();
}); });
it('switches to classic editor', () => { it('switches to classic editor', () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment