Commit 0116f87c authored by Natalia Tepluhina's avatar Natalia Tepluhina

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

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

See merge request gitlab-org/gitlab!79047
parents e7e05e17 53ecafdd
......@@ -169,7 +169,7 @@ describe('Subscription Breakdown', () => {
it('updates visible of subscription activation modal when change emitted', async () => {
findSubscriptionActivationModal().vm.$emit('change', true);
await wrapper.vm.$nextTick();
await nextTick();
expect(findSubscriptionActivationModal().props('visible')).toBe(true);
});
......
import { shallowMount } from '@vue/test-utils';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import FilterBar from 'ee/analytics/code_review_analytics/components/filter_bar.vue';
import storeConfig from 'ee/analytics/code_review_analytics/store';
......@@ -38,7 +38,7 @@ const defaultParams = {
};
async function shouldMergeUrlParams(wrapper, result) {
await wrapper.vm.$nextTick();
await nextTick();
expect(urlUtils.mergeUrlParams).toHaveBeenCalledWith(result, window.location.href, {
spreadArrays: true,
});
......
......@@ -2,7 +2,7 @@ import { GlEmptyState } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import Component from 'ee/analytics/cycle_analytics/components/base.vue';
import DurationChart from 'ee/analytics/cycle_analytics/components/duration_chart.vue';
......@@ -97,7 +97,7 @@ function mockRequiredRoutes(mockAdapter) {
}
async function shouldMergeUrlParams(wrapper, result) {
await wrapper.vm.$nextTick();
await nextTick();
expect(urlUtils.mergeUrlParams).toHaveBeenCalledWith(result, window.location.href, {
spreadArrays: true,
});
......@@ -506,7 +506,7 @@ describe('EE Value Stream Analytics component', () => {
beforeEach(async () => {
wrapper = await createComponent();
await store.dispatch('initializeCycleAnalytics', initialCycleAnalyticsState);
await wrapper.vm.$nextTick();
await nextTick();
});
it('sets the value_stream_id url parameter', async () => {
......@@ -523,7 +523,7 @@ describe('EE Value Stream Analytics component', () => {
beforeEach(async () => {
wrapper = await createComponent();
await store.dispatch('setSelectedProjects', selectedProjects);
await wrapper.vm.$nextTick();
await nextTick();
});
it('sets the project_ids url parameter', async () => {
......
......@@ -2,7 +2,7 @@ import { GlDropdownSectionHeader } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import LabelsSelector from 'ee/analytics/cycle_analytics/components/labels_selector.vue';
import createStore from 'ee/analytics/cycle_analytics/store';
......@@ -103,19 +103,18 @@ describe('Value Stream Analytics LabelsSelector', () => {
return waitForPromises();
});
it('will emit the "select-label" event', () => {
it('will emit the "select-label" event', async () => {
expect(wrapper.emitted('select-label')).toBeUndefined();
const elem = wrapper.findAll('.dropdown-item').at(1);
elem.trigger('click');
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(wrapper.emitted('select-label').length > 0).toBe(true);
expect(wrapper.emitted('select-label')[0]).toContain(groupLabels[1].id);
});
});
});
});
describe('with selectedLabelIds set', () => {
beforeEach(() => {
......
......@@ -2,7 +2,7 @@ import { GlDropdownItem, GlSegmentedControl, GlSprintf } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import LabelsSelector from 'ee/analytics/cycle_analytics/components/labels_selector.vue';
import TasksByTypeFilters from 'ee/analytics/cycle_analytics/components/tasks_by_type/tasks_by_type_filters.vue';
......@@ -187,13 +187,13 @@ describe('TasksByTypeFilters', () => {
expect(findSelectedSubjectFilters(wrapper)).toBe(TASKS_BY_TYPE_SUBJECT_ISSUE);
});
it('emits the `update-filter` event when a subject filter is clicked', () => {
it('emits the `update-filter` event when a subject filter is clicked', async () => {
wrapper = createComponent({ mountFn: mount });
expect(wrapper.emitted('update-filter')).toBeUndefined();
findSubjectFilters(wrapper).findAll('label:not(.active)').at(0).trigger('click');
return wrapper.vm.$nextTick(() => {
await nextTick();
expect(wrapper.emitted('update-filter')).toBeDefined();
expect(wrapper.emitted('update-filter')[0]).toEqual([
{
......@@ -203,5 +203,4 @@ describe('TasksByTypeFilters', () => {
]);
});
});
});
});
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import TasksByTypeChart from 'ee/analytics/cycle_analytics/components/tasks_by_type/tasks_by_type_chart.vue';
import TasksByTypeFilters from 'ee/analytics/cycle_analytics/components/tasks_by_type/tasks_by_type_filters.vue';
......@@ -128,10 +128,10 @@ describe('TypeOfWorkCharts', () => {
value: TASKS_BY_TYPE_SUBJECT_MERGE_REQUEST,
};
beforeEach(() => {
beforeEach(async () => {
wrapper = createComponent();
findSubjectFilters(wrapper).vm.$emit('update-filter', payload);
return wrapper.vm.$nextTick();
await nextTick();
});
it('calls the setTasksByTypeFilters method', () => {
......
import { GlAlert, GlTabs } from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import DevopsAdoptionAddDropdown from 'ee/analytics/devops_reports/devops_adoption/components/devops_adoption_add_dropdown.vue';
import DevopsAdoptionApp from 'ee/analytics/devops_reports/devops_adoption/components/devops_adoption_app.vue';
......@@ -225,7 +225,7 @@ describe('DevopsAdoptionApp', () => {
};
wrapper = createComponent({ mockApollo, provide });
await waitForPromises();
await wrapper.vm.$nextTick();
await nextTick();
});
it('does not attempt to enable a group', () => {
......@@ -242,7 +242,7 @@ describe('DevopsAdoptionApp', () => {
};
wrapper = createComponent({ mockApollo, provide });
await waitForPromises();
await wrapper.vm.$nextTick();
await nextTick();
});
describe('enables the group', () => {
......@@ -282,7 +282,7 @@ describe('DevopsAdoptionApp', () => {
});
wrapper = createComponent({ mockApollo, provide });
await waitForPromises();
await wrapper.vm.$nextTick();
await nextTick();
});
it('does not render the devops section', () => {
......
import { GlModal, GlSprintf, GlAlert } from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import DevopsAdoptionDeleteModal from 'ee/analytics/devops_reports/devops_adoption/components/devops_adoption_delete_modal.vue';
import disableDevopsAdoptionNamespaceMutation from 'ee/analytics/devops_reports/devops_adoption/graphql/mutations/disable_devops_adoption_namespace.mutation.graphql';
......@@ -110,7 +110,7 @@ describe('DevopsAdoptionDeleteModal', () => {
findModal().vm.$emit('primary', mockEvent);
await wrapper.vm.$nextTick();
await nextTick();
expect(cancelButtonDisabledState()).toBe(true);
});
......@@ -120,7 +120,7 @@ describe('DevopsAdoptionDeleteModal', () => {
findModal().vm.$emit('primary', mockEvent);
await wrapper.vm.$nextTick();
await nextTick();
expect(actionButtonLoadingState()).toBe(true);
});
......
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DevopsAdoptionTableCellFlag from 'ee/analytics/devops_reports/devops_adoption/components/devops_adoption_table_cell_flag.vue';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
......@@ -40,7 +41,7 @@ describe('DevopsAdoptionTableCellFlag', () => {
beforeEach(async () => {
wrapper.setProps({ enabled: false });
await wrapper.vm.$nextTick();
await nextTick();
});
it('matches the snapshot', () => {
......@@ -59,7 +60,7 @@ describe('DevopsAdoptionTableCellFlag', () => {
beforeEach(async () => {
wrapper.setProps({ variant: 'primary' });
await wrapper.vm.$nextTick();
await nextTick();
});
it('matches the snapshot', () => {
......@@ -86,7 +87,7 @@ describe('DevopsAdoptionTableCellFlag', () => {
beforeEach(async () => {
wrapper.setProps({ enabled: true });
await wrapper.vm.$nextTick();
await nextTick();
});
it('matches the snapshot', () => {
......
import { shallowMount } from '@vue/test-utils';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import FilterBar from 'ee/analytics/merge_request_analytics/components/filter_bar.vue';
import storeConfig from 'ee/analytics/merge_request_analytics/store';
......@@ -57,7 +57,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 { 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 Vuex from 'vuex';
import ThroughputChart from 'ee/analytics/merge_request_analytics/components/throughput_chart.vue';
import ThroughputStats from 'ee/analytics/merge_request_analytics/components/throughput_stats.vue';
......@@ -221,7 +221,7 @@ describe('ThroughputChart', () => {
{ value: labels[1], operator },
],
});
await wrapper.vm.$nextTick();
await nextTick();
expect(
wrapper.vm.$options.apollo.throughputChartData.variables.bind(wrapper.vm)(),
).toMatchObject({
......
......@@ -7,7 +7,7 @@ import {
GlPagination,
} from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import ThroughputTable from 'ee/analytics/merge_request_analytics/components/throughput_table.vue';
import {
......@@ -223,7 +223,7 @@ describe('ThroughputTable', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
const labelDetails = findColSubItem(
TEST_IDS.MERGE_REQUEST_DETAILS,
......@@ -242,7 +242,7 @@ describe('ThroughputTable', () => {
userNotesCount: 2,
});
await wrapper.vm.$nextTick();
await nextTick();
const commentCount = findColSubItem(
TEST_IDS.MERGE_REQUEST_DETAILS,
......@@ -269,7 +269,7 @@ describe('ThroughputTable', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
const icon = findColSubComponent(TEST_IDS.MERGE_REQUEST_DETAILS, GlIcon);
......@@ -297,7 +297,7 @@ describe('ThroughputTable', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
const approved = findColSubItem(TEST_IDS.MERGE_REQUEST_DETAILS, TEST_IDS.APPROVED);
const icon = approved.findComponent(GlIcon);
......@@ -321,7 +321,7 @@ describe('ThroughputTable', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
const approved = findColSubItem(TEST_IDS.MERGE_REQUEST_DETAILS, TEST_IDS.APPROVED);
const icon = approved.findComponent(GlIcon);
......@@ -352,7 +352,7 @@ describe('ThroughputTable', () => {
milestone: { title },
});
await wrapper.vm.$nextTick();
await nextTick();
expect(findCol(TEST_IDS.MILESTONE).text()).toBe(title);
});
......@@ -410,7 +410,7 @@ describe('ThroughputTable', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
expect(findPrevious().classes()).not.toContain('disabled');
expect(findNext().classes()).toContain('disabled');
......@@ -431,7 +431,7 @@ describe('ThroughputTable', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
expect(findPrevious().classes()).not.toContain('disabled');
expect(findNext().classes()).not.toContain('disabled');
......@@ -489,7 +489,7 @@ describe('ThroughputTable', () => {
{ value: labels[1], operator },
],
});
await wrapper.vm.$nextTick();
await nextTick();
expect(
wrapper.vm.$options.apollo.throughputTableData.variables.bind(wrapper.vm)(),
).toMatchObject({
......
......@@ -10,7 +10,7 @@ import { GlColumnChart } from '@gitlab/ui/dist/charts';
import { shallowMount } from '@vue/test-utils';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import ProductivityApp from 'ee/analytics/productivity_analytics/components/app.vue';
import MetricChart from 'ee/analytics/productivity_analytics/components/metric_chart.vue';
......@@ -153,10 +153,10 @@ describe('ProductivityApp component', () => {
});
describe('user has access to the group', () => {
beforeEach(() => {
beforeEach(async () => {
mockStore.state.charts.charts[chartKeys.main].errorCode = null;
return wrapper.vm.$nextTick();
await nextTick();
});
describe('when the main chart is loading', () => {
......@@ -305,10 +305,10 @@ describe('ProductivityApp component', () => {
});
describe('when the user changes the metric', () => {
beforeEach(() => {
beforeEach(async () => {
jest.spyOn(mockStore, 'dispatch');
findCommitBasedMetricChart().vm.$emit('metricTypeChange', 'loc_per_commit');
return wrapper.vm.$nextTick();
await nextTick();
});
it('should call setMetricType when `metricTypeChange` is emitted on the metric chart', () => {
......@@ -357,10 +357,10 @@ describe('ProductivityApp component', () => {
});
describe('when the user changes the metric', () => {
beforeEach(() => {
beforeEach(async () => {
jest.spyOn(mockStore, 'dispatch');
findScatterplotMetricChart().vm.$emit('metricTypeChange', 'loc_per_commit');
return wrapper.vm.$nextTick();
await nextTick();
});
it('should call setMetricType when `metricTypeChange` is emitted on the metric chart', () => {
......
import { GlLoadingIcon, GlDropdown, GlDropdownItem, GlAlert, GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import MetricChart from 'ee/analytics/productivity_analytics/components/metric_chart.vue';
import httpStatusCodes from '~/lib/utils/http_status';
......@@ -145,16 +146,15 @@ describe('MetricChart component', () => {
expect(wrapper.vm.$emit).toHaveBeenCalledWith('metricTypeChange', 'time_to_merge');
});
it('should set the `invisible` class on the icon of the first dropdown item', () => {
it('should set the `invisible` class on the icon of the first dropdown item', async () => {
wrapper.setProps({ selectedMetric: 'time_to_last_commit' });
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(findMetricDropdownItems().at(0).findComponent(GlIcon).classes()).toContain(
'invisible',
);
});
});
});
describe('and a description exists', () => {
it('renders a description', () => {
......
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import MergeRequestTable from 'ee/analytics/productivity_analytics/components/mr_table.vue';
import MergeRequestTableRow from 'ee/analytics/productivity_analytics/components/mr_table_row.vue';
import { mockMergeRequests } from '../mock_data';
......@@ -72,12 +73,11 @@ describe('MergeRequestTable component', () => {
});
describe('columnMetricChange', () => {
it('it emits the metric key when item is selected from the dropdown', () => {
it('it emits the metric key when item is selected from the dropdown', async () => {
findFirstDropdownItem().vm.$emit('click');
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(wrapper.emitted().columnMetricChange[0]).toEqual(['time_to_first_comment']);
});
});
});
});
import { GlAlert, GlDropdown, GlDropdownItem, GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DownloadTestCoverage from 'ee/analytics/repository_analytics/components/download_test_coverage.vue';
import SelectProjectsDropdown from 'ee/analytics/repository_analytics/components/select_projects_dropdown.vue';
......@@ -58,61 +59,57 @@ describe('Download test coverage component', () => {
});
describe('when there is an error fetching the projects', () => {
it('displays an alert for the failed query', () => {
it('displays an alert for the failed query', 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({ hasError: true });
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(findAlert().exists()).toBe(true);
});
});
});
describe('when selecting a project', () => {
const groupAnalyticsCoverageReportsPathWithDates = `${injectedProperties.groupAnalyticsCoverageReportsPath}?start_date=2020-06-06&end_date=2020-07-06`;
describe('with all projects selected', () => {
it('renders primary action as a link with no project_ids param', () => {
it('renders primary action as a link with no project_ids param', 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({ allProjectsSelected: true, selectedProjectIds: [] });
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(findCodeCoverageDownloadButton().attributes('href')).toBe(
groupAnalyticsCoverageReportsPathWithDates,
);
});
});
});
describe('with two or more projects selected without selecting all projects', () => {
it('renders primary action as a link with two project IDs as parameters', () => {
it('renders primary action as a link with two project IDs as parameters', 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({ allProjectsSelected: false, selectedProjectIds: [1, 2] });
const projectIdsQueryParam = `project_ids[]=1&project_ids[]=2`;
const expectedPath = `${groupAnalyticsCoverageReportsPathWithDates}&${projectIdsQueryParam}`;
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(findCodeCoverageDownloadButton().attributes('href')).toBe(expectedPath);
});
});
});
describe('with one project selected', () => {
it('renders primary action as a link with one project ID as a parameter', () => {
it('renders primary action as a link with one project ID as a parameter', 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({ allProjectsSelected: false, selectedProjectIds: [1] });
const projectIdsQueryParam = `project_ids[]=1`;
const expectedPath = `${groupAnalyticsCoverageReportsPathWithDates}&${projectIdsQueryParam}`;
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(findCodeCoverageDownloadButton().attributes('href')).toBe(expectedPath);
});
});
});
describe('with no projects selected', () => {
it('renders a disabled primary action button', () => {
......@@ -121,13 +118,13 @@ describe('Download test coverage component', () => {
});
describe('when clicking the select all button', () => {
it('selects all projects and removes the disabled attribute from the download button', () => {
it('selects all projects and removes the disabled attribute from the download button', 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({ allProjectsSelected: false, selectedProjectIds: [] });
clickSelectAllProjectsButton();
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(findCodeCoverageDownloadButton().attributes('href')).toBe(
groupAnalyticsCoverageReportsPathWithDates,
);
......@@ -135,7 +132,6 @@ describe('Download test coverage component', () => {
});
});
});
});
describe('when selecting a date range', () => {
it.each`
......@@ -147,14 +143,13 @@ describe('Download test coverage component', () => {
${90} | ${`${injectedProperties.groupAnalyticsCoverageReportsPath}?start_date=2020-04-07&end_date=2020-07-06`}
`(
'updates CSV path to have the start date be $date days before today',
({ date, expected }) => {
async ({ date, expected }) => {
wrapper
.find(`[data-testid="group-code-coverage-download-select-date-${date}"]`)
.vm.$emit('click');
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(findCodeCoverageDownloadButton().attributes('href')).toBe(expected);
});
},
);
});
......
......@@ -6,6 +6,7 @@ import {
GlIcon,
} from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import SelectProjectsDropdown from 'ee/analytics/repository_analytics/components/select_projects_dropdown.vue';
describe('Select projects dropdown component', () => {
......@@ -62,15 +63,14 @@ describe('Select projects dropdown component', () => {
createComponent({ data: initialData });
});
it('should reset all selected projects', () => {
it('should reset all selected projects', async () => {
selectAllProjects();
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(
findProjectById(initialData.groupProjects[0].id).findComponent(GlIcon).classes(),
).toContain('gl-visibility-hidden');
});
});
it('should emit select-all-projects event', () => {
jest.spyOn(wrapper.vm, '$emit');
......@@ -94,26 +94,24 @@ describe('Select projects dropdown component', () => {
});
});
it('should check selected project', () => {
it('should check selected project', async () => {
const project = initialData.groupProjects[0];
selectProjectById(project.id);
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(findProjectById(project.id).findComponent(GlIcon).classes()).not.toContain(
'gl-visibility-hidden',
);
});
});
it('should uncheck select all projects', () => {
it('should uncheck select all projects', async () => {
selectProjectById(initialData.groupProjects[0].id);
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(findSelectAllProjects().findComponent(GlIcon).classes()).toContain(
'gl-visibility-hidden',
);
});
});
it('should emit select-project event', () => {
const project = initialData.groupProjects[0];
......@@ -145,32 +143,30 @@ describe('Select projects dropdown component', () => {
});
describe('when the intersection observer component appears in view', () => {
it('makes a query to fetch more projects', () => {
it('makes a query to fetch more projects', async () => {
jest
.spyOn(wrapper.vm.$apollo.queries.groupProjects, 'fetchMore')
.mockImplementation(jest.fn().mockResolvedValue());
findIntersectionObserver().vm.$emit('appear');
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(wrapper.vm.$apollo.queries.groupProjects.fetchMore).toHaveBeenCalledTimes(1);
});
});
describe('when the fetchMore query throws an error', () => {
it('emits an error event', () => {
it('emits an error event', async () => {
jest.spyOn(wrapper.vm, '$emit');
jest
.spyOn(wrapper.vm.$apollo.queries.groupProjects, 'fetchMore')
.mockImplementation(jest.fn().mockRejectedValue());
findIntersectionObserver().vm.$emit('appear');
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(wrapper.vm.$emit).toHaveBeenCalledWith('projects-query-error');
});
});
});
});
describe('when a query is loading a new page of projects', () => {
it('should render the loading spinner', () => {
......
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import GroupsDropdownFilter from 'ee/analytics/shared/components/groups_dropdown_filter.vue';
import { TEST_HOST } from 'helpers/test_constants';
import Api from '~/api';
......@@ -116,21 +117,19 @@ describe('GroupsDropdownFilter component', () => {
expect(wrapper.emitted().selected).toEqual([[groups[1]]]);
});
it('renders an avatar in the dropdown button when the group has an avatar_url', () => {
it('renders an avatar in the dropdown button when the group has an avatar_url', async () => {
selectDropdownAtIndex(0);
return wrapper.vm.$nextTick().then(() => {
await nextTick();
shouldContainAvatar({ dropdown: findDropdownButton(), hasIdenticon: false });
});
});
it("renders an identicon in the dropdown button when the group doesn't have an avatar_url", () => {
it("renders an identicon in the dropdown button when the group doesn't have an avatar_url", async () => {
selectDropdownAtIndex(1);
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(findDropdownButton().find('img.gl-avatar').exists()).toBe(false);
expect(findDropdownButton().find('.gl-avatar-identicon').exists()).toBe(true);
});
});
});
});
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import App from 'ee/approvals/components/app.vue';
import ModalRuleCreate from 'ee/approvals/components/modal_rule_create.vue';
......@@ -212,15 +212,16 @@ describe('EE Approvals App', () => {
store.modules.approvals.state.rules = [{ id: 1 }];
});
it('calls fetchRules to reset to defaults', () => {
it('calls fetchRules to reset to defaults', async () => {
factory();
findResetButton().vm.$emit('click');
return wrapper.vm.$nextTick().then(() => {
expect(
store.modules.approvals.actions.fetchRules,
).toHaveBeenLastCalledWith(expect.anything(), { targetBranch, resetToDefault: true });
await nextTick();
expect(store.modules.approvals.actions.fetchRules).toHaveBeenLastCalledWith(
expect.anything(),
{ targetBranch, resetToDefault: true },
);
expect(showToast).toHaveBeenCalledWith('Approval rules reset to project defaults', {
action: {
text: 'Undo',
......@@ -229,5 +230,4 @@ describe('EE Approvals App', () => {
});
});
});
});
});
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import ApproversList from 'ee/approvals/components/approvers_list.vue';
import ApproversListEmpty from 'ee/approvals/components/approvers_list_empty.vue';
import ApproversListItem from 'ee/approvals/components/approvers_list_item.vue';
......@@ -58,18 +59,17 @@ describe('ApproversList', () => {
});
TEST_APPROVERS.forEach((approver, idx) => {
it(`when remove (${idx}), emits new input`, () => {
it(`when remove (${idx}), emits new input`, async () => {
factory();
const item = wrapper.findAll(ApproversListItem).at(idx);
item.vm.$emit('remove', approver);
return wrapper.vm.$nextTick().then(() => {
await nextTick();
const expected = TEST_APPROVERS.filter((x, i) => i !== idx);
expect(wrapper.emitted().input).toEqual([[expected]]);
});
});
});
});
});
import { GlButton, GlLink, GlCollapse } from '@gitlab/ui';
import { nextTick } from 'vue';
import { shallowMountExtended, extendedWrapper } from 'helpers/vue_test_utils_helper';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
......@@ -40,7 +41,6 @@ describe('FreeTierPromo component', () => {
trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
};
const waitForReady = () => wrapper.vm.$nextTick();
const findCollapseToggleButton = () => wrapper.findByTestId('collapse-btn');
const findCollapse = () => extendedWrapper(wrapper.findComponent(GlCollapse));
const findLearnMore = () => findCollapse().findComponent(GlLink);
......@@ -55,7 +55,7 @@ describe('FreeTierPromo component', () => {
describe('when ready', () => {
beforeEach(async () => {
createComponent();
await waitForReady();
await nextTick();
});
it('shows summary', () => {
......@@ -163,7 +163,7 @@ describe('FreeTierPromo component', () => {
beforeEach(async () => {
localStorage.setItem(MR_APPROVALS_PROMO_DISMISSED, 'true');
createComponent();
await waitForReady();
await nextTick();
localStorage.setItem.mockClear();
});
......
import { mount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import MRRules from 'ee/approvals/components/mr_edit/mr_rules.vue';
import RuleControls from 'ee/approvals/components/rule_controls.vue';
......@@ -94,14 +94,13 @@ describe('EE Approvals MRRules', () => {
expect(store.modules.approvals.actions.setTargetBranch).toHaveBeenCalled();
});
it('re-fetches rules when target branch has changed', () => {
it('re-fetches rules when target branch has changed', async () => {
factory();
store.modules.approvals.state.targetBranch = 'main123';
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(store.modules.approvals.actions.fetchRules).toHaveBeenCalled();
});
});
it('disconnects MutationObserver when component gets destroyed', () => {
const mockDisconnect = jest.fn();
......
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import RuleInput from 'ee/approvals/components/mr_edit/rule_input.vue';
import { createStoreOptions } from 'ee/approvals/stores';
......@@ -73,7 +73,7 @@ describe('Rule Input', () => {
expect(Number(wrapper.attributes('min'))).toEqual(0);
});
it('dispatches putRule on change', () => {
it('dispatches putRule on change', async () => {
const action = store.modules.approvals.actions.putRule;
createComponent();
wrapper.element.value = wrapper.props().rule.approvalsRequired + 1;
......@@ -81,8 +81,7 @@ describe('Rule Input', () => {
jest.runAllTimers();
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(action).toHaveBeenCalledWith(expect.anything(), { approvalsRequired: 10, id: 5 });
});
});
});
import { GlPagination, GlTable } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import AuditEventsTable from 'ee/audit_events/components/audit_events_table.vue';
import setWindowLocation from 'helpers/set_window_location_helper';
import createEvents from '../mock_data';
......@@ -45,25 +46,23 @@ describe('AuditEventsTable component', () => {
expect(getCell(0, 1).text()).toBe('User');
});
it('should show the empty state if there is no data', () => {
it('should show the empty state if there is no data', async () => {
wrapper.setProps({ events: [] });
wrapper.vm.$nextTick(() => {
await nextTick();
expect(getCell(0, 0).text()).toBe('There are no records to show');
});
});
});
describe('Pagination behaviour', () => {
it('should show', () => {
expect(wrapper.findComponent(GlPagination).exists()).toBe(true);
});
it('should hide if there is no data', () => {
it('should hide if there is no data', async () => {
wrapper.setProps({ events: [] });
wrapper.vm.$nextTick(() => {
await nextTick();
expect(wrapper.findComponent(GlPagination).exists()).toBe(false);
});
});
it('should get the page number from the URL', () => {
setWindowLocation('?page=2');
......@@ -86,12 +85,11 @@ describe('AuditEventsTable component', () => {
expect(wrapper.findComponent(GlPagination).props().prevPage).toBe(1);
});
it('should not have a nextPage if isLastPage is true', () => {
it('should not have a nextPage if isLastPage is true', async () => {
wrapper.setProps({ isLastPage: true });
wrapper.vm.$nextTick(() => {
await nextTick();
expect(wrapper.findComponent(GlPagination).props().nextPage).toBe(null);
});
});
it('should set the nextPage to 2 if the page is 1', () => {
setWindowLocation('?page=1');
......
import { GlDaterangePicker } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DateRangeButtons from 'ee/audit_events/components/date_range_buttons.vue';
import DateRangeField from 'ee/audit_events/components/date_range_field.vue';
import { CURRENT_DATE, MAX_DATE_RANGE } from 'ee/audit_events/constants';
......@@ -91,7 +92,7 @@ describe('DateRangeField component', () => {
createComponent();
findDatePicker().vm.$emit('input', { endDate });
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.emitted().selected[0]).toEqual([
{
startDate: getDateInPast(endDate, 1),
......@@ -106,7 +107,7 @@ describe('DateRangeField component', () => {
createComponent();
findDatePicker().vm.$emit('input', { startDate, endDate });
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.emitted().selected[0]).toEqual([
{
startDate,
......@@ -121,7 +122,7 @@ describe('DateRangeField component', () => {
createComponent();
findDateRangeButtons().vm.$emit('input', { startDate, endDate });
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.emitted().selected[0]).toEqual([
{
startDate,
......
import { GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import MockAdapter from 'axios-mock-adapter';
import Vuex from 'vuex';
import SubscriptionTable from 'ee/billings/subscriptions/components/subscription_table.vue';
......@@ -33,7 +33,7 @@ describe('SubscriptionTable component', () => {
const findRenewButton = () => wrapper.findByTestId('renew-button');
const findRefreshSeatsButton = () => wrapper.findByTestId('refresh-seats-button');
const createComponentWithStore = ({ props = {}, provide = {}, state = {} } = {}) => {
const createComponentWithStore = async ({ props = {}, provide = {}, state = {} } = {}) => {
store = new Vuex.Store(initialStore());
jest.spyOn(store, 'dispatch').mockImplementation();
......@@ -49,7 +49,7 @@ describe('SubscriptionTable component', () => {
);
Object.assign(store.state, state);
return wrapper.vm.$nextTick();
await nextTick();
};
afterEach(() => {
......@@ -77,11 +77,11 @@ describe('SubscriptionTable component', () => {
});
describe('with success', () => {
beforeEach(() => {
beforeEach(async () => {
createComponentWithStore();
store.state.isLoadingSubscription = false;
store.commit(types.RECEIVE_SUBSCRIPTION_SUCCESS, mockDataSubscription.gold);
return wrapper.vm.$nextTick();
await nextTick();
});
it('should render the card title "GitLab.com: Gold"', () => {
......
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import BoardFilteredSearch from 'ee/boards/components/board_filtered_search.vue';
import BoardFilteredSearchCe from '~/boards/components/board_filtered_search.vue';
......@@ -36,7 +36,7 @@ describe('ee/BoardFilteredSearch', () => {
store.state.boardConfig = { labels: [{ title: 'test', color: 'black', id: '1' }] };
await wrapper.vm.$nextTick();
await nextTick();
});
it('calls performSearch', () => {
......@@ -66,13 +66,13 @@ describe('ee/BoardFilteredSearch', () => {
it('renders BoardFilteredSearchCe', async () => {
store.state.boardConfig = {};
await wrapper.vm.$nextTick();
await nextTick();
expect(findFilteredSearch().exists()).toEqual(false);
store.state.boardConfig = { labels: [] };
await wrapper.vm.$nextTick();
await nextTick();
expect(findFilteredSearch().exists()).toBe(true);
});
......
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import BoardNewEpic from 'ee/boards/components/board_new_epic.vue';
......@@ -40,13 +40,13 @@ describe('Epic boards new epic form', () => {
boardNewItem.vm.$emit('form-submit', { title: 'Foo' });
await wrapper.vm.$nextTick();
await nextTick();
};
beforeEach(async () => {
wrapper = createComponent();
await wrapper.vm.$nextTick();
await nextTick();
});
afterEach(() => {
......@@ -87,7 +87,7 @@ describe('Epic boards new epic form', () => {
jest.spyOn(eventHub, '$emit').mockImplementation();
findBoardNewItem().vm.$emit('form-cancel');
await wrapper.vm.$nextTick();
await nextTick();
expect(eventHub.$emit).toHaveBeenCalledWith(`toggle-epic-form-${mockList.id}`);
});
});
import { GlFormInput } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { noop } from 'lodash';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import BoardSettingsWipLimit from 'ee_component/boards/components/board_settings_wip_limit.vue';
import waitForPromises from 'helpers/wait_for_promises';
......@@ -101,7 +101,7 @@ describe('BoardSettingsWipLimit', () => {
clickEdit();
await wrapper.vm.$nextTick();
await nextTick();
});
it('renders an input', () => {
......@@ -138,7 +138,7 @@ describe('BoardSettingsWipLimit', () => {
findRemoveWipLimit().vm.$emit('click');
await waitForPromises();
await wrapper.vm.$nextTick();
await nextTick();
expect(spy).toHaveBeenCalledWith(
expect.anything(),
......@@ -182,7 +182,7 @@ describe('BoardSettingsWipLimit', () => {
triggerBlur(blurMethod);
await wrapper.vm.$nextTick();
await nextTick();
expect(spy).toHaveBeenCalledTimes(1);
});
......@@ -201,7 +201,7 @@ describe('BoardSettingsWipLimit', () => {
triggerBlur(blurMethod);
await wrapper.vm.$nextTick();
await nextTick();
expect(spy).toHaveBeenCalledTimes(0);
});
......@@ -218,7 +218,7 @@ describe('BoardSettingsWipLimit', () => {
triggerBlur(blurMethod);
await wrapper.vm.$nextTick();
await nextTick();
expect(spy).toHaveBeenCalledTimes(0);
});
......
import { GlButton, GlIcon, GlLoadingIcon } from '@gitlab/ui';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import EpicLane from 'ee/boards/components/epic_lane.vue';
import IssuesLaneList from 'ee/boards/components/issues_lane_list.vue';
......@@ -93,17 +93,16 @@ describe('EpicLane', () => {
expect(wrapper.findAllComponents(IssuesLaneList)).toHaveLength(wrapper.props('lists').length);
});
it('hides issues when collapsing', () => {
it('hides issues when collapsing', async () => {
expect(wrapper.findAllComponents(IssuesLaneList)).toHaveLength(wrapper.props('lists').length);
expect(wrapper.vm.isCollapsed).toBe(false);
findChevronButton().vm.$emit('click');
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(wrapper.findAllComponents(IssuesLaneList)).toHaveLength(0);
expect(wrapper.vm.isCollapsed).toBe(true);
});
});
it('does not display loading icon when issues are not loading', () => {
expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(false);
......@@ -115,14 +114,14 @@ describe('EpicLane', () => {
expect(wrapper.findByTestId('epic-lane-issue-count').exists()).toBe(false);
});
it('invokes `updateBoardEpicUserPreferences` method on collapse', () => {
it('invokes `updateBoardEpicUserPreferences` method on collapse', async () => {
const collapsedValue = false;
expect(wrapper.vm.isCollapsed).toBe(collapsedValue);
findChevronButton().vm.$emit('click');
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(updateBoardEpicUserPreferencesSpy).toHaveBeenCalled();
const payload = updateBoardEpicUserPreferencesSpy.mock.calls[0][1];
......@@ -134,7 +133,6 @@ describe('EpicLane', () => {
expect(wrapper.vm.isCollapsed).toBe(true);
});
});
it('does not render when issuesCount is 0', () => {
createComponent({ boardItemsByListId: {} });
......
import { GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import VirtualList from 'vue-virtual-scroll-list';
import Draggable from 'vuedraggable';
import Vuex from 'vuex';
......@@ -164,7 +164,7 @@ describe('EpicsSwimlanes', () => {
it('displays IssueLaneList component when toggling unassigned issues lane', async () => {
wrapper.findByTestId('unassigned-lane-toggle').vm.$emit('click');
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.findComponent(IssueLaneList).exists()).toBe(true);
});
......@@ -198,7 +198,7 @@ describe('EpicsSwimlanes', () => {
it('calls fetchEpicsSwimlanes action when loading more epics', async () => {
findLoadMoreEpicsButton().vm.$emit('click');
await wrapper.vm.$nextTick();
await nextTick();
expect(fetchEpicsSwimlanesSpy).toHaveBeenCalled();
});
......
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 GroupSelect from 'ee/boards/components/group_select.vue';
import defaultState from 'ee/boards/stores/state';
......@@ -101,7 +101,7 @@ describe('GroupSelect component', () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ initialLoading: true });
await wrapper.vm.$nextTick();
await nextTick();
expect(findGlDropdownLoadingIcon().exists()).toBe(true);
});
......
import { GlToggle } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import ToggleLabels from 'ee/boards/components/toggle_labels.vue';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
......@@ -40,7 +40,7 @@ describe('ToggleLabels component', () => {
const localStorageSync = wrapper.findComponent(LocalStorageSync);
localStorageSync.vm.$emit('input', '');
await wrapper.vm.$nextTick();
await nextTick();
expect(setShowLabels).toHaveBeenCalledWith(expect.any(Object), false);
});
......
......@@ -2,6 +2,7 @@ import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
import BurnCharts from 'ee/burndown_chart/components/burn_charts.vue';
import BurndownChart from 'ee/burndown_chart/components/burndown_chart.vue';
import BurnupChart from 'ee/burndown_chart/components/burnup_chart.vue';
......@@ -105,7 +106,7 @@ describe('burndown_chart', () => {
findWeightButton().vm.$emit('click');
await wrapper.vm.$nextTick();
await nextTick();
expect(findActiveButtons()).toHaveLength(1);
expect(findActiveButtons().at(0).text()).toBe('Issue weight');
......@@ -130,7 +131,7 @@ describe('burndown_chart', () => {
findWeightButton().vm.$emit('click');
await wrapper.vm.$nextTick();
await nextTick();
expect(findBurnupChart().props('issuesSelected')).toBe(false);
});
......
......@@ -2,6 +2,7 @@ import { GlTabs, GlTab } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Cookies from 'js-cookie';
import { nextTick } from 'vue';
import ComplianceDashboard from 'ee/compliance_dashboard/components/dashboard.vue';
import MergeRequestDrawer from 'ee/compliance_dashboard/components/drawer.vue';
import MergeRequestGrid from 'ee/compliance_dashboard/components/merge_requests/grid.vue';
......@@ -103,12 +104,11 @@ describe('ComplianceDashboard component', () => {
wrapper = createComponent({ mergeCommitsCsvExportPath: '' });
});
it('does not render the merge commit export button', () => {
return wrapper.vm.$nextTick().then(() => {
it('does not render the merge commit export button', async () => {
await nextTick();
expect(findMergeCommitsExportButton().exists()).toBe(false);
});
});
});
describe('with the merge request drawer', () => {
beforeEach(() => {
......
import { GlPopover } from '@gitlab/ui';
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
import { mount, shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import {
POPOVER,
TRACKING_PROPERTY_WHEN_FORCED,
......@@ -172,7 +172,7 @@ describe('TrialStatusPopover component', () => {
describe('when clicked', () => {
beforeEach(async () => {
wrapper.findByTestId('closeBtn').trigger('click');
await wrapper.vm.$nextTick();
await nextTick();
});
it('closes the popover component', () => {
......@@ -211,7 +211,7 @@ describe('TrialStatusPopover component', () => {
jest.spyOn(GlBreakpointInstance, 'getBreakpointSize').mockReturnValue(bp);
wrapper.vm.onResize();
await wrapper.vm.$nextTick();
await nextTick();
expect(findGlPopover().attributes('disabled')).toBe(isDisabled);
},
......
import { GlEmptyState, GlLoadingIcon, GlLink } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DependenciesApp from 'ee/dependencies/components/app.vue';
import DependenciesActions from 'ee/dependencies/components/dependencies_actions.vue';
import DependencyListIncompleteAlert from 'ee/dependencies/components/dependency_list_incomplete_alert.vue';
......@@ -180,10 +181,10 @@ describe('DependenciesApp component', () => {
});
describe('given the dependency list job has not yet run', () => {
beforeEach(() => {
beforeEach(async () => {
setStateJobNotRun();
return wrapper.vm.$nextTick();
await nextTick();
});
it('shows only the empty state', () => {
......@@ -197,10 +198,10 @@ describe('DependenciesApp component', () => {
});
describe('given a list of dependencies and ok report', () => {
beforeEach(() => {
beforeEach(async () => {
setStateLoaded();
return wrapper.vm.$nextTick();
await nextTick();
});
it('shows the dependencies table with the correct props', () => {
......@@ -231,11 +232,11 @@ describe('DependenciesApp component', () => {
});
describe('given the user has public permissions', () => {
beforeEach(() => {
beforeEach(async () => {
store.state[allNamespace].reportInfo.generatedAt = '';
store.state[allNamespace].reportInfo.jobPath = '';
return wrapper.vm.$nextTick();
await nextTick();
});
it('shows the header', () => {
......@@ -253,10 +254,10 @@ describe('DependenciesApp component', () => {
});
describe('given the dependency list job failed', () => {
beforeEach(() => {
beforeEach(async () => {
setStateJobFailed();
return wrapper.vm.$nextTick();
await nextTick();
});
it('passes the correct props to the job failure alert', () => {
......@@ -268,10 +269,10 @@ describe('DependenciesApp component', () => {
it('shows the dependencies table with the correct props', expectDependenciesTable);
describe('when the job failure alert emits the dismiss event', () => {
beforeEach(() => {
beforeEach(async () => {
const alertWrapper = findJobFailedAlert();
alertWrapper.vm.$emit('dismiss');
return wrapper.vm.$nextTick();
await nextTick();
});
it('does not render the job failure alert', () => {
......@@ -281,10 +282,10 @@ describe('DependenciesApp component', () => {
});
describe('given a dependency list which is known to be incomplete', () => {
beforeEach(() => {
beforeEach(async () => {
setStateListIncomplete();
return wrapper.vm.$nextTick();
await nextTick();
});
it('passes the correct props to the incomplete-list alert', () => {
......@@ -294,10 +295,10 @@ describe('DependenciesApp component', () => {
it('shows the dependencies table with the correct props', expectDependenciesTable);
describe('when the incomplete-list alert emits the dismiss event', () => {
beforeEach(() => {
beforeEach(async () => {
const alertWrapper = findIncompleteListAlert();
alertWrapper.vm.$emit('dismiss');
return wrapper.vm.$nextTick();
await nextTick();
});
it('does not render the incomplete-list alert', () => {
......
import { GlSorting, GlSortingItem } from '@gitlab/ui';
import { nextTick } from 'vue';
import DependenciesActions from 'ee/dependencies/components/dependencies_actions.vue';
import createStore from 'ee/dependencies/store';
import { DEPENDENCY_LIST_TYPES } from 'ee/dependencies/store/constants';
......@@ -28,12 +29,12 @@ describe('DependenciesActions component', () => {
const findExportButton = () => wrapper.findByTestId('export');
const findSorting = () => wrapper.findComponent(GlSorting);
beforeEach(() => {
beforeEach(async () => {
factory({
propsData: { namespace },
});
store.state[namespace].endpoint = `${TEST_HOST}/dependencies.json`;
return wrapper.vm.$nextTick();
await nextTick();
});
afterEach(() => {
......
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DependenciesTable from 'ee/dependencies/components/dependencies_table.vue';
import PaginatedDependenciesTable from 'ee/dependencies/components/paginated_dependencies_table.vue';
import createStore from 'ee/dependencies/store';
......@@ -26,7 +27,7 @@ describe('PaginatedDependenciesTable component', () => {
expect(componentWrapper.props()).toEqual(expect.objectContaining(props));
};
beforeEach(() => {
beforeEach(async () => {
factory({ namespace });
const originalDispatch = store.dispatch;
......@@ -36,7 +37,7 @@ describe('PaginatedDependenciesTable component', () => {
headers: { 'X-Total': mockDependenciesResponse.dependencies.length },
});
return wrapper.vm.$nextTick();
await nextTick();
});
afterEach(() => {
......@@ -72,7 +73,7 @@ describe('PaginatedDependenciesTable component', () => {
`('given $context', ({ isLoading, errorLoading, isListEmpty }) => {
let module;
beforeEach(() => {
beforeEach(async () => {
module = store.state[namespace];
if (isListEmpty) {
module.dependencies = [];
......@@ -82,7 +83,7 @@ describe('PaginatedDependenciesTable component', () => {
module.isLoading = isLoading;
module.errorLoading = errorLoading;
return wrapper.vm.$nextTick();
await nextTick();
});
// See https://github.com/jest-community/eslint-plugin-jest/issues/229 for
......
import { GlSprintf } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
import lastWeekData from 'test_fixtures/api/dora/metrics/daily_lead_time_for_changes_for_last_week.json';
import lastMonthData from 'test_fixtures/api/dora/metrics/daily_lead_time_for_changes_for_last_month.json';
import last90DaysData from 'test_fixtures/api/dora/metrics/daily_lead_time_for_changes_for_last_90_days.json';
......@@ -109,7 +110,7 @@ describe('lead_time_charts.vue', () => {
const formatTooltipText = findCiCdAnalyticsCharts().vm.$attrs['format-tooltip-text'];
formatTooltipText(params);
await wrapper.vm.$nextTick();
await nextTick();
expect(getTooltipValue()).toBe('1.5 hours');
});
......
import { mount, shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import EnvironmentAlert from 'ee/environments/components/environment_alert.vue';
import EnvironmentTable from '~/environments/components/environments_table.vue';
......@@ -13,7 +14,7 @@ describe('Environment table', () => {
wrapper = m(EnvironmentTable, {
...options,
});
await wrapper.vm.$nextTick();
await nextTick();
await jest.runOnlyPendingTimers();
};
......
......@@ -147,9 +147,9 @@ describe('dashboard', () => {
});
describe('project selector modal', () => {
beforeEach(() => {
beforeEach(async () => {
wrapper.findComponent(GlButton).trigger('click');
return nextTick();
await nextTick();
});
it('should fire the add projects action on ok', () => {
......@@ -198,7 +198,7 @@ describe('dashboard', () => {
store.state.projectsPage.pageInfo.totalPages = totalPages;
const shouldRenderPagination = totalPages > 1;
await wrapper.vm.$nextTick();
await nextTick();
expect(findPagination().exists()).toBe(shouldRenderPagination);
};
......
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import component from 'ee/environments_dashboard/components/dashboard/project_header.vue';
import ProjectAvatar from '~/vue_shared/components/deprecated_project_avatar/default.vue';
......@@ -72,16 +73,15 @@ describe('Project Header', () => {
expect(removeLink.exists()).toBe(true);
});
it('should emit a "remove" event when "remove" is clicked', () => {
it('should emit a "remove" event when "remove" is clicked', async () => {
const removeLink = wrapper
.findComponent(GlDropdown)
.findAllComponents(GlDropdownItem)
.filter((w) => w.text() === 'Remove');
removeLink.at(0).vm.$emit('click');
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(wrapper.emitted('remove')).toContainEqual([propsData.project.remove_path]);
});
});
});
});
import { GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import EpicHeader from 'ee/epic/components/epic_header.vue';
import { statusType } from 'ee/epic/constants';
import createStore from 'ee/epic/store';
......@@ -47,14 +48,13 @@ describe('EpicHeaderComponent', () => {
expect(findStatusIcon().props('name')).toBe('issue-open-m');
});
it('returns string `mobile-issue-close` when `isEpicOpen` is false', () => {
it('returns string `mobile-issue-close` when `isEpicOpen` is false', async () => {
store.state.state = statusType.close;
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(findStatusIcon().props('name')).toBe('mobile-issue-close');
});
});
});
describe('statusText', () => {
it('returns string `Open` when `isEpicOpen` is true', () => {
......@@ -63,14 +63,13 @@ describe('EpicHeaderComponent', () => {
expect(findStatusText().text()).toBe('Open');
});
it('returns string `Closed` when `isEpicOpen` is false', () => {
it('returns string `Closed` when `isEpicOpen` is false', async () => {
store.state.state = statusType.close;
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(findStatusText().text()).toBe('Closed');
});
});
});
describe('actionButtonClass', () => {
it('returns `btn-close` when `isEpicOpen` is true', () => {
......@@ -79,14 +78,13 @@ describe('EpicHeaderComponent', () => {
expect(findToggleStatusButton().classes()).toContain('btn-close');
});
it('returns `btn-open` when `isEpicOpen` is false', () => {
it('returns `btn-open` when `isEpicOpen` is false', async () => {
store.state.state = statusType.close;
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(findToggleStatusButton().classes()).toContain('btn-open');
});
});
});
describe('actionButtonText', () => {
it('returns string `Close epic` when `isEpicOpen` is true', () => {
......@@ -95,15 +93,14 @@ describe('EpicHeaderComponent', () => {
expect(findToggleStatusButton().text()).toBe('Close epic');
});
it('returns string `Reopen epic` when `isEpicOpen` is false', () => {
it('returns string `Reopen epic` when `isEpicOpen` is false', async () => {
store.state.state = statusType.close;
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(findToggleStatusButton().text()).toBe('Reopen epic');
});
});
});
});
describe('template', () => {
it('renders component container element with class `detail-page-header`', () => {
......@@ -119,16 +116,15 @@ describe('EpicHeaderComponent', () => {
expect(statusBox.find('span').text()).toBe('Open');
});
it('renders confidential icon when `confidential` prop is true', () => {
it('renders confidential icon when `confidential` prop is true', async () => {
store.state.confidential = true;
return wrapper.vm.$nextTick(() => {
await nextTick();
const confidentialIcon = findConfidentialIcon();
expect(confidentialIcon.exists()).toBe(true);
expect(confidentialIcon.props('name')).toBe('eye-slash');
});
});
it('renders epic author details element', () => {
const epicDetails = findAuthorDetails();
......@@ -157,29 +153,26 @@ describe('EpicHeaderComponent', () => {
);
});
it('renders GitLab team member badge when `author.isGitlabEmployee` is `true`', () => {
it('renders GitLab team member badge when `author.isGitlabEmployee` is `true`', async () => {
store.state.author.isGitlabEmployee = true;
// Wait for dynamic imports to resolve
return new Promise(setImmediate).then(() => {
await new Promise(setImmediate);
expect(wrapper.vm.$refs.gitlabTeamMemberBadge).not.toBeUndefined();
});
});
it('does not render new epic button if user cannot create it', () => {
it('does not render new epic button if user cannot create it', async () => {
store.state.canCreate = false;
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(findNewEpicButton().exists()).toBe(false);
});
});
it('renders new epic button if user can create it', () => {
it('renders new epic button if user can create it', async () => {
store.state.canCreate = true;
return wrapper.vm.$nextTick().then(() => {
await nextTick();
expect(findNewEpicButton().exists()).toBe(true);
});
});
});
});
import { GlForm, GlFormGroup } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import EpicsListBulkEditSidebar from 'ee/epics_list/components/epics_list_bulk_edit_sidebar.vue';
import { mockFormattedEpic, mockFormattedEpic2 } from 'ee_jest/roadmap/mock_data';
import {
......@@ -73,13 +74,13 @@ describe('EpicsListBulkEditSidebar', () => {
// 2 labels (as last 2 elements) that epics have present.
findLabelsSelect().vm.$emit('updateSelectedLabels', mockLabels.slice(0, 2));
await wrapper.vm.$nextTick();
await nextTick();
wrapper.findComponent(GlForm).vm.$emit('submit', {
preventDefault: jest.fn(),
});
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.emitted('bulk-update')).toBeDefined();
expect(wrapper.emitted('bulk-update')[0]).toEqual([
......
import { GlEmptyState } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import EpicsListEmptyState from 'ee/epics_list/components/epics_list_empty_state.vue';
const createComponent = (props = {}) =>
......@@ -47,7 +48,7 @@ describe('EpicsListEmptyState', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.find('h1').text()).toBe('There are no open epics');
});
......@@ -62,7 +63,7 @@ describe('EpicsListEmptyState', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.find('h1').text()).toBe('There are no closed epics');
});
......@@ -82,7 +83,7 @@ describe('EpicsListEmptyState', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.find('p').exists()).toBe(true);
expect(wrapper.find('p').text()).toContain(
......@@ -99,7 +100,7 @@ describe('EpicsListEmptyState', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.find('p').exists()).toBe(false);
});
......
import { shallowMount } from '@vue/test-utils';
import { pick } from 'lodash';
import { nextTick } from 'vue';
import EpicsListRoot from 'ee/epics_list/components/epics_list_root.vue';
import { EpicsSortOptions } from 'ee/epics_list/constants';
import { mockFormattedEpic } from 'ee_jest/roadmap/mock_data';
......@@ -161,7 +162,7 @@ describe('EpicsListRoot', () => {
});
wrapper.vm.fetchEpicsBy('currentPage', 2);
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.vm.prevPageCursor).toBe('');
expect(wrapper.vm.nextPageCursor).toBe(mockPageInfo.endCursor);
......@@ -183,7 +184,7 @@ describe('EpicsListRoot', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
expect(getIssuableList().exists()).toBe(true);
expect(getIssuableList().props()).toMatchObject({
......@@ -227,7 +228,7 @@ describe('EpicsListRoot', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
expect(getIssuableList().props('showPaginationControls')).toBe(returnValue);
},
......@@ -240,7 +241,7 @@ describe('EpicsListRoot', () => {
currentPage: 3,
});
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.vm.previousPage).toBe(2);
});
......@@ -257,7 +258,7 @@ describe('EpicsListRoot', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
expect(getIssuableList().props('nextPage')).toBe(2);
});
......@@ -274,7 +275,7 @@ describe('EpicsListRoot', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
expect(getIssuableList().props('nextPage')).toBeNull();
});
......
......@@ -104,7 +104,7 @@ describe('AddEscalationPolicyForm', () => {
};
createComponent({ props: { form: { rules: [ruleBeforeUpdate] } } });
await wrapper.vm.$nextTick();
await nextTick();
const updatedRule = {
status: 'TRIGGERED',
elapsedTimeMinutes: 3,
......
import { GlModal, GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { cloneDeep } from 'lodash';
import { nextTick } from 'vue';
import AddEscalationPolicyForm from 'ee/escalation_policies/components/add_edit_escalation_policy_form.vue';
import AddEscalationPolicyModal, {
i18n,
......@@ -111,7 +112,7 @@ describe('AddEditsEscalationPolicyModal', () => {
it('clears the form on modal cancel', async () => {
updateForm();
await wrapper.vm.$nextTick();
await nextTick();
expect(findEscalationPolicyForm().props('form')).toMatchObject({
name: updatedName,
description: updatedDescription,
......@@ -119,7 +120,7 @@ describe('AddEditsEscalationPolicyModal', () => {
});
findModal().vm.$emit('canceled', { preventDefault: jest.fn() });
await wrapper.vm.$nextTick();
await nextTick();
expect(findEscalationPolicyForm().props('form')).toMatchObject({
name: '',
description: '',
......@@ -136,11 +137,11 @@ describe('AddEditsEscalationPolicyModal', () => {
field: 'name',
value: '',
});
await wrapper.vm.$nextTick();
await nextTick();
expect(getNameValidationState()).toBe(false);
findModal().vm.$emit('canceled', { preventDefault: jest.fn() });
await wrapper.vm.$nextTick();
await nextTick();
expect(getNameValidationState()).toBe(null);
});
});
......@@ -182,7 +183,7 @@ describe('AddEditsEscalationPolicyModal', () => {
it('clears the form on modal cancel', async () => {
updateForm();
await wrapper.vm.$nextTick();
await nextTick();
const getForm = () => findEscalationPolicyForm().props('form');
expect(getForm()).toMatchObject({
name: updatedName,
......@@ -193,7 +194,7 @@ describe('AddEditsEscalationPolicyModal', () => {
findModal().vm.$emit('canceled', { preventDefault: jest.fn() });
const { name, description, rules } = mockEscalationPolicy;
await wrapper.vm.$nextTick();
await nextTick();
expect(getForm()).toMatchObject({
name,
......@@ -213,11 +214,11 @@ describe('AddEditsEscalationPolicyModal', () => {
field: 'name',
value: '',
});
await wrapper.vm.$nextTick();
await nextTick();
expect(getNameValidationState()).toBe(false);
findModal().vm.$emit('canceled', { preventDefault: jest.fn() });
await wrapper.vm.$nextTick();
await nextTick();
expect(getNameValidationState()).toBe(null);
});
});
......@@ -256,7 +257,7 @@ describe('AddEditsEscalationPolicyModal', () => {
field: 'name',
value: '',
});
await wrapper.vm.$nextTick();
await nextTick();
expect(findModal().props('actionPrimary').attributes).toContainEqual({ disabled: true });
});
......@@ -277,7 +278,7 @@ describe('AddEditsEscalationPolicyModal', () => {
},
],
});
await wrapper.vm.$nextTick();
await nextTick();
expect(findModal().props('actionPrimary').attributes).toContainEqual({ disabled: false });
});
});
......
import { GlModal, GlAlert, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import { cloneDeep } from 'lodash';
import VueApollo from 'vue-apollo';
import DeleteEscalationPolicyModal, {
......@@ -158,7 +158,7 @@ describe('DeleteEscalationPolicyModal', () => {
createComponentWithApollo();
await jest.runOnlyPendingTimers();
await wrapper.vm.$nextTick();
await nextTick();
expect(findModal().text()).toContain(cachedPolicy.name);
});
......
import { GlTokenSelector, GlAvatar, GlToken } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import UserSelect from 'ee/escalation_policies/components/user_select.vue';
const mockUsers = [
......@@ -64,14 +65,14 @@ describe('UserSelect', () => {
const tokenSelector = findTokenSelector();
expect(tokenSelector.exists()).toBe(true);
tokenSelector.vm.$emit('input', [mockUsers[0]]);
await wrapper.vm.$nextTick();
await nextTick();
expect(tokenSelector.exists()).toBe(false);
});
it('shows selected user token with name and avatar', async () => {
const selectedUser = mockUsers[0];
findTokenSelector().vm.$emit('input', [selectedUser]);
await wrapper.vm.$nextTick();
await nextTick();
const userToken = findSelectedUserToken();
expect(userToken.exists()).toBe(true);
expect(userToken.text()).toMatchInterpolatedText(selectedUser.name);
......@@ -84,12 +85,12 @@ describe('UserSelect', () => {
it('hides selected user token and avatar, shows token selector', async () => {
// select user
findTokenSelector().vm.$emit('input', [mockUsers[0]]);
await wrapper.vm.$nextTick();
await nextTick();
const userToken = findSelectedUserToken();
expect(userToken.exists()).toBe(true);
// deselect user
userToken.vm.$emit('close');
await wrapper.vm.$nextTick();
await nextTick();
expect(userToken.exists()).toBe(false);
expect(findTokenSelector().exists()).toBe(true);
});
......
import { GlEmptyState, GlSprintf, GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import ExternalIssuesListEmptyState from 'ee/external_issues_list/components/external_issues_list_empty_state.vue';
import { externalIssuesListEmptyStateI18n } from 'ee/external_issues_list/constants';
import { IssuableStates } from '~/vue_shared/issuable/list/constants';
......@@ -50,7 +51,7 @@ describe('ExternalIssuesListEmptyState', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.vm.hasIssues).toBe(true);
});
......@@ -62,7 +63,7 @@ describe('ExternalIssuesListEmptyState', () => {
hasFiltersApplied: true,
});
await wrapper.vm.$nextTick();
await nextTick();
expect(findEmptyState().props('title')).toBe(
externalIssuesListEmptyStateI18n.titleWhenFilters,
......@@ -78,7 +79,7 @@ describe('ExternalIssuesListEmptyState', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
expect(findEmptyState().props('title')).toBe(
externalIssuesListEmptyStateI18n.filterStateEmptyMessage[IssuableStates.Opened],
......@@ -90,7 +91,7 @@ describe('ExternalIssuesListEmptyState', () => {
hasFiltersApplied: false,
});
await wrapper.vm.$nextTick();
await nextTick();
expect(findEmptyState().props('title')).toBe(mockProvide.emptyStateNoIssueText);
});
......@@ -102,7 +103,7 @@ describe('ExternalIssuesListEmptyState', () => {
hasFiltersApplied: true,
});
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.vm.emptyStateDescription).toBe(
externalIssuesListEmptyStateI18n.descriptionWhenFilters,
......@@ -114,7 +115,7 @@ describe('ExternalIssuesListEmptyState', () => {
hasFiltersApplied: false,
});
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.vm.emptyStateDescription).toBe(
externalIssuesListEmptyStateI18n.descriptionWhenNoIssues,
......@@ -130,7 +131,7 @@ describe('ExternalIssuesListEmptyState', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
expect(wrapper.vm.emptyStateDescription).toBe('');
});
......@@ -154,7 +155,7 @@ describe('ExternalIssuesListEmptyState', () => {
hasFiltersApplied: true,
});
await wrapper.vm.$nextTick();
await nextTick();
expect(emptyStateEl.props('title')).toBe(externalIssuesListEmptyStateI18n.titleWhenFilters);
......@@ -166,7 +167,7 @@ describe('ExternalIssuesListEmptyState', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
expect(emptyStateEl.props('title')).toBe(
externalIssuesListEmptyStateI18n.filterStateEmptyMessage[IssuableStates.Opened],
......@@ -190,7 +191,7 @@ describe('ExternalIssuesListEmptyState', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
const descriptionEl = wrapper.findComponent(GlSprintf);
......
import { GlAlert } from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
import { shallowMount, mount } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import MockAdapter from 'axios-mock-adapter';
import VueApollo from 'vue-apollo';
......@@ -106,7 +106,7 @@ describe('ExternalIssuesListRoot', () => {
jest.spyOn(axios, 'get').mockResolvedValue(new Promise(() => {}));
createComponent();
await wrapper.vm.$nextTick();
await nextTick();
const issuableList = findIssuableList();
expect(issuableList.props('issuablesLoading')).toBe(true);
......@@ -253,7 +253,7 @@ describe('ExternalIssuesListRoot', () => {
},
});
await wrapper.vm.$nextTick();
await nextTick();
expect(issuableList.props()).toMatchObject({
currentPage: mockPage,
previousPage: mockPage - 1,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment