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