Commit b9960643 authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch 'slashmanov/refactor-next-tick-5' into 'master'

Refactor nextTick to use a direct import from a Vue package (5/9)

See merge request gitlab-org/gitlab!79052
parents b957c387 0d6b1f91
...@@ -19,7 +19,7 @@ async function files(store, count) { ...@@ -19,7 +19,7 @@ async function files(store, count) {
const copies = Array(count).fill(file); const copies = Array(count).fill(file);
store.state.diffs.diffFiles.push(...copies); store.state.diffs.diffFiles.push(...copies);
return nextTick(); await nextTick();
} }
describe('CollapsedFilesWarning', () => { describe('CollapsedFilesWarning', () => {
...@@ -84,7 +84,7 @@ describe('CollapsedFilesWarning', () => { ...@@ -84,7 +84,7 @@ describe('CollapsedFilesWarning', () => {
getAlertCloseButton().element.click(); getAlertCloseButton().element.click();
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.find('[data-testid="root"]').exists()).toBe(false); expect(wrapper.find('[data-testid="root"]').exists()).toBe(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 getDiffWithCommit from 'test_fixtures/merge_request_diffs/with_commit.json'; import getDiffWithCommit from 'test_fixtures/merge_request_diffs/with_commit.json';
import setWindowLocation from 'helpers/set_window_location_helper'; import setWindowLocation from 'helpers/set_window_location_helper';
...@@ -232,16 +232,15 @@ describe('CompareVersions', () => { ...@@ -232,16 +232,15 @@ describe('CompareVersions', () => {
expect(link.element.getAttribute('href')).toEqual(PREV_COMMIT_URL); expect(link.element.getAttribute('href')).toEqual(PREV_COMMIT_URL);
}); });
it('triggers the correct Vuex action on click', () => { it('triggers the correct Vuex action on click', async () => {
const link = getPrevCommitNavElement(); const link = getPrevCommitNavElement();
link.trigger('click'); link.trigger('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.vm.moveToNeighboringCommit).toHaveBeenCalledWith({ expect(wrapper.vm.moveToNeighboringCommit).toHaveBeenCalledWith({
direction: 'previous', direction: 'previous',
}); });
}); });
});
it('renders a disabled button when there is no prev commit', () => { it('renders a disabled button when there is no prev commit', () => {
createWrapper({}, { ...mrCommit, prev_commit_id: null }); createWrapper({}, { ...mrCommit, prev_commit_id: null });
...@@ -267,14 +266,13 @@ describe('CompareVersions', () => { ...@@ -267,14 +266,13 @@ describe('CompareVersions', () => {
expect(link.element.getAttribute('href')).toEqual(NEXT_COMMIT_URL); expect(link.element.getAttribute('href')).toEqual(NEXT_COMMIT_URL);
}); });
it('triggers the correct Vuex action on click', () => { it('triggers the correct Vuex action on click', async () => {
const link = getNextCommitNavElement(); const link = getNextCommitNavElement();
link.trigger('click'); link.trigger('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.vm.moveToNeighboringCommit).toHaveBeenCalledWith({ direction: 'next' }); expect(wrapper.vm.moveToNeighboringCommit).toHaveBeenCalledWith({ direction: 'next' });
}); });
});
it('renders a disabled button when there is no next commit', () => { it('renders a disabled button when there is no next commit', () => {
createWrapper({}, { ...mrCommit, next_commit_id: null }); createWrapper({}, { ...mrCommit, next_commit_id: null });
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import Vue from 'vue'; import Vue, { nextTick } from 'vue';
import { cloneDeep } from 'lodash'; import { cloneDeep } from 'lodash';
import Vuex from 'vuex'; import Vuex from 'vuex';
...@@ -125,31 +125,28 @@ describe('DiffFileHeader component', () => { ...@@ -125,31 +125,28 @@ describe('DiffFileHeader component', () => {
expect(findCollapseIcon().props('name')).toBe(icon); expect(findCollapseIcon().props('name')).toBe(icon);
}); });
it('when header is clicked emits toggleFile', () => { it('when header is clicked emits toggleFile', async () => {
createComponent(); createComponent();
findHeader().trigger('click'); findHeader().trigger('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted().toggleFile).toBeDefined(); expect(wrapper.emitted().toggleFile).toBeDefined();
}); });
});
it('when collapseIcon is clicked emits toggleFile', () => { it('when collapseIcon is clicked emits toggleFile', async () => {
createComponent({ props: { collapsible: true } }); createComponent({ props: { collapsible: true } });
findCollapseIcon().vm.$emit('click', new Event('click')); findCollapseIcon().vm.$emit('click', new Event('click'));
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted().toggleFile).toBeDefined(); expect(wrapper.emitted().toggleFile).toBeDefined();
}); });
});
it('when other element in header is clicked does not emits toggleFile', () => { it('when other element in header is clicked does not emits toggleFile', async () => {
createComponent({ props: { collapsible: true } }); createComponent({ props: { collapsible: true } });
findTitleLink().trigger('click'); findTitleLink().trigger('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted().toggleFile).not.toBeDefined(); expect(wrapper.emitted().toggleFile).not.toBeDefined();
}); });
});
describe('copy to clipboard', () => { describe('copy to clipboard', () => {
beforeEach(() => { beforeEach(() => {
......
...@@ -160,7 +160,7 @@ describe('DiffFile', () => { ...@@ -160,7 +160,7 @@ describe('DiffFile', () => {
last, last,
})); }));
await wrapper.vm.$nextTick(); await nextTick();
expect(eventHub.$emit).toHaveBeenCalledTimes(events.length); expect(eventHub.$emit).toHaveBeenCalledTimes(events.length);
events.forEach((event) => { events.forEach((event) => {
...@@ -184,13 +184,13 @@ describe('DiffFile', () => { ...@@ -184,13 +184,13 @@ describe('DiffFile', () => {
makeFileAutomaticallyCollapsed(store); makeFileAutomaticallyCollapsed(store);
await wrapper.vm.$nextTick(); // Wait for store updates to flow into the component await nextTick(); // Wait for store updates to flow into the component
toggleFile(wrapper); toggleFile(wrapper);
await wrapper.vm.$nextTick(); // Wait for the load to resolve await nextTick(); // Wait for the load to resolve
await wrapper.vm.$nextTick(); // Wait for the idleCallback await nextTick(); // Wait for the idleCallback
await wrapper.vm.$nextTick(); // Wait for nextTick inside postRender await nextTick(); // Wait for nextTick inside postRender
expect(eventHub.$emit).toHaveBeenCalledTimes(2); expect(eventHub.$emit).toHaveBeenCalledTimes(2);
expect(eventHub.$emit).toHaveBeenCalledWith(EVT_PERF_MARK_FIRST_DIFF_FILE_SHOWN); expect(eventHub.$emit).toHaveBeenCalledWith(EVT_PERF_MARK_FIRST_DIFF_FILE_SHOWN);
...@@ -214,7 +214,7 @@ describe('DiffFile', () => { ...@@ -214,7 +214,7 @@ describe('DiffFile', () => {
markFileToBeRendered(store); markFileToBeRendered(store);
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.find(DiffContentComponent).exists()).toBe(true); expect(wrapper.find(DiffContentComponent).exists()).toBe(true);
}); });
...@@ -264,7 +264,7 @@ describe('DiffFile', () => { ...@@ -264,7 +264,7 @@ describe('DiffFile', () => {
it('performs the normal file toggle when the file is collapsed', async () => { it('performs the normal file toggle when the file is collapsed', async () => {
makeFileAutomaticallyCollapsed(store); makeFileAutomaticallyCollapsed(store);
await wrapper.vm.$nextTick(); await nextTick();
eventHub.$emit(EVT_EXPAND_ALL_FILES); eventHub.$emit(EVT_EXPAND_ALL_FILES);
...@@ -274,7 +274,7 @@ describe('DiffFile', () => { ...@@ -274,7 +274,7 @@ describe('DiffFile', () => {
it('does nothing when the file is not collapsed', async () => { it('does nothing when the file is not collapsed', async () => {
eventHub.$emit(EVT_EXPAND_ALL_FILES); eventHub.$emit(EVT_EXPAND_ALL_FILES);
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.vm.handleToggle).not.toHaveBeenCalled(); expect(wrapper.vm.handleToggle).not.toHaveBeenCalled();
}); });
...@@ -286,7 +286,7 @@ describe('DiffFile', () => { ...@@ -286,7 +286,7 @@ describe('DiffFile', () => {
}); });
it('should not have any content at all', async () => { it('should not have any content at all', async () => {
await wrapper.vm.$nextTick(); await nextTick();
expect(findDiffContentArea(wrapper).element.children.length).toBe(0); expect(findDiffContentArea(wrapper).element.children.length).toBe(0);
}); });
...@@ -392,7 +392,7 @@ describe('DiffFile', () => { ...@@ -392,7 +392,7 @@ describe('DiffFile', () => {
readableText, readableText,
}); });
await wrapper.vm.$nextTick(); await nextTick();
toggleFile(wrapper); toggleFile(wrapper);
}; };
...@@ -440,7 +440,7 @@ describe('DiffFile', () => { ...@@ -440,7 +440,7 @@ describe('DiffFile', () => {
makeFileAutomaticallyCollapsed(store); makeFileAutomaticallyCollapsed(store);
wrapper.vm.requestDiff(); wrapper.vm.requestDiff();
await wrapper.vm.$nextTick(); await nextTick();
expect(findLoader(wrapper).exists()).toBe(true); expect(findLoader(wrapper).exists()).toBe(true);
}); });
...@@ -451,7 +451,7 @@ describe('DiffFile', () => { ...@@ -451,7 +451,7 @@ describe('DiffFile', () => {
({ wrapper, store } = createComponent({ file: getUnreadableFile() })); ({ wrapper, store } = createComponent({ file: getUnreadableFile() }));
makeFileAutomaticallyCollapsed(store); makeFileAutomaticallyCollapsed(store);
await wrapper.vm.$nextTick(); await nextTick();
expect(findDiffContentArea(wrapper).html()).toContain( expect(findDiffContentArea(wrapper).html()).toContain(
'Files with large changes are collapsed by default.', 'Files with large changes are collapsed by default.',
...@@ -470,7 +470,7 @@ describe('DiffFile', () => { ...@@ -470,7 +470,7 @@ describe('DiffFile', () => {
markFileToBeRendered(store); markFileToBeRendered(store);
changeViewerType(store, mode); changeViewerType(store, mode);
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.classes('has-body')).toBe(true); expect(wrapper.classes('has-body')).toBe(true);
expect(wrapper.find(DiffContentComponent).exists()).toBe(true); expect(wrapper.find(DiffContentComponent).exists()).toBe(true);
...@@ -496,7 +496,7 @@ describe('DiffFile', () => { ...@@ -496,7 +496,7 @@ describe('DiffFile', () => {
}, },
}); });
await wrapper.vm.$nextTick(); await nextTick();
const button = wrapper.find('[data-testid="blob-button"]'); const button = wrapper.find('[data-testid="blob-button"]');
...@@ -521,7 +521,7 @@ describe('DiffFile', () => { ...@@ -521,7 +521,7 @@ describe('DiffFile', () => {
({ wrapper, store } = createComponent({ file, props: { viewDiffsFileByFile: true } })); ({ wrapper, store } = createComponent({ file, props: { viewDiffsFileByFile: true } }));
await wrapper.vm.$nextTick(); await nextTick();
expect(findLoader(wrapper).exists()).toBe(true); expect(findLoader(wrapper).exists()).toBe(true);
}); });
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DiffGutterAvatars from '~/diffs/components/diff_gutter_avatars.vue'; import DiffGutterAvatars from '~/diffs/components/diff_gutter_avatars.vue';
import discussionsMockData from '../mock_data/diff_discussions'; import discussionsMockData from '../mock_data/diff_discussions';
...@@ -35,14 +36,13 @@ describe('DiffGutterAvatars', () => { ...@@ -35,14 +36,13 @@ describe('DiffGutterAvatars', () => {
expect(findCollapseButton().exists()).toBe(true); expect(findCollapseButton().exists()).toBe(true);
}); });
it('should emit toggleDiscussions event on button click', () => { it('should emit toggleDiscussions event on button click', async () => {
findCollapseButton().trigger('click'); findCollapseButton().trigger('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted().toggleLineDiscussions).toBeTruthy(); expect(wrapper.emitted().toggleLineDiscussions).toBeTruthy();
}); });
}); });
});
describe('when collapsed', () => { describe('when collapsed', () => {
beforeEach(() => { beforeEach(() => {
...@@ -65,22 +65,20 @@ describe('DiffGutterAvatars', () => { ...@@ -65,22 +65,20 @@ describe('DiffGutterAvatars', () => {
expect(findMoreCount().text()).toBe('+2'); expect(findMoreCount().text()).toBe('+2');
}); });
it('should emit toggleDiscussions event on avatars click', () => { it('should emit toggleDiscussions event on avatars click', async () => {
findUserAvatars().at(0).trigger('click'); findUserAvatars().at(0).trigger('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted().toggleLineDiscussions).toBeTruthy(); expect(wrapper.emitted().toggleLineDiscussions).toBeTruthy();
}); });
});
it('should emit toggleDiscussions event on more count text click', () => { it('should emit toggleDiscussions event on more count text click', async () => {
findMoreCount().trigger('click'); findMoreCount().trigger('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted().toggleLineDiscussions).toBeTruthy(); expect(wrapper.emitted().toggleLineDiscussions).toBeTruthy();
}); });
}); });
});
it('renders an empty more count string if there are no discussions', () => { it('renders an empty more count string if there are no discussions', () => {
createComponent({ createComponent({
......
import { shallowMount, mount } from '@vue/test-utils'; import { shallowMount, mount } from '@vue/test-utils';
import Vue from 'vue'; import Vue, { nextTick } from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import TreeList from '~/diffs/components/tree_list.vue'; import TreeList from '~/diffs/components/tree_list.vue';
import createStore from '~/diffs/store/modules'; import createStore from '~/diffs/store/modules';
...@@ -91,13 +91,12 @@ describe('Diffs tree list component', () => { ...@@ -91,13 +91,12 @@ describe('Diffs tree list component', () => {
expect(getFileRows().at(1).html()).toContain('app'); expect(getFileRows().at(1).html()).toContain('app');
}); });
it('hides file stats', () => { it('hides file stats', async () => {
wrapper.setProps({ hideFileStats: true }); wrapper.setProps({ hideFileStats: true });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.find('.file-row-stats').exists()).toBe(false); expect(wrapper.find('.file-row-stats').exists()).toBe(false);
}); });
});
it('calls toggleTreeOpen when clicking folder', () => { it('calls toggleTreeOpen when clicking folder', () => {
jest.spyOn(wrapper.vm.$store, 'dispatch').mockReturnValue(undefined); jest.spyOn(wrapper.vm.$store, 'dispatch').mockReturnValue(undefined);
...@@ -117,22 +116,20 @@ describe('Diffs tree list component', () => { ...@@ -117,22 +116,20 @@ describe('Diffs tree list component', () => {
}); });
}); });
it('renders as file list when renderTreeList is false', () => { it('renders as file list when renderTreeList is false', async () => {
wrapper.vm.$store.state.diffs.renderTreeList = false; wrapper.vm.$store.state.diffs.renderTreeList = false;
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(getFileRows()).toHaveLength(1); expect(getFileRows()).toHaveLength(1);
}); });
});
it('renders file paths when renderTreeList is false', () => { it('renders file paths when renderTreeList is false', async () => {
wrapper.vm.$store.state.diffs.renderTreeList = false; wrapper.vm.$store.state.diffs.renderTreeList = false;
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.find('.file-row').html()).toContain('index.js'); expect(wrapper.find('.file-row').html()).toContain('index.js');
}); });
}); });
});
describe('with viewedDiffFileIds', () => { describe('with viewedDiffFileIds', () => {
const viewedDiffFileIds = { fileId: '#12345' }; const viewedDiffFileIds = { fileId: '#12345' };
...@@ -142,14 +139,13 @@ describe('Diffs tree list component', () => { ...@@ -142,14 +139,13 @@ describe('Diffs tree list component', () => {
store.state.diffs.viewedDiffFileIds = viewedDiffFileIds; store.state.diffs.viewedDiffFileIds = viewedDiffFileIds;
}); });
it('passes the viewedDiffFileIds to the FileTree', () => { it('passes the viewedDiffFileIds to the FileTree', async () => {
createComponent(shallowMount); createComponent(shallowMount);
return wrapper.vm.$nextTick().then(() => { await nextTick();
// Have to use $attrs['viewed-files'] because we are passing down an object // Have to use $attrs['viewed-files'] because we are passing down an object
// and attributes('') stringifies values (e.g. [object])... // and attributes('') stringifies values (e.g. [object])...
expect(wrapper.find(FileTree).vm.$attrs['viewed-files']).toBe(viewedDiffFileIds); expect(wrapper.find(FileTree).vm.$attrs['viewed-files']).toBe(viewedDiffFileIds);
}); });
}); });
});
}); });
import { GlAlert, GlModal } from '@gitlab/ui'; import { GlAlert, GlModal } 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 CanaryUpdateModal from '~/environments/components/canary_update_modal.vue'; import CanaryUpdateModal from '~/environments/components/canary_update_modal.vue';
import updateCanaryIngress from '~/environments/graphql/mutations/update_canary_ingress.mutation.graphql'; import updateCanaryIngress from '~/environments/graphql/mutations/update_canary_ingress.mutation.graphql';
...@@ -86,7 +87,7 @@ describe('/environments/components/canary_update_modal.vue', () => { ...@@ -86,7 +87,7 @@ describe('/environments/components/canary_update_modal.vue', () => {
mutate.mockResolvedValue({ data: { environmentsCanaryIngressUpdate: { errors: [] } } }); mutate.mockResolvedValue({ data: { environmentsCanaryIngressUpdate: { errors: [] } } });
modal.vm.$emit('primary'); modal.vm.$emit('primary');
await wrapper.vm.$nextTick(); await nextTick();
expect(findAlert().exists()).toBe(false); expect(findAlert().exists()).toBe(false);
}); });
...@@ -95,7 +96,7 @@ describe('/environments/components/canary_update_modal.vue', () => { ...@@ -95,7 +96,7 @@ describe('/environments/components/canary_update_modal.vue', () => {
mutate.mockResolvedValue({ data: { environmentsCanaryIngressUpdate: { errors: ['error'] } } }); mutate.mockResolvedValue({ data: { environmentsCanaryIngressUpdate: { errors: ['error'] } } });
modal.vm.$emit('primary'); modal.vm.$emit('primary');
await wrapper.vm.$nextTick(); await nextTick();
expect(findAlert().text()).toBe('error'); expect(findAlert().text()).toBe('error');
}); });
...@@ -105,7 +106,7 @@ describe('/environments/components/canary_update_modal.vue', () => { ...@@ -105,7 +106,7 @@ describe('/environments/components/canary_update_modal.vue', () => {
modal.vm.$emit('primary'); modal.vm.$emit('primary');
await waitForPromises(); await waitForPromises();
await wrapper.vm.$nextTick(); await nextTick();
expect(findAlert().text()).toBe('Something went wrong. Please try again later'); expect(findAlert().text()).toBe('Something went wrong. Please try again later');
}); });
...@@ -114,12 +115,12 @@ describe('/environments/components/canary_update_modal.vue', () => { ...@@ -114,12 +115,12 @@ describe('/environments/components/canary_update_modal.vue', () => {
mutate.mockResolvedValue({ data: { environmentsCanaryIngressUpdate: { errors: ['error'] } } }); mutate.mockResolvedValue({ data: { environmentsCanaryIngressUpdate: { errors: ['error'] } } });
modal.vm.$emit('primary'); modal.vm.$emit('primary');
await wrapper.vm.$nextTick(); await nextTick();
const alert = findAlert(); const alert = findAlert();
alert.vm.$emit('dismiss'); alert.vm.$emit('dismiss');
await wrapper.vm.$nextTick(); await nextTick();
expect(alert.exists()).toBe(false); expect(alert.exists()).toBe(false);
}); });
......
import { GlTooltip, GlIcon, GlLoadingIcon } from '@gitlab/ui'; import { GlTooltip, GlIcon, 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 CanaryIngress from '~/environments/components/canary_ingress.vue'; import CanaryIngress from '~/environments/components/canary_ingress.vue';
import DeployBoard from '~/environments/components/deploy_board.vue'; import DeployBoard from '~/environments/components/deploy_board.vue';
import { deployBoardMockData, environment } from './mock_data'; import { deployBoardMockData, environment } from './mock_data';
...@@ -24,7 +24,7 @@ describe('Deploy Board', () => { ...@@ -24,7 +24,7 @@ describe('Deploy Board', () => {
describe('with valid data', () => { describe('with valid data', () => {
beforeEach((done) => { beforeEach((done) => {
wrapper = createComponent(); wrapper = createComponent();
wrapper.vm.$nextTick(done); nextTick(done);
}); });
it('should render percentage with completion value provided', () => { it('should render percentage with completion value provided', () => {
...@@ -79,7 +79,7 @@ describe('Deploy Board', () => { ...@@ -79,7 +79,7 @@ describe('Deploy Board', () => {
isEmpty: true, isEmpty: true,
logsPath, logsPath,
}); });
wrapper.vm.$nextTick(done); nextTick(done);
}); });
it('should render the empty state', () => { it('should render the empty state', () => {
...@@ -98,7 +98,7 @@ describe('Deploy Board', () => { ...@@ -98,7 +98,7 @@ describe('Deploy Board', () => {
isEmpty: false, isEmpty: false,
logsPath, logsPath,
}); });
wrapper.vm.$nextTick(done); nextTick(done);
}); });
it('should render loading spinner', () => { it('should render loading spinner', () => {
...@@ -116,7 +116,7 @@ describe('Deploy Board', () => { ...@@ -116,7 +116,7 @@ describe('Deploy Board', () => {
deployBoardData: deployBoardMockData, deployBoardData: deployBoardMockData,
}); });
({ statuses } = wrapper.vm); ({ statuses } = wrapper.vm);
wrapper.vm.$nextTick(done); nextTick(done);
}); });
it('with all the possible statuses', () => { it('with all the possible statuses', () => {
......
import { GlDropdown, GlDropdownItem, GlLoadingIcon, GlIcon } from '@gitlab/ui'; import { GlDropdown, GlDropdownItem, GlLoadingIcon, GlIcon } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils'; import { shallowMount, mount } from '@vue/test-utils';
import Vue from 'vue'; import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
...@@ -108,7 +108,7 @@ describe('EnvironmentActions Component', () => { ...@@ -108,7 +108,7 @@ describe('EnvironmentActions Component', () => {
jest.spyOn(window, 'confirm').mockImplementation(() => confirm); jest.spyOn(window, 'confirm').mockImplementation(() => confirm);
findDropdownItem(scheduledJobAction).vm.$emit('click'); findDropdownItem(scheduledJobAction).vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
}; };
beforeEach(() => { beforeEach(() => {
......
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import CanaryUpdateModal from '~/environments/components/canary_update_modal.vue'; import CanaryUpdateModal from '~/environments/components/canary_update_modal.vue';
import DeployBoard from '~/environments/components/deploy_board.vue'; import DeployBoard from '~/environments/components/deploy_board.vue';
import EnvironmentTable from '~/environments/components/environments_table.vue'; import EnvironmentTable from '~/environments/components/environments_table.vue';
...@@ -181,7 +182,7 @@ describe('Environment table', () => { ...@@ -181,7 +182,7 @@ describe('Environment table', () => {
}); });
wrapper.find(DeployBoard).vm.$emit('changeCanaryWeight', 40); wrapper.find(DeployBoard).vm.$emit('changeCanaryWeight', 40);
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.find(CanaryUpdateModal).props()).toMatchObject({ expect(wrapper.find(CanaryUpdateModal).props()).toMatchObject({
weight: 40, weight: 40,
......
import { GlTabs } from '@gitlab/ui'; import { GlTabs } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils'; import { mount, shallowMount } from '@vue/test-utils';
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 Container from '~/environments/components/container.vue'; import Container from '~/environments/components/container.vue';
import DeployBoard from '~/environments/components/deploy_board.vue'; import DeployBoard from '~/environments/components/deploy_board.vue';
...@@ -186,15 +187,14 @@ describe('Environment', () => { ...@@ -186,15 +187,14 @@ describe('Environment', () => {
expect(wrapper.find('.folder-icon[data-testid="chevron-right-icon"]').exists()).toBe(false); expect(wrapper.find('.folder-icon[data-testid="chevron-right-icon"]').exists()).toBe(false);
}); });
it('should close an opened folder', () => { it('should close an opened folder', async () => {
expect(wrapper.find('.folder-icon[data-testid="chevron-down-icon"]').exists()).toBe(true); expect(wrapper.find('.folder-icon[data-testid="chevron-down-icon"]').exists()).toBe(true);
// close folder // close folder
wrapper.find('.folder-name').trigger('click'); wrapper.find('.folder-name').trigger('click');
wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.find('.folder-icon[data-testid="chevron-down-icon"]').exists()).toBe(false); expect(wrapper.find('.folder-icon[data-testid="chevron-down-icon"]').exists()).toBe(false);
}); });
});
it('should show children environments', () => { it('should show children environments', () => {
expect(wrapper.findAll('.js-child-row').length).toEqual(1); expect(wrapper.findAll('.js-child-row').length).toEqual(1);
......
...@@ -8,7 +8,7 @@ import { ...@@ -8,7 +8,7 @@ import {
GlSprintf, GlSprintf,
} from '@gitlab/ui'; } 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 { import {
severityLevel, severityLevel,
...@@ -139,24 +139,23 @@ describe('ErrorDetails', () => { ...@@ -139,24 +139,23 @@ describe('ErrorDetails', () => {
mountComponent(); mountComponent();
}); });
it('when before timeout, still shows loading', () => { it('when before timeout, still shows loading', async () => {
Date.now.mockReturnValue(endTime - 1); Date.now.mockReturnValue(endTime - 1);
wrapper.vm.onNoApolloResult(); wrapper.vm.onNoApolloResult();
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
expect(createFlash).not.toHaveBeenCalled(); expect(createFlash).not.toHaveBeenCalled();
expect(mocks.$apollo.queries.error.stopPolling).not.toHaveBeenCalled(); expect(mocks.$apollo.queries.error.stopPolling).not.toHaveBeenCalled();
}); });
});
it('when timeout is hit and no apollo result, stops loading and shows flash', () => { it('when timeout is hit and no apollo result, stops loading and shows flash', async () => {
Date.now.mockReturnValue(endTime + 1); Date.now.mockReturnValue(endTime + 1);
wrapper.vm.onNoApolloResult(); wrapper.vm.onNoApolloResult();
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.find(GlLoadingIcon).exists()).toBe(false); expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
expect(wrapper.find(GlLink).exists()).toBe(false); expect(wrapper.find(GlLink).exists()).toBe(false);
expect(createFlash).toHaveBeenCalledWith({ expect(createFlash).toHaveBeenCalledWith({
...@@ -166,7 +165,6 @@ describe('ErrorDetails', () => { ...@@ -166,7 +165,6 @@ describe('ErrorDetails', () => {
expect(mocks.$apollo.queries.error.stopPolling).toHaveBeenCalled(); expect(mocks.$apollo.queries.error.stopPolling).toHaveBeenCalled();
}); });
}); });
});
describe('Error details', () => { describe('Error details', () => {
beforeEach(() => { beforeEach(() => {
...@@ -224,7 +222,7 @@ describe('ErrorDetails', () => { ...@@ -224,7 +222,7 @@ describe('ErrorDetails', () => {
}); });
describe('Badges', () => { describe('Badges', () => {
it('should show language and error level badges', () => { it('should show language and error level badges', 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({
...@@ -232,12 +230,11 @@ describe('ErrorDetails', () => { ...@@ -232,12 +230,11 @@ describe('ErrorDetails', () => {
tags: { level: 'error', logger: 'ruby' }, tags: { level: 'error', logger: 'ruby' },
}, },
}); });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.findAll(GlBadge).length).toBe(2); expect(wrapper.findAll(GlBadge).length).toBe(2);
}); });
});
it('should NOT show the badge if the tag is not present', () => { it('should NOT show the badge if the tag is not present', 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({
...@@ -245,14 +242,13 @@ describe('ErrorDetails', () => { ...@@ -245,14 +242,13 @@ describe('ErrorDetails', () => {
tags: { level: 'error' }, tags: { level: 'error' },
}, },
}); });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.findAll(GlBadge).length).toBe(1); expect(wrapper.findAll(GlBadge).length).toBe(1);
}); });
});
it.each(Object.keys(severityLevel))( it.each(Object.keys(severityLevel))(
'should set correct severity level variant for %s badge', 'should set correct severity level variant for %s badge',
(level) => { async (level) => {
// 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({
...@@ -260,15 +256,14 @@ describe('ErrorDetails', () => { ...@@ -260,15 +256,14 @@ describe('ErrorDetails', () => {
tags: { level: severityLevel[level] }, tags: { level: severityLevel[level] },
}, },
}); });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.find(GlBadge).props('variant')).toEqual( expect(wrapper.find(GlBadge).props('variant')).toEqual(
severityLevelVariant[severityLevel[level]], severityLevelVariant[severityLevel[level]],
); );
});
}, },
); );
it('should fallback for ERROR severityLevelVariant when severityLevel is unknown', () => { it('should fallback for ERROR severityLevelVariant when severityLevel is unknown', 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({
...@@ -276,34 +271,31 @@ describe('ErrorDetails', () => { ...@@ -276,34 +271,31 @@ describe('ErrorDetails', () => {
tags: { level: 'someNewErrorLevel' }, tags: { level: 'someNewErrorLevel' },
}, },
}); });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.find(GlBadge).props('variant')).toEqual( expect(wrapper.find(GlBadge).props('variant')).toEqual(
severityLevelVariant[severityLevel.ERROR], severityLevelVariant[severityLevel.ERROR],
); );
}); });
}); });
});
describe('Stacktrace', () => { describe('Stacktrace', () => {
it('should show stacktrace', () => { it('should show stacktrace', async () => {
store.state.details.loadingStacktrace = false; store.state.details.loadingStacktrace = false;
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.find(GlLoadingIcon).exists()).toBe(false); expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
expect(wrapper.find(Stacktrace).exists()).toBe(true); expect(wrapper.find(Stacktrace).exists()).toBe(true);
expect(findAlert().exists()).toBe(false); expect(findAlert().exists()).toBe(false);
}); });
});
it('should NOT show stacktrace if no entries and show Alert message', () => { it('should NOT show stacktrace if no entries and show Alert message', async () => {
store.state.details.loadingStacktrace = false; store.state.details.loadingStacktrace = false;
store.getters = { 'details/sentryUrl': () => 'sentry.io', 'details/stacktrace': () => [] }; store.getters = { 'details/sentryUrl': () => 'sentry.io', 'details/stacktrace': () => [] };
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.find(GlLoadingIcon).exists()).toBe(false); expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
expect(wrapper.find(Stacktrace).exists()).toBe(false); expect(wrapper.find(Stacktrace).exists()).toBe(false);
expect(findAlert().text()).toBe('No stack trace for this error'); expect(findAlert().text()).toBe('No stack trace for this error');
}); });
}); });
});
describe('When a user clicks the create issue button', () => { describe('When a user clicks the create issue button', () => {
it('should send sentry_issue_identifier', () => { it('should send sentry_issue_identifier', () => {
...@@ -338,10 +330,10 @@ describe('ErrorDetails', () => { ...@@ -338,10 +330,10 @@ describe('ErrorDetails', () => {
}); });
describe('when error is unresolved', () => { describe('when error is unresolved', () => {
beforeEach(() => { beforeEach(async () => {
store.state.details.errorStatus = errorStatus.UNRESOLVED; store.state.details.errorStatus = errorStatus.UNRESOLVED;
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('displays Ignore and Resolve buttons', () => { it('displays Ignore and Resolve buttons', () => {
...@@ -365,10 +357,10 @@ describe('ErrorDetails', () => { ...@@ -365,10 +357,10 @@ describe('ErrorDetails', () => {
}); });
describe('when error is ignored', () => { describe('when error is ignored', () => {
beforeEach(() => { beforeEach(async () => {
store.state.details.errorStatus = errorStatus.IGNORED; store.state.details.errorStatus = errorStatus.IGNORED;
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('displays Undo Ignore and Resolve buttons', () => { it('displays Undo Ignore and Resolve buttons', () => {
...@@ -392,10 +384,10 @@ describe('ErrorDetails', () => { ...@@ -392,10 +384,10 @@ describe('ErrorDetails', () => {
}); });
describe('when error is resolved', () => { describe('when error is resolved', () => {
beforeEach(() => { beforeEach(async () => {
store.state.details.errorStatus = errorStatus.RESOLVED; store.state.details.errorStatus = errorStatus.RESOLVED;
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('displays Ignore and Unresolve buttons', () => { it('displays Ignore and Unresolve buttons', () => {
...@@ -417,7 +409,7 @@ describe('ErrorDetails', () => { ...@@ -417,7 +409,7 @@ describe('ErrorDetails', () => {
); );
}); });
it('should show alert with closed issueId', () => { it('should show alert with closed issueId', async () => {
const closedIssueId = 123; const closedIssueId = 123;
// 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
...@@ -426,13 +418,12 @@ describe('ErrorDetails', () => { ...@@ -426,13 +418,12 @@ describe('ErrorDetails', () => {
closedIssueId, closedIssueId,
}); });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findAlert().exists()).toBe(true); expect(findAlert().exists()).toBe(true);
expect(findAlert().text()).toContain(`#${closedIssueId}`); expect(findAlert().text()).toContain(`#${closedIssueId}`);
}); });
}); });
}); });
});
describe('GitLab issue link', () => { describe('GitLab issue link', () => {
const gitlabIssuePath = 'https://gitlab.example.com/issues/1'; const gitlabIssuePath = 'https://gitlab.example.com/issues/1';
...@@ -495,7 +486,7 @@ describe('ErrorDetails', () => { ...@@ -495,7 +486,7 @@ describe('ErrorDetails', () => {
'/gitlab-org/gitlab-test/commit/7975be0116940bf2ad4321f79d02a55c5f7779aa'; '/gitlab-org/gitlab-test/commit/7975be0116940bf2ad4321f79d02a55c5f7779aa';
const findGitLabCommitLink = () => wrapper.find(`[href$="${gitlabCommitPath}"]`); const findGitLabCommitLink = () => wrapper.find(`[href$="${gitlabCommitPath}"]`);
it('should display a link', () => { it('should display a link', async () => {
mocks.$apollo.queries.error.loading = false; mocks.$apollo.queries.error.loading = false;
// 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
...@@ -505,12 +496,11 @@ describe('ErrorDetails', () => { ...@@ -505,12 +496,11 @@ describe('ErrorDetails', () => {
gitlabCommitPath, gitlabCommitPath,
}, },
}); });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findGitLabCommitLink().exists()).toBe(true); expect(findGitLabCommitLink().exists()).toBe(true);
}); });
});
it('should not display a link', () => { it('should not display a link', async () => {
mocks.$apollo.queries.error.loading = false; mocks.$apollo.queries.error.loading = false;
// 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
...@@ -519,11 +509,10 @@ describe('ErrorDetails', () => { ...@@ -519,11 +509,10 @@ describe('ErrorDetails', () => {
gitlabCommit: null, gitlabCommit: null,
}, },
}); });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findGitLabCommitLink().exists()).toBe(false); expect(findGitLabCommitLink().exists()).toBe(false);
}); });
}); });
});
describe('Release links', () => { describe('Release links', () => {
const firstReleaseVersion = '7975be01'; const firstReleaseVersion = '7975be01';
......
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 ErrorTrackingActions from '~/error_tracking/components/error_tracking_actions.vue'; import ErrorTrackingActions from '~/error_tracking/components/error_tracking_actions.vue';
describe('Error Tracking Actions', () => { describe('Error Tracking Actions', () => {
...@@ -37,41 +38,38 @@ describe('Error Tracking Actions', () => { ...@@ -37,41 +38,38 @@ describe('Error Tracking Actions', () => {
const findButtons = () => wrapper.findAll(GlButton); const findButtons = () => wrapper.findAll(GlButton);
describe('when error status is unresolved', () => { describe('when error status is unresolved', () => {
it('renders the correct actions buttons to allow ignore and resolve', () => { it('renders the correct actions buttons to allow ignore and resolve', async () => {
expect(findButtons().exists()).toBe(true); expect(findButtons().exists()).toBe(true);
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findButtons().at(0).attributes('title')).toBe('Ignore'); expect(findButtons().at(0).attributes('title')).toBe('Ignore');
expect(findButtons().at(1).attributes('title')).toBe('Resolve'); expect(findButtons().at(1).attributes('title')).toBe('Resolve');
}); });
}); });
});
describe('when error status is ignored', () => { describe('when error status is ignored', () => {
beforeEach(() => { beforeEach(() => {
mountComponent({ error: { status: 'ignored' } }); mountComponent({ error: { status: 'ignored' } });
}); });
it('renders the correct action button to undo ignore', () => { it('renders the correct action button to undo ignore', async () => {
expect(findButtons().exists()).toBe(true); expect(findButtons().exists()).toBe(true);
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findButtons().at(0).attributes('title')).toBe('Undo Ignore'); expect(findButtons().at(0).attributes('title')).toBe('Undo Ignore');
}); });
}); });
});
describe('when error status is resolved', () => { describe('when error status is resolved', () => {
beforeEach(() => { beforeEach(() => {
mountComponent({ error: { status: 'resolved' } }); mountComponent({ error: { status: 'resolved' } });
}); });
it('renders the correct action button to undo unresolve', () => { it('renders the correct action button to undo unresolve', async () => {
expect(findButtons().exists()).toBe(true); expect(findButtons().exists()).toBe(true);
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findButtons().at(1).attributes('title')).toBe('Unresolve'); expect(findButtons().at(1).attributes('title')).toBe('Unresolve');
}); });
}); });
});
}); });
import { GlEmptyState, GlLoadingIcon, GlFormInput, GlPagination, GlDropdown } from '@gitlab/ui'; import { GlEmptyState, GlLoadingIcon, GlFormInput, GlPagination, 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 Vuex from 'vuex'; import Vuex from 'vuex';
import stubChildren from 'helpers/stub_children'; import stubChildren from 'helpers/stub_children';
import ErrorTrackingActions from '~/error_tracking/components/error_tracking_actions.vue'; import ErrorTrackingActions from '~/error_tracking/components/error_tracking_actions.vue';
...@@ -316,16 +316,15 @@ describe('ErrorTrackingList', () => { ...@@ -316,16 +316,15 @@ describe('ErrorTrackingList', () => {
expect(findRecentSearchesDropdown().text()).toContain("You don't have any recent searches"); expect(findRecentSearchesDropdown().text()).toContain("You don't have any recent searches");
}); });
it('shows items', () => { it('shows items', async () => {
store.state.list.recentSearches = ['great', 'search']; store.state.list.recentSearches = ['great', 'search'];
return wrapper.vm.$nextTick().then(() => { await nextTick();
const dropdownItems = wrapper.findAll('.filtered-search-box li'); const dropdownItems = wrapper.findAll('.filtered-search-box li');
expect(dropdownItems.length).toBe(3); expect(dropdownItems.length).toBe(3);
expect(dropdownItems.at(0).text()).toBe('great'); expect(dropdownItems.at(0).text()).toBe('great');
expect(dropdownItems.at(1).text()).toBe('search'); expect(dropdownItems.at(1).text()).toBe('search');
}); });
});
describe('clear', () => { describe('clear', () => {
const clearRecentButton = () => wrapper.find({ ref: 'clearRecentSearches' }); const clearRecentButton = () => wrapper.find({ ref: 'clearRecentSearches' });
...@@ -336,26 +335,24 @@ describe('ErrorTrackingList', () => { ...@@ -336,26 +335,24 @@ describe('ErrorTrackingList', () => {
expect(clearRecentButton().exists()).toBe(false); expect(clearRecentButton().exists()).toBe(false);
}); });
it('is visible when list has items', () => { it('is visible when list has items', async () => {
store.state.list.recentSearches = ['some', 'searches']; store.state.list.recentSearches = ['some', 'searches'];
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(clearRecentButton().exists()).toBe(true); expect(clearRecentButton().exists()).toBe(true);
expect(clearRecentButton().text()).toBe('Clear recent searches'); expect(clearRecentButton().text()).toBe('Clear recent searches');
}); });
});
it('clears items on click', () => { it('clears items on click', async () => {
store.state.list.recentSearches = ['some', 'searches']; store.state.list.recentSearches = ['some', 'searches'];
return wrapper.vm.$nextTick().then(() => { await nextTick();
clearRecentButton().vm.$emit('click'); clearRecentButton().vm.$emit('click');
expect(actions.clearRecentSearches).toHaveBeenCalledTimes(1); expect(actions.clearRecentSearches).toHaveBeenCalledTimes(1);
}); });
}); });
}); });
});
describe('When pagination is not required', () => { describe('When pagination is not required', () => {
beforeEach(() => { beforeEach(() => {
...@@ -387,7 +384,7 @@ describe('ErrorTrackingList', () => { ...@@ -387,7 +384,7 @@ describe('ErrorTrackingList', () => {
describe('and the user is not on the first page', () => { describe('and the user is not on the first page', () => {
describe('and the previous button is clicked', () => { describe('and the previous button is clicked', () => {
beforeEach(() => { beforeEach(async () => {
store.state.list.loading = false; store.state.list.loading = false;
mountComponent({ mountComponent({
stubs: { stubs: {
...@@ -398,7 +395,7 @@ describe('ErrorTrackingList', () => { ...@@ -398,7 +395,7 @@ describe('ErrorTrackingList', () => {
// 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({ pageValue: 2 }); wrapper.setData({ pageValue: 2 });
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('fetches the previous page of results', () => { it('fetches the previous page of results', () => {
......
...@@ -79,14 +79,13 @@ describe('error tracking settings app', () => { ...@@ -79,14 +79,13 @@ describe('error tracking settings app', () => {
expect(wrapper.find('.js-error-tracking-button').attributes('disabled')).toBeFalsy(); expect(wrapper.find('.js-error-tracking-button').attributes('disabled')).toBeFalsy();
}); });
it('disables the button when saving', () => { it('disables the button when saving', async () => {
store.state.settingsLoading = true; store.state.settingsLoading = true;
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.find('.js-error-tracking-button').attributes('disabled')).toBeTruthy(); expect(wrapper.find('.js-error-tracking-button').attributes('disabled')).toBeTruthy();
}); });
}); });
});
describe('tracking-backend settings', () => { describe('tracking-backend settings', () => {
it('contains a form-group with the correct label', () => { it('contains a form-group with the correct label', () => {
......
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 Vue from 'vue'; import Vue, { nextTick } from 'vue';
import { pick, clone } from 'lodash'; import { pick, clone } from 'lodash';
import Vuex from 'vuex'; import Vuex from 'vuex';
import ProjectDropdown from '~/error_tracking_settings/components/project_dropdown.vue'; import ProjectDropdown from '~/error_tracking_settings/components/project_dropdown.vue';
...@@ -63,10 +63,10 @@ describe('error tracking settings project dropdown', () => { ...@@ -63,10 +63,10 @@ describe('error tracking settings project dropdown', () => {
}); });
describe('populated project list', () => { describe('populated project list', () => {
beforeEach(() => { beforeEach(async () => {
wrapper.setProps({ projects: clone(projectList), hasProjects: true }); wrapper.setProps({ projects: clone(projectList), hasProjects: true });
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('renders the dropdown', () => { it('renders the dropdown', () => {
...@@ -83,9 +83,9 @@ describe('error tracking settings project dropdown', () => { ...@@ -83,9 +83,9 @@ describe('error tracking settings project dropdown', () => {
describe('selected project', () => { describe('selected project', () => {
const selectedProject = clone(projectList[0]); const selectedProject = clone(projectList[0]);
beforeEach(() => { beforeEach(async () => {
wrapper.setProps({ projects: clone(projectList), selectedProject, hasProjects: true }); wrapper.setProps({ projects: clone(projectList), selectedProject, hasProjects: true });
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('does not show helper text', () => { it('does not show helper text', () => {
...@@ -95,13 +95,13 @@ describe('error tracking settings project dropdown', () => { ...@@ -95,13 +95,13 @@ describe('error tracking settings project dropdown', () => {
}); });
describe('invalid project selected', () => { describe('invalid project selected', () => {
beforeEach(() => { beforeEach(async () => {
wrapper.setProps({ wrapper.setProps({
projects: clone(projectList), projects: clone(projectList),
selectedProject: staleProject, selectedProject: staleProject,
isProjectInvalid: true, isProjectInvalid: true,
}); });
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('displays a error', () => { it('displays a error', () => {
......
import { GlModal, GlSprintf, GlAlert } from '@gitlab/ui'; import { GlModal, GlSprintf, GlAlert } from '@gitlab/ui';
import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import Component from '~/feature_flags/components/configure_feature_flags_modal.vue'; import Component from '~/feature_flags/components/configure_feature_flags_modal.vue';
...@@ -56,7 +57,7 @@ describe('Configure Feature Flags Modal', () => { ...@@ -56,7 +57,7 @@ describe('Configure Feature Flags Modal', () => {
it('should emit a `token` event when clicking on the Primary action', async () => { it('should emit a `token` event when clicking on the Primary action', async () => {
findGlModal().vm.$emit('secondary', mockEvent); findGlModal().vm.$emit('secondary', mockEvent);
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.emitted('token')).toEqual([[]]); expect(wrapper.emitted('token')).toEqual([[]]);
expect(mockEvent.preventDefault).toHaveBeenCalled(); expect(mockEvent.preventDefault).toHaveBeenCalled();
}); });
...@@ -64,7 +65,7 @@ describe('Configure Feature Flags Modal', () => { ...@@ -64,7 +65,7 @@ describe('Configure Feature Flags Modal', () => {
it('should clear the project name input after generating the token', async () => { it('should clear the project name input after generating the token', async () => {
findProjectNameInput().vm.$emit('input', provide.projectName); findProjectNameInput().vm.$emit('input', provide.projectName);
findGlModal().vm.$emit('primary', mockEvent); findGlModal().vm.$emit('primary', mockEvent);
await wrapper.vm.$nextTick(); await nextTick();
expect(findProjectNameInput().attributes('value')).toBe(''); expect(findProjectNameInput().attributes('value')).toBe('');
}); });
...@@ -116,7 +117,7 @@ describe('Configure Feature Flags Modal', () => { ...@@ -116,7 +117,7 @@ describe('Configure Feature Flags Modal', () => {
it('should enable the secondary action', async () => { it('should enable the secondary action', async () => {
findProjectNameInput().vm.$emit('input', provide.projectName); findProjectNameInput().vm.$emit('input', provide.projectName);
await wrapper.vm.$nextTick(); await nextTick();
const [{ disabled }] = findSecondaryAction().attributes; const [{ disabled }] = findSecondaryAction().attributes;
expect(disabled).toBe(false); expect(disabled).toBe(false);
}); });
......
import { GlToggle, GlAlert } from '@gitlab/ui'; import { GlToggle, GlAlert } from '@gitlab/ui';
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 Vue from 'vue'; import Vue, { nextTick } from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { mockTracking } from 'helpers/tracking_helper'; import { mockTracking } from 'helpers/tracking_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
...@@ -12,6 +12,7 @@ import createStore from '~/feature_flags/store/edit'; ...@@ -12,6 +12,7 @@ import createStore from '~/feature_flags/store/edit';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
Vue.use(Vuex); Vue.use(Vuex);
describe('Edit feature flag form', () => { describe('Edit feature flag form', () => {
let wrapper; let wrapper;
let mock; let mock;
...@@ -66,15 +67,14 @@ describe('Edit feature flag form', () => { ...@@ -66,15 +67,14 @@ describe('Edit feature flag form', () => {
}); });
describe('with error', () => { describe('with error', () => {
it('should render the error', () => { it('should render the error', async () => {
store.dispatch('receiveUpdateFeatureFlagError', { message: ['The name is required'] }); store.dispatch('receiveUpdateFeatureFlagError', { message: ['The name is required'] });
return wrapper.vm.$nextTick(() => { await nextTick();
const warningGlAlert = findWarningGlAlert(); const warningGlAlert = findWarningGlAlert();
expect(warningGlAlert.exists()).toEqual(true); expect(warningGlAlert.exists()).toEqual(true);
expect(warningGlAlert.text()).toContain('The name is required'); expect(warningGlAlert.text()).toContain('The name is required');
}); });
}); });
});
describe('without error', () => { describe('without error', () => {
it('renders form title', () => { it('renders form title', () => {
......
import { GlAlert, GlEmptyState, GlLink, GlLoadingIcon } from '@gitlab/ui'; import { GlAlert, GlEmptyState, GlLink, GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import EmptyState from '~/feature_flags/components/empty_state.vue'; import EmptyState from '~/feature_flags/components/empty_state.vue';
const DEFAULT_PROPS = { const DEFAULT_PROPS = {
...@@ -123,7 +124,7 @@ describe('feature_flags/components/feature_flags_tab.vue', () => { ...@@ -123,7 +124,7 @@ describe('feature_flags/components/feature_flags_tab.vue', () => {
beforeEach(async () => { beforeEach(async () => {
wrapper = factory(); wrapper = factory();
await wrapper.vm.$nextTick(); await nextTick();
slot = wrapper.find('[data-testid="test-slot"]'); slot = wrapper.find('[data-testid="test-slot"]');
}); });
......
import { GlLoadingIcon, GlButton, GlSearchBoxByType } from '@gitlab/ui'; import { GlLoadingIcon, GlButton, GlSearchBoxByType } from '@gitlab/ui';
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 { TEST_HOST } from 'spec/test_constants'; import { TEST_HOST } from 'spec/test_constants';
import EnvironmentsDropdown from '~/feature_flags/components/environments_dropdown.vue'; import EnvironmentsDropdown from '~/feature_flags/components/environments_dropdown.vue';
...@@ -54,7 +55,7 @@ describe('Feature flags > Environments dropdown ', () => { ...@@ -54,7 +55,7 @@ describe('Feature flags > Environments dropdown ', () => {
factory(); factory();
findEnvironmentSearchInput().vm.$emit('focus'); findEnvironmentSearchInput().vm.$emit('focus');
await waitForPromises(); await waitForPromises();
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.find('.dropdown-content > ul').exists()).toBe(true); expect(wrapper.find('.dropdown-content > ul').exists()).toBe(true);
expect(wrapper.findAll('.dropdown-content > ul > li').exists()).toBe(true); expect(wrapper.findAll('.dropdown-content > ul > li').exists()).toBe(true);
}); });
...@@ -66,7 +67,7 @@ describe('Feature flags > Environments dropdown ', () => { ...@@ -66,7 +67,7 @@ describe('Feature flags > Environments dropdown ', () => {
factory(); factory();
findEnvironmentSearchInput().vm.$emit('keyup'); findEnvironmentSearchInput().vm.$emit('keyup');
await waitForPromises(); await waitForPromises();
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.find('.dropdown-content > ul').exists()).toBe(true); expect(wrapper.find('.dropdown-content > ul').exists()).toBe(true);
expect(wrapper.findAll('.dropdown-content > ul > li').exists()).toBe(true); expect(wrapper.findAll('.dropdown-content > ul > li').exists()).toBe(true);
}); });
...@@ -80,7 +81,7 @@ describe('Feature flags > Environments dropdown ', () => { ...@@ -80,7 +81,7 @@ describe('Feature flags > Environments dropdown ', () => {
findEnvironmentSearchInput().vm.$emit('focus'); findEnvironmentSearchInput().vm.$emit('focus');
findEnvironmentSearchInput().vm.$emit('input', 'production'); findEnvironmentSearchInput().vm.$emit('input', 'production');
await waitForPromises(); await waitForPromises();
await wrapper.vm.$nextTick(); await nextTick();
}); });
it('sets filter value', () => { it('sets filter value', () => {
...@@ -103,7 +104,7 @@ describe('Feature flags > Environments dropdown ', () => { ...@@ -103,7 +104,7 @@ describe('Feature flags > Environments dropdown ', () => {
.filter((b) => b.text() === 'production') .filter((b) => b.text() === 'production')
.at(0); .at(0);
button.vm.$emit('click'); button.vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.emitted('selectEnvironment')).toEqual([['production']]); expect(wrapper.emitted('selectEnvironment')).toEqual([['production']]);
}); });
}); });
...@@ -111,7 +112,7 @@ describe('Feature flags > Environments dropdown ', () => { ...@@ -111,7 +112,7 @@ describe('Feature flags > Environments dropdown ', () => {
describe('on click clear button', () => { describe('on click clear button', () => {
beforeEach(async () => { beforeEach(async () => {
wrapper.find(GlButton).vm.$emit('click'); wrapper.find(GlButton).vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
}); });
it('resets filter value', () => { it('resets filter value', () => {
...@@ -132,12 +133,12 @@ describe('Feature flags > Environments dropdown ', () => { ...@@ -132,12 +133,12 @@ describe('Feature flags > Environments dropdown ', () => {
findEnvironmentSearchInput().vm.$emit('focus'); findEnvironmentSearchInput().vm.$emit('focus');
findEnvironmentSearchInput().vm.$emit('input', 'production'); findEnvironmentSearchInput().vm.$emit('input', 'production');
await waitForPromises(); await waitForPromises();
await wrapper.vm.$nextTick(); await nextTick();
}); });
it('emits create event', async () => { it('emits create event', async () => {
wrapper.findAll(GlButton).at(0).vm.$emit('click'); wrapper.findAll(GlButton).at(0).vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.emitted('createClicked')).toEqual([['production']]); expect(wrapper.emitted('createClicked')).toEqual([['production']]);
}); });
}); });
......
import { GlAlert, GlEmptyState, GlLoadingIcon } from '@gitlab/ui'; import { GlAlert, GlEmptyState, 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 waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
...@@ -172,7 +172,7 @@ describe('Feature flags', () => { ...@@ -172,7 +172,7 @@ describe('Feature flags', () => {
factory(); factory();
await waitForPromises(); await waitForPromises();
await wrapper.vm.$nextTick(); await nextTick();
emptyState = wrapper.findComponent(GlEmptyState); emptyState = wrapper.findComponent(GlEmptyState);
}); });
......
import { GlToggle, GlBadge } from '@gitlab/ui'; import { GlToggle, GlBadge } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { trimText } from 'helpers/text_helper'; import { trimText } from 'helpers/text_helper';
import { mockTracking } from 'helpers/tracking_helper'; import { mockTracking } from 'helpers/tracking_helper';
import FeatureFlagsTable from '~/feature_flags/components/feature_flags_table.vue'; import FeatureFlagsTable from '~/feature_flags/components/feature_flags_table.vue';
...@@ -148,14 +149,13 @@ describe('Feature flag table', () => { ...@@ -148,14 +149,13 @@ describe('Feature flag table', () => {
}); });
}); });
it('should trigger a toggle event', () => { it('should trigger a toggle event', async () => {
toggle.vm.$emit('change'); toggle.vm.$emit('change');
const flag = { ...props.featureFlags[0], active: !props.featureFlags[0].active }; const flag = { ...props.featureFlags[0], active: !props.featureFlags[0].active };
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted('toggle-flag')).toEqual([[flag]]); expect(wrapper.emitted('toggle-flag')).toEqual([[flag]]);
}); });
});
it('tracks a click', () => { it('tracks a click', () => {
toggle.trigger('click'); toggle.trigger('click');
......
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 { extendedWrapper } from 'helpers/vue_test_utils_helper'; import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import Api from '~/api'; import Api from '~/api';
import Form from '~/feature_flags/components/form.vue'; import Form from '~/feature_flags/components/form.vue';
...@@ -126,28 +127,26 @@ describe('feature flag form', () => { ...@@ -126,28 +127,26 @@ describe('feature flag form', () => {
expect(wrapper.findAll(Strategy)).toHaveLength(2); expect(wrapper.findAll(Strategy)).toHaveLength(2);
}); });
it('adds an all users strategy when clicking the Add button', () => { it('adds an all users strategy when clicking the Add button', async () => {
wrapper.find(GlButton).vm.$emit('click'); wrapper.find(GlButton).vm.$emit('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
const strategies = wrapper.findAll(Strategy); const strategies = wrapper.findAll(Strategy);
expect(strategies).toHaveLength(3); expect(strategies).toHaveLength(3);
expect(strategies.at(2).props('strategy')).toEqual(allUsersStrategy); expect(strategies.at(2).props('strategy')).toEqual(allUsersStrategy);
}); });
});
it('should remove a strategy on delete', () => { it('should remove a strategy on delete', async () => {
const strategy = { const strategy = {
type: ROLLOUT_STRATEGY_PERCENT_ROLLOUT, type: ROLLOUT_STRATEGY_PERCENT_ROLLOUT,
parameters: { percentage: '30' }, parameters: { percentage: '30' },
scopes: [], scopes: [],
}; };
wrapper.find(Strategy).vm.$emit('delete'); wrapper.find(Strategy).vm.$emit('delete');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.findAll(Strategy)).toHaveLength(1); expect(wrapper.findAll(Strategy)).toHaveLength(1);
expect(wrapper.find(Strategy).props('strategy')).not.toEqual(strategy); expect(wrapper.find(Strategy).props('strategy')).not.toEqual(strategy);
}); });
}); });
});
}); });
import { GlLoadingIcon, GlSearchBoxByType, GlDropdownItem } from '@gitlab/ui'; import { GlLoadingIcon, GlSearchBoxByType, GlDropdownItem } from '@gitlab/ui';
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 NewEnvironmentsDropdown from '~/feature_flags/components/new_environments_dropdown.vue'; import NewEnvironmentsDropdown from '~/feature_flags/components/new_environments_dropdown.vue';
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';
...@@ -47,17 +48,14 @@ describe('New Environments Dropdown', () => { ...@@ -47,17 +48,14 @@ describe('New Environments Dropdown', () => {
describe('with empty results', () => { describe('with empty results', () => {
let item; let item;
beforeEach(() => { beforeEach(async () => {
axiosMock.onGet(TEST_HOST).reply(200, []); axiosMock.onGet(TEST_HOST).reply(200, []);
wrapper.find(GlSearchBoxByType).vm.$emit('focus'); wrapper.find(GlSearchBoxByType).vm.$emit('focus');
wrapper.find(GlSearchBoxByType).vm.$emit('input', TEST_SEARCH); wrapper.find(GlSearchBoxByType).vm.$emit('input', TEST_SEARCH);
return axios await axios.waitForAll();
.waitForAll() await nextTick();
.then(() => wrapper.vm.$nextTick())
.then(() => {
item = wrapper.find(GlDropdownItem); item = wrapper.find(GlDropdownItem);
}); });
});
it('should display a Create item label', () => { it('should display a Create item label', () => {
expect(item.text()).toBe('Create production'); expect(item.text()).toBe('Create production');
......
import { GlAlert } from '@gitlab/ui'; import { GlAlert } 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 { TEST_HOST } from 'spec/test_constants'; import { TEST_HOST } from 'spec/test_constants';
import Form from '~/feature_flags/components/form.vue'; import Form from '~/feature_flags/components/form.vue';
...@@ -51,15 +51,14 @@ describe('New feature flag form', () => { ...@@ -51,15 +51,14 @@ describe('New feature flag form', () => {
}); });
describe('with error', () => { describe('with error', () => {
it('should render the error', () => { it('should render the error', async () => {
store.dispatch('receiveCreateFeatureFlagError', { message: ['The name is required'] }); store.dispatch('receiveCreateFeatureFlagError', { message: ['The name is required'] });
return wrapper.vm.$nextTick(() => { await nextTick();
const warningGlAlert = findWarningGlAlert(); const warningGlAlert = findWarningGlAlert();
expect(warningGlAlert.at(0).exists()).toBe(true); expect(warningGlAlert.at(0).exists()).toBe(true);
expect(warningGlAlert.at(0).text()).toContain('The name is required'); expect(warningGlAlert.at(0).text()).toContain('The name is required');
}); });
}); });
});
it('renders form title', () => { it('renders form title', () => {
expect(wrapper.find('h3').text()).toEqual('New feature flag'); expect(wrapper.find('h3').text()).toEqual('New feature flag');
......
import { GlFormInput, GlFormSelect } from '@gitlab/ui'; import { GlFormInput, GlFormSelect } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import FlexibleRollout from '~/feature_flags/components/strategies/flexible_rollout.vue'; import FlexibleRollout from '~/feature_flags/components/strategies/flexible_rollout.vue';
import ParameterFormGroup from '~/feature_flags/components/strategies/parameter_form_group.vue'; import ParameterFormGroup from '~/feature_flags/components/strategies/parameter_form_group.vue';
import { PERCENT_ROLLOUT_GROUP_ID } from '~/feature_flags/constants'; import { PERCENT_ROLLOUT_GROUP_ID } from '~/feature_flags/constants';
...@@ -51,7 +52,7 @@ describe('feature_flags/components/strategies/flexible_rollout.vue', () => { ...@@ -51,7 +52,7 @@ describe('feature_flags/components/strategies/flexible_rollout.vue', () => {
it('emits a change when the percentage value changes', async () => { it('emits a change when the percentage value changes', async () => {
percentageInput.setValue('75'); percentageInput.setValue('75');
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.emitted('change')).toEqual([ expect(wrapper.emitted('change')).toEqual([
[ [
{ {
......
import { GlDropdown, GlDropdownItem, GlSearchBoxByType, GlLoadingIcon } from '@gitlab/ui'; import { GlDropdown, GlDropdownItem, GlSearchBoxByType, 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 Vuex from 'vuex'; import Vuex from 'vuex';
import Api from '~/api'; import Api from '~/api';
import GitlabUserList from '~/feature_flags/components/strategies/gitlab_user_list.vue'; import GitlabUserList from '~/feature_flags/components/strategies/gitlab_user_list.vue';
...@@ -71,7 +71,7 @@ describe('~/feature_flags/components/strategies/gitlab_user_list.vue', () => { ...@@ -71,7 +71,7 @@ describe('~/feature_flags/components/strategies/gitlab_user_list.vue', () => {
); );
const searchWrapper = wrapper.find(GlSearchBoxByType); const searchWrapper = wrapper.find(GlSearchBoxByType);
searchWrapper.vm.$emit('input', 'new'); searchWrapper.vm.$emit('input', 'new');
await wrapper.vm.$nextTick(); await nextTick();
const loadingIcon = wrapper.find(GlLoadingIcon); const loadingIcon = wrapper.find(GlLoadingIcon);
expect(loadingIcon.exists()).toBe(true); expect(loadingIcon.exists()).toBe(true);
...@@ -79,7 +79,7 @@ describe('~/feature_flags/components/strategies/gitlab_user_list.vue', () => { ...@@ -79,7 +79,7 @@ describe('~/feature_flags/components/strategies/gitlab_user_list.vue', () => {
r({ data: [userList] }); r({ data: [userList] });
await wrapper.vm.$nextTick(); await nextTick();
expect(loadingIcon.exists()).toBe(false); expect(loadingIcon.exists()).toBe(false);
}); });
......
import { GlFormInput } from '@gitlab/ui'; import { GlFormInput } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import ParameterFormGroup from '~/feature_flags/components/strategies/parameter_form_group.vue'; import ParameterFormGroup from '~/feature_flags/components/strategies/parameter_form_group.vue';
import PercentRollout from '~/feature_flags/components/strategies/percent_rollout.vue'; import PercentRollout from '~/feature_flags/components/strategies/percent_rollout.vue';
import { PERCENT_ROLLOUT_GROUP_ID } from '~/feature_flags/constants'; import { PERCENT_ROLLOUT_GROUP_ID } from '~/feature_flags/constants';
...@@ -39,7 +40,7 @@ describe('~/feature_flags/components/strategies/percent_rollout.vue', () => { ...@@ -39,7 +40,7 @@ describe('~/feature_flags/components/strategies/percent_rollout.vue', () => {
it('emits a change when the value changes', async () => { it('emits a change when the value changes', async () => {
input.setValue('75'); input.setValue('75');
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.emitted('change')).toEqual([ expect(wrapper.emitted('change')).toEqual([
[{ parameters: { percentage: '75', groupId: PERCENT_ROLLOUT_GROUP_ID } }], [{ parameters: { percentage: '75', groupId: PERCENT_ROLLOUT_GROUP_ID } }],
]); ]);
......
import { GlAlert, GlFormSelect, GlLink, GlToken, GlButton } from '@gitlab/ui'; import { GlAlert, GlFormSelect, GlLink, GlToken, GlButton } 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 Api from '~/api'; import Api from '~/api';
...@@ -85,11 +85,11 @@ describe('Feature flags strategy', () => { ...@@ -85,11 +85,11 @@ describe('Feature flags strategy', () => {
let propsData; let propsData;
let strategy; let strategy;
beforeEach(() => { beforeEach(async () => {
strategy = { name, parameters: {}, scopes: [] }; strategy = { name, parameters: {}, scopes: [] };
propsData = { strategy, index: 0 }; propsData = { strategy, index: 0 };
factory({ propsData, provide }); factory({ propsData, provide });
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('should set the select to match the strategy name', () => { it('should set the select to match the strategy name', () => {
...@@ -138,10 +138,10 @@ describe('Feature flags strategy', () => { ...@@ -138,10 +138,10 @@ describe('Feature flags strategy', () => {
factory({ propsData, provide }); factory({ propsData, provide });
}); });
it('should revert to all-environments scope when last scope is removed', () => { it('should revert to all-environments scope when last scope is removed', async () => {
const token = wrapper.find(GlToken); const token = wrapper.find(GlToken);
token.vm.$emit('close'); token.vm.$emit('close');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.findAll(GlToken)).toHaveLength(0); expect(wrapper.findAll(GlToken)).toHaveLength(0);
expect(last(wrapper.emitted('change'))).toEqual([ expect(last(wrapper.emitted('change'))).toEqual([
{ {
...@@ -152,7 +152,6 @@ describe('Feature flags strategy', () => { ...@@ -152,7 +152,6 @@ describe('Feature flags strategy', () => {
]); ]);
}); });
}); });
});
describe('with an all-environments scope defined', () => { describe('with an all-environments scope defined', () => {
let strategy; let strategy;
...@@ -167,10 +166,10 @@ describe('Feature flags strategy', () => { ...@@ -167,10 +166,10 @@ describe('Feature flags strategy', () => {
factory({ propsData, provide }); factory({ propsData, provide });
}); });
it('should change the parameters if a different strategy is chosen', () => { it('should change the parameters if a different strategy is chosen', async () => {
const select = wrapper.find(GlFormSelect); const select = wrapper.find(GlFormSelect);
select.setValue(ROLLOUT_STRATEGY_ALL_USERS); select.setValue(ROLLOUT_STRATEGY_ALL_USERS);
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(last(wrapper.emitted('change'))).toEqual([ expect(last(wrapper.emitted('change'))).toEqual([
{ {
name: ROLLOUT_STRATEGY_ALL_USERS, name: ROLLOUT_STRATEGY_ALL_USERS,
...@@ -179,33 +178,30 @@ describe('Feature flags strategy', () => { ...@@ -179,33 +178,30 @@ describe('Feature flags strategy', () => {
}, },
]); ]);
}); });
});
it('should display selected scopes', () => { it('should display selected scopes', async () => {
const dropdown = wrapper.find(NewEnvironmentsDropdown); const dropdown = wrapper.find(NewEnvironmentsDropdown);
dropdown.vm.$emit('add', 'production'); dropdown.vm.$emit('add', 'production');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.findAll(GlToken)).toHaveLength(1); expect(wrapper.findAll(GlToken)).toHaveLength(1);
expect(wrapper.find(GlToken).text()).toBe('production'); expect(wrapper.find(GlToken).text()).toBe('production');
}); });
});
it('should display all selected scopes', () => { it('should display all selected scopes', async () => {
const dropdown = wrapper.find(NewEnvironmentsDropdown); const dropdown = wrapper.find(NewEnvironmentsDropdown);
dropdown.vm.$emit('add', 'production'); dropdown.vm.$emit('add', 'production');
dropdown.vm.$emit('add', 'staging'); dropdown.vm.$emit('add', 'staging');
return wrapper.vm.$nextTick().then(() => { await nextTick();
const tokens = wrapper.findAll(GlToken); const tokens = wrapper.findAll(GlToken);
expect(tokens).toHaveLength(2); expect(tokens).toHaveLength(2);
expect(tokens.at(0).text()).toBe('production'); expect(tokens.at(0).text()).toBe('production');
expect(tokens.at(1).text()).toBe('staging'); expect(tokens.at(1).text()).toBe('staging');
}); });
});
it('should emit selected scopes', () => { it('should emit selected scopes', async () => {
const dropdown = wrapper.find(NewEnvironmentsDropdown); const dropdown = wrapper.find(NewEnvironmentsDropdown);
dropdown.vm.$emit('add', 'production'); dropdown.vm.$emit('add', 'production');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(last(wrapper.emitted('change'))).toEqual([ expect(last(wrapper.emitted('change'))).toEqual([
{ {
name: ROLLOUT_STRATEGY_PERCENT_ROLLOUT, name: ROLLOUT_STRATEGY_PERCENT_ROLLOUT,
...@@ -217,7 +213,6 @@ describe('Feature flags strategy', () => { ...@@ -217,7 +213,6 @@ describe('Feature flags strategy', () => {
}, },
]); ]);
}); });
});
it('should emit a delete if the delete button is clicked', () => { it('should emit a delete if the delete button is clicked', () => {
wrapper.find(GlButton).vm.$emit('click'); wrapper.find(GlButton).vm.$emit('click');
...@@ -236,31 +231,29 @@ describe('Feature flags strategy', () => { ...@@ -236,31 +231,29 @@ describe('Feature flags strategy', () => {
factory({ propsData, provide }); factory({ propsData, provide });
}); });
it('should display selected scopes', () => { it('should display selected scopes', async () => {
const dropdown = wrapper.find(NewEnvironmentsDropdown); const dropdown = wrapper.find(NewEnvironmentsDropdown);
dropdown.vm.$emit('add', 'production'); dropdown.vm.$emit('add', 'production');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.findAll(GlToken)).toHaveLength(1); expect(wrapper.findAll(GlToken)).toHaveLength(1);
expect(wrapper.find(GlToken).text()).toBe('production'); expect(wrapper.find(GlToken).text()).toBe('production');
}); });
});
it('should display all selected scopes', () => { it('should display all selected scopes', async () => {
const dropdown = wrapper.find(NewEnvironmentsDropdown); const dropdown = wrapper.find(NewEnvironmentsDropdown);
dropdown.vm.$emit('add', 'production'); dropdown.vm.$emit('add', 'production');
dropdown.vm.$emit('add', 'staging'); dropdown.vm.$emit('add', 'staging');
return wrapper.vm.$nextTick().then(() => { await nextTick();
const tokens = wrapper.findAll(GlToken); const tokens = wrapper.findAll(GlToken);
expect(tokens).toHaveLength(2); expect(tokens).toHaveLength(2);
expect(tokens.at(0).text()).toBe('production'); expect(tokens.at(0).text()).toBe('production');
expect(tokens.at(1).text()).toBe('staging'); expect(tokens.at(1).text()).toBe('staging');
}); });
});
it('should emit selected scopes', () => { it('should emit selected scopes', async () => {
const dropdown = wrapper.find(NewEnvironmentsDropdown); const dropdown = wrapper.find(NewEnvironmentsDropdown);
dropdown.vm.$emit('add', 'production'); dropdown.vm.$emit('add', 'production');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(last(wrapper.emitted('change'))).toEqual([ expect(last(wrapper.emitted('change'))).toEqual([
{ {
name: ROLLOUT_STRATEGY_PERCENT_ROLLOUT, name: ROLLOUT_STRATEGY_PERCENT_ROLLOUT,
...@@ -271,5 +264,4 @@ describe('Feature flags strategy', () => { ...@@ -271,5 +264,4 @@ describe('Feature flags strategy', () => {
}); });
}); });
}); });
});
}); });
import { GlPopover, GlLink, GlButton } from '@gitlab/ui'; import { GlPopover, GlLink, GlButton } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { POPOVER_TARGET_ID } from '~/feature_highlight/constants'; import { POPOVER_TARGET_ID } from '~/feature_highlight/constants';
import { dismiss } from '~/feature_highlight/feature_highlight_helper'; import { dismiss } from '~/feature_highlight/feature_highlight_helper';
import FeatureHighlightPopover from '~/feature_highlight/feature_highlight_popover.vue'; import FeatureHighlightPopover from '~/feature_highlight/feature_highlight_popover.vue';
...@@ -71,7 +72,7 @@ describe('feature_highlight/feature_highlight_popover', () => { ...@@ -71,7 +72,7 @@ describe('feature_highlight/feature_highlight_popover', () => {
it('hides the popover target', async () => { it('hides the popover target', async () => {
await findDismissButton().trigger('click'); await findDismissButton().trigger('click');
findPopover().vm.$emit('hidden'); findPopover().vm.$emit('hidden');
await wrapper.vm.$nextTick(); await nextTick();
expect(findPopoverTarget().exists()).toBe(false); expect(findPopoverTarget().exists()).toBe(false);
}); });
......
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import Vue from 'vue'; import Vue, { nextTick } from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { useLocalStorageSpy } from 'helpers/local_storage_helper'; import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import { mountExtended } from 'helpers/vue_test_utils_helper'; import { mountExtended } from 'helpers/vue_test_utils_helper';
...@@ -97,7 +97,7 @@ describe('Frequent Items App Component', () => { ...@@ -97,7 +97,7 @@ describe('Frequent Items App Component', () => {
triggerDropdownOpen(); triggerDropdownOpen();
store.state[TEST_VUEX_MODULE].isLoadingItems = true; store.state[TEST_VUEX_MODULE].isLoadingItems = true;
await wrapper.vm.$nextTick(); await nextTick();
const loading = findLoading(); const loading = findLoading();
...@@ -119,7 +119,7 @@ describe('Frequent Items App Component', () => { ...@@ -119,7 +119,7 @@ describe('Frequent Items App Component', () => {
expect(findFrequentItems().length).toBe(1); expect(findFrequentItems().length).toBe(1);
triggerDropdownOpen(); triggerDropdownOpen();
await wrapper.vm.$nextTick(); await nextTick();
expect(findFrequentItems().length).toBe(expectedResult.length); expect(findFrequentItems().length).toBe(expectedResult.length);
expect(findFrequentItemsList().props()).toEqual({ expect(findFrequentItemsList().props()).toEqual({
...@@ -135,7 +135,7 @@ describe('Frequent Items App Component', () => { ...@@ -135,7 +135,7 @@ describe('Frequent Items App Component', () => {
mock.onGet(/\/api\/v4\/projects.json(.*)$/).replyOnce(200, mockSearchedProjects.data); mock.onGet(/\/api\/v4\/projects.json(.*)$/).replyOnce(200, mockSearchedProjects.data);
setSearch('gitlab'); setSearch('gitlab');
await wrapper.vm.$nextTick(); await nextTick();
expect(findLoading().exists()).toBe(true); expect(findLoading().exists()).toBe(true);
......
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 frequentItemsListComponent from '~/frequent_items/components/frequent_items_list.vue'; import frequentItemsListComponent from '~/frequent_items/components/frequent_items_list.vue';
import frequentItemsListItemComponent from '~/frequent_items/components/frequent_items_list_item.vue'; import frequentItemsListItemComponent from '~/frequent_items/components/frequent_items_list_item.vue';
...@@ -44,7 +44,7 @@ describe('FrequentItemsListComponent', () => { ...@@ -44,7 +44,7 @@ describe('FrequentItemsListComponent', () => {
wrapper.setProps({ wrapper.setProps({
items: mockFrequentProjects, items: mockFrequentProjects,
}); });
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.vm.isListEmpty).toBe(false); expect(wrapper.vm.isListEmpty).toBe(false);
}); });
...@@ -63,7 +63,7 @@ describe('FrequentItemsListComponent', () => { ...@@ -63,7 +63,7 @@ describe('FrequentItemsListComponent', () => {
wrapper.setProps({ wrapper.setProps({
isFetchFailed: false, isFetchFailed: false,
}); });
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.vm.listEmptyMessage).toBe('Projects you visit often will appear here'); expect(wrapper.vm.listEmptyMessage).toBe('Projects you visit often will appear here');
}); });
...@@ -81,7 +81,7 @@ describe('FrequentItemsListComponent', () => { ...@@ -81,7 +81,7 @@ describe('FrequentItemsListComponent', () => {
wrapper.setProps({ wrapper.setProps({
isFetchFailed: false, isFetchFailed: false,
}); });
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.vm.listEmptyMessage).toBe('Sorry, no projects matched your search'); expect(wrapper.vm.listEmptyMessage).toBe('Sorry, no projects matched your search');
}); });
...@@ -89,25 +89,23 @@ describe('FrequentItemsListComponent', () => { ...@@ -89,25 +89,23 @@ describe('FrequentItemsListComponent', () => {
}); });
describe('template', () => { describe('template', () => {
it('should render component element with list of projects', () => { it('should render component element with list of projects', async () => {
createComponent(); createComponent();
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.classes('frequent-items-list-container')).toBe(true); expect(wrapper.classes('frequent-items-list-container')).toBe(true);
expect(wrapper.findAll({ ref: 'frequentItemsList' })).toHaveLength(1); expect(wrapper.findAll({ ref: 'frequentItemsList' })).toHaveLength(1);
expect(wrapper.findAll(frequentItemsListItemComponent)).toHaveLength(5); expect(wrapper.findAll(frequentItemsListItemComponent)).toHaveLength(5);
}); });
});
it('should render component element with empty message', () => { it('should render component element with empty message', async () => {
createComponent({ createComponent({
items: [], items: [],
}); });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.vm.$el.querySelectorAll('li.section-empty')).toHaveLength(1); expect(wrapper.vm.$el.querySelectorAll('li.section-empty')).toHaveLength(1);
expect(wrapper.findAll(frequentItemsListItemComponent)).toHaveLength(0); expect(wrapper.findAll(frequentItemsListItemComponent)).toHaveLength(0);
}); });
}); });
});
}); });
import { GlSearchBoxByType } from '@gitlab/ui'; import { GlSearchBoxByType } 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 { mockTracking, unmockTracking } from 'helpers/tracking_helper'; import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import searchComponent from '~/frequent_items/components/frequent_items_search_input.vue'; import searchComponent from '~/frequent_items/components/frequent_items_search_input.vue';
...@@ -61,7 +61,7 @@ describe('FrequentItemsSearchInputComponent', () => { ...@@ -61,7 +61,7 @@ describe('FrequentItemsSearchInputComponent', () => {
findSearchBoxByType().vm.$emit('input', value); findSearchBoxByType().vm.$emit('input', value);
await wrapper.vm.$nextTick(); await nextTick();
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'type_search_query', { expect(trackingSpy).toHaveBeenCalledWith(undefined, 'type_search_query', {
label: 'projects_dropdown_frequent_items_search_input', label: 'projects_dropdown_frequent_items_search_input',
......
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 { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
import { mountExtended } from 'helpers/vue_test_utils_helper'; import { mountExtended } from 'helpers/vue_test_utils_helper';
import createFlash from '~/flash'; import createFlash from '~/flash';
...@@ -93,29 +94,28 @@ describe('grafana integration component', () => { ...@@ -93,29 +94,28 @@ describe('grafana integration component', () => {
}, },
]; ];
it('submits form on click', () => { it('submits form on click', async () => {
axios.patch.mockResolvedValue(); axios.patch.mockResolvedValue();
findSubmitButton(wrapper).trigger('click'); findSubmitButton(wrapper).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 () => {
const message = 'mockErrorMessage'; const message = 'mockErrorMessage';
axios.patch.mockRejectedValue({ response: { data: { message } } }); axios.patch.mockRejectedValue({ response: { data: { message } } });
findSubmitButton().trigger('click'); findSubmitButton().trigger('click');
expect(axios.patch).toHaveBeenCalledWith(...endpointRequest); expect(axios.patch).toHaveBeenCalledWith(...endpointRequest);
return wrapper.vm
.$nextTick() await nextTick();
.then(jest.runAllTicks) await jest.runAllTicks();
.then(() =>
expect(createFlash).toHaveBeenCalledWith({ expect(createFlash).toHaveBeenCalledWith({
message: `There was an error saving your changes. ${message}`, message: `There was an error saving your changes. ${message}`,
}), });
);
}); });
}); });
}); });
......
import { GlLoadingIcon, GlAlert } from '@gitlab/ui'; import { GlLoadingIcon, GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import MockAxiosAdapter from 'axios-mock-adapter'; import MockAxiosAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import SharedRunnersForm from '~/group_settings/components/shared_runners_form.vue'; import SharedRunnersForm from '~/group_settings/components/shared_runners_form.vue';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
...@@ -76,7 +77,7 @@ describe('group_settings/components/shared_runners_form', () => { ...@@ -76,7 +77,7 @@ describe('group_settings/components/shared_runners_form', () => {
findEnabledToggle().vm.$emit('change', true); findEnabledToggle().vm.$emit('change', true);
await wrapper.vm.$nextTick(); await nextTick();
expect(isLoadingIconVisible()).toBe(true); expect(isLoadingIconVisible()).toBe(true);
......
import { GlBanner } from '@gitlab/ui'; import { GlBanner } from '@gitlab/ui';
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 { mockTracking, unmockTracking } from 'helpers/tracking_helper'; import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import InviteMembersBanner from '~/groups/components/invite_members_banner.vue'; import InviteMembersBanner from '~/groups/components/invite_members_banner.vue';
import eventHub from '~/invite_members/event_hub'; import eventHub from '~/invite_members/event_hub';
...@@ -140,7 +141,7 @@ describe('InviteMembersBanner', () => { ...@@ -140,7 +141,7 @@ describe('InviteMembersBanner', () => {
expect(wrapper.find(GlBanner).exists()).toBe(true); expect(wrapper.find(GlBanner).exists()).toBe(true);
wrapper.find(GlBanner).vm.$emit('close'); wrapper.find(GlBanner).vm.$emit('close');
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.find(GlBanner).exists()).toBe(false); expect(wrapper.find(GlBanner).exists()).toBe(false);
}); });
}); });
......
import { GlSearchBoxByType } from '@gitlab/ui'; import { GlSearchBoxByType } from '@gitlab/ui';
import Vue from 'vue'; import Vue, { nextTick } from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import HeaderSearchApp from '~/header_search/components/app.vue'; import HeaderSearchApp from '~/header_search/components/app.vue';
...@@ -202,7 +202,7 @@ describe('HeaderSearchApp', () => { ...@@ -202,7 +202,7 @@ describe('HeaderSearchApp', () => {
expect(findHeaderSearchDropdown().exists()).toBe(false); expect(findHeaderSearchDropdown().exists()).toBe(false);
findHeaderSearchInput().vm.$emit('focus'); findHeaderSearchInput().vm.$emit('focus');
await wrapper.vm.$nextTick(); await nextTick();
expect(findHeaderSearchDropdown().exists()).toBe(true); expect(findHeaderSearchDropdown().exists()).toBe(true);
}); });
...@@ -211,7 +211,7 @@ describe('HeaderSearchApp', () => { ...@@ -211,7 +211,7 @@ describe('HeaderSearchApp', () => {
expect(findHeaderSearchDropdown().exists()).toBe(false); expect(findHeaderSearchDropdown().exists()).toBe(false);
findHeaderSearchInput().vm.$emit('click'); findHeaderSearchInput().vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(findHeaderSearchDropdown().exists()).toBe(true); expect(findHeaderSearchDropdown().exists()).toBe(true);
}); });
...@@ -265,7 +265,7 @@ describe('HeaderSearchApp', () => { ...@@ -265,7 +265,7 @@ describe('HeaderSearchApp', () => {
expect(findHeaderSearchDropdown().exists()).toBe(true); expect(findHeaderSearchDropdown().exists()).toBe(true);
findDropdownKeyboardNavigation().vm.$emit('tab'); findDropdownKeyboardNavigation().vm.$emit('tab');
await wrapper.vm.$nextTick(); await nextTick();
expect(findHeaderSearchDropdown().exists()).toBe(false); expect(findHeaderSearchDropdown().exists()).toBe(false);
}); });
...@@ -284,7 +284,7 @@ describe('HeaderSearchApp', () => { ...@@ -284,7 +284,7 @@ describe('HeaderSearchApp', () => {
it(`when currentFocusIndex changes to ${MOCK_INDEX} updates the data to searchOptions[${MOCK_INDEX}]`, async () => { it(`when currentFocusIndex changes to ${MOCK_INDEX} updates the data to searchOptions[${MOCK_INDEX}]`, async () => {
findDropdownKeyboardNavigation().vm.$emit('change', MOCK_INDEX); findDropdownKeyboardNavigation().vm.$emit('change', MOCK_INDEX);
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.vm.currentFocusedOption).toBe(MOCK_DEFAULT_SEARCH_OPTIONS[MOCK_INDEX]); expect(wrapper.vm.currentFocusedOption).toBe(MOCK_DEFAULT_SEARCH_OPTIONS[MOCK_INDEX]);
}); });
}); });
...@@ -299,7 +299,7 @@ describe('HeaderSearchApp', () => { ...@@ -299,7 +299,7 @@ describe('HeaderSearchApp', () => {
it('onKey-enter submits a search', async () => { it('onKey-enter submits a search', async () => {
findHeaderSearchInput().vm.$emit('keydown', new KeyboardEvent({ key: ENTER_KEY })); findHeaderSearchInput().vm.$emit('keydown', new KeyboardEvent({ key: ENTER_KEY }));
await wrapper.vm.$nextTick(); await nextTick();
expect(visitUrl).toHaveBeenCalledWith(MOCK_SEARCH_QUERY); expect(visitUrl).toHaveBeenCalledWith(MOCK_SEARCH_QUERY);
}); });
...@@ -316,7 +316,7 @@ describe('HeaderSearchApp', () => { ...@@ -316,7 +316,7 @@ describe('HeaderSearchApp', () => {
it('onKey-enter clicks the selected dropdown item rather than submitting a search', async () => { it('onKey-enter clicks the selected dropdown item rather than submitting a search', async () => {
findDropdownKeyboardNavigation().vm.$emit('change', MOCK_INDEX); findDropdownKeyboardNavigation().vm.$emit('change', MOCK_INDEX);
await wrapper.vm.$nextTick(); await nextTick();
findHeaderSearchInput().vm.$emit('keydown', new KeyboardEvent({ key: ENTER_KEY })); findHeaderSearchInput().vm.$emit('keydown', new KeyboardEvent({ key: ENTER_KEY }));
expect(visitUrl).toHaveBeenCalledWith(MOCK_DEFAULT_SEARCH_OPTIONS[MOCK_INDEX].url); expect(visitUrl).toHaveBeenCalledWith(MOCK_DEFAULT_SEARCH_OPTIONS[MOCK_INDEX].url);
}); });
......
import { GlDropdownItem, GlLoadingIcon, GlAvatar } from '@gitlab/ui'; import { GlDropdownItem, GlLoadingIcon, GlAvatar } 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 HeaderSearchAutocompleteItems from '~/header_search/components/header_search_autocomplete_items.vue'; import HeaderSearchAutocompleteItems from '~/header_search/components/header_search_autocomplete_items.vue';
import { import {
...@@ -143,7 +143,7 @@ describe('HeaderSearchAutocompleteItems', () => { ...@@ -143,7 +143,7 @@ describe('HeaderSearchAutocompleteItems', () => {
wrapper.setProps({ currentFocusedOption: MOCK_SORTED_AUTOCOMPLETE_OPTIONS[0] }); wrapper.setProps({ currentFocusedOption: MOCK_SORTED_AUTOCOMPLETE_OPTIONS[0] });
await wrapper.vm.$nextTick(); await nextTick();
expect(scrollSpy).toHaveBeenCalledWith(false); expect(scrollSpy).toHaveBeenCalledWith(false);
scrollSpy.mockRestore(); scrollSpy.mockRestore();
......
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } 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 Item from '~/ide/components/branches/item.vue'; import Item from '~/ide/components/branches/item.vue';
import List from '~/ide/components/branches/search_list.vue'; import List from '~/ide/components/branches/search_list.vue';
...@@ -50,14 +50,13 @@ describe('IDE branches search list', () => { ...@@ -50,14 +50,13 @@ describe('IDE branches search list', () => {
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
}); });
it('renders branches not found when search is not empty and branches list is empty', () => { it('renders branches not found when search is not empty and branches list is empty', async () => {
createComponent({ branches: [] }); createComponent({ branches: [] });
wrapper.find('input[type="search"]').setValue('something'); wrapper.find('input[type="search"]').setValue('something');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.text()).toContain(__('No branches found')); expect(wrapper.text()).toContain(__('No branches found'));
}); });
});
describe('with branches', () => { describe('with branches', () => {
it('renders list', () => { it('renders list', () => {
......
import { GlModal } from '@gitlab/ui'; import { GlModal } 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 { stubComponent } from 'helpers/stub_component'; import { stubComponent } from 'helpers/stub_component';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
...@@ -98,7 +98,7 @@ describe('IDE commit form', () => { ...@@ -98,7 +98,7 @@ describe('IDE commit form', () => {
it(`at view=${viewFn.name}, ${buttonFn.name} has disabled=${disabled} tooltip=${tooltip}`, async () => { it(`at view=${viewFn.name}, ${buttonFn.name} has disabled=${disabled} tooltip=${tooltip}`, async () => {
viewFn(); viewFn();
await wrapper.vm.$nextTick(); await nextTick();
expect(buttonFn()).toEqual({ expect(buttonFn()).toEqual({
disabled, disabled,
...@@ -116,7 +116,7 @@ describe('IDE commit form', () => { ...@@ -116,7 +116,7 @@ describe('IDE commit form', () => {
goToEditView(); goToEditView();
await wrapper.vm.$nextTick(); await nextTick();
}); });
it('renders commit button in compact mode', () => { it('renders commit button in compact mode', () => {
...@@ -135,7 +135,7 @@ describe('IDE commit form', () => { ...@@ -135,7 +135,7 @@ describe('IDE commit form', () => {
it('when begin commit button is clicked, shows form', async () => { it('when begin commit button is clicked, shows form', async () => {
findBeginCommitButton().vm.$emit('click'); findBeginCommitButton().vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(findForm().exists()).toBe(true); expect(findForm().exists()).toBe(true);
}); });
...@@ -143,7 +143,7 @@ describe('IDE commit form', () => { ...@@ -143,7 +143,7 @@ describe('IDE commit form', () => {
it('when begin commit button is clicked, sets activity view', async () => { it('when begin commit button is clicked, sets activity view', async () => {
findBeginCommitButton().vm.$emit('click'); findBeginCommitButton().vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(store.state.currentActivityView).toBe(leftSidebarViews.commit.name); expect(store.state.currentActivityView).toBe(leftSidebarViews.commit.name);
}); });
...@@ -153,14 +153,14 @@ describe('IDE commit form', () => { ...@@ -153,14 +153,14 @@ describe('IDE commit form', () => {
setLastCommitMessage('test'); setLastCommitMessage('test');
goToEditView(); goToEditView();
await wrapper.vm.$nextTick(); await nextTick();
expect(findForm().exists()).toBe(true); expect(findForm().exists()).toBe(true);
// Now test that it collapses when lastCommitMsg is cleared // Now test that it collapses when lastCommitMsg is cleared
setLastCommitMessage(''); setLastCommitMessage('');
await wrapper.vm.$nextTick(); await nextTick();
expect(findForm().exists()).toBe(false); expect(findForm().exists()).toBe(false);
}); });
...@@ -177,7 +177,7 @@ describe('IDE commit form', () => { ...@@ -177,7 +177,7 @@ describe('IDE commit form', () => {
goToCommitView(); goToCommitView();
await wrapper.vm.$nextTick(); await nextTick();
}); });
afterEach(() => { afterEach(() => {
...@@ -188,12 +188,12 @@ describe('IDE commit form', () => { ...@@ -188,12 +188,12 @@ describe('IDE commit form', () => {
expect(findForm().exists()).toBe(false); expect(findForm().exists()).toBe(false);
store.state.stagedFiles = []; store.state.stagedFiles = [];
await wrapper.vm.$nextTick(); await nextTick();
expect(findForm().exists()).toBe(false); expect(findForm().exists()).toBe(false);
store.state.stagedFiles.push('test'); store.state.stagedFiles.push('test');
await wrapper.vm.$nextTick(); await nextTick();
expect(findForm().exists()).toBe(false); expect(findForm().exists()).toBe(false);
}); });
...@@ -208,7 +208,7 @@ describe('IDE commit form', () => { ...@@ -208,7 +208,7 @@ describe('IDE commit form', () => {
goToCommitView(); goToCommitView();
await wrapper.vm.$nextTick(); await nextTick();
}); });
it('shows form', () => { it('shows form', () => {
...@@ -222,7 +222,7 @@ describe('IDE commit form', () => { ...@@ -222,7 +222,7 @@ describe('IDE commit form', () => {
describe('when no changed files', () => { describe('when no changed files', () => {
beforeEach(async () => { beforeEach(async () => {
store.state.stagedFiles = []; store.state.stagedFiles = [];
await wrapper.vm.$nextTick(); await nextTick();
}); });
it('hides form', () => { it('hides form', () => {
...@@ -231,7 +231,7 @@ describe('IDE commit form', () => { ...@@ -231,7 +231,7 @@ describe('IDE commit form', () => {
it('expands again when staged files are added', async () => { it('expands again when staged files are added', async () => {
store.state.stagedFiles.push('test'); store.state.stagedFiles.push('test');
await wrapper.vm.$nextTick(); await nextTick();
expect(findForm().exists()).toBe(true); expect(findForm().exists()).toBe(true);
}); });
...@@ -240,7 +240,7 @@ describe('IDE commit form', () => { ...@@ -240,7 +240,7 @@ describe('IDE commit form', () => {
it('updates commitMessage in store on input', async () => { it('updates commitMessage in store on input', async () => {
setCommitMessageInput('testing commit message'); setCommitMessageInput('testing commit message');
await wrapper.vm.$nextTick(); await nextTick();
expect(store.state.commit.commitMessage).toBe('testing commit message'); expect(store.state.commit.commitMessage).toBe('testing commit message');
}); });
...@@ -253,14 +253,14 @@ describe('IDE commit form', () => { ...@@ -253,14 +253,14 @@ describe('IDE commit form', () => {
it('resets commitMessage when clicking discard button', async () => { it('resets commitMessage when clicking discard button', async () => {
setCommitMessageInput('testing commit message'); setCommitMessageInput('testing commit message');
await wrapper.vm.$nextTick(); await nextTick();
expect(findCommitMessageInput().props('text')).toBe('testing commit message'); expect(findCommitMessageInput().props('text')).toBe('testing commit message');
// Test that commitMessage is cleared on click // Test that commitMessage is cleared on click
findDiscardDraftButton().vm.$emit('click'); findDiscardDraftButton().vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(findCommitMessageInput().props('text')).toBe(''); expect(findCommitMessageInput().props('text')).toBe('');
}); });
...@@ -274,11 +274,11 @@ describe('IDE commit form', () => { ...@@ -274,11 +274,11 @@ describe('IDE commit form', () => {
goToCommitView(); goToCommitView();
await wrapper.vm.$nextTick(); await nextTick();
setCommitMessageInput('testing commit message'); setCommitMessageInput('testing commit message');
await wrapper.vm.$nextTick(); await nextTick();
jest.spyOn(store, 'dispatch').mockResolvedValue(); jest.spyOn(store, 'dispatch').mockResolvedValue();
}); });
...@@ -291,7 +291,7 @@ describe('IDE commit form', () => { ...@@ -291,7 +291,7 @@ describe('IDE commit form', () => {
it('when cannot push code, submitting does nothing', async () => { it('when cannot push code, submitting does nothing', async () => {
store.state.projects.abcproject.userPermissions.pushCode = false; store.state.projects.abcproject.userPermissions.pushCode = false;
await wrapper.vm.$nextTick(); await nextTick();
submitForm(); submitForm();
...@@ -309,7 +309,7 @@ describe('IDE commit form', () => { ...@@ -309,7 +309,7 @@ describe('IDE commit form', () => {
const error = createError(); const error = createError();
store.state.commit.commitError = error; store.state.commit.commitError = error;
await wrapper.vm.$nextTick(); await nextTick();
expect(modal.vm.show).toHaveBeenCalled(); expect(modal.vm.show).toHaveBeenCalled();
expect(modal.props()).toMatchObject({ expect(modal.props()).toMatchObject({
...@@ -342,7 +342,7 @@ describe('IDE commit form', () => { ...@@ -342,7 +342,7 @@ describe('IDE commit form', () => {
async ({ commitError, expectedActions }) => { async ({ commitError, expectedActions }) => {
store.state.commit.commitError = commitError('test message'); store.state.commit.commitError = commitError('test message');
await wrapper.vm.$nextTick(); await nextTick();
wrapper.find(GlModal).vm.$emit('ok'); wrapper.find(GlModal).vm.$emit('ok');
......
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 Vuex from 'vuex'; import Vuex from 'vuex';
import ErrorMessage from '~/ide/components/error_message.vue'; import ErrorMessage from '~/ide/components/error_message.vue';
...@@ -86,19 +86,15 @@ describe('IDE error message component', () => { ...@@ -86,19 +86,15 @@ describe('IDE error message component', () => {
expect(actionMock).toHaveBeenCalledWith(message.actionPayload); expect(actionMock).toHaveBeenCalledWith(message.actionPayload);
}); });
it('does not dispatch action when already loading', () => { it('does not dispatch action when already loading', async () => {
findActionButton().trigger('click'); findActionButton().trigger('click');
actionMock.mockReset(); actionMock.mockReset();
return wrapper.vm.$nextTick(() => {
findActionButton().trigger('click'); findActionButton().trigger('click');
await nextTick();
return wrapper.vm.$nextTick().then(() => {
expect(actionMock).not.toHaveBeenCalled(); expect(actionMock).not.toHaveBeenCalled();
}); });
});
});
it('shows loading icon when loading', () => { it('shows loading icon when loading', async () => {
let resolveAction; let resolveAction;
actionMock.mockImplementation( actionMock.mockImplementation(
() => () =>
...@@ -108,19 +104,16 @@ describe('IDE error message component', () => { ...@@ -108,19 +104,16 @@ describe('IDE error message component', () => {
); );
findActionButton().trigger('click'); findActionButton().trigger('click');
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.find(GlLoadingIcon).isVisible()).toBe(true); expect(wrapper.find(GlLoadingIcon).isVisible()).toBe(true);
resolveAction(); resolveAction();
}); });
});
it('hides loading icon when operation finishes', () => { it('hides loading icon when operation finishes', async () => {
findActionButton().trigger('click'); findActionButton().trigger('click');
return actionMock() await actionMock();
.then(() => wrapper.vm.$nextTick()) await nextTick();
.then(() => {
expect(wrapper.find(GlLoadingIcon).isVisible()).toBe(false); expect(wrapper.find(GlLoadingIcon).isVisible()).toBe(false);
}); });
}); });
});
}); });
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } 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 $ from 'jquery'; import $ from 'jquery';
import Vuex from 'vuex'; import Vuex from 'vuex';
import Dropdown from '~/ide/components/file_templates/dropdown.vue'; import Dropdown from '~/ide/components/file_templates/dropdown.vue';
...@@ -54,16 +54,15 @@ describe('IDE file templates dropdown component', () => { ...@@ -54,16 +54,15 @@ describe('IDE file templates dropdown component', () => {
wrapper = null; wrapper = null;
}); });
it('calls clickItem on click', () => { it('calls clickItem on click', async () => {
const itemData = { name: 'test.yml ' }; const itemData = { name: 'test.yml ' };
createComponent({ props: { data: [itemData] } }); createComponent({ props: { data: [itemData] } });
const item = findItemButtons().at(0); const item = findItemButtons().at(0);
item.trigger('click'); item.trigger('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted().click[0][0]).toBe(itemData); expect(wrapper.emitted().click[0][0]).toBe(itemData);
}); });
});
it('renders dropdown title', () => { it('renders dropdown title', () => {
const title = 'Test title'; const title = 'Test title';
...@@ -111,7 +110,7 @@ describe('IDE file templates dropdown component', () => { ...@@ -111,7 +110,7 @@ describe('IDE file templates dropdown component', () => {
expect(items.wrappers.map((x) => x.text())).toEqual(templates.map((x) => x.name)); expect(items.wrappers.map((x) => x.text())).toEqual(templates.map((x) => x.name));
}); });
it('searches template data', () => { it('searches template data', async () => {
const templates = [{ name: 'match 1' }, { name: 'other' }, { name: 'match 2' }]; const templates = [{ name: 'match 1' }, { name: 'other' }, { name: 'match 2' }];
const matches = ['match 1', 'match 2']; const matches = ['match 1', 'match 2'];
createComponent({ createComponent({
...@@ -119,13 +118,12 @@ describe('IDE file templates dropdown component', () => { ...@@ -119,13 +118,12 @@ describe('IDE file templates dropdown component', () => {
state: { templates }, state: { templates },
}); });
findSearch().setValue('match'); findSearch().setValue('match');
return wrapper.vm.$nextTick().then(() => { await nextTick();
const items = findItemButtons(); const items = findItemButtons();
expect(items.length).toBe(matches.length); expect(items.length).toBe(matches.length);
expect(items.wrappers.map((x) => x.text())).toEqual(matches); expect(items.wrappers.map((x) => x.text())).toEqual(matches);
}); });
});
it('does not render input when `searchable` is true & `showLoading` is true', () => { it('does not render input when `searchable` is true & `showLoading` is true', () => {
createComponent({ createComponent({
...@@ -159,17 +157,16 @@ describe('IDE file templates dropdown component', () => { ...@@ -159,17 +157,16 @@ describe('IDE file templates dropdown component', () => {
expect(findSearch().exists()).toBe(true); expect(findSearch().exists()).toBe(true);
}); });
it('searches data', () => { it('searches data', async () => {
const data = [{ name: 'match 1' }, { name: 'other' }, { name: 'match 2' }]; const data = [{ name: 'match 1' }, { name: 'other' }, { name: 'match 2' }];
const matches = ['match 1', 'match 2']; const matches = ['match 1', 'match 2'];
createComponent({ props: { searchable: true, data } }); createComponent({ props: { searchable: true, data } });
findSearch().setValue('match'); findSearch().setValue('match');
return wrapper.vm.$nextTick().then(() => { await nextTick();
const items = findItemButtons(); const items = findItemButtons();
expect(items.length).toBe(matches.length); expect(items.length).toBe(matches.length);
expect(items.wrappers.map((x) => x.text())).toEqual(matches); expect(items.wrappers.map((x) => x.text())).toEqual(matches);
}); });
}); });
});
}); });
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 FileRowExtra from '~/ide/components/file_row_extra.vue'; import FileRowExtra from '~/ide/components/file_row_extra.vue';
import IdeFileRow from '~/ide/components/ide_file_row.vue'; import IdeFileRow from '~/ide/components/ide_file_row.vue';
...@@ -43,7 +43,7 @@ describe('Ide File Row component', () => { ...@@ -43,7 +43,7 @@ describe('Ide File Row component', () => {
const findFileRow = () => wrapper.find(FileRow); const findFileRow = () => wrapper.find(FileRow);
const hasDropdownOpen = () => findFileRowExtra().props('dropdownOpen'); const hasDropdownOpen = () => findFileRowExtra().props('dropdownOpen');
it('fileRow component has listeners', () => { it('fileRow component has listeners', async () => {
const toggleTreeOpen = jest.fn(); const toggleTreeOpen = jest.fn();
createComponent( createComponent(
{}, {},
...@@ -56,10 +56,9 @@ describe('Ide File Row component', () => { ...@@ -56,10 +56,9 @@ describe('Ide File Row component', () => {
findFileRow().vm.$emit('toggleTreeOpen'); findFileRow().vm.$emit('toggleTreeOpen');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(toggleTreeOpen).toHaveBeenCalled(); expect(toggleTreeOpen).toHaveBeenCalled();
}); });
});
describe('default', () => { describe('default', () => {
beforeEach(() => { beforeEach(() => {
...@@ -85,32 +84,30 @@ describe('Ide File Row component', () => { ...@@ -85,32 +84,30 @@ describe('Ide File Row component', () => {
}); });
describe('with open dropdown', () => { describe('with open dropdown', () => {
beforeEach(() => { beforeEach(async () => {
createComponent(); createComponent();
findFileRowExtra().vm.$emit('toggle', true); findFileRowExtra().vm.$emit('toggle', true);
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('shows open dropdown', () => { it('shows open dropdown', () => {
expect(hasDropdownOpen()).toBe(true); expect(hasDropdownOpen()).toBe(true);
}); });
it('hides dropdown when mouseleave', () => { it('hides dropdown when mouseleave', async () => {
findFileRow().vm.$emit('mouseleave'); findFileRow().vm.$emit('mouseleave');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(hasDropdownOpen()).toEqual(false); expect(hasDropdownOpen()).toEqual(false);
}); });
});
it('hides dropdown on toggle', () => { it('hides dropdown on toggle', async () => {
findFileRowExtra().vm.$emit('toggle', false); findFileRowExtra().vm.$emit('toggle', false);
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(hasDropdownOpen()).toEqual(false); expect(hasDropdownOpen()).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 { keepAlive } from 'helpers/keep_alive_component_helper'; import { keepAlive } from 'helpers/keep_alive_component_helper';
import { trimText } from 'helpers/text_helper'; import { trimText } from 'helpers/text_helper';
...@@ -74,14 +74,14 @@ describe('IDE review mode', () => { ...@@ -74,14 +74,14 @@ describe('IDE review mode', () => {
}); });
describe('merge request', () => { describe('merge request', () => {
beforeEach(() => { beforeEach(async () => {
store.state.currentMergeRequestId = '1'; store.state.currentMergeRequestId = '1';
store.state.projects.abcproject.mergeRequests['1'] = { store.state.projects.abcproject.mergeRequests['1'] = {
iid: 123, iid: 123,
web_url: 'testing123', web_url: 'testing123',
}; };
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('renders edit dropdown', () => { it('renders edit dropdown', () => {
...@@ -91,7 +91,7 @@ describe('IDE review mode', () => { ...@@ -91,7 +91,7 @@ describe('IDE review mode', () => {
it('renders merge request link & IID', async () => { it('renders merge request link & IID', async () => {
store.state.viewer = 'mrdiff'; store.state.viewer = 'mrdiff';
await wrapper.vm.$nextTick(); await nextTick();
expect(trimText(wrapper.text())).toContain('Merge request (!123)'); expect(trimText(wrapper.text())).toContain('Merge request (!123)');
}); });
...@@ -99,7 +99,7 @@ describe('IDE review mode', () => { ...@@ -99,7 +99,7 @@ describe('IDE review mode', () => {
it('changes text to latest changes when viewer is not mrdiff', async () => { it('changes text to latest changes when viewer is not mrdiff', async () => {
store.state.viewer = 'diff'; store.state.viewer = 'diff';
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.text()).toContain('Latest changes'); expect(wrapper.text()).toContain('Latest changes');
}); });
......
import { GlSkeletonLoading } from '@gitlab/ui'; import { GlSkeletonLoading } 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 Vuex from 'vuex'; import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import IdeReview from '~/ide/components/ide_review.vue'; import IdeReview from '~/ide/components/ide_review.vue';
...@@ -45,7 +45,7 @@ describe('IdeSidebar', () => { ...@@ -45,7 +45,7 @@ describe('IdeSidebar', () => {
store.state.loading = true; store.state.loading = true;
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.findAll(GlSkeletonLoading)).toHaveLength(3); expect(wrapper.findAll(GlSkeletonLoading)).toHaveLength(3);
}); });
...@@ -60,7 +60,7 @@ describe('IdeSidebar', () => { ...@@ -60,7 +60,7 @@ describe('IdeSidebar', () => {
store.state.currentActivityView = leftSidebarViews.review.name; store.state.currentActivityView = leftSidebarViews.review.name;
await waitForPromises(); await waitForPromises();
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.find(IdeTree).exists()).toBe(false); expect(wrapper.find(IdeTree).exists()).toBe(false);
expect(wrapper.find(IdeReview).exists()).toBe(true); expect(wrapper.find(IdeReview).exists()).toBe(true);
...@@ -68,7 +68,7 @@ describe('IdeSidebar', () => { ...@@ -68,7 +68,7 @@ describe('IdeSidebar', () => {
store.state.currentActivityView = leftSidebarViews.commit.name; store.state.currentActivityView = leftSidebarViews.commit.name;
await waitForPromises(); await waitForPromises();
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.find(IdeTree).exists()).toBe(false); expect(wrapper.find(IdeTree).exists()).toBe(false);
expect(wrapper.find(IdeReview).exists()).toBe(false); expect(wrapper.find(IdeReview).exists()).toBe(false);
...@@ -84,7 +84,7 @@ describe('IdeSidebar', () => { ...@@ -84,7 +84,7 @@ describe('IdeSidebar', () => {
view, view,
}); });
await waitForPromises(); await waitForPromises();
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.find(IdeTree).exists()).toBe(tree); expect(wrapper.find(IdeTree).exists()).toBe(tree);
expect(wrapper.find(IdeReview).exists()).toBe(review); expect(wrapper.find(IdeReview).exists()).toBe(review);
...@@ -99,7 +99,7 @@ describe('IdeSidebar', () => { ...@@ -99,7 +99,7 @@ describe('IdeSidebar', () => {
store.state.currentActivityView = leftSidebarViews.commit.name; store.state.currentActivityView = leftSidebarViews.commit.name;
await waitForPromises(); await waitForPromises();
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.find(IdeTree).exists()).toBe(false); expect(wrapper.find(IdeTree).exists()).toBe(false);
expect(wrapper.find(RepoCommitSection).exists()).toBe(true); expect(wrapper.find(RepoCommitSection).exists()).toBe(true);
...@@ -107,7 +107,7 @@ describe('IdeSidebar', () => { ...@@ -107,7 +107,7 @@ describe('IdeSidebar', () => {
store.state.currentActivityView = leftSidebarViews.edit.name; store.state.currentActivityView = leftSidebarViews.edit.name;
await waitForPromises(); await waitForPromises();
await wrapper.vm.$nextTick(); await nextTick();
// reference to the elements remains the same, meaning the components were kept alive // reference to the elements remains the same, meaning the components were kept alive
expect(wrapper.find(IdeTree).element).toEqual(ideTreeComponent); expect(wrapper.find(IdeTree).element).toEqual(ideTreeComponent);
......
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import Item from '~/ide/components/jobs/item.vue'; import Item from '~/ide/components/jobs/item.vue';
import Stage from '~/ide/components/jobs/stage.vue'; import Stage from '~/ide/components/jobs/stage.vue';
import { stages, jobs } from '../../mock_data'; import { stages, jobs } from '../../mock_data';
...@@ -47,24 +48,22 @@ describe('IDE pipeline stage', () => { ...@@ -47,24 +48,22 @@ describe('IDE pipeline stage', () => {
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
}); });
it('emits toggleCollaped event with stage id when clicking header', () => { it('emits toggleCollaped event with stage id when clicking header', async () => {
const id = 5; const id = 5;
createComponent({ stage: { ...defaultProps.stage, id } }); createComponent({ stage: { ...defaultProps.stage, id } });
findHeader().trigger('click'); findHeader().trigger('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted().toggleCollapsed[0][0]).toBe(id); expect(wrapper.emitted().toggleCollapsed[0][0]).toBe(id);
}); });
});
it('emits clickViewLog entity with job', () => { it('emits clickViewLog entity with job', async () => {
const [job] = defaultProps.stage.jobs; const [job] = defaultProps.stage.jobs;
createComponent(); createComponent();
wrapper.findAll(Item).at(0).vm.$emit('clickViewLog', job); wrapper.findAll(Item).at(0).vm.$emit('clickViewLog', job);
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted().clickViewLog[0][0]).toBe(job); expect(wrapper.emitted().clickViewLog[0][0]).toBe(job);
}); });
});
it('renders stage details & icon', () => { it('renders stage details & icon', () => {
createComponent(); createComponent();
......
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } 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 Item from '~/ide/components/merge_requests/item.vue'; import Item from '~/ide/components/merge_requests/item.vue';
import List from '~/ide/components/merge_requests/list.vue'; import List from '~/ide/components/merge_requests/list.vue';
...@@ -66,25 +66,21 @@ describe('IDE merge requests list', () => { ...@@ -66,25 +66,21 @@ describe('IDE merge requests list', () => {
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
}); });
it('renders no search results text when search is not empty', () => { it('renders no search results text when search is not empty', async () => {
createComponent(); createComponent();
findTokenedInput().vm.$emit('input', 'something'); findTokenedInput().vm.$emit('input', 'something');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.text()).toContain('No merge requests found'); expect(wrapper.text()).toContain('No merge requests found');
}); });
});
it('clicking on search type, sets currentSearchType and loads merge requests', () => { it('clicking on search type, sets currentSearchType and loads merge requests', async () => {
createComponent(); createComponent();
findTokenedInput().vm.$emit('focus'); findTokenedInput().vm.$emit('focus');
return wrapper.vm await nextTick();
.$nextTick()
.then(() => {
findSearchTypeButtons().at(0).trigger('click'); findSearchTypeButtons().at(0).trigger('click');
return wrapper.vm.$nextTick();
}) await nextTick();
.then(() => {
const searchType = wrapper.vm.$options.searchTypes[0]; const searchType = wrapper.vm.$options.searchTypes[0];
expect(findTokenedInput().props('tokens')).toEqual([searchType]); expect(findTokenedInput().props('tokens')).toEqual([searchType]);
...@@ -93,7 +89,6 @@ describe('IDE merge requests list', () => { ...@@ -93,7 +89,6 @@ describe('IDE merge requests list', () => {
search: '', search: '',
}); });
}); });
});
describe('with merge requests', () => { describe('with merge requests', () => {
let defaultStateWithMergeRequests; let defaultStateWithMergeRequests;
...@@ -119,12 +114,12 @@ describe('IDE merge requests list', () => { ...@@ -119,12 +114,12 @@ describe('IDE merge requests list', () => {
}); });
describe('when searching merge requests', () => { describe('when searching merge requests', () => {
it('calls `loadMergeRequests` on input in search field', () => { it('calls `loadMergeRequests` on input in search field', async () => {
createComponent(defaultStateWithMergeRequests); createComponent(defaultStateWithMergeRequests);
const input = findTokenedInput(); const input = findTokenedInput();
input.vm.$emit('input', 'something'); input.vm.$emit('input', 'something');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(fetchMergeRequestsMock).toHaveBeenCalledWith(expect.any(Object), { expect(fetchMergeRequestsMock).toHaveBeenCalledWith(expect.any(Object), {
search: 'something', search: 'something',
type: '', type: '',
...@@ -132,7 +127,6 @@ describe('IDE merge requests list', () => { ...@@ -132,7 +127,6 @@ describe('IDE merge requests list', () => {
}); });
}); });
}); });
});
describe('on search focus', () => { describe('on search focus', () => {
let input; let input;
...@@ -143,9 +137,9 @@ describe('IDE merge requests list', () => { ...@@ -143,9 +137,9 @@ describe('IDE merge requests list', () => {
}); });
describe('without search value', () => { describe('without search value', () => {
beforeEach(() => { beforeEach(async () => {
input.vm.$emit('focus'); input.vm.$emit('focus');
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('shows search types', () => { it('shows search types', () => {
...@@ -155,22 +149,20 @@ describe('IDE merge requests list', () => { ...@@ -155,22 +149,20 @@ describe('IDE merge requests list', () => {
); );
}); });
it('hides search types when search changes', () => { it('hides search types when search changes', async () => {
input.vm.$emit('input', 'something'); input.vm.$emit('input', 'something');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findSearchTypeButtons().exists()).toBe(false); expect(findSearchTypeButtons().exists()).toBe(false);
}); });
});
describe('with search type', () => { describe('with search type', () => {
beforeEach(() => { beforeEach(async () => {
findSearchTypeButtons().at(0).trigger('click'); findSearchTypeButtons().at(0).trigger('click');
return wrapper.vm await nextTick();
.$nextTick() await input.vm.$emit('focus');
.then(() => input.vm.$emit('focus')) await nextTick();
.then(() => wrapper.vm.$nextTick());
}); });
it('does not show search types', () => { it('does not show search types', () => {
...@@ -180,10 +172,10 @@ describe('IDE merge requests list', () => { ...@@ -180,10 +172,10 @@ describe('IDE merge requests list', () => {
}); });
describe('with search value', () => { describe('with search value', () => {
beforeEach(() => { beforeEach(async () => {
input.vm.$emit('input', 'something'); input.vm.$emit('input', 'something');
input.vm.$emit('focus'); input.vm.$emit('focus');
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('does not show search types', () => { it('does not show search types', () => {
......
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 CollapsibleSidebar from '~/ide/components/panes/collapsible_sidebar.vue'; import CollapsibleSidebar from '~/ide/components/panes/collapsible_sidebar.vue';
import RightPane from '~/ide/components/panes/right.vue'; import RightPane from '~/ide/components/panes/right.vue';
...@@ -86,10 +86,10 @@ describe('ide/components/panes/right.vue', () => { ...@@ -86,10 +86,10 @@ describe('ide/components/panes/right.vue', () => {
createComponent(); createComponent();
}); });
it('adds terminal tab', () => { it('adds terminal tab', async () => {
store.state.terminal.isVisible = true; store.state.terminal.isVisible = true;
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.find(CollapsibleSidebar).props('extensionTabs')).toEqual( expect(wrapper.find(CollapsibleSidebar).props('extensionTabs')).toEqual(
expect.arrayContaining([ expect.arrayContaining([
expect.objectContaining({ expect.objectContaining({
...@@ -99,7 +99,6 @@ describe('ide/components/panes/right.vue', () => { ...@@ -99,7 +99,6 @@ describe('ide/components/panes/right.vue', () => {
]), ]),
); );
}); });
});
it('hides terminal tab when not visible', () => { it('hides terminal tab when not visible', () => {
store.state.terminal.isVisible = false; store.state.terminal.isVisible = false;
......
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } 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 smooshpack from 'smooshpack'; import smooshpack from 'smooshpack';
import Vuex from 'vuex'; import Vuex from 'vuex';
import Clientside from '~/ide/components/preview/clientside.vue'; import Clientside from '~/ide/components/preview/clientside.vue';
...@@ -351,41 +351,38 @@ describe('IDE clientside preview', () => { ...@@ -351,41 +351,38 @@ describe('IDE clientside preview', () => {
}); });
describe('template', () => { describe('template', () => {
it('renders ide-preview element when showPreview is true', () => { it('renders ide-preview element when showPreview is true', async () => {
createComponent({ getters: { packageJson: dummyPackageJson } }); createComponent({ getters: { packageJson: dummyPackageJson } });
// 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({ loading: false }); wrapper.setData({ loading: false });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.find('#ide-preview').exists()).toBe(true); expect(wrapper.find('#ide-preview').exists()).toBe(true);
}); });
});
it('renders empty state', () => { it('renders empty state', async () => {
createComponent(); createComponent();
// 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({ loading: false }); wrapper.setData({ loading: false });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.text()).toContain( expect(wrapper.text()).toContain(
'Preview your web application using Web IDE client-side evaluation.', 'Preview your web application using Web IDE client-side evaluation.',
); );
}); });
});
it('renders loading icon', () => { it('renders loading icon', async () => {
createComponent(); createComponent();
// 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({ loading: true }); wrapper.setData({ loading: true });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
}); });
}); });
});
describe('when destroyed', () => { describe('when destroyed', () => {
let spy; let spy;
......
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { listen } from 'codesandbox-api'; import { listen } from 'codesandbox-api';
import { nextTick } from 'vue';
import { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
import ClientsideNavigator from '~/ide/components/preview/navigator.vue'; import ClientsideNavigator from '~/ide/components/preview/navigator.vue';
...@@ -29,32 +30,29 @@ describe('IDE clientside preview navigator', () => { ...@@ -29,32 +30,29 @@ describe('IDE clientside preview navigator', () => {
wrapper.destroy(); wrapper.destroy();
}); });
it('renders readonly URL bar', () => { it('renders readonly URL bar', async () => {
listenHandler({ type: 'urlchange', url: manager.bundlerURL }); listenHandler({ type: 'urlchange', url: manager.bundlerURL });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.find('input[readonly]').element.value).toBe('/'); expect(wrapper.find('input[readonly]').element.value).toBe('/');
}); });
});
it('renders loading icon by default', () => { it('renders loading icon by default', () => {
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
}); });
it('removes loading icon when done event is fired', () => { it('removes loading icon when done event is fired', async () => {
listenHandler({ type: 'done' }); listenHandler({ type: 'done' });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.find(GlLoadingIcon).exists()).toBe(false); expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
}); });
});
it('does not count visiting same url multiple times', () => { it('does not count visiting same url multiple times', async () => {
listenHandler({ type: 'done' }); listenHandler({ type: 'done' });
listenHandler({ type: 'done', url: `${TEST_HOST}/url1` }); listenHandler({ type: 'done', url: `${TEST_HOST}/url1` });
listenHandler({ type: 'done', url: `${TEST_HOST}/url1` }); listenHandler({ type: 'done', url: `${TEST_HOST}/url1` });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findBackButton().attributes('disabled')).toBe('disabled'); expect(findBackButton().attributes('disabled')).toBe('disabled');
}); });
});
it('unsubscribes from listen on destroy', () => { it('unsubscribes from listen on destroy', () => {
const unsubscribeFn = listen(); const unsubscribeFn = listen();
...@@ -64,107 +62,93 @@ describe('IDE clientside preview navigator', () => { ...@@ -64,107 +62,93 @@ describe('IDE clientside preview navigator', () => {
}); });
describe('back button', () => { describe('back button', () => {
beforeEach(() => { beforeEach(async () => {
listenHandler({ type: 'done' }); listenHandler({ type: 'done' });
listenHandler({ type: 'urlchange', url: TEST_HOST }); listenHandler({ type: 'urlchange', url: TEST_HOST });
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('is disabled by default', () => { it('is disabled by default', () => {
expect(findBackButton().attributes('disabled')).toBe('disabled'); expect(findBackButton().attributes('disabled')).toBe('disabled');
}); });
it('is enabled when there is previous entry', () => { it('is enabled when there is previous entry', async () => {
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` }); listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
return wrapper.vm.$nextTick().then(() => { await nextTick();
findBackButton().trigger('click'); findBackButton().trigger('click');
expect(findBackButton().attributes('disabled')).toBeFalsy(); expect(findBackButton().attributes('disabled')).toBeFalsy();
}); });
});
it('is disabled when there is no previous entry', () => { it('is disabled when there is no previous entry', async () => {
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` }); listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
return wrapper.vm
.$nextTick() await nextTick();
.then(() => {
findBackButton().trigger('click'); findBackButton().trigger('click');
return wrapper.vm.$nextTick(); await nextTick();
})
.then(() => {
expect(findBackButton().attributes('disabled')).toBe('disabled'); expect(findBackButton().attributes('disabled')).toBe('disabled');
}); });
});
it('updates manager iframe src', () => { it('updates manager iframe src', async () => {
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` }); listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url2` }); listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url2` });
return wrapper.vm.$nextTick().then(() => { await nextTick();
findBackButton().trigger('click'); findBackButton().trigger('click');
expect(manager.iframe.src).toBe(`${TEST_HOST}/url1`); expect(manager.iframe.src).toBe(`${TEST_HOST}/url1`);
}); });
}); });
});
describe('forward button', () => { describe('forward button', () => {
beforeEach(() => { beforeEach(async () => {
listenHandler({ type: 'done' }); listenHandler({ type: 'done' });
listenHandler({ type: 'urlchange', url: TEST_HOST }); listenHandler({ type: 'urlchange', url: TEST_HOST });
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('is disabled by default', () => { it('is disabled by default', () => {
expect(findForwardButton().attributes('disabled')).toBe('disabled'); expect(findForwardButton().attributes('disabled')).toBe('disabled');
}); });
it('is enabled when there is next entry', () => { it('is enabled when there is next entry', async () => {
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` }); listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
return wrapper.vm
.$nextTick() await nextTick();
.then(() => {
findBackButton().trigger('click'); findBackButton().trigger('click');
return wrapper.vm.$nextTick();
}) await nextTick();
.then(() => {
expect(findForwardButton().attributes('disabled')).toBeFalsy(); expect(findForwardButton().attributes('disabled')).toBeFalsy();
}); });
});
it('is disabled when there is no next entry', () => { it('is disabled when there is no next entry', async () => {
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` }); listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
return wrapper.vm
.$nextTick() await nextTick();
.then(() => {
findBackButton().trigger('click'); findBackButton().trigger('click');
return wrapper.vm.$nextTick();
}) await nextTick();
.then(() => {
findForwardButton().trigger('click'); findForwardButton().trigger('click');
return wrapper.vm.$nextTick();
}) await nextTick();
.then(() => {
expect(findForwardButton().attributes('disabled')).toBe('disabled'); expect(findForwardButton().attributes('disabled')).toBe('disabled');
}); });
});
it('updates manager iframe src', () => { it('updates manager iframe src', async () => {
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` }); listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url2` }); listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url2` });
return wrapper.vm.$nextTick().then(() => { await nextTick();
findBackButton().trigger('click'); findBackButton().trigger('click');
expect(manager.iframe.src).toBe(`${TEST_HOST}/url1`); expect(manager.iframe.src).toBe(`${TEST_HOST}/url1`);
}); });
}); });
});
describe('refresh button', () => { describe('refresh button', () => {
const url = `${TEST_HOST}/some_url`; const url = `${TEST_HOST}/some_url`;
beforeEach(() => { beforeEach(async () => {
listenHandler({ type: 'done' }); listenHandler({ type: 'done' });
listenHandler({ type: 'urlchange', url }); listenHandler({ type: 'urlchange', url });
return wrapper.vm.$nextTick(); await nextTick();
}); });
it('calls refresh with current path', () => { it('calls refresh with current path', () => {
......
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 RepoTabs from '~/ide/components/repo_tabs.vue'; import RepoTabs from '~/ide/components/repo_tabs.vue';
import { createStore } from '~/ide/stores'; import { createStore } from '~/ide/stores';
...@@ -29,17 +29,14 @@ describe('RepoTabs', () => { ...@@ -29,17 +29,14 @@ describe('RepoTabs', () => {
wrapper.destroy(); wrapper.destroy();
}); });
it('renders a list of tabs', (done) => { it('renders a list of tabs', async () => {
store.state.openFiles[0].active = true; store.state.openFiles[0].active = true;
wrapper.vm.$nextTick(() => { await nextTick();
const tabs = [...wrapper.vm.$el.querySelectorAll('.multi-file-tab')]; const tabs = [...wrapper.vm.$el.querySelectorAll('.multi-file-tab')];
expect(tabs.length).toEqual(2); expect(tabs.length).toEqual(2);
expect(tabs[0].parentNode.classList.contains('active')).toEqual(true); expect(tabs[0].parentNode.classList.contains('active')).toEqual(true);
expect(tabs[1].parentNode.classList.contains('active')).toEqual(false); expect(tabs[1].parentNode.classList.contains('active')).toEqual(false);
done();
});
}); });
}); });
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 ResizablePanel from '~/ide/components/resizable_panel.vue'; import ResizablePanel from '~/ide/components/resizable_panel.vue';
import { SIDE_LEFT, SIDE_RIGHT } from '~/ide/constants'; import { SIDE_LEFT, SIDE_RIGHT } from '~/ide/constants';
...@@ -99,15 +99,14 @@ describe('~/ide/components/resizable_panel', () => { ...@@ -99,15 +99,14 @@ describe('~/ide/components/resizable_panel', () => {
}); });
}); });
it('when resizer emits update:size, changes inline width', () => { it('when resizer emits update:size, changes inline width', async () => {
const newSize = TEST_WIDTH - 100; const newSize = TEST_WIDTH - 100;
const resizer = findResizer(); const resizer = findResizer();
resizer.vm.$emit('update:size', newSize); resizer.vm.$emit('update:size', newSize);
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findInlineStyle()).toBe(createInlineStyle(newSize)); expect(findInlineStyle()).toBe(createInlineStyle(newSize));
}); });
}); });
});
}); });
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 TerminalSession from '~/ide/components/terminal/session.vue'; import TerminalSession from '~/ide/components/terminal/session.vue';
import Terminal from '~/ide/components/terminal/terminal.vue'; import Terminal from '~/ide/components/terminal/terminal.vue';
...@@ -67,32 +67,30 @@ describe('IDE TerminalSession', () => { ...@@ -67,32 +67,30 @@ describe('IDE TerminalSession', () => {
}); });
[STARTING, PENDING, RUNNING].forEach((status) => { [STARTING, PENDING, RUNNING].forEach((status) => {
it(`show stop button when status is ${status}`, () => { it(`show stop button when status is ${status}`, async () => {
state.session = { status }; state.session = { status };
factory(); factory();
const button = findButton(); const button = findButton();
button.vm.$emit('click'); button.vm.$emit('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(button.text()).toEqual('Stop Terminal'); expect(button.text()).toEqual('Stop Terminal');
expect(actions.stopSession).toHaveBeenCalled(); expect(actions.stopSession).toHaveBeenCalled();
}); });
}); });
});
[STOPPING, STOPPED].forEach((status) => { [STOPPING, STOPPED].forEach((status) => {
it(`show stop button when status is ${status}`, () => { it(`show stop button when status is ${status}`, async () => {
state.session = { status }; state.session = { status };
factory(); factory();
const button = findButton(); const button = findButton();
button.vm.$emit('click'); button.vm.$emit('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(button.text()).toEqual('Restart Terminal'); expect(button.text()).toEqual('Restart Terminal');
expect(actions.restartSession).toHaveBeenCalled(); expect(actions.restartSession).toHaveBeenCalled();
}); });
}); });
});
}); });
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import ScrollButton from '~/ide/components/jobs/detail/scroll_button.vue'; import ScrollButton from '~/ide/components/jobs/detail/scroll_button.vue';
import TerminalControls from '~/ide/components/terminal/terminal_controls.vue'; import TerminalControls from '~/ide/components/terminal/terminal_controls.vue';
...@@ -39,27 +40,25 @@ describe('IDE TerminalControls', () => { ...@@ -39,27 +40,25 @@ describe('IDE TerminalControls', () => {
); );
}); });
it('emits "scroll-up" when click up button', () => { it('emits "scroll-up" when click up button', async () => {
factory({ propsData: { canScrollUp: true } }); factory({ propsData: { canScrollUp: true } });
expect(wrapper.emitted()).toEqual({}); expect(wrapper.emitted()).toEqual({});
buttons.at(0).vm.$emit('click'); buttons.at(0).vm.$emit('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted('scroll-up')).toEqual([[]]); expect(wrapper.emitted('scroll-up')).toEqual([[]]);
}); });
});
it('emits "scroll-down" when click down button', () => { it('emits "scroll-down" when click down button', async () => {
factory({ propsData: { canScrollDown: true } }); factory({ propsData: { canScrollDown: true } });
expect(wrapper.emitted()).toEqual({}); expect(wrapper.emitted()).toEqual({});
buttons.at(1).vm.$emit('click'); buttons.at(1).vm.$emit('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.emitted('scroll-down')).toEqual([[]]); expect(wrapper.emitted('scroll-down')).toEqual([[]]);
}); });
});
}); });
import { GlAlert, GlLoadingIcon, GlTable, GlAvatar, GlEmptyState } from '@gitlab/ui'; import { GlAlert, GlLoadingIcon, GlTable, GlAvatar, GlEmptyState } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import IncidentsList from '~/incidents/components/incidents_list.vue'; import IncidentsList from '~/incidents/components/incidents_list.vue';
import { import {
I18N, I18N,
...@@ -210,7 +211,7 @@ describe('Incidents List', () => { ...@@ -210,7 +211,7 @@ describe('Incidents List', () => {
it('sets button loading on click', async () => { it('sets button loading on click', async () => {
findCreateIncidentBtn().vm.$emit('click'); findCreateIncidentBtn().vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(findCreateIncidentBtn().attributes('loading')).toBe('true'); expect(findCreateIncidentBtn().attributes('loading')).toBe('true');
}); });
...@@ -233,7 +234,7 @@ describe('Incidents List', () => { ...@@ -233,7 +234,7 @@ describe('Incidents List', () => {
it('should track create new incident button', async () => { it('should track create new incident button', async () => {
findCreateIncidentBtn().vm.$emit('click'); findCreateIncidentBtn().vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(Tracking.event).toHaveBeenCalled(); expect(Tracking.event).toHaveBeenCalled();
}); });
}); });
...@@ -263,10 +264,10 @@ describe('Incidents List', () => { ...@@ -263,10 +264,10 @@ describe('Incidents List', () => {
const columnHeader = () => wrapper.find(`[${attr}="${value}"]`); const columnHeader = () => wrapper.find(`[${attr}="${value}"]`);
expect(columnHeader().attributes('aria-sort')).toBe(initialSort); expect(columnHeader().attributes('aria-sort')).toBe(initialSort);
columnHeader().trigger('click'); columnHeader().trigger('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(columnHeader().attributes('aria-sort')).toBe(firstSort); expect(columnHeader().attributes('aria-sort')).toBe(firstSort);
columnHeader().trigger('click'); columnHeader().trigger('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(columnHeader().attributes('aria-sort')).toBe(nextSort); expect(columnHeader().attributes('aria-sort')).toBe(nextSort);
}, },
); );
...@@ -287,7 +288,7 @@ describe('Incidents List', () => { ...@@ -287,7 +288,7 @@ describe('Incidents List', () => {
it('should track incident creation events', async () => { it('should track incident creation events', async () => {
findCreateIncidentBtn().vm.$emit('click'); findCreateIncidentBtn().vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
const { category, action } = trackIncidentCreateNewOptions; const { category, action } = trackIncidentCreateNewOptions;
expect(Tracking.event).toHaveBeenCalledWith(category, action); expect(Tracking.event).toHaveBeenCalledWith(category, action);
}); });
......
import { GlFormCheckbox } from '@gitlab/ui'; import { GlFormCheckbox } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import ActiveCheckbox from '~/integrations/edit/components/active_checkbox.vue'; import ActiveCheckbox from '~/integrations/edit/components/active_checkbox.vue';
import { createStore } from '~/integrations/edit/store'; import { createStore } from '~/integrations/edit/store';
...@@ -68,7 +69,7 @@ describe('ActiveCheckbox', () => { ...@@ -68,7 +69,7 @@ describe('ActiveCheckbox', () => {
it('switches the form value', async () => { it('switches the form value', async () => {
findInputInCheckbox().trigger('click'); findInputInCheckbox().trigger('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(findGlFormCheckbox().vm.$attrs.checked).toBe(false); expect(findGlFormCheckbox().vm.$attrs.checked).toBe(false);
}); });
}); });
......
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 ConfirmationModal from '~/integrations/edit/components/confirmation_modal.vue'; import ConfirmationModal from '~/integrations/edit/components/confirmation_modal.vue';
import { createStore } from '~/integrations/edit/store'; import { createStore } from '~/integrations/edit/store';
...@@ -40,7 +41,7 @@ describe('ConfirmationModal', () => { ...@@ -40,7 +41,7 @@ describe('ConfirmationModal', () => {
findGlModal().vm.$emit('primary'); findGlModal().vm.$emit('primary');
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.emitted().submit).toHaveLength(1); expect(wrapper.emitted().submit).toHaveLength(1);
}); });
......
import { GlFormCheckbox, GlFormInput } from '@gitlab/ui'; import { GlFormCheckbox, GlFormInput } from '@gitlab/ui';
import { nextTick } from 'vue';
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
import JiraIssuesFields from '~/integrations/edit/components/jira_issues_fields.vue'; import JiraIssuesFields from '~/integrations/edit/components/jira_issues_fields.vue';
...@@ -193,7 +194,7 @@ describe('JiraIssuesFields', () => { ...@@ -193,7 +194,7 @@ describe('JiraIssuesFields', () => {
await setEnableCheckbox(true); await setEnableCheckbox(true);
expect(findJiraForVulnerabilities().attributes('show-full-feature')).toBe('true'); expect(findJiraForVulnerabilities().attributes('show-full-feature')).toBe('true');
wrapper.setProps({ showJiraVulnerabilitiesIntegration: false }); wrapper.setProps({ showJiraVulnerabilitiesIntegration: false });
await wrapper.vm.$nextTick(); await nextTick();
expect(findJiraForVulnerabilities().attributes('show-full-feature')).toBeUndefined(); expect(findJiraForVulnerabilities().attributes('show-full-feature')).toBeUndefined();
}); });
......
import { GlFormCheckbox } from '@gitlab/ui'; import { GlFormCheckbox } from '@gitlab/ui';
import { nextTick } from 'vue';
import { mountExtended } from 'helpers/vue_test_utils_helper'; import { mountExtended } from 'helpers/vue_test_utils_helper';
import JiraTriggerFields from '~/integrations/edit/components/jira_trigger_fields.vue'; import JiraTriggerFields from '~/integrations/edit/components/jira_trigger_fields.vue';
...@@ -71,15 +72,14 @@ describe('JiraTriggerFields', () => { ...@@ -71,15 +72,14 @@ describe('JiraTriggerFields', () => {
}); });
describe('on enable comments', () => { describe('on enable comments', () => {
it('shows comment detail', () => { it('shows comment detail', async () => {
findCommentSettingsCheckbox().vm.$emit('input', true); findCommentSettingsCheckbox().vm.$emit('input', true);
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(findCommentDetail().isVisible()).toBe(true); expect(findCommentDetail().isVisible()).toBe(true);
}); });
}); });
}); });
});
describe('initialTriggerMergeRequest is true', () => { describe('initialTriggerMergeRequest is true', () => {
it('shows trigger settings', () => { it('shows trigger settings', () => {
...@@ -107,7 +107,7 @@ describe('JiraTriggerFields', () => { ...@@ -107,7 +107,7 @@ describe('JiraTriggerFields', () => {
}); });
describe('initialJiraIssueTransitionAutomatic is false, initialJiraIssueTransitionId is not set', () => { describe('initialJiraIssueTransitionAutomatic is false, initialJiraIssueTransitionId is not set', () => {
it('selects automatic transitions when enabling transitions', () => { it('selects automatic transitions when enabling transitions', async () => {
createComponent({ createComponent({
initialTriggerCommit: true, initialTriggerCommit: true,
initialEnableComments: true, initialEnableComments: true,
...@@ -117,13 +117,12 @@ describe('JiraTriggerFields', () => { ...@@ -117,13 +117,12 @@ describe('JiraTriggerFields', () => {
expect(checkbox.element.checked).toBe(false); expect(checkbox.element.checked).toBe(false);
checkbox.trigger('click'); checkbox.trigger('click');
return wrapper.vm.$nextTick().then(() => { await nextTick();
const [radio1, radio2] = findIssueTransitionModeRadios().wrappers; const [radio1, radio2] = findIssueTransitionModeRadios().wrappers;
expect(radio1.element.checked).toBe(true); expect(radio1.element.checked).toBe(true);
expect(radio2.element.checked).toBe(false); expect(radio2.element.checked).toBe(false);
}); });
}); });
});
describe('initialJiraIssueTransitionAutomatic is true', () => { describe('initialJiraIssueTransitionAutomatic is true', () => {
it('uses automatic transitions', () => { it('uses automatic transitions', () => {
......
import { GlFormGroup, GlSprintf, GlModal } from '@gitlab/ui'; import { GlFormGroup, GlSprintf, GlModal } from '@gitlab/ui';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
import { stubComponent } from 'helpers/stub_component'; import { stubComponent } from 'helpers/stub_component';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
...@@ -91,7 +92,7 @@ describe('ImportAProjectModal', () => { ...@@ -91,7 +92,7 @@ describe('ImportAProjectModal', () => {
it('sets isLoading to true when the Invite button is clicked', async () => { it('sets isLoading to true when the Invite button is clicked', async () => {
clickImportButton(); clickImportButton();
await wrapper.vm.$nextTick(); await nextTick();
expect(findImportButton().props('loading')).toBe(true); expect(findImportButton().props('loading')).toBe(true);
}); });
...@@ -157,7 +158,7 @@ describe('ImportAProjectModal', () => { ...@@ -157,7 +158,7 @@ describe('ImportAProjectModal', () => {
clickCancelButton(); clickCancelButton();
await wrapper.vm.$nextTick(); await nextTick();
expect(formGroupInvalidFeedback()).toBe(''); expect(formGroupInvalidFeedback()).toBe('');
expect(formGroupErrorState()).not.toBe(false); expect(formGroupErrorState()).not.toBe(false);
......
...@@ -8,6 +8,7 @@ import { ...@@ -8,6 +8,7 @@ import {
GlModal, GlModal,
} from '@gitlab/ui'; } from '@gitlab/ui';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
import { stubComponent } from 'helpers/stub_component'; import { stubComponent } from 'helpers/stub_component';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
...@@ -508,7 +509,7 @@ describe('InviteMembersModal', () => { ...@@ -508,7 +509,7 @@ describe('InviteMembersModal', () => {
findMembersSelect().vm.$emit('clear'); findMembersSelect().vm.$emit('clear');
await wrapper.vm.$nextTick(); await nextTick();
expect(membersFormGroupInvalidFeedback()).toBe(''); expect(membersFormGroupInvalidFeedback()).toBe('');
expect(findMembersFormGroup().props('state')).not.toBe(false); expect(findMembersFormGroup().props('state')).not.toBe(false);
...@@ -518,7 +519,7 @@ describe('InviteMembersModal', () => { ...@@ -518,7 +519,7 @@ describe('InviteMembersModal', () => {
it('clears the error when the cancel button is clicked', async () => { it('clears the error when the cancel button is clicked', async () => {
clickCancelButton(); clickCancelButton();
await wrapper.vm.$nextTick(); await nextTick();
expect(membersFormGroupInvalidFeedback()).toBe(''); expect(membersFormGroupInvalidFeedback()).toBe('');
expect(findMembersFormGroup().props('state')).not.toBe(false); expect(findMembersFormGroup().props('state')).not.toBe(false);
...@@ -528,7 +529,7 @@ describe('InviteMembersModal', () => { ...@@ -528,7 +529,7 @@ describe('InviteMembersModal', () => {
it('clears the error when the modal is hidden', async () => { it('clears the error when the modal is hidden', async () => {
wrapper.findComponent(GlModal).vm.$emit('hide'); wrapper.findComponent(GlModal).vm.$emit('hide');
await wrapper.vm.$nextTick(); await nextTick();
expect(membersFormGroupInvalidFeedback()).toBe(''); expect(membersFormGroupInvalidFeedback()).toBe('');
expect(findMembersFormGroup().props('state')).not.toBe(false); expect(findMembersFormGroup().props('state')).not.toBe(false);
......
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
import IssueDueDate from '~/boards/components/issue_due_date.vue'; import IssueDueDate from '~/boards/components/issue_due_date.vue';
import { formatDate } from '~/lib/utils/datetime_utility'; import { formatDate } from '~/lib/utils/datetime_utility';
...@@ -105,7 +106,7 @@ describe('RelatedIssuableItem', () => { ...@@ -105,7 +106,7 @@ describe('RelatedIssuableItem', () => {
state: 'closed', state: 'closed',
closedAt: '2018-12-01T00:00:00.00Z', closedAt: '2018-12-01T00:00:00.00Z',
}); });
await wrapper.vm.$nextTick(); await nextTick();
expect(tokenState().classes('issue-token-state-icon-closed')).toBe(true); expect(tokenState().classes('issue-token-state-icon-closed')).toBe(true);
}); });
...@@ -140,7 +141,7 @@ describe('RelatedIssuableItem', () => { ...@@ -140,7 +141,7 @@ describe('RelatedIssuableItem', () => {
closedAt: '2018-12-01T00:00:00.00Z', closedAt: '2018-12-01T00:00:00.00Z',
}, },
}); });
await wrapper.vm.$nextTick(); await nextTick();
expect(wrapper.find(IssueDueDate).props('closed')).toBe(true); expect(wrapper.find(IssueDueDate).props('closed')).toBe(true);
}); });
...@@ -172,14 +173,14 @@ describe('RelatedIssuableItem', () => { ...@@ -172,14 +173,14 @@ describe('RelatedIssuableItem', () => {
// 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({ removeDisabled: true }); wrapper.setData({ removeDisabled: true });
await wrapper.vm.$nextTick(); await nextTick();
expect(findRemoveButton().attributes('disabled')).toEqual('disabled'); expect(findRemoveButton().attributes('disabled')).toEqual('disabled');
}); });
it('triggers onRemoveRequest when clicked', async () => { it('triggers onRemoveRequest when clicked', async () => {
findRemoveButton().trigger('click'); findRemoveButton().trigger('click');
await wrapper.vm.$nextTick(); await nextTick();
const { relatedIssueRemoveRequest } = wrapper.emitted(); const { relatedIssueRemoveRequest } = wrapper.emitted();
expect(relatedIssueRemoveRequest.length).toBe(1); expect(relatedIssueRemoveRequest.length).toBe(1);
......
import { mount, shallowMount } from '@vue/test-utils'; import { mount, shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import AddIssuableForm from '~/related_issues/components/add_issuable_form.vue'; import AddIssuableForm from '~/related_issues/components/add_issuable_form.vue';
import IssueToken from '~/related_issues/components/issue_token.vue'; import IssueToken from '~/related_issues/components/issue_token.vue';
import { issuableTypesMap, linkedIssueTypesMap, PathIdSeparator } from '~/related_issues/constants'; import { issuableTypesMap, linkedIssueTypesMap, PathIdSeparator } from '~/related_issues/constants';
...@@ -194,63 +195,55 @@ describe('AddIssuableForm', () => { ...@@ -194,63 +195,55 @@ describe('AddIssuableForm', () => {
}); });
describe('when the form is submitted', () => { describe('when the form is submitted', () => {
it('emits an event with a "relates_to" link type when the "relates to" radio input selected', (done) => { it('emits an event with a "relates_to" link type when the "relates to" radio input selected', async () => {
jest.spyOn(wrapper.vm, '$emit').mockImplementation(() => {}); jest.spyOn(wrapper.vm, '$emit').mockImplementation(() => {});
wrapper.vm.linkedIssueType = linkedIssueTypesMap.RELATES_TO; wrapper.vm.linkedIssueType = linkedIssueTypesMap.RELATES_TO;
wrapper.vm.onFormSubmit(); wrapper.vm.onFormSubmit();
wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.vm.$emit).toHaveBeenCalledWith('addIssuableFormSubmit', { expect(wrapper.vm.$emit).toHaveBeenCalledWith('addIssuableFormSubmit', {
pendingReferences: '', pendingReferences: '',
linkedIssueType: linkedIssueTypesMap.RELATES_TO, linkedIssueType: linkedIssueTypesMap.RELATES_TO,
}); });
done();
});
}); });
it('emits an event with a "blocks" link type when the "blocks" radio input selected', (done) => { it('emits an event with a "blocks" link type when the "blocks" radio input selected', async () => {
jest.spyOn(wrapper.vm, '$emit').mockImplementation(() => {}); jest.spyOn(wrapper.vm, '$emit').mockImplementation(() => {});
wrapper.vm.linkedIssueType = linkedIssueTypesMap.BLOCKS; wrapper.vm.linkedIssueType = linkedIssueTypesMap.BLOCKS;
wrapper.vm.onFormSubmit(); wrapper.vm.onFormSubmit();
wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.vm.$emit).toHaveBeenCalledWith('addIssuableFormSubmit', { expect(wrapper.vm.$emit).toHaveBeenCalledWith('addIssuableFormSubmit', {
pendingReferences: '', pendingReferences: '',
linkedIssueType: linkedIssueTypesMap.BLOCKS, linkedIssueType: linkedIssueTypesMap.BLOCKS,
}); });
done();
});
}); });
it('emits an event with a "is_blocked_by" link type when the "is blocked by" radio input selected', (done) => { it('emits an event with a "is_blocked_by" link type when the "is blocked by" radio input selected', async () => {
jest.spyOn(wrapper.vm, '$emit').mockImplementation(() => {}); jest.spyOn(wrapper.vm, '$emit').mockImplementation(() => {});
wrapper.vm.linkedIssueType = linkedIssueTypesMap.IS_BLOCKED_BY; wrapper.vm.linkedIssueType = linkedIssueTypesMap.IS_BLOCKED_BY;
wrapper.vm.onFormSubmit(); wrapper.vm.onFormSubmit();
wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.vm.$emit).toHaveBeenCalledWith('addIssuableFormSubmit', { expect(wrapper.vm.$emit).toHaveBeenCalledWith('addIssuableFormSubmit', {
pendingReferences: '', pendingReferences: '',
linkedIssueType: linkedIssueTypesMap.IS_BLOCKED_BY, linkedIssueType: linkedIssueTypesMap.IS_BLOCKED_BY,
}); });
done();
});
}); });
it('shows error message when error is present', (done) => { it('shows error message when error is present', async () => {
const itemAddFailureMessage = 'Something went wrong while submitting.'; const itemAddFailureMessage = 'Something went wrong while submitting.';
wrapper.setProps({ wrapper.setProps({
hasError: true, hasError: true,
itemAddFailureMessage, itemAddFailureMessage,
}); });
wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.find('.gl-field-error').exists()).toBe(true); expect(wrapper.find('.gl-field-error').exists()).toBe(true);
expect(wrapper.find('.gl-field-error').text()).toContain(itemAddFailureMessage); expect(wrapper.find('.gl-field-error').text()).toContain(itemAddFailureMessage);
done();
});
}); });
}); });
}); });
......
import { mount, shallowMount } from '@vue/test-utils'; import { mount, 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 { import {
defaultProps, defaultProps,
...@@ -210,42 +211,39 @@ describe('RelatedIssuesRoot', () => { ...@@ -210,42 +211,39 @@ describe('RelatedIssuesRoot', () => {
}), }),
); );
it('when canceling and hiding add issuable form', () => { it('when canceling and hiding add issuable form', async () => {
wrapper.vm.onPendingFormCancel(); wrapper.vm.onPendingFormCancel();
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.vm.isFormVisible).toEqual(false); expect(wrapper.vm.isFormVisible).toEqual(false);
expect(wrapper.vm.inputValue).toEqual(''); expect(wrapper.vm.inputValue).toEqual('');
expect(wrapper.vm.state.pendingReferences).toHaveLength(0); expect(wrapper.vm.state.pendingReferences).toHaveLength(0);
}); });
}); });
});
describe('fetchRelatedIssues', () => { describe('fetchRelatedIssues', () => {
beforeEach(() => createComponent()); beforeEach(() => createComponent());
it('sets isFetching while fetching', () => { it('sets isFetching while fetching', async () => {
wrapper.vm.fetchRelatedIssues(); wrapper.vm.fetchRelatedIssues();
expect(wrapper.vm.isFetching).toEqual(true); expect(wrapper.vm.isFetching).toEqual(true);
return waitForPromises().then(() => { await waitForPromises();
expect(wrapper.vm.isFetching).toEqual(false); expect(wrapper.vm.isFetching).toEqual(false);
}); });
});
it('should fetch related issues', () => { it('should fetch related issues', async () => {
mock.onGet(defaultProps.endpoint).reply(200, [issuable1, issuable2]); mock.onGet(defaultProps.endpoint).reply(200, [issuable1, issuable2]);
wrapper.vm.fetchRelatedIssues(); wrapper.vm.fetchRelatedIssues();
return waitForPromises().then(() => { await waitForPromises();
expect(wrapper.vm.state.relatedIssues).toHaveLength(2); expect(wrapper.vm.state.relatedIssues).toHaveLength(2);
expect(wrapper.vm.state.relatedIssues[0].id).toEqual(issuable1.id); expect(wrapper.vm.state.relatedIssues[0].id).toEqual(issuable1.id);
expect(wrapper.vm.state.relatedIssues[1].id).toEqual(issuable2.id); expect(wrapper.vm.state.relatedIssues[1].id).toEqual(issuable2.id);
}); });
}); });
});
describe('onInput', () => { describe('onInput', () => {
beforeEach(() => createComponent()); beforeEach(() => createComponent());
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import TitleSuggestions from '~/issues/new/components/title_suggestions.vue'; import TitleSuggestions from '~/issues/new/components/title_suggestions.vue';
import TitleSuggestionsItem from '~/issues/new/components/title_suggestions_item.vue'; import TitleSuggestionsItem from '~/issues/new/components/title_suggestions_item.vue';
...@@ -22,13 +23,12 @@ describe('Issue title suggestions component', () => { ...@@ -22,13 +23,12 @@ describe('Issue title suggestions component', () => {
wrapper.destroy(); wrapper.destroy();
}); });
it('does not render with empty search', () => { it('does not render with empty search', async () => {
wrapper.setProps({ search: '' }); wrapper.setProps({ search: '' });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.isVisible()).toBe(false); expect(wrapper.isVisible()).toBe(false);
}); });
});
describe('with data', () => { describe('with data', () => {
let data; let data;
...@@ -37,28 +37,26 @@ describe('Issue title suggestions component', () => { ...@@ -37,28 +37,26 @@ describe('Issue title suggestions component', () => {
data = { issues: [{ id: 1 }, { id: 2 }] }; data = { issues: [{ id: 1 }, { id: 2 }] };
}); });
it('renders component', () => { it('renders component', 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(data); wrapper.setData(data);
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.findAll('li').length).toBe(data.issues.length); expect(wrapper.findAll('li').length).toBe(data.issues.length);
}); });
});
it('does not render with empty search', () => { it('does not render with empty search', async () => {
wrapper.setProps({ search: '' }); wrapper.setProps({ search: '' });
// 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(data); wrapper.setData(data);
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.isVisible()).toBe(false); expect(wrapper.isVisible()).toBe(false);
}); });
});
it('does not render when loading', () => { it('does not render when loading', 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({
...@@ -66,49 +64,44 @@ describe('Issue title suggestions component', () => { ...@@ -66,49 +64,44 @@ describe('Issue title suggestions component', () => {
loading: 1, loading: 1,
}); });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.isVisible()).toBe(false); expect(wrapper.isVisible()).toBe(false);
}); });
});
it('does not render with empty issues data', () => { it('does not render with empty issues 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({ issues: [] }); wrapper.setData({ issues: [] });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.isVisible()).toBe(false); expect(wrapper.isVisible()).toBe(false);
}); });
});
it('renders list of issues', () => { it('renders list of issues', 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(data); wrapper.setData(data);
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.findAll(TitleSuggestionsItem).length).toBe(2); expect(wrapper.findAll(TitleSuggestionsItem).length).toBe(2);
}); });
});
it('adds margin class to first item', () => { it('adds margin class to first item', 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(data); wrapper.setData(data);
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.findAll('li').at(0).classes()).toContain('gl-mb-3'); expect(wrapper.findAll('li').at(0).classes()).toContain('gl-mb-3');
}); });
});
it('does not add margin class to last item', () => { it('does not add margin class to last item', 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(data); wrapper.setData(data);
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.findAll('li').at(1).classes()).not.toContain('gl-mb-3'); expect(wrapper.findAll('li').at(1).classes()).not.toContain('gl-mb-3');
}); });
}); });
});
}); });
...@@ -145,34 +145,31 @@ describe('Issuable output', () => { ...@@ -145,34 +145,31 @@ describe('Issuable output', () => {
}); });
}); });
it('shows actions if permissions are correct', () => { it('shows actions if permissions are correct', async () => {
wrapper.vm.showForm = true; wrapper.vm.showForm = true;
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.find('.markdown-selector').exists()).toBe(true); expect(wrapper.find('.markdown-selector').exists()).toBe(true);
}); });
});
it('does not show actions if permissions are incorrect', () => { it('does not show actions if permissions are incorrect', async () => {
wrapper.vm.showForm = true; wrapper.vm.showForm = true;
wrapper.setProps({ canUpdate: false }); wrapper.setProps({ canUpdate: false });
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.find('.markdown-selector').exists()).toBe(false); expect(wrapper.find('.markdown-selector').exists()).toBe(false);
}); });
});
it('does not update formState if form is already open', () => { it('does not update formState if form is already open', async () => {
wrapper.vm.updateAndShowForm(); wrapper.vm.updateAndShowForm();
wrapper.vm.state.titleText = 'testing 123'; wrapper.vm.state.titleText = 'testing 123';
wrapper.vm.updateAndShowForm(); wrapper.vm.updateAndShowForm();
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(wrapper.vm.store.formState.title).not.toBe('testing 123'); expect(wrapper.vm.store.formState.title).not.toBe('testing 123');
}); });
});
describe('Pinned links propagated', () => { describe('Pinned links propagated', () => {
it.each` it.each`
...@@ -186,31 +183,29 @@ describe('Issuable output', () => { ...@@ -186,31 +183,29 @@ describe('Issuable output', () => {
}); });
describe('updateIssuable', () => { describe('updateIssuable', () => {
it('fetches new data after update', () => { it('fetches new data after update', async () => {
const updateStoreSpy = jest.spyOn(wrapper.vm, 'updateStoreState'); const updateStoreSpy = jest.spyOn(wrapper.vm, 'updateStoreState');
const getDataSpy = jest.spyOn(wrapper.vm.service, 'getData'); const getDataSpy = jest.spyOn(wrapper.vm.service, 'getData');
jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({ jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({
data: { web_url: window.location.pathname }, data: { web_url: window.location.pathname },
}); });
return wrapper.vm.updateIssuable().then(() => { await wrapper.vm.updateIssuable();
expect(updateStoreSpy).toHaveBeenCalled(); expect(updateStoreSpy).toHaveBeenCalled();
expect(getDataSpy).toHaveBeenCalled(); expect(getDataSpy).toHaveBeenCalled();
}); });
});
it('correctly updates issuable data', () => { it('correctly updates issuable data', async () => {
const spy = jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({ const spy = jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({
data: { web_url: window.location.pathname }, data: { web_url: window.location.pathname },
}); });
return wrapper.vm.updateIssuable().then(() => { await wrapper.vm.updateIssuable();
expect(spy).toHaveBeenCalledWith(wrapper.vm.formState); expect(spy).toHaveBeenCalledWith(wrapper.vm.formState);
expect(eventHub.$emit).toHaveBeenCalledWith('close.form'); expect(eventHub.$emit).toHaveBeenCalledWith('close.form');
}); });
});
it('does not redirect if issue has not moved', () => { it('does not redirect if issue has not moved', async () => {
jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({ jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({
data: { data: {
web_url: window.location.pathname, web_url: window.location.pathname,
...@@ -218,12 +213,11 @@ describe('Issuable output', () => { ...@@ -218,12 +213,11 @@ describe('Issuable output', () => {
}, },
}); });
return wrapper.vm.updateIssuable().then(() => { await wrapper.vm.updateIssuable();
expect(visitUrl).not.toHaveBeenCalled(); expect(visitUrl).not.toHaveBeenCalled();
}); });
});
it('does not redirect if issue has not moved and user has switched tabs', () => { it('does not redirect if issue has not moved and user has switched tabs', async () => {
jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({ jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({
data: { data: {
web_url: '', web_url: '',
...@@ -231,12 +225,11 @@ describe('Issuable output', () => { ...@@ -231,12 +225,11 @@ describe('Issuable output', () => {
}, },
}); });
return wrapper.vm.updateIssuable().then(() => { await wrapper.vm.updateIssuable();
expect(visitUrl).not.toHaveBeenCalled(); expect(visitUrl).not.toHaveBeenCalled();
}); });
});
it('redirects if returned web_url has changed', () => { it('redirects if returned web_url has changed', async () => {
jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({ jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({
data: { data: {
web_url: '/testing-issue-move', web_url: '/testing-issue-move',
...@@ -246,110 +239,97 @@ describe('Issuable output', () => { ...@@ -246,110 +239,97 @@ describe('Issuable output', () => {
wrapper.vm.updateIssuable(); wrapper.vm.updateIssuable();
return wrapper.vm.updateIssuable().then(() => { await wrapper.vm.updateIssuable();
expect(visitUrl).toHaveBeenCalledWith('/testing-issue-move'); expect(visitUrl).toHaveBeenCalledWith('/testing-issue-move');
}); });
});
describe('shows dialog when issue has unsaved changed', () => { describe('shows dialog when issue has unsaved changed', () => {
it('confirms on title change', () => { it('confirms on title change', async () => {
wrapper.vm.showForm = true; wrapper.vm.showForm = true;
wrapper.vm.state.titleText = 'title has changed'; wrapper.vm.state.titleText = 'title has changed';
const e = { returnValue: null }; const e = { returnValue: null };
wrapper.vm.handleBeforeUnloadEvent(e); wrapper.vm.handleBeforeUnloadEvent(e);
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(e.returnValue).not.toBeNull(); expect(e.returnValue).not.toBeNull();
}); });
});
it('confirms on description change', () => { it('confirms on description change', async () => {
wrapper.vm.showForm = true; wrapper.vm.showForm = true;
wrapper.vm.state.descriptionText = 'description has changed'; wrapper.vm.state.descriptionText = 'description has changed';
const e = { returnValue: null }; const e = { returnValue: null };
wrapper.vm.handleBeforeUnloadEvent(e); wrapper.vm.handleBeforeUnloadEvent(e);
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(e.returnValue).not.toBeNull(); expect(e.returnValue).not.toBeNull();
}); });
});
it('does nothing when nothing has changed', () => { it('does nothing when nothing has changed', async () => {
const e = { returnValue: null }; const e = { returnValue: null };
wrapper.vm.handleBeforeUnloadEvent(e); wrapper.vm.handleBeforeUnloadEvent(e);
return wrapper.vm.$nextTick().then(() => { await nextTick();
expect(e.returnValue).toBeNull(); expect(e.returnValue).toBeNull();
}); });
}); });
});
describe('error when updating', () => { describe('error when updating', () => {
it('closes form on error', () => { it('closes form on error', async () => {
jest.spyOn(wrapper.vm.service, 'updateIssuable').mockRejectedValue(); jest.spyOn(wrapper.vm.service, 'updateIssuable').mockRejectedValue();
return wrapper.vm.updateIssuable().then(() => { await wrapper.vm.updateIssuable();
expect(eventHub.$emit).not.toHaveBeenCalledWith('close.form'); expect(eventHub.$emit).not.toHaveBeenCalledWith('close.form');
expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe( expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
`Error updating issue`, `Error updating issue`,
); );
}); });
});
it('returns the correct error message for issuableType', () => { it('returns the correct error message for issuableType', async () => {
jest.spyOn(wrapper.vm.service, 'updateIssuable').mockRejectedValue(); jest.spyOn(wrapper.vm.service, 'updateIssuable').mockRejectedValue();
wrapper.setProps({ issuableType: 'merge request' }); wrapper.setProps({ issuableType: 'merge request' });
return wrapper.vm await nextTick();
.$nextTick() await wrapper.vm.updateIssuable();
.then(wrapper.vm.updateIssuable)
.then(() => {
expect(eventHub.$emit).not.toHaveBeenCalledWith('close.form'); expect(eventHub.$emit).not.toHaveBeenCalledWith('close.form');
expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe( expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
`Error updating merge request`, `Error updating merge request`,
); );
}); });
});
it('shows error message from backend if exists', () => { it('shows error message from backend if exists', async () => {
const msg = 'Custom error message from backend'; const msg = 'Custom error message from backend';
jest jest
.spyOn(wrapper.vm.service, 'updateIssuable') .spyOn(wrapper.vm.service, 'updateIssuable')
.mockRejectedValue({ response: { data: { errors: [msg] } } }); .mockRejectedValue({ response: { data: { errors: [msg] } } });
return wrapper.vm.updateIssuable().then(() => { await wrapper.vm.updateIssuable();
expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe( expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
`${wrapper.vm.defaultErrorMessage}. ${msg}`, `${wrapper.vm.defaultErrorMessage}. ${msg}`,
); );
}); });
}); });
}); });
});
describe('updateAndShowForm', () => { describe('updateAndShowForm', () => {
it('shows locked warning if form is open & data is different', () => { it('shows locked warning if form is open & data is different', async () => {
return wrapper.vm await nextTick();
.$nextTick()
.then(() => {
wrapper.vm.updateAndShowForm(); wrapper.vm.updateAndShowForm();
wrapper.vm.poll.makeRequest(); wrapper.vm.poll.makeRequest();
return new Promise((resolve) => { await new Promise((resolve) => {
wrapper.vm.$watch('formState.lockedWarningVisible', (value) => { wrapper.vm.$watch('formState.lockedWarningVisible', (value) => {
if (value) { if (value) {
resolve(); resolve();
} }
}); });
}); });
})
.then(() => {
expect(wrapper.vm.formState.lockedWarningVisible).toBe(true); expect(wrapper.vm.formState.lockedWarningVisible).toBe(true);
expect(wrapper.vm.formState.lock_version).toBe(1); expect(wrapper.vm.formState.lock_version).toBe(1);
expect(findAlert().exists()).toBe(true); expect(findAlert().exists()).toBe(true);
}); });
}); });
});
describe('requestTemplatesAndShowForm', () => { describe('requestTemplatesAndShowForm', () => {
let formSpy; let formSpy;
...@@ -398,14 +378,13 @@ describe('Issuable output', () => { ...@@ -398,14 +378,13 @@ describe('Issuable output', () => {
expect(wrapper.find('.btn-edit').exists()).toBe(true); expect(wrapper.find('.btn-edit').exists()).toBe(true);
}); });
it('should render if showInlineEditButton', () => { it('should render if showInlineEditButton', async () => {
wrapper.setProps({ showInlineEditButton: true }); wrapper.setProps({ showInlineEditButton: true });
return wrapper.vm.$nextTick(() => { await nextTick();
expect(wrapper.find('.btn-edit').exists()).toBe(true); expect(wrapper.find('.btn-edit').exists()).toBe(true);
}); });
}); });
});
describe('updateStoreState', () => { describe('updateStoreState', () => {
it('should make a request and update the state of the store', () => { it('should make a request and update the state of the store', () => {
......
...@@ -2,6 +2,7 @@ import { GlFormGroup, GlDropdown, GlDropdownItem, GlIcon } from '@gitlab/ui'; ...@@ -2,6 +2,7 @@ import { GlFormGroup, GlDropdown, GlDropdownItem, GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import Vue from 'vue'; import Vue from 'vue';
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 IssueTypeField, { i18n } from '~/issues/show/components/fields/type.vue'; import IssueTypeField, { i18n } from '~/issues/show/components/fields/type.vue';
...@@ -92,7 +93,7 @@ describe('Issue type field component', () => { ...@@ -92,7 +93,7 @@ describe('Issue type field component', () => {
it('updates the `issue_type` in the apollo cache when the value is changed', async () => { it('updates the `issue_type` in the apollo cache when the value is changed', async () => {
findTypeFromDropDownItems().at(1).vm.$emit('click', issuableTypes.incident); findTypeFromDropDownItems().at(1).vm.$emit('click', issuableTypes.incident);
await wrapper.vm.$nextTick(); await nextTick();
expect(findTypeFromDropDown().attributes('value')).toBe(issuableTypes.incident); expect(findTypeFromDropDown().attributes('value')).toBe(issuableTypes.incident);
}); });
......
import { GlAlert } from '@gitlab/ui'; import { GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import Autosave from '~/autosave'; import Autosave from '~/autosave';
import DescriptionTemplate from '~/issues/show/components/fields/description_template.vue'; import DescriptionTemplate from '~/issues/show/components/fields/description_template.vue';
import IssueTypeField from '~/issues/show/components/fields/type.vue'; import IssueTypeField from '~/issues/show/components/fields/type.vue';
...@@ -148,7 +149,7 @@ describe('Inline edit form component', () => { ...@@ -148,7 +149,7 @@ describe('Inline edit form component', () => {
formState: { ...defaultProps.formState, lock_version: 'lock version from server' }, formState: { ...defaultProps.formState, lock_version: 'lock version from server' },
}); });
await wrapper.vm.$nextTick(); await nextTick();
expect(findAlert().exists()).toBe(true); expect(findAlert().exists()).toBe(true);
}); });
}); });
......
import { GlButton, GlDropdown, GlDropdownItem, GlLink, GlModal } from '@gitlab/ui'; import { GlButton, GlDropdown, GlDropdownItem, GlLink, GlModal } from '@gitlab/ui';
import Vue from 'vue'; import Vue, { nextTick } from 'vue';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { mockTracking } from 'helpers/tracking_helper'; import { mockTracking } from 'helpers/tracking_helper';
...@@ -153,7 +153,7 @@ describe('HeaderActions component', () => { ...@@ -153,7 +153,7 @@ describe('HeaderActions component', () => {
it('dispatches a custom event to update the issue page', async () => { it('dispatches a custom event to update the issue page', async () => {
findToggleIssueStateButton().vm.$emit('click'); findToggleIssueStateButton().vm.$emit('click');
await wrapper.vm.$nextTick(); await nextTick();
expect(dispatchEventSpy).toHaveBeenCalledTimes(1); expect(dispatchEventSpy).toHaveBeenCalledTimes(1);
}); });
......
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