Commit f8c7f771 authored by Stanislav Lashmanov's avatar Stanislav Lashmanov

Refactor nextTick to use direct import from Vue package

RFC: https://gitlab.com/gitlab-org/frontend/rfcs/-/issues/47
parent 79f66000
import { GlModal, GlSearchBoxByType } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import getDiffWithCommit from 'test_fixtures/merge_request_diffs/with_commit.json';
import AddReviewItemsModal from '~/add_context_commits_modal/components/add_context_commits_modal_wrapper.vue';
......@@ -84,11 +84,10 @@ describe('AddContextCommitsModal', () => {
expect(findModal().attributes('ok-disabled')).toBe('true');
});
it('enabled ok button when atleast one row is selected', () => {
it('enabled ok button when atleast one row is selected', async () => {
wrapper.vm.$store.state.selectedCommits = [{ ...commit, isSelected: true }];
return wrapper.vm.$nextTick().then(() => {
expect(findModal().attributes('ok-disabled')).toBeFalsy();
});
await nextTick();
expect(findModal().attributes('ok-disabled')).toBeFalsy();
});
});
......@@ -100,11 +99,10 @@ describe('AddContextCommitsModal', () => {
expect(findModal().attributes('ok-disabled')).toBe('true');
});
it('an enabled ok button when atleast one row is selected', () => {
it('an enabled ok button when atleast one row is selected', async () => {
wrapper.vm.$store.state.selectedCommits = [{ ...commit, isSelected: true }];
return wrapper.vm.$nextTick().then(() => {
expect(findModal().attributes('ok-disabled')).toBeFalsy();
});
await nextTick();
expect(findModal().attributes('ok-disabled')).toBeFalsy();
});
it('a disabled ok button in first tab, when row is selected in second tab', () => {
......@@ -114,33 +112,30 @@ describe('AddContextCommitsModal', () => {
});
describe('has an ok button when clicked calls action', () => {
it('"createContextCommits" when only new commits to be added ', () => {
it('"createContextCommits" when only new commits to be added ', async () => {
wrapper.vm.$store.state.selectedCommits = [{ ...commit, isSelected: true }];
findModal().vm.$emit('ok');
return wrapper.vm.$nextTick().then(() => {
expect(createContextCommits).toHaveBeenCalledWith(expect.anything(), {
commits: [{ ...commit, isSelected: true }],
forceReload: true,
});
await nextTick();
expect(createContextCommits).toHaveBeenCalledWith(expect.anything(), {
commits: [{ ...commit, isSelected: true }],
forceReload: true,
});
});
it('"removeContextCommits" when only added commits are to be removed ', () => {
it('"removeContextCommits" when only added commits are to be removed ', async () => {
wrapper.vm.$store.state.toRemoveCommits = [commit.short_id];
findModal().vm.$emit('ok');
return wrapper.vm.$nextTick().then(() => {
expect(removeContextCommits).toHaveBeenCalledWith(expect.anything(), true);
});
await nextTick();
expect(removeContextCommits).toHaveBeenCalledWith(expect.anything(), true);
});
it('"createContextCommits" and "removeContextCommits" when new commits are to be added and old commits are to be removed', () => {
it('"createContextCommits" and "removeContextCommits" when new commits are to be added and old commits are to be removed', async () => {
wrapper.vm.$store.state.selectedCommits = [{ ...commit, isSelected: true }];
wrapper.vm.$store.state.toRemoveCommits = [commit.short_id];
findModal().vm.$emit('ok');
return wrapper.vm.$nextTick().then(() => {
expect(createContextCommits).toHaveBeenCalledWith(expect.anything(), {
commits: [{ ...commit, isSelected: true }],
});
expect(removeContextCommits).toHaveBeenCalledWith(expect.anything(), undefined);
await nextTick();
expect(createContextCommits).toHaveBeenCalledWith(expect.anything(), {
commits: [{ ...commit, isSelected: true }],
});
expect(removeContextCommits).toHaveBeenCalledWith(expect.anything(), undefined);
});
});
......
import { GlButton, GlFormInput, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DeleteUserModal from '~/admin/users/components/modals/delete_user_modal.vue';
import UserDeletionObstaclesList from '~/vue_shared/components/user_deletion_obstacles/user_deletion_obstacles_list.vue';
import ModalStub from './stubs/modal_stub';
......@@ -82,11 +83,11 @@ describe('User Operation confirmation modal', () => {
});
describe('with incorrect username', () => {
beforeEach(() => {
beforeEach(async () => {
createComponent();
setUsername(badUsername);
return wrapper.vm.$nextTick();
await nextTick();
});
it('shows incorrect username', () => {
......@@ -100,11 +101,11 @@ describe('User Operation confirmation modal', () => {
});
describe('with correct username', () => {
beforeEach(() => {
beforeEach(async () => {
createComponent();
setUsername(username);
return wrapper.vm.$nextTick();
await nextTick();
});
it('shows correct username', () => {
......@@ -117,10 +118,10 @@ describe('User Operation confirmation modal', () => {
});
describe('when primary action is submitted', () => {
beforeEach(() => {
beforeEach(async () => {
findPrimaryButton().vm.$emit('click');
return wrapper.vm.$nextTick();
await nextTick();
});
it('clears the input', () => {
......@@ -136,10 +137,10 @@ describe('User Operation confirmation modal', () => {
});
describe('when secondary action is submitted', () => {
beforeEach(() => {
beforeEach(async () => {
findSecondaryButton().vm.$emit('click');
return wrapper.vm.$nextTick();
await nextTick();
});
it('has correct form attributes and calls submit', () => {
......@@ -168,7 +169,7 @@ describe('User Operation confirmation modal', () => {
it("shows enabled buttons when user's name is entered without whitespace", async () => {
setUsername('John Smith');
await wrapper.vm.$nextTick();
await nextTick();
expect(findPrimaryButton().attributes('disabled')).toBeUndefined();
expect(findSecondaryButton().attributes('disabled')).toBeUndefined();
......
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import UserModalManager from '~/admin/users/components/modals/user_modal_manager.vue';
import ModalStub from './stubs/modal_stub';
......@@ -50,20 +51,19 @@ describe('Users admin page Modal Manager', () => {
expect(() => wrapper.vm.show({ glModalAction: 'action1' })).toThrow();
});
it('renders modal with expected props when valid configuration is passed', () => {
it('renders modal with expected props when valid configuration is passed', async () => {
createComponent();
wrapper.vm.show({
glModalAction: 'action1',
extraProp: 'extraPropValue',
});
return wrapper.vm.$nextTick().then(() => {
const modal = findModal();
expect(modal.exists()).toBeTruthy();
expect(modal.vm.$attrs.csrfToken).toEqual('dummyCSRF');
expect(modal.vm.$attrs.extraProp).toEqual('extraPropValue');
expect(modal.vm.showWasCalled).toBeTruthy();
});
await nextTick();
const modal = findModal();
expect(modal.exists()).toBeTruthy();
expect(modal.vm.$attrs.csrfToken).toEqual('dummyCSRF');
expect(modal.vm.$attrs.extraProp).toEqual('extraPropValue');
expect(modal.vm.showWasCalled).toBeTruthy();
});
});
......@@ -101,7 +101,7 @@ describe('Users admin page Modal Manager', () => {
it('renders the modal when the button is clicked', async () => {
button.click();
await wrapper.vm.$nextTick();
await nextTick();
expect(findModal().exists()).toBe(true);
});
......@@ -110,7 +110,7 @@ describe('Users admin page Modal Manager', () => {
button.removeAttribute('data-gl-modal-action');
button.click();
await wrapper.vm.$nextTick();
await nextTick();
expect(findModal().exists()).toBe(false);
});
......@@ -118,7 +118,7 @@ describe('Users admin page Modal Manager', () => {
it('does not render the modal when a button without the selector class is clicked', async () => {
button2.click();
await wrapper.vm.$nextTick();
await nextTick();
expect(findModal().exists()).toBe(false);
});
......
......@@ -2,6 +2,7 @@ import { GlTable, GlAlert, GlLoadingIcon, GlDropdown, GlIcon, GlAvatar } from '@
import { mount } from '@vue/test-utils';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import mockAlerts from 'jest/vue_shared/alert_details/mocks/alerts.json';
......@@ -169,7 +170,7 @@ describe('AlertManagementTable', () => {
loading: false,
});
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.find(GlTable).exists()).toBe(true);
expect(findAlertsTable().find(GlIcon).classes('icon-critical')).toBe(true);
......
import { GlLoadingIcon, GlAlert } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import AxiosMockAdapter from 'axios-mock-adapter';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createHttpIntegrationMutation from 'ee_else_ce/alerts_settings/graphql/mutations/create_http_integration.mutation.graphql';
import updateHttpIntegrationMutation from 'ee_else_ce/alerts_settings/graphql/mutations/update_http_integration.mutation.graphql';
......@@ -70,7 +70,7 @@ describe('AlertsSettingsWrapper', () => {
async function destroyHttpIntegration(localWrapper) {
await jest.runOnlyPendingTimers();
await localWrapper.vm.$nextTick();
await nextTick();
localWrapper
.find(IntegrationsList)
......
import { GlDaterangePicker } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { useFakeDate } from 'helpers/fake_date';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import Daterange from '~/analytics/shared/components/daterange.vue';
......@@ -48,7 +49,7 @@ describe('Daterange component', () => {
});
describe('with a minDate being set', () => {
it('emits the change event with the minDate when the user enters a start date before the minDate', () => {
it('emits the change event with the minDate when the user enters a start date before the minDate', async () => {
const startDate = new Date('2019-09-01');
const endDate = new Date('2019-09-30');
const minDate = new Date('2019-06-01');
......@@ -60,9 +61,8 @@ describe('Daterange component', () => {
input.setValue('2019-01-01');
input.trigger('change');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted().change).toEqual([[{ startDate: minDate, endDate }]]);
});
await nextTick();
expect(wrapper.emitted().change).toEqual([[{ startDate: minDate, endDate }]]);
});
});
......
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { nextTick } from 'vue';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import { stubComponent } from 'helpers/stub_component';
import { TEST_HOST } from 'helpers/test_constants';
......@@ -99,9 +100,9 @@ describe('ProjectsDropdownFilter component', () => {
const findDropdownFullPathAtIndex = (index) =>
findDropdownAtIndex(index).find('[data-testid="project-full-path"]');
const selectDropdownItemAtIndex = (index) => {
const selectDropdownItemAtIndex = async (index) => {
findDropdownAtIndex(index).find('button').trigger('click');
return wrapper.vm.$nextTick();
await nextTick();
};
// NOTE: Selected items are now visually separated from unselected items
......@@ -132,16 +133,15 @@ describe('ProjectsDropdownFilter component', () => {
expect(spyQuery).toHaveBeenCalledTimes(1);
await wrapper.vm.$nextTick(() => {
expect(spyQuery).toHaveBeenCalledWith({
query: getProjects,
variables: {
search: 'gitlab',
groupFullPath: wrapper.vm.groupNamespace,
first: 50,
includeSubgroups: true,
},
});
await nextTick();
expect(spyQuery).toHaveBeenCalledWith({
query: getProjects,
variables: {
search: 'gitlab',
groupFullPath: wrapper.vm.groupNamespace,
first: 50,
includeSubgroups: true,
},
});
});
});
......@@ -193,7 +193,7 @@ describe('ProjectsDropdownFilter component', () => {
expect(wrapper.text()).toContain('2 projects selected');
findClearAllButton().trigger('click');
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.text()).not.toContain('2 projects selected');
expect(wrapper.text()).toContain('Select projects');
......@@ -366,9 +366,8 @@ describe('ProjectsDropdownFilter component', () => {
selectDropdownItemAtIndex(0);
selectDropdownItemAtIndex(1);
await wrapper.vm.$nextTick().then(() => {
expect(findDropdownButton().text()).toBe('2 projects selected');
});
await nextTick();
expect(findDropdownButton().text()).toBe('2 projects selected');
});
});
});
......
import { GlAlert } from '@gitlab/ui';
import { GlLineChart } from '@gitlab/ui/dist/charts';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
......@@ -164,7 +164,7 @@ describe('UsageTrendsCountChart', () => {
.spyOn(wrapper.vm.$apollo.queries[identifier], 'fetchMore')
.mockImplementation(jest.fn().mockRejectedValue());
await wrapper.vm.$nextTick();
await nextTick();
});
it('calls fetchMore', () => {
......
import { GlAlert } from '@gitlab/ui';
import { GlAreaChart } from '@gitlab/ui/dist/charts';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import UsersChart from '~/analytics/usage_trends/components/users_chart.vue';
......@@ -67,7 +67,7 @@ describe('UsersChart', () => {
describe('without data', () => {
beforeEach(async () => {
wrapper = createComponent({ users: [] });
await wrapper.vm.$nextTick();
await nextTick();
});
it('renders an no data message', () => {
......@@ -86,7 +86,7 @@ describe('UsersChart', () => {
describe('with data', () => {
beforeEach(async () => {
wrapper = createComponent({ users: mockCountsData2 });
await wrapper.vm.$nextTick();
await nextTick();
});
it('hides the skeleton loader', () => {
......@@ -107,7 +107,7 @@ describe('UsersChart', () => {
describe('with errors', () => {
beforeEach(async () => {
wrapper = createComponent({ loadingError: true });
await wrapper.vm.$nextTick();
await nextTick();
});
it('renders an error message', () => {
......@@ -134,7 +134,7 @@ describe('UsersChart', () => {
});
jest.spyOn(wrapper.vm.$apollo.queries.users, 'fetchMore');
await wrapper.vm.$nextTick();
await nextTick();
});
it('requests data twice', () => {
......@@ -147,7 +147,7 @@ describe('UsersChart', () => {
});
describe('when the fetchMore query throws an error', () => {
beforeEach(() => {
beforeEach(async () => {
wrapper = createComponent({
users: mockCountsData2,
additionalData: mockCountsData1,
......@@ -156,7 +156,7 @@ describe('UsersChart', () => {
jest
.spyOn(wrapper.vm.$apollo.queries.users, 'fetchMore')
.mockImplementation(jest.fn().mockRejectedValue());
return wrapper.vm.$nextTick();
await nextTick();
});
it('calls fetchMore', () => {
......
import { GlFormCheckbox, GlLink } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import UpdateKeepLatestArtifactProjectSetting from '~/artifacts_settings/graphql/mutations/update_keep_latest_artifact_project_setting.mutation.graphql';
......@@ -109,13 +109,13 @@ describe('Keep latest artifact checkbox', () => {
});
it('sets correct setting value in checkbox with query result', async () => {
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.element).toMatchSnapshot();
});
it('checkbox is enabled when application setting is enabled', async () => {
await wrapper.vm.$nextTick();
await nextTick();
expect(findCheckbox().attributes('disabled')).toBeUndefined();
});
......
import { GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import BadgeList from '~/badges/components/badge_list.vue';
import BadgeListRow from '~/badges/components/badge_list_row.vue';
......@@ -40,7 +40,7 @@ describe('BadgeSettings component', () => {
const button = wrapper.find('[data-testid="delete-badge"]');
button.vm.$emit('click');
await wrapper.vm.$nextTick();
await nextTick();
const modal = wrapper.find(GlModal);
expect(modal.isVisible()).toBe(true);
......
import { getByRole } from '@testing-library/dom';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { stubComponent } from 'helpers/stub_component';
import DraftNote from '~/batch_comments/components/draft_note.vue';
import { createStore } from '~/batch_comments/stores';
......@@ -71,45 +72,37 @@ describe('Batch comments draft note component', () => {
);
});
it('sets as loading when draft is publishing', (done) => {
it('sets as loading when draft is publishing', async () => {
createComponent();
wrapper.vm.$store.state.batchComments.currentlyPublishingDrafts.push(1);
wrapper.vm.$nextTick(() => {
const publishNowButton = wrapper.find({ ref: 'publishNowButton' });
expect(publishNowButton.props().loading).toBe(true);
await nextTick();
const publishNowButton = wrapper.find({ ref: 'publishNowButton' });
done();
});
expect(publishNowButton.props().loading).toBe(true);
});
});
describe('update', () => {
it('dispatches updateDraft', (done) => {
it('dispatches updateDraft', async () => {
createComponent();
const note = wrapper.find(NoteableNote);
note.vm.$emit('handleEdit');
wrapper.vm
.$nextTick()
.then(() => {
const formData = {
note: draft,
noteText: 'a',
resolveDiscussion: false,
};
note.vm.$emit('handleUpdateNote', formData);
expect(wrapper.vm.$store.dispatch).toHaveBeenCalledWith(
'batchComments/updateDraft',
formData,
);
})
.then(done)
.catch(done.fail);
await nextTick();
const formData = {
note: draft,
noteText: 'a',
resolveDiscussion: false,
};
note.vm.$emit('handleUpdateNote', formData);
expect(wrapper.vm.$store.dispatch).toHaveBeenCalledWith(
'batchComments/updateDraft',
formData,
);
});
});
......@@ -127,7 +120,7 @@ describe('Batch comments draft note component', () => {
});
describe('quick actions', () => {
it('renders referenced commands', (done) => {
it('renders referenced commands', async () => {
createComponent();
wrapper.setProps({
draft: {
......@@ -138,14 +131,11 @@ describe('Batch comments draft note component', () => {
},
});
wrapper.vm.$nextTick(() => {
const referencedCommands = wrapper.find('.referenced-commands');
await nextTick();
const referencedCommands = wrapper.find('.referenced-commands');
expect(referencedCommands.exists()).toBe(true);
expect(referencedCommands.text()).toContain('test command');
done();
});
expect(referencedCommands.exists()).toBe(true);
expect(referencedCommands.text()).toContain('test command');
});
});
......
import { GlFormInput, GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import BlobEditHeader from '~/blob/components/blob_edit_header.vue';
describe('Blob Header Editing', () => {
......@@ -40,7 +41,7 @@ describe('Blob Header Editing', () => {
});
describe('functionality', () => {
it('emits input event when the blob name is changed', () => {
it('emits input event when the blob name is changed', async () => {
const inputComponent = wrapper.find(GlFormInput);
const newValue = 'bar.txt';
......@@ -51,9 +52,8 @@ describe('Blob Header Editing', () => {
});
inputComponent.vm.$emit('change');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted().input[0]).toEqual([newValue]);
});
await nextTick();
expect(wrapper.emitted().input[0]).toEqual([newValue]);
});
});
......
import { shallowMount, mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import BlobHeader from '~/blob/components/blob_header.vue';
import DefaultActions from '~/blob/components/blob_header_default_actions.vue';
import BlobFilepath from '~/blob/components/blob_header_filepath.vue';
......@@ -139,26 +140,24 @@ describe('Blob Header Default Actions', () => {
expect(wrapper.vm.viewer).toBe(null);
});
it('watches the changes in viewer data and emits event when the change is registered', () => {
it('watches the changes in viewer data and emits event when the change is registered', async () => {
factory();
jest.spyOn(wrapper.vm, '$emit');
wrapper.vm.viewer = newViewer;
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.$emit).toHaveBeenCalledWith('viewer-changed', newViewer);
});
await nextTick();
expect(wrapper.vm.$emit).toHaveBeenCalledWith('viewer-changed', newViewer);
});
it('does not emit event if the switcher is not rendered', () => {
it('does not emit event if the switcher is not rendered', async () => {
factory(true);
expect(wrapper.vm.showViewerSwitcher).toBe(false);
jest.spyOn(wrapper.vm, '$emit');
wrapper.vm.viewer = newViewer;
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.$emit).not.toHaveBeenCalled();
});
await nextTick();
expect(wrapper.vm.$emit).not.toHaveBeenCalled();
});
});
});
import { GlButtonGroup, GlButton } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import BlobHeaderViewerSwitcher from '~/blob/components/blob_header_viewer_switcher.vue';
import {
RICH_BLOB_VIEWER,
......@@ -72,26 +73,24 @@ describe('Blob Header Viewer Switcher', () => {
expect(wrapper.vm.$emit).not.toHaveBeenCalled();
});
it('emits an event when a Rich Viewer button is clicked', () => {
it('emits an event when a Rich Viewer button is clicked', async () => {
factory();
expect(wrapper.vm.value).toBe(SIMPLE_BLOB_VIEWER);
richBtn.vm.$emit('click');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', RICH_BLOB_VIEWER);
});
await nextTick();
expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', RICH_BLOB_VIEWER);
});
it('emits an event when a Simple Viewer button is clicked', () => {
it('emits an event when a Simple Viewer button is clicked', async () => {
factory({
value: RICH_BLOB_VIEWER,
});
simpleBtn.vm.$emit('click');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', SIMPLE_BLOB_VIEWER);
});
await nextTick();
expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', SIMPLE_BLOB_VIEWER);
});
});
});
import { GlLabel, GlLoadingIcon, GlTooltip } from '@gitlab/ui';
import { range } from 'lodash';
import Vuex from 'vuex';
import { nextTick } from 'vue';
import setWindowLocation from 'helpers/set_window_location_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { mountExtended } from 'helpers/vue_test_utils_helper';
......@@ -261,7 +262,7 @@ describe('Board card component', () => {
],
});
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.find('.board-card-assignee img').attributes('src')).toBe(
'test_image_from_avatar_url?width=24',
......@@ -376,7 +377,7 @@ describe('Board card component', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.find('.board-card-assignee .avatar-counter').text().trim()).toEqual('99+');
});
......@@ -399,7 +400,7 @@ describe('Board card component', () => {
it('does not render label if label does not have an ID', async () => {
wrapper.setProps({ item: { ...issue, labels: [label1, { title: 'closed' }] } });
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.findAll(GlLabel).length).toBe(1);
expect(wrapper.text()).not.toContain('closed');
......
import Draggable from 'vuedraggable';
import { nextTick } from 'vue';
import { DraggableItemTypes } from 'ee_else_ce/boards/constants';
import { useFakeRequestAnimationFrame } from 'helpers/fake_request_animation_frame';
import waitForPromises from 'helpers/wait_for_promises';
......@@ -65,14 +66,14 @@ describe('Board list component', () => {
it('shows new issue form', async () => {
wrapper.vm.toggleForm();
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.find('.board-new-issue-form').exists()).toBe(true);
});
it('shows new issue form after eventhub event', async () => {
eventHub.$emit(`toggle-issue-form-${wrapper.vm.list.id}`);
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.find('.board-new-issue-form').exists()).toBe(true);
});
......@@ -86,7 +87,7 @@ describe('Board list component', () => {
it('shows count list item', async () => {
wrapper.vm.showCount = true;
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.find('.board-list-count').exists()).toBe(true);
expect(wrapper.find('.board-list-count').text()).toBe('Showing all issues');
......@@ -95,7 +96,7 @@ describe('Board list component', () => {
it('sets data attribute with invalid id', async () => {
wrapper.vm.showCount = true;
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.find('.board-list-count').attributes('data-issue-id')).toBe('-1');
});
});
......@@ -127,7 +128,7 @@ describe('Board list component', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
expect(findIssueCountLoadingIcon().exists()).toBe(true);
});
......@@ -139,9 +140,9 @@ describe('Board list component', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
await waitForPromises();
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.find('.board-list-count').text()).toBe('Showing 1 of 20 issues');
});
......@@ -158,7 +159,7 @@ describe('Board list component', () => {
it('sets background to bg-danger-100', async () => {
wrapper.setProps({ list: { issuesCount: 4, maxIssueCount: 3 } });
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.find('.bg-danger-100').exists()).toBe(true);
});
});
......
import { GlButton } from '@gitlab/ui';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import BoardAddNewColumnTrigger from '~/boards/components/board_add_new_column_trigger.vue';
......@@ -49,7 +49,7 @@ describe('BoardAddNewColumnTrigger', () => {
it('shows the tooltip', async () => {
wrapper.find(GlButton).vm.$emit('click');
await wrapper.vm.$nextTick();
await nextTick();
const tooltip = findTooltipText();
......
import { GlIcon, GlLink, GlPopover, GlLoadingIcon } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
......@@ -39,7 +39,7 @@ describe('BoardBlockedIcon', () => {
const mouseenter = async () => {
findGlIcon().vm.$emit('mouseenter');
await wrapper.vm.$nextTick();
await nextTick();
await waitForApollo();
};
......
import { GlLabel } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import BoardCard from '~/boards/components/board_card.vue';
......@@ -65,12 +65,12 @@ describe('Board card', () => {
const selectCard = async () => {
wrapper.trigger('click');
await wrapper.vm.$nextTick();
await nextTick();
};
const multiSelectCard = async () => {
wrapper.trigger('click', { ctrlKey: true });
await wrapper.vm.$nextTick();
await nextTick();
};
beforeEach(() => {
......
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import Vuex from 'vuex';
import createMockApollo from 'helpers/mock_apollo_helper';
......@@ -148,7 +148,7 @@ describe('Board List Header Component', () => {
findCaret().vm.$emit('click');
await wrapper.vm.$nextTick();
await nextTick();
expect(toggleListCollapsedSpy).toHaveBeenCalledTimes(1);
});
......@@ -156,7 +156,7 @@ describe('Board List Header Component', () => {
createComponent({ withLocalStorage: false, currentUserId: 1 });
findCaret().vm.$emit('click');
await wrapper.vm.$nextTick();
await nextTick();
expect(updateListSpy).toHaveBeenCalledTimes(1);
expect(localStorage.getItem(`${wrapper.vm.uniqueKey}.collapsed`)).toBe(null);
......@@ -168,7 +168,7 @@ describe('Board List Header Component', () => {
});
findCaret().vm.$emit('click');
await wrapper.vm.$nextTick();
await nextTick();
expect(updateListSpy).not.toHaveBeenCalled();
expect(localStorage.getItem(`${wrapper.vm.uniqueKey}.collapsed`)).toBe(String(isCollapsed()));
......
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import BoardNewIssue from '~/boards/components/board_new_issue.vue';
import BoardNewItem from '~/boards/components/board_new_item.vue';
......@@ -45,7 +45,7 @@ describe('Issue boards new issue form', () => {
beforeEach(async () => {
wrapper = createComponent();
await wrapper.vm.$nextTick();
await nextTick();
});
afterEach(() => {
......@@ -66,7 +66,7 @@ describe('Issue boards new issue form', () => {
it('calls addListNewIssue action when `board-new-item` emits form-submit event', async () => {
findBoardNewItem().vm.$emit('form-submit', { title: 'Foo' });
await wrapper.vm.$nextTick();
await nextTick();
expect(addListNewIssuesSpy).toHaveBeenCalledWith(expect.any(Object), {
list: mockList,
issueInput: {
......@@ -83,7 +83,7 @@ describe('Issue boards new issue form', () => {
jest.spyOn(eventHub, '$emit').mockImplementation();
findBoardNewItem().vm.$emit('form-cancel');
await wrapper.vm.$nextTick();
await nextTick();
expect(eventHub.$emit).toHaveBeenCalledWith(`toggle-issue-form-${mockList.id}`);
});
......
import { GlForm, GlFormInput, GlButton } from '@gitlab/ui';
import { nextTick } from 'vue';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import BoardNewItem from '~/boards/components/board_new_item.vue';
......@@ -44,7 +45,7 @@ describe('BoardNewItem', () => {
expect(wrapper.findByTestId('create-button').props('disabled')).toBe(true);
wrapper.find(GlFormInput).vm.$emit('input', 'hello');
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.findByTestId('create-button').props('disabled')).toBe(false);
});
......@@ -54,7 +55,7 @@ describe('BoardNewItem', () => {
it('disables the Create Issue button', async () => {
wrapper.find(GlFormInput).vm.$emit('input', ' ');
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.findByTestId('create-button').props('disabled')).toBe(true);
});
......@@ -124,7 +125,7 @@ describe('BoardNewItem', () => {
it('emits `form-cancel` event and clears title value when `reset` is triggered on gl-form', async () => {
titleInput().setValue('Foo');
await wrapper.vm.$nextTick();
await nextTick();
expect(titleInput().element.value).toBe('Foo');
await glForm().trigger('reset');
......
import { GlDrawer, GlLabel } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { MountingPortal } from 'portal-vue';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import { stubComponent } from 'helpers/stub_component';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
......@@ -86,7 +86,7 @@ describe('BoardSettingsSidebar', () => {
findDrawer().vm.$emit('close');
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.find(GlDrawer).exists()).toBe(false);
});
......@@ -96,7 +96,7 @@ describe('BoardSettingsSidebar', () => {
sidebarEventHub.$emit('sidebar.closeAll');
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.find(GlDrawer).exists()).toBe(false);
});
......
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import BoardSidebarItem from '~/boards/components/sidebar/board_editable_item.vue';
describe('boards sidebar remove issue', () => {
......@@ -79,17 +80,16 @@ describe('boards sidebar remove issue', () => {
createComponent({ canUpdate: true, slots });
findEditButton().vm.$emit('click');
return wrapper.vm.$nextTick().then(() => {
expect(findCollapsed().isVisible()).toBe(false);
expect(findExpanded().isVisible()).toBe(true);
});
await nextTick();
expect(findCollapsed().isVisible()).toBe(false);
expect(findExpanded().isVisible()).toBe(true);
});
it('hides the header while editing if `toggleHeader` is true', async () => {
createComponent({ canUpdate: true, props: { toggleHeader: true } });
findEditButton().vm.$emit('click');
await wrapper.vm.$nextTick();
await nextTick();
expect(findEditButton().isVisible()).toBe(false);
expect(findTitle().isVisible()).toBe(false);
......@@ -101,14 +101,14 @@ describe('boards sidebar remove issue', () => {
beforeEach(async () => {
createComponent({ canUpdate: true });
findEditButton().vm.$emit('click');
await wrapper.vm.$nextTick();
await nextTick();
});
it('hides expanded section and displays collapsed section', async () => {
expect(findExpanded().isVisible()).toBe(true);
document.body.click();
await wrapper.vm.$nextTick();
await nextTick();
expect(findCollapsed().isVisible()).toBe(true);
expect(findExpanded().isVisible()).toBe(false);
......@@ -117,7 +117,7 @@ describe('boards sidebar remove issue', () => {
it('emits events', async () => {
document.body.click();
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.emitted().close).toHaveLength(1);
expect(wrapper.emitted()['off-click']).toHaveLength(1);
......@@ -129,7 +129,7 @@ describe('boards sidebar remove issue', () => {
findEditButton().vm.$emit('click');
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.emitted().open.length).toBe(1);
});
......@@ -139,7 +139,7 @@ describe('boards sidebar remove issue', () => {
findEditButton().vm.$emit('click');
await wrapper.vm.$nextTick();
await nextTick();
wrapper.vm.collapse({ emitEvent: false });
......
import { GlAlert, GlFormInput, GlForm } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import BoardEditableItem from '~/boards/components/sidebar/board_editable_item.vue';
import BoardSidebarTitle from '~/boards/components/sidebar/board_sidebar_title.vue';
import { createStore } from '~/boards/stores';
......@@ -75,7 +76,7 @@ describe('~/boards/components/sidebar/board_sidebar_title.vue', () => {
});
findFormInput().vm.$emit('input', TEST_TITLE);
findForm().vm.$emit('submit', { preventDefault: () => {} });
await wrapper.vm.$nextTick();
await nextTick();
});
it('collapses sidebar and renders new title', () => {
......@@ -98,7 +99,7 @@ describe('~/boards/components/sidebar/board_sidebar_title.vue', () => {
jest.spyOn(wrapper.vm, 'setActiveItemTitle').mockImplementation(() => {});
findFormInput().vm.$emit('input', '');
findForm().vm.$emit('submit', { preventDefault: () => {} });
await wrapper.vm.$nextTick();
await nextTick();
});
it('commits change to the server', () => {
......@@ -113,7 +114,7 @@ describe('~/boards/components/sidebar/board_sidebar_title.vue', () => {
wrapper.vm.$refs.sidebarItem.expand();
findFormInput().vm.$emit('input', TEST_TITLE);
findEditableItem().vm.$emit('off-click');
await wrapper.vm.$nextTick();
await nextTick();
});
it('does not collapses sidebar and shows alert', () => {
......@@ -148,7 +149,7 @@ describe('~/boards/components/sidebar/board_sidebar_title.vue', () => {
});
findFormInput().vm.$emit('input', TEST_TITLE);
findCancelButton().vm.$emit('click');
await wrapper.vm.$nextTick();
await nextTick();
});
it('collapses sidebar and render former title', () => {
......@@ -168,7 +169,7 @@ describe('~/boards/components/sidebar/board_sidebar_title.vue', () => {
jest.spyOn(wrapper.vm, 'setError').mockImplementation(() => {});
findFormInput().vm.$emit('input', 'Invalid title');
findForm().vm.$emit('submit', { preventDefault: () => {} });
await wrapper.vm.$nextTick();
await nextTick();
});
it('collapses sidebar and renders former item title', () => {
......
import { GlDropdown, GlDropdownItem, GlSearchBoxByType, GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import ProjectSelect from '~/boards/components/project_select.vue';
import defaultState from '~/boards/stores/state';
......@@ -88,7 +88,7 @@ describe('ProjectSelect component', () => {
expect(findGlDropdownLoadingIcon().exists()).toBe(true);
await wrapper.vm.$nextTick();
await nextTick();
expect(findGlDropdownLoadingIcon().exists()).toBe(false);
});
......
import { GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises';
import CiLint from '~/ci_lint/components/ci_lint.vue';
import CiLintResults from '~/pipeline_editor/components/lint/ci_lint_results.vue';
......@@ -81,7 +82,7 @@ describe('CI Lint', () => {
it('validation displays results', async () => {
findValidateBtn().vm.$emit('click');
await wrapper.vm.$nextTick();
await nextTick();
expect(findValidateBtn().props('loading')).toBe(true);
......@@ -96,7 +97,7 @@ describe('CI Lint', () => {
findValidateBtn().vm.$emit('click');
await wrapper.vm.$nextTick();
await nextTick();
expect(findValidateBtn().props('loading')).toBe(true);
......
import { GlTable, GlBadge } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import TriggersList from '~/ci_settings_pipeline_triggers/components/triggers_list.vue';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
......@@ -25,10 +26,10 @@ describe('TriggersList', () => {
const findEditBtn = (i) => findRowAt(i).find('[data-testid="edit-btn"]');
const findRevokeBtn = (i) => findRowAt(i).find('[data-testid="trigger_revoke_button"]');
beforeEach(() => {
beforeEach(async () => {
createComponent();
return wrapper.vm.$nextTick();
await nextTick();
});
it('displays a table with expected headers', () => {
......
import { GlDropdown, GlDropdownItem, GlIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import CiEnvironmentsDropdown from '~/ci_variable_list/components/ci_environments_dropdown.vue';
......@@ -73,7 +73,7 @@ describe('Ci environments dropdown', () => {
describe('Environments found', () => {
beforeEach(async () => {
createComponent('prod');
await wrapper.vm.$nextTick();
await nextTick();
});
it('renders only the environment searched for', () => {
......@@ -110,7 +110,7 @@ describe('Ci environments dropdown', () => {
it('should emit createClicked if an environment is clicked', async () => {
createComponent('newscope');
await wrapper.vm.$nextTick();
await nextTick();
findDropdownItemByIndex(1).vm.$emit('click');
expect(wrapper.emitted('createClicked')).toEqual([['newscope']]);
});
......
import { mount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import CiVariableTable from '~/ci_variable_list/components/ci_variable_table.vue';
import createStore from '~/ci_variable_list/store';
......@@ -41,13 +41,12 @@ describe('Ci variable table', () => {
expect(findEmptyVariablesPlaceholder().exists()).toBe(true);
});
it('displays correct amount of variables present and no empty message', () => {
it('displays correct amount of variables present and no empty message', async () => {
store.state.variables = mockData.mockVariables;
return wrapper.vm.$nextTick(() => {
expect(wrapper.findAll('.js-ci-variable-row').length).toBe(1);
expect(findEmptyVariablesPlaceholder().exists()).toBe(false);
});
await nextTick();
expect(wrapper.findAll('.js-ci-variable-row').length).toBe(1);
expect(findEmptyVariablesPlaceholder().exists()).toBe(false);
});
});
......
import { GlLink, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import NewCluster from '~/clusters/components/new_cluster.vue';
import createClusterStore from '~/clusters/stores/new_cluster';
......@@ -7,10 +8,10 @@ describe('NewCluster', () => {
let store;
let wrapper;
const createWrapper = () => {
const createWrapper = async () => {
store = createClusterStore({ clusterConnectHelpPath: '/some/help/path' });
wrapper = shallowMount(NewCluster, { store, stubs: { GlLink, GlSprintf } });
return wrapper.vm.$nextTick();
await nextTick();
};
const findDescription = () => wrapper.find(GlSprintf);
......
import { GlModal, GlSprintf } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { stubComponent } from 'helpers/stub_component';
import RemoveClusterConfirmation from '~/clusters/components/remove_cluster_confirmation.vue';
import SplitButton from '~/vue_shared/components/split_button.vue';
......@@ -43,7 +44,7 @@ describe('Remove cluster confirmation modal', () => {
it('opens modal with "cleanup" option', async () => {
findSplitButton().vm.$emit('remove-cluster-and-cleanup');
await wrapper.vm.$nextTick();
await nextTick();
expect(findModal().vm.show).toHaveBeenCalled();
expect(wrapper.vm.confirmCleanup).toEqual(true);
......@@ -55,7 +56,7 @@ describe('Remove cluster confirmation modal', () => {
it('opens modal without "cleanup" option', async () => {
findSplitButton().vm.$emit('remove-cluster');
await wrapper.vm.$nextTick();
await nextTick();
expect(findModal().vm.show).toHaveBeenCalled();
expect(wrapper.vm.confirmCleanup).toEqual(false);
......
import { GlDropdown, GlDropdownItem, GlModal, GlFormInput } from '@gitlab/ui';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { ENTER_KEY } from '~/lib/utils/keys';
......@@ -54,7 +54,7 @@ describe('AgentOptions', () => {
});
};
const createWrapper = ({ mutationResponse = mockDeleteResponse } = {}) => {
const createWrapper = async ({ mutationResponse = mockDeleteResponse } = {}) => {
apolloProvider = createMockApolloProvider({ mutationResponse });
const provide = {
projectPath,
......@@ -77,7 +77,7 @@ describe('AgentOptions', () => {
wrapper.vm.$refs.modal.hide = jest.fn();
writeQuery();
return wrapper.vm.$nextTick();
await nextTick();
};
const submitAgentToDelete = async () => {
......
import { GlAlert, GlKeysetPagination, GlLoadingIcon } from '@gitlab/ui';
import { createLocalVue, shallowMount } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import { nextTick } from 'vue';
import AgentEmptyState from '~/clusters_list/components/agent_empty_state.vue';
import AgentTable from '~/clusters_list/components/agent_table.vue';
import Agents from '~/clusters_list/components/agents.vue';
......@@ -21,7 +22,13 @@ describe('Agents', () => {
projectPath: 'path/to/project',
};
const createWrapper = ({ props = {}, agents = [], pageInfo = null, trees = [], count = 0 }) => {
const createWrapper = async ({
props = {},
agents = [],
pageInfo = null,
trees = [],
count = 0,
}) => {
const provide = provideData;
const apolloQueryResponse = {
data: {
......@@ -47,7 +54,7 @@ describe('Agents', () => {
provide: provideData,
});
return wrapper.vm.$nextTick();
await nextTick();
};
const findAgentTable = () => wrapper.find(AgentTable);
......@@ -239,14 +246,14 @@ describe('Agents', () => {
},
};
beforeEach(() => {
beforeEach(async () => {
wrapper = shallowMount(Agents, {
mocks,
propsData: defaultProps,
provide: provideData,
});
return wrapper.vm.$nextTick();
await nextTick();
});
it('displays a loading icon', () => {
......
import { GlLink, GlSprintf, GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import AncestorNotice from '~/clusters_list/components/ancestor_notice.vue';
import ClusterStore from '~/clusters_list/store';
......@@ -7,10 +8,10 @@ describe('ClustersAncestorNotice', () => {
let store;
let wrapper;
const createWrapper = () => {
const createWrapper = async () => {
store = ClusterStore({ ancestorHelperPath: '/some/ancestor/path' });
wrapper = shallowMount(AncestorNotice, { store, stubs: { GlSprintf, GlAlert } });
return wrapper.vm.$nextTick();
await nextTick();
};
beforeEach(() => {
......@@ -22,9 +23,9 @@ describe('ClustersAncestorNotice', () => {
});
describe('when cluster does not have ancestors', () => {
beforeEach(() => {
beforeEach(async () => {
store.state.hasAncestorClusters = false;
return wrapper.vm.$nextTick();
await nextTick();
});
it('displays no notice', () => {
......@@ -33,9 +34,9 @@ describe('ClustersAncestorNotice', () => {
});
describe('when cluster has ancestors', () => {
beforeEach(() => {
beforeEach(async () => {
store.state.hasAncestorClusters = true;
return wrapper.vm.$nextTick();
await nextTick();
});
it('displays notice text', () => {
......
......@@ -7,6 +7,7 @@ import {
import * as Sentry from '@sentry/browser';
import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
import Clusters from '~/clusters_list/components/clusters.vue';
import ClustersEmptyState from '~/clusters_list/components/clusters_empty_state.vue';
import ClusterStore from '~/clusters_list/store';
......@@ -176,9 +177,9 @@ describe('Clusters', () => {
});
describe('nodes finish loading', () => {
beforeEach(() => {
beforeEach(async () => {
wrapper.vm.$store.state.loadingNodes = false;
return wrapper.vm.$nextTick();
await nextTick();
});
it.each`
......
import { GlPopover } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import NodeErrorHelpText from '~/clusters_list/components/node_error_help_text.vue';
describe('NodeErrorHelpText', () => {
let wrapper;
const createWrapper = (propsData) => {
const createWrapper = async (propsData) => {
wrapper = shallowMount(NodeErrorHelpText, { propsData, stubs: { GlPopover } });
return wrapper.vm.$nextTick();
await nextTick();
};
const findPopover = () => wrapper.find(GlPopover);
......
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Visibility from 'visibilityjs';
import { nextTick } from 'vue';
import fixture from 'test_fixtures/pipelines/pipelines.json';
import createFlash from '~/flash';
import Poll from '~/lib/utils/poll';
......@@ -112,7 +113,7 @@ describe('Commit pipeline status component', () => {
createComponent();
});
it('shows the loading icon at start', () => {
it('shows the loading icon at start', async () => {
createComponent();
expect(findLoader().exists()).toBe(true);
......@@ -120,17 +121,16 @@ describe('Commit pipeline status component', () => {
data: { pipelines: [] },
});
return wrapper.vm.$nextTick().then(() => {
expect(findLoader().exists()).toBe(false);
});
await nextTick();
expect(findLoader().exists()).toBe(false);
});
describe('is successful', () => {
beforeEach(() => {
beforeEach(async () => {
pollConfig.successCallback({
data: { pipelines: [{ details: { status: mockCiStatus } }] },
});
return wrapper.vm.$nextTick();
await nextTick();
});
it('does not render loader', () => {
......
import { GlEmptyState, GlLoadingIcon, GlModal, GlTableLite } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
import fixture from 'test_fixtures/pipelines/pipelines.json';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
......@@ -238,7 +239,7 @@ describe('Pipelines table in Commits and Merge requests', () => {
it('on desktop, shows a security warning modal', async () => {
await findRunPipelineBtn().trigger('click');
await wrapper.vm.$nextTick();
await nextTick();
expect(findModal()).not.toBeNull();
});
......
import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import ContributorsCharts from '~/contributors/components/contributors.vue';
import { createStore } from '~/contributors/stores';
import axios from '~/lib/utils/axios_utils';
......@@ -49,20 +49,18 @@ describe('Contributors charts', () => {
expect(axios.get).toHaveBeenCalledWith(endpoint);
});
it('should display loader whiled loading data', () => {
it('should display loader whiled loading data', async () => {
wrapper.vm.$store.state.loading = true;
return wrapper.vm.$nextTick(() => {
expect(wrapper.find('.contributors-loader').exists()).toBe(true);
});
await nextTick();
expect(wrapper.find('.contributors-loader').exists()).toBe(true);
});
it('should render charts when loading completed and there is chart data', () => {
it('should render charts when loading completed and there is chart data', async () => {
wrapper.vm.$store.state.loading = false;
wrapper.vm.$store.state.chartData = chartData;
return wrapper.vm.$nextTick(() => {
expect(wrapper.find('.contributors-loader').exists()).toBe(false);
expect(wrapper.find('.contributors-charts').exists()).toBe(true);
expect(wrapper.element).toMatchSnapshot();
});
await nextTick();
expect(wrapper.find('.contributors-loader').exists()).toBe(false);
expect(wrapper.find('.contributors-charts').exists()).toBe(true);
expect(wrapper.element).toMatchSnapshot();
});
});
......@@ -2,6 +2,7 @@ import { GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import $ from 'jquery';
import { nextTick } from 'vue';
import ClusterFormDropdown from '~/create_cluster/components/cluster_form_dropdown.vue';
import DropdownButton from '~/vue_shared/components/dropdown/dropdown_button.vue';
import DropdownSearchInput from '~/vue_shared/components/dropdown/dropdown_search_input.vue';
......@@ -18,35 +19,31 @@ describe('ClusterFormDropdown', () => {
afterEach(() => wrapper.destroy());
describe('when initial value is provided', () => {
it('sets selectedItem to initial value', () => {
it('sets selectedItem to initial value', async () => {
wrapper.setProps({ items, value: secondItem.value });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(DropdownButton).props('toggleText')).toEqual(secondItem.name);
});
await nextTick();
expect(wrapper.find(DropdownButton).props('toggleText')).toEqual(secondItem.name);
});
});
describe('when no item is selected', () => {
it('displays placeholder text', () => {
it('displays placeholder text', async () => {
const placeholder = 'placeholder';
wrapper.setProps({ placeholder });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(DropdownButton).props('toggleText')).toEqual(placeholder);
});
await nextTick();
expect(wrapper.find(DropdownButton).props('toggleText')).toEqual(placeholder);
});
});
describe('when an item is selected', () => {
beforeEach(() => {
beforeEach(async () => {
wrapper.setProps({ items });
return wrapper.vm.$nextTick().then(() => {
wrapper.findAll('.js-dropdown-item').at(1).trigger('click');
return wrapper.vm.$nextTick();
});
await nextTick();
wrapper.findAll('.js-dropdown-item').at(1).trigger('click');
await nextTick();
});
it('emits input event with selected item', () => {
......@@ -57,18 +54,16 @@ describe('ClusterFormDropdown', () => {
describe('when multiple items are selected', () => {
const value = ['1'];
beforeEach(() => {
beforeEach(async () => {
wrapper.setProps({ items, multiple: true, value });
return wrapper.vm
.$nextTick()
.then(() => {
wrapper.findAll('.js-dropdown-item').at(0).trigger('click');
return wrapper.vm.$nextTick();
})
.then(() => {
wrapper.findAll('.js-dropdown-item').at(1).trigger('click');
return wrapper.vm.$nextTick();
});
await nextTick();
wrapper.findAll('.js-dropdown-item').at(0).trigger('click');
await nextTick();
wrapper.findAll('.js-dropdown-item').at(1).trigger('click');
await nextTick();
});
it('emits input event with an array of selected items', () => {
......@@ -77,9 +72,9 @@ describe('ClusterFormDropdown', () => {
});
describe('when multiple items can be selected', () => {
beforeEach(() => {
beforeEach(async () => {
wrapper.setProps({ items, multiple: true, value: firstItem.value });
return wrapper.vm.$nextTick();
await nextTick();
});
it('displays a checked GlIcon next to the item', () => {
......@@ -89,19 +84,18 @@ describe('ClusterFormDropdown', () => {
});
describe('when multiple values can be selected and initial value is null', () => {
it('emits input event with an array of a single selected item', () => {
it('emits input event with an array of a single selected item', async () => {
wrapper.setProps({ items, multiple: true, value: null });
return wrapper.vm.$nextTick().then(() => {
wrapper.findAll('.js-dropdown-item').at(0).trigger('click');
await nextTick();
wrapper.findAll('.js-dropdown-item').at(0).trigger('click');
expect(wrapper.emitted('input')[0]).toEqual([[firstItem.value]]);
});
expect(wrapper.emitted('input')[0]).toEqual([[firstItem.value]]);
});
});
describe('when an item is selected and has a custom label property', () => {
it('displays selected item custom label', () => {
it('displays selected item custom label', async () => {
const labelProperty = 'customLabel';
const label = 'Name';
const currentValue = '1';
......@@ -109,9 +103,8 @@ describe('ClusterFormDropdown', () => {
wrapper.setProps({ labelProperty, items: customLabelItems, value: currentValue });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(DropdownButton).props('toggleText')).toEqual(label);
});
await nextTick();
expect(wrapper.find(DropdownButton).props('toggleText')).toEqual(label);
});
});
......@@ -123,86 +116,79 @@ describe('ClusterFormDropdown', () => {
});
describe('when loading and loadingText is provided', () => {
it('uses loading text as toggle button text', () => {
it('uses loading text as toggle button text', async () => {
const loadingText = 'loading text';
wrapper.setProps({ loading: true, loadingText });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(DropdownButton).props('toggleText')).toEqual(loadingText);
});
await nextTick();
expect(wrapper.find(DropdownButton).props('toggleText')).toEqual(loadingText);
});
});
describe('when disabled', () => {
it('dropdown button isDisabled', () => {
it('dropdown button isDisabled', async () => {
wrapper.setProps({ disabled: true });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(DropdownButton).props('isDisabled')).toBe(true);
});
await nextTick();
expect(wrapper.find(DropdownButton).props('isDisabled')).toBe(true);
});
});
describe('when disabled and disabledText is provided', () => {
it('uses disabled text as toggle button text', () => {
it('uses disabled text as toggle button text', async () => {
const disabledText = 'disabled text';
wrapper.setProps({ disabled: true, disabledText });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(DropdownButton).props('toggleText')).toBe(disabledText);
});
await nextTick();
expect(wrapper.find(DropdownButton).props('toggleText')).toBe(disabledText);
});
});
describe('when has errors', () => {
it('sets border-danger class selector to dropdown toggle', () => {
it('sets border-danger class selector to dropdown toggle', async () => {
wrapper.setProps({ hasErrors: true });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(DropdownButton).classes('border-danger')).toBe(true);
});
await nextTick();
expect(wrapper.find(DropdownButton).classes('border-danger')).toBe(true);
});
});
describe('when has errors and an error message', () => {
it('displays error message', () => {
it('displays error message', async () => {
const errorMessage = 'error message';
wrapper.setProps({ hasErrors: true, errorMessage });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find('.js-eks-dropdown-error-message').text()).toEqual(errorMessage);
});
await nextTick();
expect(wrapper.find('.js-eks-dropdown-error-message').text()).toEqual(errorMessage);
});
});
describe('when no results are available', () => {
it('displays empty text', () => {
it('displays empty text', async () => {
const emptyText = 'error message';
wrapper.setProps({ items: [], emptyText });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find('.js-empty-text').text()).toEqual(emptyText);
});
await nextTick();
expect(wrapper.find('.js-empty-text').text()).toEqual(emptyText);
});
});
it('displays search field placeholder', () => {
it('displays search field placeholder', async () => {
const searchFieldPlaceholder = 'Placeholder';
wrapper.setProps({ searchFieldPlaceholder });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(DropdownSearchInput).props('placeholderText')).toEqual(
searchFieldPlaceholder,
);
});
await nextTick();
expect(wrapper.find(DropdownSearchInput).props('placeholderText')).toEqual(
searchFieldPlaceholder,
);
});
it('it filters results by search query', () => {
it('it filters results by search query', async () => {
const searchQuery = secondItem.name;
wrapper.setProps({ items });
......@@ -210,21 +196,19 @@ describe('ClusterFormDropdown', () => {
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ searchQuery });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.findAll('.js-dropdown-item').length).toEqual(1);
expect(wrapper.find('.js-dropdown-item').text()).toEqual(secondItem.name);
});
await nextTick();
expect(wrapper.findAll('.js-dropdown-item').length).toEqual(1);
expect(wrapper.find('.js-dropdown-item').text()).toEqual(secondItem.name);
});
it('focuses dropdown search input when dropdown is displayed', () => {
it('focuses dropdown search input when dropdown is displayed', async () => {
const dropdownEl = wrapper.find('.dropdown').element;
expect(wrapper.find(DropdownSearchInput).props('focused')).toBe(false);
$(dropdownEl).trigger('shown.bs.dropdown');
return wrapper.vm.$nextTick(() => {
expect(wrapper.find(DropdownSearchInput).props('focused')).toBe(true);
});
await nextTick();
expect(wrapper.find(DropdownSearchInput).props('focused')).toBe(true);
});
});
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import GkeMachineTypeDropdown from '~/create_cluster/gke_cluster/components/gke_machine_type_dropdown.vue';
import createState from '~/create_cluster/gke_cluster/store/state';
......@@ -73,7 +73,7 @@ describe('GkeMachineTypeDropdown', () => {
expect(dropdownButtonLabel()).toBe(LABELS.DISABLED_NO_ZONE);
});
it('returns loading toggle text', () => {
it('returns loading toggle text', async () => {
store = createStore();
wrapper = createComponent(store);
......@@ -81,9 +81,8 @@ describe('GkeMachineTypeDropdown', () => {
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ isLoading: true });
return wrapper.vm.$nextTick().then(() => {
expect(dropdownButtonLabel()).toBe(LABELS.LOADING);
});
await nextTick();
expect(dropdownButtonLabel()).toBe(LABELS.LOADING);
});
it('returns default toggle text', () => {
......@@ -113,7 +112,7 @@ describe('GkeMachineTypeDropdown', () => {
});
describe('form input', () => {
it('reflects new value when dropdown item is clicked', () => {
it('reflects new value when dropdown item is clicked', async () => {
store = createStore({
machineTypes: gapiMachineTypesResponseMock.items,
});
......@@ -123,9 +122,8 @@ describe('GkeMachineTypeDropdown', () => {
wrapper.find('.dropdown-content button').trigger('click');
return wrapper.vm.$nextTick().then(() => {
expect(setMachineType).toHaveBeenCalledWith(expect.anything(), selectedMachineTypeMock);
});
await nextTick();
expect(setMachineType).toHaveBeenCalledWith(expect.anything(), selectedMachineTypeMock);
});
});
});
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import GkeProjectIdDropdown from '~/create_cluster/gke_cluster/components/gke_project_id_dropdown.vue';
import createState from '~/create_cluster/gke_cluster/store/state';
......@@ -78,19 +78,18 @@ describe('GkeProjectIdDropdown', () => {
expect(dropdownButtonLabel()).toBe(LABELS.VALIDATING_PROJECT_BILLING);
});
it('returns default toggle text', () => {
it('returns default toggle text', async () => {
bootstrap();
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ isLoading: false });
return wrapper.vm.$nextTick().then(() => {
expect(dropdownButtonLabel()).toBe(LABELS.DEFAULT);
});
await nextTick();
expect(dropdownButtonLabel()).toBe(LABELS.DEFAULT);
});
it('returns project name if project selected', () => {
it('returns project name if project selected', async () => {
bootstrap(
{
selectedProject: selectedProjectMock,
......@@ -103,12 +102,11 @@ describe('GkeProjectIdDropdown', () => {
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ isLoading: false });
return wrapper.vm.$nextTick().then(() => {
expect(dropdownButtonLabel()).toBe(selectedProjectMock.name);
});
await nextTick();
expect(dropdownButtonLabel()).toBe(selectedProjectMock.name);
});
it('returns empty toggle text', () => {
it('returns empty toggle text', async () => {
bootstrap({
projects: null,
});
......@@ -116,26 +114,24 @@ describe('GkeProjectIdDropdown', () => {
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ isLoading: false });
return wrapper.vm.$nextTick().then(() => {
expect(dropdownButtonLabel()).toBe(LABELS.EMPTY);
});
await nextTick();
expect(dropdownButtonLabel()).toBe(LABELS.EMPTY);
});
});
describe('selectItem', () => {
it('reflects new value when dropdown item is clicked', () => {
it('reflects new value when dropdown item is clicked', async () => {
bootstrap({ projects: gapiProjectsResponseMock.projects });
expect(dropdownHiddenInputValue()).toBe('');
wrapper.find('.dropdown-content button').trigger('click');
return wrapper.vm.$nextTick().then(() => {
expect(setProject).toHaveBeenCalledWith(
expect.anything(),
gapiProjectsResponseMock.projects[0],
);
});
await nextTick();
expect(setProject).toHaveBeenCalledWith(
expect.anything(),
gapiProjectsResponseMock.projects[0],
);
});
});
});
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import GkeZoneDropdown from '~/create_cluster/gke_cluster/components/gke_zone_dropdown.vue';
import { createStore } from '~/create_cluster/gke_cluster/store';
import {
......@@ -46,11 +47,11 @@ describe('GkeZoneDropdown', () => {
});
describe('isLoading', () => {
beforeEach(() => {
beforeEach(async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ isLoading: true });
return wrapper.vm.$nextTick();
await nextTick();
});
it('returns loading toggle text', () => {
......@@ -59,10 +60,10 @@ describe('GkeZoneDropdown', () => {
});
describe('project is set', () => {
beforeEach(() => {
beforeEach(async () => {
wrapper.vm.$store.commit(SET_PROJECT, selectedProjectMock);
wrapper.vm.$store.commit(SET_PROJECT_BILLING_STATUS, true);
return wrapper.vm.$nextTick();
await nextTick();
});
it('returns default toggle text', () => {
......@@ -71,9 +72,9 @@ describe('GkeZoneDropdown', () => {
});
describe('project is selected', () => {
beforeEach(() => {
beforeEach(async () => {
wrapper.vm.setItem(selectedZoneMock);
return wrapper.vm.$nextTick();
await nextTick();
});
it('returns project name if project selected', () => {
......@@ -83,21 +84,20 @@ describe('GkeZoneDropdown', () => {
});
describe('selectItem', () => {
beforeEach(() => {
beforeEach(async () => {
wrapper.vm.$store.commit(SET_ZONES, gapiZonesResponseMock.items);
return wrapper.vm.$nextTick();
await nextTick();
});
it('reflects new value when dropdown item is clicked', () => {
it('reflects new value when dropdown item is clicked', async () => {
const dropdown = wrapper.find(DropdownHiddenInput);
expect(dropdown.attributes('value')).toBe('');
wrapper.find('.dropdown-content button').trigger('click');
return wrapper.vm.$nextTick().then(() => {
expect(dropdown.attributes('value')).toBe(selectedZoneMock);
});
await nextTick();
expect(dropdown.attributes('value')).toBe(selectedZoneMock);
});
});
});
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import Vuex from 'vuex';
......@@ -42,7 +42,7 @@ const defaultParams = {
};
async function shouldMergeUrlParams(wrapper, result) {
await wrapper.vm.$nextTick();
await nextTick();
expect(urlUtils.mergeUrlParams).toHaveBeenCalledWith(result, window.location.href, {
spreadArrays: true,
});
......
import { GlEmptyState, GlLoadingIcon, GlTable } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import StageTable from '~/cycle_analytics/components/stage_table.vue';
......@@ -263,7 +264,7 @@ describe('StageTable', () => {
expect(wrapper.emitted('handleUpdatePagination')).toBeUndefined();
findPagination().vm.$emit('input', 2);
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.emitted('handleUpdatePagination')[0]).toEqual([{ page: 2 }]);
});
......
import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui';
import { GlSingleStat } from '@gitlab/ui/dist/charts';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import metricsData from 'test_fixtures/projects/analytics/value_stream_analytics/summary.json';
import waitForPromises from 'helpers/wait_for_promises';
import { METRIC_TYPE_SUMMARY } from '~/api/analytics_api';
......@@ -55,7 +56,7 @@ describe('ValueStreamMetrics', () => {
});
it('will display a loader with pending requests', async () => {
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.findComponent(GlSkeletonLoading).exists()).toBe(true);
});
......@@ -67,7 +68,7 @@ describe('ValueStreamMetrics', () => {
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ isLoading: true });
await wrapper.vm.$nextTick();
await nextTick();
const components = findMetrics();
......
import { GlModal } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import DeployFreezeTable from '~/deploy_freeze/components/deploy_freeze_table.vue';
import createStore from '~/deploy_freeze/store';
......@@ -56,7 +56,7 @@ describe('Deploy freeze table', () => {
describe('with data', () => {
beforeEach(async () => {
store.commit(RECEIVE_FREEZE_PERIODS_SUCCESS, freezePeriodsFixture);
await wrapper.vm.$nextTick();
await nextTick();
});
it('displays data', () => {
......@@ -68,7 +68,7 @@ describe('Deploy freeze table', () => {
it('allows user to edit deploy freeze', async () => {
findEditDeployFreezeButton().trigger('click');
await wrapper.vm.$nextTick();
await nextTick();
expect(store.dispatch).toHaveBeenCalledWith(
'setFreezePeriod',
......
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import data from 'test_fixtures/deploy_keys/keys.json';
import actionBtn from '~/deploy_keys/components/action_btn.vue';
import eventHub from '~/deploy_keys/eventhub';
......@@ -37,21 +38,19 @@ describe('Deploy keys action btn', () => {
});
});
it('sends eventHub event with btn type', () => {
it('sends eventHub event with btn type', async () => {
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
findButton().vm.$emit('click');
return wrapper.vm.$nextTick().then(() => {
expect(eventHub.$emit).toHaveBeenCalledWith('enable.key', deployKey, expect.anything());
});
await nextTick();
expect(eventHub.$emit).toHaveBeenCalledWith('enable.key', deployKey, expect.anything());
});
it('shows loading spinner after click', () => {
it('shows loading spinner after click', async () => {
findButton().vm.$emit('click');
return wrapper.vm.$nextTick().then(() => {
expect(findButton().props('loading')).toBe(true);
});
await nextTick();
expect(findButton().props('loading')).toBe(true);
});
});
import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
import data from 'test_fixtures/deploy_keys/keys.json';
import waitForPromises from 'helpers/wait_for_promises';
import { TEST_HOST } from 'spec/test_constants';
......@@ -39,20 +40,18 @@ describe('Deploy keys app component', () => {
const findKeyPanels = () => wrapper.findAll('.deploy-keys .gl-tabs-nav li');
const findModal = () => wrapper.findComponent(ConfirmModal);
it('renders loading icon while waiting for request', () => {
it('renders loading icon while waiting for request', async () => {
mock.onGet(TEST_ENDPOINT).reply(() => new Promise());
mountComponent();
return wrapper.vm.$nextTick().then(() => {
expect(findLoadingIcon().exists()).toBe(true);
});
await nextTick();
expect(findLoadingIcon().exists()).toBe(true);
});
it('renders keys panels', () => {
return mountComponent().then(() => {
expect(findKeyPanels().length).toBe(3);
});
it('renders keys panels', async () => {
await mountComponent();
expect(findKeyPanels().length).toBe(3);
});
it.each`
......@@ -75,72 +74,55 @@ describe('Deploy keys app component', () => {
});
});
it('re-fetches deploy keys when enabling a key', () => {
it('re-fetches deploy keys when enabling a key', async () => {
const key = data.public_keys[0];
return mountComponent()
.then(() => {
jest.spyOn(wrapper.vm.service, 'getKeys').mockImplementation(() => {});
jest.spyOn(wrapper.vm.service, 'enableKey').mockImplementation(() => Promise.resolve());
eventHub.$emit('enable.key', key);
return wrapper.vm.$nextTick();
})
.then(() => {
expect(wrapper.vm.service.enableKey).toHaveBeenCalledWith(key.id);
expect(wrapper.vm.service.getKeys).toHaveBeenCalled();
});
await mountComponent();
jest.spyOn(wrapper.vm.service, 'getKeys').mockImplementation(() => {});
jest.spyOn(wrapper.vm.service, 'enableKey').mockImplementation(() => Promise.resolve());
eventHub.$emit('enable.key', key);
await nextTick();
expect(wrapper.vm.service.enableKey).toHaveBeenCalledWith(key.id);
expect(wrapper.vm.service.getKeys).toHaveBeenCalled();
});
it('re-fetches deploy keys when disabling a key', () => {
it('re-fetches deploy keys when disabling a key', async () => {
const key = data.public_keys[0];
return mountComponent()
.then(() => {
jest.spyOn(wrapper.vm.service, 'getKeys').mockImplementation(() => {});
jest.spyOn(wrapper.vm.service, 'disableKey').mockImplementation(() => Promise.resolve());
eventHub.$emit('disable.key', key, () => {});
return wrapper.vm.$nextTick();
})
.then(() => {
expect(findModal().props('visible')).toBe(true);
findModal().vm.$emit('remove');
return wrapper.vm.$nextTick();
})
.then(() => {
expect(wrapper.vm.service.disableKey).toHaveBeenCalledWith(key.id);
expect(wrapper.vm.service.getKeys).toHaveBeenCalled();
});
await mountComponent();
jest.spyOn(wrapper.vm.service, 'getKeys').mockImplementation(() => {});
jest.spyOn(wrapper.vm.service, 'disableKey').mockImplementation(() => Promise.resolve());
eventHub.$emit('disable.key', key, () => {});
await nextTick();
expect(findModal().props('visible')).toBe(true);
findModal().vm.$emit('remove');
await nextTick();
expect(wrapper.vm.service.disableKey).toHaveBeenCalledWith(key.id);
expect(wrapper.vm.service.getKeys).toHaveBeenCalled();
});
it('calls disableKey when removing a key', () => {
it('calls disableKey when removing a key', async () => {
const key = data.public_keys[0];
return mountComponent()
.then(() => {
jest.spyOn(wrapper.vm.service, 'getKeys').mockImplementation(() => {});
jest.spyOn(wrapper.vm.service, 'disableKey').mockImplementation(() => Promise.resolve());
eventHub.$emit('remove.key', key, () => {});
return wrapper.vm.$nextTick();
})
.then(() => {
expect(findModal().props('visible')).toBe(true);
findModal().vm.$emit('remove');
return wrapper.vm.$nextTick();
})
.then(() => {
expect(wrapper.vm.service.disableKey).toHaveBeenCalledWith(key.id);
expect(wrapper.vm.service.getKeys).toHaveBeenCalled();
});
await mountComponent();
jest.spyOn(wrapper.vm.service, 'getKeys').mockImplementation(() => {});
jest.spyOn(wrapper.vm.service, 'disableKey').mockImplementation(() => Promise.resolve());
eventHub.$emit('remove.key', key, () => {});
await nextTick();
expect(findModal().props('visible')).toBe(true);
findModal().vm.$emit('remove');
await nextTick();
expect(wrapper.vm.service.disableKey).toHaveBeenCalledWith(key.id);
expect(wrapper.vm.service.getKeys).toHaveBeenCalled();
});
it('hasKeys returns true when there are keys', () => {
return mountComponent().then(() => {
expect(wrapper.vm.hasKeys).toEqual(3);
});
it('hasKeys returns true when there are keys', async () => {
await mountComponent();
expect(wrapper.vm.hasKeys).toEqual(3);
});
});
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import data from 'test_fixtures/deploy_keys/keys.json';
import key from '~/deploy_keys/components/key.vue';
import DeployKeysStore from '~/deploy_keys/store';
......@@ -95,18 +96,17 @@ describe('Deploy keys key', () => {
expect(labels.at(1).attributes('title')).toContain('Expand');
});
it('expands all project labels after click', () => {
it('expands all project labels after click', async () => {
createComponent({ deployKey });
const { length } = deployKey.deploy_keys_projects;
wrapper.findAll('.deploy-project-label').at(1).trigger('click');
return wrapper.vm.$nextTick().then(() => {
const labels = wrapper.findAll('.deploy-project-label');
await nextTick();
const labels = wrapper.findAll('.deploy-project-label');
expect(labels.length).toBe(length);
expect(labels.at(1).text()).not.toContain(`+${length} others`);
expect(labels.at(1).attributes('title')).not.toContain('Expand');
});
expect(labels.length).toBe(length);
expect(labels.at(1).text()).not.toContain(`+${length} others`);
expect(labels.at(1).attributes('title')).not.toContain('Expand');
});
it('shows two projects', () => {
......
import { GlButton, GlModal, GlModalDirective } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import BatchDeleteButton from '~/design_management/components/delete_button.vue';
describe('Batch delete button component', () => {
......@@ -36,18 +37,15 @@ describe('Batch delete button component', () => {
expect(findButton().attributes('disabled')).toBeTruthy();
});
it('emits `delete-selected-designs` event on modal ok click', () => {
it('emits `delete-selected-designs` event on modal ok click', async () => {
createComponent();
findButton().vm.$emit('click');
return wrapper.vm
.$nextTick()
.then(() => {
findModal().vm.$emit('ok');
return wrapper.vm.$nextTick();
})
.then(() => {
expect(wrapper.emitted('delete-selected-designs')).toBeTruthy();
});
await nextTick();
findModal().vm.$emit('ok');
await nextTick();
expect(wrapper.emitted('delete-selected-designs')).toBeTruthy();
});
it('renders slot content', () => {
......
import { GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { ApolloMutation } from 'vue-apollo';
import { nextTick } from 'vue';
import DesignDiscussion from '~/design_management/components/design_notes/design_discussion.vue';
import DesignNote from '~/design_management/components/design_notes/design_note.vue';
import DesignNoteSignedOut from '~/design_management/components/design_notes/design_note_signed_out.vue';
......@@ -119,12 +120,11 @@ describe('Design discussions component', () => {
expect(findResolveIcon().exists()).toBe(false);
});
it('does not render a checkbox in reply form', () => {
it('does not render a checkbox in reply form', async () => {
findReplyPlaceholder().vm.$emit('focus');
return wrapper.vm.$nextTick().then(() => {
expect(findResolveCheckbox().exists()).toBe(false);
});
await nextTick();
expect(findResolveCheckbox().exists()).toBe(false);
});
});
......@@ -150,13 +150,12 @@ describe('Design discussions component', () => {
expect(findResolveIcon().props('name')).toBe('check-circle');
});
it('renders a checkbox with Resolve thread text in reply form', () => {
it('renders a checkbox with Resolve thread text in reply form', async () => {
findReplyPlaceholder().vm.$emit('focus');
wrapper.setProps({ discussionWithOpenForm: defaultMockDiscussion.id });
return wrapper.vm.$nextTick().then(() => {
expect(findResolveCheckbox().text()).toBe('Resolve thread');
});
await nextTick();
expect(findResolveCheckbox().text()).toBe('Resolve thread');
});
it('does not render resolved message', () => {
......@@ -216,7 +215,7 @@ describe('Design discussions component', () => {
findReplyForm().vm.$emit('submitForm');
await mutate();
await wrapper.vm.$nextTick();
await nextTick();
const dispatchedEvent = dispatchEventSpy.mock.calls[0][0];
......@@ -226,9 +225,9 @@ describe('Design discussions component', () => {
});
describe('when replies are expanded', () => {
beforeEach(() => {
beforeEach(async () => {
findRepliesWidget().vm.$emit('toggle');
return wrapper.vm.$nextTick();
await nextTick();
});
it('renders replies widget with collapsed prop equal to false', () => {
......@@ -243,26 +242,24 @@ describe('Design discussions component', () => {
expect(findReplyPlaceholder().isVisible()).toBe(true);
});
it('renders a checkbox with Unresolve thread text in reply form', () => {
it('renders a checkbox with Unresolve thread text in reply form', async () => {
findReplyPlaceholder().vm.$emit('focus');
wrapper.setProps({ discussionWithOpenForm: defaultMockDiscussion.id });
return wrapper.vm.$nextTick().then(() => {
expect(findResolveCheckbox().text()).toBe('Unresolve thread');
});
await nextTick();
expect(findResolveCheckbox().text()).toBe('Unresolve thread');
});
});
});
it('hides reply placeholder and opens form on placeholder click', () => {
it('hides reply placeholder and opens form on placeholder click', async () => {
createComponent();
findReplyPlaceholder().vm.$emit('focus');
wrapper.setProps({ discussionWithOpenForm: defaultMockDiscussion.id });
return wrapper.vm.$nextTick().then(() => {
expect(findReplyPlaceholder().exists()).toBe(false);
expect(findReplyForm().exists()).toBe(true);
});
await nextTick();
expect(findReplyPlaceholder().exists()).toBe(false);
expect(findReplyForm().exists()).toBe(true);
});
it('calls mutation on submitting form and closes the form', async () => {
......@@ -275,28 +272,24 @@ describe('Design discussions component', () => {
expect(mutate).toHaveBeenCalledWith(mutationVariables);
await mutate();
await wrapper.vm.$nextTick();
await nextTick();
expect(findReplyForm().exists()).toBe(false);
});
it('clears the discussion comment on closing comment form', () => {
it('clears the discussion comment on closing comment form', async () => {
createComponent(
{ discussionWithOpenForm: defaultMockDiscussion.id },
{ discussionComment: 'test', isFormRendered: true },
);
return wrapper.vm
.$nextTick()
.then(() => {
findReplyForm().vm.$emit('cancel-form');
await nextTick();
findReplyForm().vm.$emit('cancel-form');
expect(wrapper.vm.discussionComment).toBe('');
return wrapper.vm.$nextTick();
})
.then(() => {
expect(findReplyForm().exists()).toBe(false);
});
expect(wrapper.vm.discussionComment).toBe('');
await nextTick();
expect(findReplyForm().exists()).toBe(false);
});
describe('when any note from a discussion is active', () => {
......@@ -322,7 +315,7 @@ describe('Design discussions component', () => {
);
});
it('calls toggleResolveDiscussion mutation on resolve thread button click', () => {
it('calls toggleResolveDiscussion mutation on resolve thread button click', async () => {
createComponent();
findResolveButton().trigger('click');
expect(mutate).toHaveBeenCalledWith({
......@@ -332,9 +325,8 @@ describe('Design discussions component', () => {
resolve: true,
},
});
return wrapper.vm.$nextTick(() => {
expect(findResolveLoadingIcon().exists()).toBe(true);
});
await nextTick();
expect(findResolveLoadingIcon().exists()).toBe(true);
});
it('calls toggleResolveDiscussion mutation after adding a note if checkbox was checked', () => {
......
import { shallowMount } from '@vue/test-utils';
import { ApolloMutation } from 'vue-apollo';
import { nextTick } from 'vue';
import DesignNote from '~/design_management/components/design_notes/design_note.vue';
import DesignReplyForm from '~/design_management/components/design_notes/design_reply_form.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
......@@ -96,7 +97,7 @@ describe('Design note component', () => {
});
describe('when user has a permission to edit note', () => {
it('should open an edit form on edit button click', () => {
it('should open an edit form on edit button click', async () => {
createComponent({
note: {
...note,
......@@ -108,10 +109,9 @@ describe('Design note component', () => {
findEditButton().trigger('click');
return wrapper.vm.$nextTick().then(() => {
expect(findReplyForm().exists()).toBe(true);
expect(findNoteContent().exists()).toBe(false);
});
await nextTick();
expect(findReplyForm().exists()).toBe(true);
expect(findNoteContent().exists()).toBe(false);
});
describe('when edit form is rendered', () => {
......@@ -134,27 +134,22 @@ describe('Design note component', () => {
expect(findReplyForm().exists()).toBe(true);
});
it('hides the form on cancel-form event', () => {
it('hides the form on cancel-form event', async () => {
findReplyForm().vm.$emit('cancel-form');
return wrapper.vm.$nextTick().then(() => {
expect(findReplyForm().exists()).toBe(false);
expect(findNoteContent().exists()).toBe(true);
});
await nextTick();
expect(findReplyForm().exists()).toBe(false);
expect(findNoteContent().exists()).toBe(true);
});
it('calls a mutation on submit-form event and hides a form', () => {
it('calls a mutation on submit-form event and hides a form', async () => {
findReplyForm().vm.$emit('submit-form');
expect(mutate).toHaveBeenCalled();
return mutate()
.then(() => {
return wrapper.vm.$nextTick();
})
.then(() => {
expect(findReplyForm().exists()).toBe(false);
expect(findNoteContent().exists()).toBe(true);
});
await mutate();
await nextTick();
expect(findReplyForm().exists()).toBe(false);
expect(findNoteContent().exists()).toBe(true);
});
});
});
......
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DesignReplyForm from '~/design_management/components/design_notes/design_reply_form.vue';
const showModal = jest.fn();
......@@ -64,24 +65,22 @@ describe('Design reply form component', () => {
expect(findSubmitButton().attributes().disabled).toBeTruthy();
});
it('does not emit submitForm event on textarea ctrl+enter keydown', () => {
it('does not emit submitForm event on textarea ctrl+enter keydown', async () => {
findTextarea().trigger('keydown.enter', {
ctrlKey: true,
});
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted('submit-form')).toBeFalsy();
});
await nextTick();
expect(wrapper.emitted('submit-form')).toBeFalsy();
});
it('does not emit submitForm event on textarea meta+enter keydown', () => {
it('does not emit submitForm event on textarea meta+enter keydown', async () => {
findTextarea().trigger('keydown.enter', {
metaKey: true,
});
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted('submit-form')).toBeFalsy();
});
await nextTick();
expect(wrapper.emitted('submit-form')).toBeFalsy();
});
it('emits cancelForm event on pressing escape button on textarea', () => {
......@@ -108,40 +107,36 @@ describe('Design reply form component', () => {
expect(findSubmitButton().attributes().disabled).toBeFalsy();
});
it('emits submitForm event on Comment button click', () => {
it('emits submitForm event on Comment button click', async () => {
findSubmitButton().vm.$emit('click');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted('submit-form')).toBeTruthy();
});
await nextTick();
expect(wrapper.emitted('submit-form')).toBeTruthy();
});
it('emits submitForm event on textarea ctrl+enter keydown', () => {
it('emits submitForm event on textarea ctrl+enter keydown', async () => {
findTextarea().trigger('keydown.enter', {
ctrlKey: true,
});
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted('submit-form')).toBeTruthy();
});
await nextTick();
expect(wrapper.emitted('submit-form')).toBeTruthy();
});
it('emits submitForm event on textarea meta+enter keydown', () => {
it('emits submitForm event on textarea meta+enter keydown', async () => {
findTextarea().trigger('keydown.enter', {
metaKey: true,
});
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted('submit-form')).toBeTruthy();
});
await nextTick();
expect(wrapper.emitted('submit-form')).toBeTruthy();
});
it('emits input event on changing textarea content', () => {
it('emits input event on changing textarea content', async () => {
findTextarea().setValue('test2');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted('input')).toBeTruthy();
});
await nextTick();
expect(wrapper.emitted('input')).toBeTruthy();
});
it('emits cancelForm event on Escape key if text was not changed', () => {
......@@ -150,13 +145,12 @@ describe('Design reply form component', () => {
expect(wrapper.emitted('cancel-form')).toBeTruthy();
});
it('opens confirmation modal on Escape key when text has changed', () => {
it('opens confirmation modal on Escape key when text has changed', async () => {
wrapper.setProps({ value: 'test2' });
return wrapper.vm.$nextTick().then(() => {
findTextarea().trigger('keyup.esc');
expect(showModal).toHaveBeenCalled();
});
await nextTick();
findTextarea().trigger('keyup.esc');
expect(showModal).toHaveBeenCalled();
});
it('emits cancelForm event on Cancel button click if text was not changed', () => {
......@@ -165,13 +159,12 @@ describe('Design reply form component', () => {
expect(wrapper.emitted('cancel-form')).toBeTruthy();
});
it('opens confirmation modal on Cancel button click when text has changed', () => {
it('opens confirmation modal on Cancel button click when text has changed', async () => {
wrapper.setProps({ value: 'test2' });
return wrapper.vm.$nextTick().then(() => {
findCancelButton().trigger('click');
expect(showModal).toHaveBeenCalled();
});
await nextTick();
findCancelButton().trigger('click');
expect(showModal).toHaveBeenCalled();
});
it('emits cancelForm event on modal Ok button click', () => {
......
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DesignScaler from '~/design_management/components/design_scaler.vue';
describe('Design management design scaler component', () => {
......@@ -32,7 +33,7 @@ describe('Design management design scaler component', () => {
describe('when `scale` value is greater than 1', () => {
beforeEach(async () => {
setScale(1.6);
await wrapper.vm.$nextTick();
await nextTick();
});
it('emits @scale event when "reset" button clicked', () => {
......@@ -68,11 +69,11 @@ describe('Design management design scaler component', () => {
it('computes & increments correct stepSize based on maxScale', async () => {
wrapper.setProps({ maxScale: 11 });
await wrapper.vm.$nextTick();
await nextTick();
getIncreaseScaleButton().vm.$emit('click');
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.emitted().scale[0][0]).toBe(3);
});
......@@ -96,7 +97,7 @@ describe('Design management design scaler component', () => {
describe('when `scale` value is maximum', () => {
beforeEach(async () => {
setScale(2);
await wrapper.vm.$nextTick();
await nextTick();
});
it('disables the "increment" button', () => {
......
import { GlCollapse, GlPopover } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Cookies from 'js-cookie';
import { nextTick } from 'vue';
import DesignDiscussion from '~/design_management/components/design_notes/design_discussion.vue';
import DesignNoteSignedOut from '~/design_management/components/design_notes/design_note_signed_out.vue';
import DesignSidebar from '~/design_management/components/design_sidebar.vue';
......@@ -138,14 +139,13 @@ describe('Design management design sidebar component', () => {
expect(wrapper.emitted('toggleResolvedComments')).toHaveLength(1);
});
it('opens a collapsible when resolvedDiscussionsExpanded prop changes to true', () => {
it('opens a collapsible when resolvedDiscussionsExpanded prop changes to true', async () => {
expect(findCollapsible().attributes('visible')).toBeUndefined();
wrapper.setProps({
resolvedDiscussionsExpanded: true,
});
return wrapper.vm.$nextTick().then(() => {
expect(findCollapsible().attributes('visible')).toBe('true');
});
await nextTick();
expect(findCollapsible().attributes('visible')).toBe('true');
});
it('does not popover about resolved comments', () => {
......@@ -182,12 +182,11 @@ describe('Design management design sidebar component', () => {
expect(wrapper.emitted('resolveDiscussionError')).toEqual([['payload']]);
});
it('changes prop correctly on opening discussion form', () => {
it('changes prop correctly on opening discussion form', async () => {
findFirstDiscussion().vm.$emit('open-form', 'some-id');
return wrapper.vm.$nextTick().then(() => {
expect(findFirstDiscussion().props('discussionWithOpenForm')).toBe('some-id');
});
await nextTick();
expect(findFirstDiscussion().props('discussionWithOpenForm')).toBe('some-id');
});
});
......@@ -246,11 +245,10 @@ describe('Design management design sidebar component', () => {
expect(scrollIntoViewMock).toHaveBeenCalled();
});
it('dismisses a popover on the outside click', () => {
it('dismisses a popover on the outside click', async () => {
wrapper.trigger('click');
return wrapper.vm.$nextTick(() => {
expect(findPopover().exists()).toBe(false);
});
await nextTick();
expect(findPopover().exists()).toBe(false);
});
it(`sets a ${cookieKey} cookie on clicking outside the popover`, () => {
......
import { shallowMount, mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DesignTodoButton from '~/design_management/components/design_todo_button.vue';
import createDesignTodoMutation from '~/design_management/graphql/mutations/create_design_todo.mutation.graphql';
import todoMarkDoneMutation from '~/graphql_shared/mutations/todo_mark_done.mutation.graphql';
......@@ -71,7 +72,7 @@ describe('Design management design todo button', () => {
describe('when clicked', () => {
let dispatchEventSpy;
beforeEach(() => {
beforeEach(async () => {
dispatchEventSpy = jest.spyOn(document, 'dispatchEvent');
jest.spyOn(document, 'querySelector').mockReturnValue({
innerText: 2,
......@@ -79,7 +80,7 @@ describe('Design management design todo button', () => {
createComponent({ design: mockDesignWithPendingTodos }, { mountFn: mount });
wrapper.trigger('click');
return wrapper.vm.$nextTick();
await nextTick();
});
it('calls `$apollo.mutate` with the `todoMarkDone` mutation and variables containing `id`', async () => {
......@@ -117,7 +118,7 @@ describe('Design management design todo button', () => {
describe('when clicked', () => {
let dispatchEventSpy;
beforeEach(() => {
beforeEach(async () => {
dispatchEventSpy = jest.spyOn(document, 'dispatchEvent');
jest.spyOn(document, 'querySelector').mockReturnValue({
innerText: 2,
......@@ -125,7 +126,7 @@ describe('Design management design todo button', () => {
createComponent({}, { mountFn: mount });
wrapper.trigger('click');
return wrapper.vm.$nextTick();
await nextTick();
});
it('calls `$apollo.mutate` with the `createDesignTodoMutation` mutation and variables containing `issuable_id`, `issue_id`, & `projectPath`', async () => {
......
import { GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DesignImage from '~/design_management/components/image.vue';
describe('Design management large image component', () => {
......@@ -36,7 +37,7 @@ describe('Design management large image component', () => {
expect(wrapper.element).toMatchSnapshot();
});
it('sets correct classes and styles if imageStyle is set', () => {
it('sets correct classes and styles if imageStyle is set', async () => {
createComponent(
{
isLoading: false,
......@@ -50,12 +51,11 @@ describe('Design management large image component', () => {
},
},
);
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.element).toMatchSnapshot();
});
await nextTick();
expect(wrapper.element).toMatchSnapshot();
});
it('renders media broken icon on error', () => {
it('renders media broken icon on error', async () => {
createComponent({
isLoading: false,
image: 'test.jpg',
......@@ -64,10 +64,9 @@ describe('Design management large image component', () => {
const image = wrapper.find('img');
image.trigger('error');
return wrapper.vm.$nextTick().then(() => {
expect(image.isVisible()).toBe(false);
expect(wrapper.find(GlIcon).element).toMatchSnapshot();
});
await nextTick();
expect(image.isVisible()).toBe(false);
expect(wrapper.find(GlIcon).element).toMatchSnapshot();
});
describe('zoom', () => {
......@@ -99,37 +98,34 @@ describe('Design management large image component', () => {
.mockReturnValue(baseImageHeight);
});
it('emits @resize event on zoom', () => {
it('emits @resize event on zoom', async () => {
const zoomAmount = 2;
wrapper.vm.zoom(zoomAmount);
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted('resize')).toEqual([
[{ width: baseImageWidth * zoomAmount, height: baseImageHeight * zoomAmount }],
]);
});
await nextTick();
expect(wrapper.emitted('resize')).toEqual([
[{ width: baseImageWidth * zoomAmount, height: baseImageHeight * zoomAmount }],
]);
});
it('emits @resize event with base image size when scale=1', () => {
it('emits @resize event with base image size when scale=1', async () => {
wrapper.vm.zoom(1);
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted('resize')).toEqual([
[{ width: baseImageWidth, height: baseImageHeight }],
]);
});
await nextTick();
expect(wrapper.emitted('resize')).toEqual([
[{ width: baseImageWidth, height: baseImageHeight }],
]);
});
it('sets image style when zoomed', () => {
it('sets image style when zoomed', async () => {
const zoomAmount = 2;
wrapper.vm.zoom(zoomAmount);
expect(wrapper.vm.imageStyle).toEqual({
width: `${baseImageWidth * zoomAmount}px`,
height: `${baseImageHeight * zoomAmount}px`,
});
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.element).toMatchSnapshot();
});
await nextTick();
expect(wrapper.element).toMatchSnapshot();
});
});
});
import { GlIcon, GlLoadingIcon, GlIntersectionObserver } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import VueRouter from 'vue-router';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import Item from '~/design_management/components/list/item.vue';
......@@ -71,13 +71,13 @@ describe('Design management list item component', () => {
let image;
let glIntersectionObserver;
beforeEach(() => {
beforeEach(async () => {
createComponent();
image = wrapper.find('img');
glIntersectionObserver = wrapper.find(GlIntersectionObserver);
glIntersectionObserver.vm.$emit('appear');
return wrapper.vm.$nextTick();
await nextTick();
});
it('renders a tooltip', () => {
......@@ -91,9 +91,9 @@ describe('Design management list item component', () => {
});
describe('after image is loaded', () => {
beforeEach(() => {
beforeEach(async () => {
image.trigger('load');
return wrapper.vm.$nextTick();
await nextTick();
});
it('renders an image', () => {
......@@ -101,29 +101,27 @@ describe('Design management list item component', () => {
expect(image.isVisible()).toBe(true);
});
it('renders media broken icon when image onerror triggered', () => {
it('renders media broken icon when image onerror triggered', async () => {
image.trigger('error');
return wrapper.vm.$nextTick().then(() => {
expect(image.isVisible()).toBe(false);
expect(wrapper.find(GlIcon).element).toMatchSnapshot();
});
await nextTick();
expect(image.isVisible()).toBe(false);
expect(wrapper.find(GlIcon).element).toMatchSnapshot();
});
describe('when imageV432x230 and image provided', () => {
it('renders imageV432x230 image', () => {
it('renders imageV432x230 image', async () => {
const mockSrc = 'mock-imageV432x230-url';
wrapper.setProps({ imageV432x230: mockSrc });
return wrapper.vm.$nextTick().then(() => {
expect(image.attributes('src')).toBe(mockSrc);
});
await nextTick();
expect(image.attributes('src')).toBe(mockSrc);
});
});
describe('when image disappears from view and then reappears', () => {
beforeEach(() => {
beforeEach(async () => {
glIntersectionObserver.vm.$emit('appear');
return wrapper.vm.$nextTick();
await nextTick();
});
it('renders an image', () => {
......
/* global Mousetrap */
import 'mousetrap';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DesignNavigation from '~/design_management/components/toolbar/design_navigation.vue';
import { DESIGN_ROUTE_NAME } from '~/design_management/router/constants';
......@@ -41,16 +42,15 @@ describe('Design management pagination component', () => {
expect(wrapper.element).toMatchSnapshot();
});
it('renders navigation buttons', () => {
it('renders navigation buttons', async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({
designCollection: { designs: [{ id: '1' }, { id: '2' }] },
});
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.element).toMatchSnapshot();
});
await nextTick();
expect(wrapper.element).toMatchSnapshot();
});
describe('keyboard buttons navigation', () => {
......
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import VueRouter from 'vue-router';
import DeleteButton from '~/design_management/components/delete_button.vue';
import Toolbar from '~/design_management/components/toolbar/index.vue';
......@@ -60,60 +60,54 @@ describe('Design management toolbar component', () => {
wrapper.destroy();
});
it('renders design and updated data', () => {
it('renders design and updated data', async () => {
createComponent();
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.element).toMatchSnapshot();
});
await nextTick();
expect(wrapper.element).toMatchSnapshot();
});
it('links back to designs list', () => {
it('links back to designs list', async () => {
createComponent();
return wrapper.vm.$nextTick().then(() => {
const link = wrapper.find('a');
await nextTick();
const link = wrapper.find('a');
expect(link.props('to')).toEqual({
name: DESIGNS_ROUTE_NAME,
query: {
version: undefined,
},
});
expect(link.props('to')).toEqual({
name: DESIGNS_ROUTE_NAME,
query: {
version: undefined,
},
});
});
it('renders delete button on latest designs version with logged in user', () => {
it('renders delete button on latest designs version with logged in user', async () => {
createComponent();
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(DeleteButton).exists()).toBe(true);
});
await nextTick();
expect(wrapper.find(DeleteButton).exists()).toBe(true);
});
it('does not render delete button on non-latest version', () => {
it('does not render delete button on non-latest version', async () => {
createComponent(false, true, { isLatestVersion: false });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(DeleteButton).exists()).toBe(false);
});
await nextTick();
expect(wrapper.find(DeleteButton).exists()).toBe(false);
});
it('does not render delete button when user is not logged in', () => {
it('does not render delete button when user is not logged in', async () => {
createComponent(false, false);
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(DeleteButton).exists()).toBe(false);
});
await nextTick();
expect(wrapper.find(DeleteButton).exists()).toBe(false);
});
it('emits `delete` event on deleteButton `delete-selected-designs` event', () => {
it('emits `delete` event on deleteButton `delete-selected-designs` event', async () => {
createComponent();
return wrapper.vm.$nextTick().then(() => {
wrapper.find(DeleteButton).vm.$emit('delete-selected-designs');
expect(wrapper.emitted().delete).toBeTruthy();
});
await nextTick();
wrapper.find(DeleteButton).vm.$emit('delete-selected-designs');
expect(wrapper.emitted().delete).toBeTruthy();
});
it('renders download button with correct link', () => {
......
import { GlDropdown, GlDropdownItem, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DesignVersionDropdown from '~/design_management/components/upload/design_version_dropdown.vue';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import mockAllVersions from './mock_data/all_versions';
......@@ -47,77 +48,69 @@ describe('Design management design version dropdown component', () => {
const findVersionLink = (index) => wrapper.findAll(GlDropdownItem).at(index);
it('renders design version dropdown button', () => {
it('renders design version dropdown button', async () => {
createComponent();
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.element).toMatchSnapshot();
});
await nextTick();
expect(wrapper.element).toMatchSnapshot();
});
it('renders design version list', () => {
it('renders design version list', async () => {
createComponent();
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.element).toMatchSnapshot();
});
await nextTick();
expect(wrapper.element).toMatchSnapshot();
});
describe('selected version name', () => {
it('has "latest" on most recent version item', () => {
it('has "latest" on most recent version item', async () => {
createComponent();
return wrapper.vm.$nextTick().then(() => {
expect(findVersionLink(0).text()).toContain('latest');
});
await nextTick();
expect(findVersionLink(0).text()).toContain('latest');
});
});
describe('versions list', () => {
it('displays latest version text by default', () => {
it('displays latest version text by default', async () => {
createComponent();
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(GlDropdown).attributes('text')).toBe('Showing latest version');
});
await nextTick();
expect(wrapper.find(GlDropdown).attributes('text')).toBe('Showing latest version');
});
it('displays latest version text when only 1 version is present', () => {
it('displays latest version text when only 1 version is present', async () => {
createComponent({ maxVersions: 1 });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(GlDropdown).attributes('text')).toBe('Showing latest version');
});
await nextTick();
expect(wrapper.find(GlDropdown).attributes('text')).toBe('Showing latest version');
});
it('displays version text when the current version is not the latest', () => {
it('displays version text when the current version is not the latest', async () => {
createComponent({ $route: designRouteFactory(PREVIOUS_VERSION_ID) });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(GlDropdown).attributes('text')).toBe(`Showing version #1`);
});
await nextTick();
expect(wrapper.find(GlDropdown).attributes('text')).toBe(`Showing version #1`);
});
it('displays latest version text when the current version is the latest', () => {
it('displays latest version text when the current version is the latest', async () => {
createComponent({ $route: designRouteFactory(LATEST_VERSION_ID) });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(GlDropdown).attributes('text')).toBe('Showing latest version');
});
await nextTick();
expect(wrapper.find(GlDropdown).attributes('text')).toBe('Showing latest version');
});
it('should have the same length as apollo query', () => {
it('should have the same length as apollo query', async () => {
createComponent();
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.findAll(GlDropdownItem)).toHaveLength(wrapper.vm.allVersions.length);
});
await nextTick();
expect(wrapper.findAll(GlDropdownItem)).toHaveLength(wrapper.vm.allVersions.length);
});
it('should render TimeAgo', async () => {
createComponent();
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.findAllComponents(TimeAgo)).toHaveLength(wrapper.vm.allVersions.length);
});
......
import { GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import { ApolloMutation } from 'vue-apollo';
import VueRouter from 'vue-router';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
......@@ -153,11 +153,11 @@ describe('Design management design index page', () => {
jest.spyOn(utils, 'getPageLayoutElement').mockReturnValue(mockPageLayoutElement);
createComponent({ loading: false }, { data: { design, scale: 2 } });
await wrapper.vm.$nextTick();
await nextTick();
expect(findDesignPresentation().props('scale')).toBe(2);
DesignIndex.beforeRouteUpdate.call(wrapper.vm, {}, {}, jest.fn());
await wrapper.vm.$nextTick();
await nextTick();
expect(findDesignPresentation().props('scale')).toBe(1);
});
......@@ -200,7 +200,7 @@ describe('Design management design index page', () => {
});
});
it('opens a new discussion form', () => {
it('opens a new discussion form', async () => {
createComponent(
{ loading: false },
{
......@@ -212,9 +212,8 @@ describe('Design management design index page', () => {
findDesignPresentation().vm.$emit('openCommentForm', { x: 0, y: 0 });
return wrapper.vm.$nextTick().then(() => {
expect(findDiscussionForm().exists()).toBe(true);
});
await nextTick();
expect(findDiscussionForm().exists()).toBe(true);
});
it('keeps new discussion form focused', () => {
......@@ -233,7 +232,7 @@ describe('Design management design index page', () => {
expect(focusInput).toHaveBeenCalled();
});
it('sends a mutation on submitting form and closes form', () => {
it('sends a mutation on submitting form and closes form', async () => {
createComponent(
{ loading: false },
{
......@@ -248,17 +247,12 @@ describe('Design management design index page', () => {
findDiscussionForm().vm.$emit('submit-form');
expect(mutate).toHaveBeenCalledWith(createDiscussionMutationVariables);
return wrapper.vm
.$nextTick()
.then(() => {
return mutate({ variables: createDiscussionMutationVariables });
})
.then(() => {
expect(findDiscussionForm().exists()).toBe(false);
});
await nextTick();
await mutate({ variables: createDiscussionMutationVariables });
expect(findDiscussionForm().exists()).toBe(false);
});
it('closes the form and clears the comment on canceling form', () => {
it('closes the form and clears the comment on canceling form', async () => {
createComponent(
{ loading: false },
{
......@@ -274,9 +268,8 @@ describe('Design management design index page', () => {
expect(wrapper.vm.comment).toBe('');
return wrapper.vm.$nextTick().then(() => {
expect(findDiscussionForm().exists()).toBe(false);
});
await nextTick();
expect(findDiscussionForm().exists()).toBe(false);
});
describe('with error', () => {
......@@ -299,22 +292,21 @@ describe('Design management design index page', () => {
describe('onDesignQueryResult', () => {
describe('with no designs', () => {
it('redirects to /designs', () => {
it('redirects to /designs', async () => {
createComponent({ loading: true });
router.push = jest.fn();
wrapper.vm.onDesignQueryResult({ data: mockResponseNoDesigns, loading: false });
return wrapper.vm.$nextTick().then(() => {
expect(createFlash).toHaveBeenCalledTimes(1);
expect(createFlash).toHaveBeenCalledWith({ message: DESIGN_NOT_FOUND_ERROR });
expect(router.push).toHaveBeenCalledTimes(1);
expect(router.push).toHaveBeenCalledWith({ name: DESIGNS_ROUTE_NAME });
});
await nextTick();
expect(createFlash).toHaveBeenCalledTimes(1);
expect(createFlash).toHaveBeenCalledWith({ message: DESIGN_NOT_FOUND_ERROR });
expect(router.push).toHaveBeenCalledTimes(1);
expect(router.push).toHaveBeenCalledWith({ name: DESIGNS_ROUTE_NAME });
});
});
describe('when no design exists for given version', () => {
it('redirects to /designs', () => {
it('redirects to /designs', async () => {
createComponent({ loading: true });
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
......@@ -327,12 +319,11 @@ describe('Design management design index page', () => {
router.push = jest.fn();
wrapper.vm.onDesignQueryResult({ data: mockResponseWithDesigns, loading: false });
return wrapper.vm.$nextTick().then(() => {
expect(createFlash).toHaveBeenCalledTimes(1);
expect(createFlash).toHaveBeenCalledWith({ message: DESIGN_VERSION_NOT_EXIST_ERROR });
expect(router.push).toHaveBeenCalledTimes(1);
expect(router.push).toHaveBeenCalledWith({ name: DESIGNS_ROUTE_NAME });
});
await nextTick();
expect(createFlash).toHaveBeenCalledTimes(1);
expect(createFlash).toHaveBeenCalledWith({ message: DESIGN_VERSION_NOT_EXIST_ERROR });
expect(router.push).toHaveBeenCalledTimes(1);
expect(router.push).toHaveBeenCalledWith({ name: DESIGNS_ROUTE_NAME });
});
});
});
......
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