Commit b957c387 authored by Natalia Tepluhina's avatar Natalia Tepluhina

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

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

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