diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-02-18 12:45:46 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-02-18 12:45:46 +0300 |
commit | a7b3560714b4d9cc4ab32dffcd1f74a284b93580 (patch) | |
tree | 7452bd5c3545c2fa67a28aa013835fb4fa071baf /spec/frontend/ide | |
parent | ee9173579ae56a3dbfe5afe9f9410c65bb327ca7 (diff) |
Add latest changes from gitlab-org/gitlab@14-8-stable-eev14.8.0-rc42
Diffstat (limited to 'spec/frontend/ide')
53 files changed, 551 insertions, 802 deletions
diff --git a/spec/frontend/ide/components/activity_bar_spec.js b/spec/frontend/ide/components/activity_bar_spec.js index 657817eb3d8..39fe2c7e723 100644 --- a/spec/frontend/ide/components/activity_bar_spec.js +++ b/spec/frontend/ide/components/activity_bar_spec.js @@ -1,4 +1,4 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; import ActivityBar from '~/ide/components/activity_bar.vue'; import { leftSidebarViews } from '~/ide/constants'; @@ -61,14 +61,11 @@ describe('IDE activity bar', () => { expect(vm.$el.querySelector('.js-ide-edit-mode').classList).toContain('active'); }); - it('sets commit item active', (done) => { + it('sets commit item active', async () => { vm.$store.state.currentActivityView = leftSidebarViews.commit.name; - vm.$nextTick(() => { - expect(vm.$el.querySelector('.js-ide-commit-mode').classList).toContain('active'); - - done(); - }); + await nextTick(); + expect(vm.$el.querySelector('.js-ide-commit-mode').classList).toContain('active'); }); }); diff --git a/spec/frontend/ide/components/branches/search_list_spec.js b/spec/frontend/ide/components/branches/search_list_spec.js index 0efa7af2c6c..b6e3274153a 100644 --- a/spec/frontend/ide/components/branches/search_list_spec.js +++ b/spec/frontend/ide/components/branches/search_list_spec.js @@ -1,13 +1,13 @@ import { GlLoadingIcon } from '@gitlab/ui'; -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import Item from '~/ide/components/branches/item.vue'; import List from '~/ide/components/branches/search_list.vue'; import { __ } from '~/locale'; import { branches } from '../../mock_data'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('IDE branches search list', () => { let wrapper; @@ -31,7 +31,6 @@ describe('IDE branches search list', () => { }); wrapper = shallowMount(List, { - localVue, store: fakeStore, }); }; @@ -51,13 +50,12 @@ describe('IDE branches search list', () => { expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); }); - it('renders branches not found when search is not empty and branches list is empty', () => { + it('renders branches not found when search is not empty and branches list is empty', async () => { createComponent({ branches: [] }); wrapper.find('input[type="search"]').setValue('something'); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.text()).toContain(__('No branches found')); - }); + await nextTick(); + expect(wrapper.text()).toContain(__('No branches found')); }); describe('with branches', () => { diff --git a/spec/frontend/ide/components/commit_sidebar/actions_spec.js b/spec/frontend/ide/components/commit_sidebar/actions_spec.js index ed9d11246ae..c9425f6c9cd 100644 --- a/spec/frontend/ide/components/commit_sidebar/actions_spec.js +++ b/spec/frontend/ide/components/commit_sidebar/actions_spec.js @@ -1,4 +1,4 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; import { projectData, branches } from 'jest/ide/mock_data'; import commitActions from '~/ide/components/commit_sidebar/actions.vue'; @@ -71,15 +71,12 @@ describe('IDE commit sidebar actions', () => { expect(findText()).toContain('Commit to main branch'); }); - it('hides merge request option when project merge requests are disabled', (done) => { + it('hides merge request option when project merge requests are disabled', async () => { createComponent({ hasMR: false }); - vm.$nextTick(() => { - expect(findRadios().length).toBe(2); - expect(findText()).not.toContain('Create a new branch and merge request'); - - done(); - }); + await nextTick(); + expect(findRadios().length).toBe(2); + expect(findText()).not.toContain('Create a new branch and merge request'); }); describe('currentBranchText', () => { @@ -105,22 +102,18 @@ describe('IDE commit sidebar actions', () => { expect(vm.$store.dispatch).not.toHaveBeenCalled(); }); - it('calls again after staged changes', (done) => { + it('calls again after staged changes', async () => { createComponent({ currentBranchId: null }); vm.$store.state.currentBranchId = 'main'; vm.$store.state.changedFiles.push({}); vm.$store.state.stagedFiles.push({}); - vm.$nextTick() - .then(() => { - expect(vm.$store.dispatch).toHaveBeenCalledWith( - ACTION_UPDATE_COMMIT_ACTION, - expect.anything(), - ); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(vm.$store.dispatch).toHaveBeenCalledWith( + ACTION_UPDATE_COMMIT_ACTION, + expect.anything(), + ); }); it.each` diff --git a/spec/frontend/ide/components/commit_sidebar/editor_header_spec.js b/spec/frontend/ide/components/commit_sidebar/editor_header_spec.js index 50635ffe894..6e4c66cb780 100644 --- a/spec/frontend/ide/components/commit_sidebar/editor_header_spec.js +++ b/spec/frontend/ide/components/commit_sidebar/editor_header_spec.js @@ -1,11 +1,11 @@ -import { mount, createLocalVue } from '@vue/test-utils'; +import { mount } from '@vue/test-utils'; +import Vue from 'vue'; import Vuex from 'vuex'; import EditorHeader from '~/ide/components/commit_sidebar/editor_header.vue'; import { createStore } from '~/ide/stores'; import { file } from '../../helpers'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); const TEST_FILE_PATH = 'test/file/path'; @@ -16,7 +16,6 @@ describe('IDE commit editor header', () => { const createComponent = (fileProps = {}) => { wrapper = mount(EditorHeader, { store, - localVue, propsData: { activeFile: { ...file(TEST_FILE_PATH), diff --git a/spec/frontend/ide/components/commit_sidebar/form_spec.js b/spec/frontend/ide/components/commit_sidebar/form_spec.js index 83d1bbb842e..d3b2923ac6c 100644 --- a/spec/frontend/ide/components/commit_sidebar/form_spec.js +++ b/spec/frontend/ide/components/commit_sidebar/form_spec.js @@ -1,6 +1,6 @@ import { GlModal } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import { stubComponent } from 'helpers/stub_component'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import waitForPromises from 'helpers/wait_for_promises'; @@ -56,7 +56,6 @@ describe('IDE commit form', () => { disabled: findCommitButton().props('disabled'), tooltip: getBinding(findCommitButtonTooltip().element, 'gl-tooltip').value.title, }); - const clickCommitButton = () => findCommitButton().vm.$emit('click'); const findForm = () => wrapper.find('form'); const submitForm = () => findForm().trigger('submit'); const findCommitMessageInput = () => wrapper.find(CommitMessageField); @@ -98,7 +97,7 @@ describe('IDE commit form', () => { it(`at view=${viewFn.name}, ${buttonFn.name} has disabled=${disabled} tooltip=${tooltip}`, async () => { viewFn(); - await wrapper.vm.$nextTick(); + await nextTick(); expect(buttonFn()).toEqual({ disabled, @@ -116,7 +115,7 @@ describe('IDE commit form', () => { goToEditView(); - await wrapper.vm.$nextTick(); + await nextTick(); }); it('renders commit button in compact mode', () => { @@ -135,7 +134,7 @@ describe('IDE commit form', () => { it('when begin commit button is clicked, shows form', async () => { findBeginCommitButton().vm.$emit('click'); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findForm().exists()).toBe(true); }); @@ -143,7 +142,7 @@ describe('IDE commit form', () => { it('when begin commit button is clicked, sets activity view', async () => { findBeginCommitButton().vm.$emit('click'); - await wrapper.vm.$nextTick(); + await nextTick(); expect(store.state.currentActivityView).toBe(leftSidebarViews.commit.name); }); @@ -153,14 +152,14 @@ describe('IDE commit form', () => { setLastCommitMessage('test'); goToEditView(); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findForm().exists()).toBe(true); // Now test that it collapses when lastCommitMsg is cleared setLastCommitMessage(''); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findForm().exists()).toBe(false); }); @@ -177,7 +176,7 @@ describe('IDE commit form', () => { goToCommitView(); - await wrapper.vm.$nextTick(); + await nextTick(); }); afterEach(() => { @@ -188,12 +187,12 @@ describe('IDE commit form', () => { expect(findForm().exists()).toBe(false); store.state.stagedFiles = []; - await wrapper.vm.$nextTick(); + await nextTick(); expect(findForm().exists()).toBe(false); store.state.stagedFiles.push('test'); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findForm().exists()).toBe(false); }); @@ -208,7 +207,7 @@ describe('IDE commit form', () => { goToCommitView(); - await wrapper.vm.$nextTick(); + await nextTick(); }); it('shows form', () => { @@ -222,7 +221,7 @@ describe('IDE commit form', () => { describe('when no changed files', () => { beforeEach(async () => { store.state.stagedFiles = []; - await wrapper.vm.$nextTick(); + await nextTick(); }); it('hides form', () => { @@ -231,7 +230,7 @@ describe('IDE commit form', () => { it('expands again when staged files are added', async () => { store.state.stagedFiles.push('test'); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findForm().exists()).toBe(true); }); @@ -240,7 +239,7 @@ describe('IDE commit form', () => { it('updates commitMessage in store on input', async () => { setCommitMessageInput('testing commit message'); - await wrapper.vm.$nextTick(); + await nextTick(); expect(store.state.commit.commitMessage).toBe('testing commit message'); }); @@ -253,14 +252,14 @@ describe('IDE commit form', () => { it('resets commitMessage when clicking discard button', async () => { setCommitMessageInput('testing commit message'); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findCommitMessageInput().props('text')).toBe('testing commit message'); // Test that commitMessage is cleared on click findDiscardDraftButton().vm.$emit('click'); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findCommitMessageInput().props('text')).toBe(''); }); @@ -274,24 +273,24 @@ describe('IDE commit form', () => { goToCommitView(); - await wrapper.vm.$nextTick(); + await nextTick(); setCommitMessageInput('testing commit message'); - await wrapper.vm.$nextTick(); + await nextTick(); jest.spyOn(store, 'dispatch').mockResolvedValue(); }); - it.each([clickCommitButton, submitForm])('when %p, commits changes', (fn) => { - fn(); + it('when submitting form, commits changes', () => { + submitForm(); expect(store.dispatch).toHaveBeenCalledWith('commit/commitChanges', undefined); }); it('when cannot push code, submitting does nothing', async () => { store.state.projects.abcproject.userPermissions.pushCode = false; - await wrapper.vm.$nextTick(); + await nextTick(); submitForm(); @@ -309,7 +308,7 @@ describe('IDE commit form', () => { const error = createError(); store.state.commit.commitError = error; - await wrapper.vm.$nextTick(); + await nextTick(); expect(modal.vm.show).toHaveBeenCalled(); expect(modal.props()).toMatchObject({ @@ -342,7 +341,7 @@ describe('IDE commit form', () => { async ({ commitError, expectedActions }) => { store.state.commit.commitError = commitError('test message'); - await wrapper.vm.$nextTick(); + await nextTick(); wrapper.find(GlModal).vm.$emit('ok'); diff --git a/spec/frontend/ide/components/commit_sidebar/list_item_spec.js b/spec/frontend/ide/components/commit_sidebar/list_item_spec.js index b91ee88e0d6..dea920ecb5e 100644 --- a/spec/frontend/ide/components/commit_sidebar/list_item_spec.js +++ b/spec/frontend/ide/components/commit_sidebar/list_item_spec.js @@ -1,5 +1,6 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import { trimText } from 'helpers/text_helper'; +import waitForPromises from 'helpers/wait_for_promises'; import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; import listItem from '~/ide/components/commit_sidebar/list_item.vue'; import { createRouter } from '~/ide/ide_router'; @@ -41,54 +42,42 @@ describe('Multi-file editor commit sidebar list item', () => { expect(findPathText()).toContain(f.path); }); - it('correctly renders renamed entries', (done) => { + it('correctly renders renamed entries', async () => { Vue.set(vm.file, 'prevName', 'Old name'); - vm.$nextTick() - .then(() => { - expect(findPathText()).toEqual(`Old name → ${f.name}`); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(findPathText()).toEqual(`Old name → ${f.name}`); }); - it('correctly renders entry, the name of which did not change after rename (as within a folder)', (done) => { + it('correctly renders entry, the name of which did not change after rename (as within a folder)', async () => { Vue.set(vm.file, 'prevName', f.name); - vm.$nextTick() - .then(() => { - expect(findPathText()).toEqual(f.name); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(findPathText()).toEqual(f.name); }); - it('opens a closed file in the editor when clicking the file path', (done) => { + it('opens a closed file in the editor when clicking the file path', async () => { jest.spyOn(vm, 'openPendingTab'); jest.spyOn(router, 'push').mockImplementation(() => {}); findPathEl.click(); - setImmediate(() => { - expect(vm.openPendingTab).toHaveBeenCalled(); - expect(router.push).toHaveBeenCalled(); + await nextTick(); - done(); - }); + expect(vm.openPendingTab).toHaveBeenCalled(); + expect(router.push).toHaveBeenCalled(); }); - it('calls updateViewer with diff when clicking file', (done) => { + it('calls updateViewer with diff when clicking file', async () => { jest.spyOn(vm, 'openFileInEditor'); jest.spyOn(vm, 'updateViewer'); jest.spyOn(router, 'push').mockImplementation(() => {}); findPathEl.click(); - setImmediate(() => { - expect(vm.updateViewer).toHaveBeenCalledWith('diff'); + await waitForPromises(); - done(); - }); + expect(vm.updateViewer).toHaveBeenCalledWith('diff'); }); describe('computed', () => { @@ -134,14 +123,11 @@ describe('Multi-file editor commit sidebar list item', () => { expect(vm.$el.querySelector('.is-active')).toBe(null); }); - it('adds active class when keys match', (done) => { + it('adds active class when keys match', async () => { vm.keyPrefix = 'staged'; - vm.$nextTick(() => { - expect(vm.$el.querySelector('.is-active')).not.toBe(null); - - done(); - }); + await nextTick(); + expect(vm.$el.querySelector('.is-active')).not.toBe(null); }); }); }); diff --git a/spec/frontend/ide/components/commit_sidebar/list_spec.js b/spec/frontend/ide/components/commit_sidebar/list_spec.js index eb12fc994a5..1d42512c9ee 100644 --- a/spec/frontend/ide/components/commit_sidebar/list_spec.js +++ b/spec/frontend/ide/components/commit_sidebar/list_spec.js @@ -1,4 +1,4 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; import commitSidebarList from '~/ide/components/commit_sidebar/list.vue'; import { createStore } from '~/ide/stores'; @@ -31,12 +31,11 @@ describe('Multi-file editor commit sidebar list', () => { }); describe('with a list of files', () => { - beforeEach((done) => { + beforeEach(async () => { const f = file('file name'); f.changed = true; vm.fileList.push(f); - - Vue.nextTick(done); + await nextTick(); }); it('renders list', () => { diff --git a/spec/frontend/ide/components/commit_sidebar/message_field_spec.js b/spec/frontend/ide/components/commit_sidebar/message_field_spec.js index 1514fbc2c3b..e66de6bb0b0 100644 --- a/spec/frontend/ide/components/commit_sidebar/message_field_spec.js +++ b/spec/frontend/ide/components/commit_sidebar/message_field_spec.js @@ -1,4 +1,4 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import createComponent from 'helpers/vue_mount_component_helper'; import CommitMessageField from '~/ide/components/commit_sidebar/message_field.vue'; @@ -23,34 +23,23 @@ describe('IDE commit message field', () => { vm.$destroy(); }); - it('adds is-focused class on focus', (done) => { + it('adds is-focused class on focus', async () => { vm.$el.querySelector('textarea').focus(); - vm.$nextTick(() => { - expect(vm.$el.querySelector('.is-focused')).not.toBeNull(); - - done(); - }); + await nextTick(); + expect(vm.$el.querySelector('.is-focused')).not.toBeNull(); }); - it('removed is-focused class on blur', (done) => { + it('removed is-focused class on blur', async () => { vm.$el.querySelector('textarea').focus(); - vm.$nextTick() - .then(() => { - expect(vm.$el.querySelector('.is-focused')).not.toBeNull(); - - vm.$el.querySelector('textarea').blur(); + await nextTick(); + expect(vm.$el.querySelector('.is-focused')).not.toBeNull(); - return vm.$nextTick(); - }) - .then(() => { - expect(vm.$el.querySelector('.is-focused')).toBeNull(); + vm.$el.querySelector('textarea').blur(); - done(); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(vm.$el.querySelector('.is-focused')).toBeNull(); }); it('emits input event on input', () => { @@ -66,105 +55,78 @@ describe('IDE commit message field', () => { describe('highlights', () => { describe('subject line', () => { - it('does not highlight less than 50 characters', (done) => { + it('does not highlight less than 50 characters', async () => { vm.text = 'text less than 50 chars'; - vm.$nextTick() - .then(() => { - expect(vm.$el.querySelector('.highlights span').textContent).toContain( - 'text less than 50 chars', - ); + await nextTick(); + expect(vm.$el.querySelector('.highlights span').textContent).toContain( + 'text less than 50 chars', + ); - expect(vm.$el.querySelector('mark').style.display).toBe('none'); - }) - .then(done) - .catch(done.fail); + expect(vm.$el.querySelector('mark').style.display).toBe('none'); }); - it('highlights characters over 50 length', (done) => { + it('highlights characters over 50 length', async () => { vm.text = 'text less than 50 chars that should not highlighted. text more than 50 should be highlighted'; - vm.$nextTick() - .then(() => { - expect(vm.$el.querySelector('.highlights span').textContent).toContain( - 'text less than 50 chars that should not highlighte', - ); - - expect(vm.$el.querySelector('mark').style.display).not.toBe('none'); - expect(vm.$el.querySelector('mark').textContent).toBe( - 'd. text more than 50 should be highlighted', - ); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(vm.$el.querySelector('.highlights span').textContent).toContain( + 'text less than 50 chars that should not highlighte', + ); + + expect(vm.$el.querySelector('mark').style.display).not.toBe('none'); + expect(vm.$el.querySelector('mark').textContent).toBe( + 'd. text more than 50 should be highlighted', + ); }); }); describe('body text', () => { - it('does not highlight body text less tan 72 characters', (done) => { + it('does not highlight body text less tan 72 characters', async () => { vm.text = 'subject line\nbody content'; - vm.$nextTick() - .then(() => { - expect(vm.$el.querySelectorAll('.highlights span').length).toBe(2); - expect(vm.$el.querySelectorAll('mark')[1].style.display).toBe('none'); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(vm.$el.querySelectorAll('.highlights span').length).toBe(2); + expect(vm.$el.querySelectorAll('mark')[1].style.display).toBe('none'); }); - it('highlights body text more than 72 characters', (done) => { + it('highlights body text more than 72 characters', async () => { vm.text = 'subject line\nbody content that will be highlighted when it is more than 72 characters in length'; - vm.$nextTick() - .then(() => { - expect(vm.$el.querySelectorAll('.highlights span').length).toBe(2); - expect(vm.$el.querySelectorAll('mark')[1].style.display).not.toBe('none'); - expect(vm.$el.querySelectorAll('mark')[1].textContent).toBe(' in length'); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(vm.$el.querySelectorAll('.highlights span').length).toBe(2); + expect(vm.$el.querySelectorAll('mark')[1].style.display).not.toBe('none'); + expect(vm.$el.querySelectorAll('mark')[1].textContent).toBe(' in length'); }); - it('highlights body text & subject line', (done) => { + it('highlights body text & subject line', async () => { vm.text = 'text less than 50 chars that should not highlighted\nbody content that will be highlighted when it is more than 72 characters in length'; - vm.$nextTick() - .then(() => { - expect(vm.$el.querySelectorAll('.highlights span').length).toBe(2); - expect(vm.$el.querySelectorAll('mark').length).toBe(2); + await nextTick(); + expect(vm.$el.querySelectorAll('.highlights span').length).toBe(2); + expect(vm.$el.querySelectorAll('mark').length).toBe(2); - expect(vm.$el.querySelectorAll('mark')[0].textContent).toContain('d'); - expect(vm.$el.querySelectorAll('mark')[1].textContent).toBe(' in length'); - }) - .then(done) - .catch(done.fail); + expect(vm.$el.querySelectorAll('mark')[0].textContent).toContain('d'); + expect(vm.$el.querySelectorAll('mark')[1].textContent).toBe(' in length'); }); }); }); describe('scrolling textarea', () => { - it('updates transform of highlights', (done) => { + it('updates transform of highlights', async () => { vm.text = 'subject line\n\n\n\n\n\n\n\n\n\n\nbody content'; - vm.$nextTick() - .then(() => { - vm.$el.querySelector('textarea').scrollTo(0, 50); - - vm.handleScroll(); - }) - .then(vm.$nextTick) - .then(() => { - expect(vm.scrollTop).toBe(50); - expect(vm.$el.querySelector('.highlights').style.transform).toBe( - 'translate3d(0, -50px, 0)', - ); - }) - .then(done) - .catch(done.fail); + await nextTick(); + vm.$el.querySelector('textarea').scrollTo(0, 50); + + vm.handleScroll(); + + await nextTick(); + expect(vm.scrollTop).toBe(50); + expect(vm.$el.querySelector('.highlights').style.transform).toBe('translate3d(0, -50px, 0)'); }); }); }); diff --git a/spec/frontend/ide/components/commit_sidebar/new_merge_request_option_spec.js b/spec/frontend/ide/components/commit_sidebar/new_merge_request_option_spec.js index 4474647552d..64b53264b4d 100644 --- a/spec/frontend/ide/components/commit_sidebar/new_merge_request_option_spec.js +++ b/spec/frontend/ide/components/commit_sidebar/new_merge_request_option_spec.js @@ -1,4 +1,4 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; import { projectData, branches } from 'jest/ide/mock_data'; import NewMergeRequestOption from '~/ide/components/commit_sidebar/new_merge_request_option.vue'; @@ -72,15 +72,11 @@ describe('create new MR checkbox', () => { expect(vm.$el.textContent).not.toBe(''); }); - it('has new MR', (done) => { + it('has new MR', async () => { setMR(); - vm.$nextTick() - .then(() => { - expect(vm.$el.textContent).not.toBe(''); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(vm.$el.textContent).not.toBe(''); }); }); @@ -96,15 +92,11 @@ describe('create new MR checkbox', () => { expect(vm.$el.textContent).toBe(''); }); - it('has new MR', (done) => { + it('has new MR', async () => { setMR(); - vm.$nextTick() - .then(() => { - expect(vm.$el.textContent).toBe(''); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(vm.$el.textContent).toBe(''); }); }); }); @@ -121,15 +113,11 @@ describe('create new MR checkbox', () => { expect(vm.$el.textContent).not.toBe(''); }); - it('is rendered if MR exists', (done) => { + it('is rendered if MR exists', async () => { setMR(); - vm.$nextTick() - .then(() => { - expect(vm.$el.textContent).not.toBe(''); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(vm.$el.textContent).not.toBe(''); }); }); @@ -144,15 +132,11 @@ describe('create new MR checkbox', () => { expect(vm.$el.textContent).not.toBe(''); }); - it('is hidden if MR exists', (done) => { + it('is hidden if MR exists', async () => { setMR(); - vm.$nextTick() - .then(() => { - expect(vm.$el.textContent).toBe(''); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(vm.$el.textContent).toBe(''); }); }); }); @@ -168,15 +152,11 @@ describe('create new MR checkbox', () => { expect(vm.$el.textContent).not.toBe(''); }); - it('is hidden if MR exists', (done) => { + it('is hidden if MR exists', async () => { setMR(); - vm.$nextTick() - .then(() => { - expect(vm.$el.textContent).toBe(''); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(vm.$el.textContent).toBe(''); }); it('shows enablded checkbox', () => { diff --git a/spec/frontend/ide/components/commit_sidebar/radio_group_spec.js b/spec/frontend/ide/components/commit_sidebar/radio_group_spec.js index a6f3253321b..d899bc4f7d8 100644 --- a/spec/frontend/ide/components/commit_sidebar/radio_group_spec.js +++ b/spec/frontend/ide/components/commit_sidebar/radio_group_spec.js @@ -1,4 +1,4 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; import radioGroup from '~/ide/components/commit_sidebar/radio_group.vue'; import { createStore } from '~/ide/stores'; @@ -7,7 +7,7 @@ describe('IDE commit sidebar radio group', () => { let vm; let store; - beforeEach((done) => { + beforeEach(async () => { store = createStore(); const Component = Vue.extend(radioGroup); @@ -22,7 +22,7 @@ describe('IDE commit sidebar radio group', () => { vm.$mount(); - Vue.nextTick(done); + await nextTick(); }); afterEach(() => { @@ -33,7 +33,7 @@ describe('IDE commit sidebar radio group', () => { expect(vm.$el.textContent).toContain('test'); }); - it('uses slot if label is not present', (done) => { + it('uses slot if label is not present', async () => { vm.$destroy(); vm = new Vue({ @@ -47,25 +47,19 @@ describe('IDE commit sidebar radio group', () => { vm.$mount(); - Vue.nextTick(() => { - expect(vm.$el.textContent).toContain('Testing slot'); - - done(); - }); + await nextTick(); + expect(vm.$el.textContent).toContain('Testing slot'); }); - it('updates store when changing radio button', (done) => { + it('updates store when changing radio button', async () => { vm.$el.querySelector('input').dispatchEvent(new Event('change')); - Vue.nextTick(() => { - expect(store.state.commit.commitAction).toBe('1'); - - done(); - }); + await nextTick(); + expect(store.state.commit.commitAction).toBe('1'); }); describe('with input', () => { - beforeEach((done) => { + beforeEach(async () => { vm.$destroy(); const Component = Vue.extend(radioGroup); @@ -82,32 +76,27 @@ describe('IDE commit sidebar radio group', () => { vm.$mount(); - Vue.nextTick(done); + await nextTick(); }); it('renders input box when commitAction matches value', () => { expect(vm.$el.querySelector('.form-control')).not.toBeNull(); }); - it('hides input when commitAction doesnt match value', (done) => { + it('hides input when commitAction doesnt match value', async () => { store.state.commit.commitAction = '2'; - Vue.nextTick(() => { - expect(vm.$el.querySelector('.form-control')).toBeNull(); - done(); - }); + await nextTick(); + expect(vm.$el.querySelector('.form-control')).toBeNull(); }); - it('updates branch name in store on input', (done) => { + it('updates branch name in store on input', async () => { const input = vm.$el.querySelector('.form-control'); input.value = 'testing-123'; input.dispatchEvent(new Event('input')); - Vue.nextTick(() => { - expect(store.state.commit.newBranchName).toBe('testing-123'); - - done(); - }); + await nextTick(); + expect(store.state.commit.newBranchName).toBe('testing-123'); }); it('renders newBranchName if present', () => { diff --git a/spec/frontend/ide/components/commit_sidebar/success_message_spec.js b/spec/frontend/ide/components/commit_sidebar/success_message_spec.js index 7bbe47d37af..52e35bdbb73 100644 --- a/spec/frontend/ide/components/commit_sidebar/success_message_spec.js +++ b/spec/frontend/ide/components/commit_sidebar/success_message_spec.js @@ -1,4 +1,4 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; import successMessage from '~/ide/components/commit_sidebar/success_message.vue'; import { createStore } from '~/ide/stores'; @@ -23,13 +23,10 @@ describe('IDE commit panel successful commit state', () => { vm.$destroy(); }); - it('renders last commit message when it exists', (done) => { + it('renders last commit message when it exists', async () => { vm.$store.state.lastCommitMsg = 'testing commit message'; - Vue.nextTick(() => { - expect(vm.$el.textContent).toContain('testing commit message'); - - done(); - }); + await nextTick(); + expect(vm.$el.textContent).toContain('testing commit message'); }); }); diff --git a/spec/frontend/ide/components/error_message_spec.js b/spec/frontend/ide/components/error_message_spec.js index 2de3fa863a8..17568158131 100644 --- a/spec/frontend/ide/components/error_message_spec.js +++ b/spec/frontend/ide/components/error_message_spec.js @@ -1,10 +1,10 @@ import { GlLoadingIcon } from '@gitlab/ui'; -import { mount, createLocalVue } from '@vue/test-utils'; +import { mount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import ErrorMessage from '~/ide/components/error_message.vue'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('IDE error message component', () => { let wrapper; @@ -25,7 +25,6 @@ describe('IDE error message component', () => { }, }, store: fakeStore, - localVue, }); }; @@ -87,19 +86,15 @@ describe('IDE error message component', () => { expect(actionMock).toHaveBeenCalledWith(message.actionPayload); }); - it('does not dispatch action when already loading', () => { + it('does not dispatch action when already loading', async () => { findActionButton().trigger('click'); actionMock.mockReset(); - return wrapper.vm.$nextTick(() => { - findActionButton().trigger('click'); - - return wrapper.vm.$nextTick().then(() => { - expect(actionMock).not.toHaveBeenCalled(); - }); - }); + findActionButton().trigger('click'); + await nextTick(); + expect(actionMock).not.toHaveBeenCalled(); }); - it('shows loading icon when loading', () => { + it('shows loading icon when loading', async () => { let resolveAction; actionMock.mockImplementation( () => @@ -109,19 +104,16 @@ describe('IDE error message component', () => { ); findActionButton().trigger('click'); - return wrapper.vm.$nextTick(() => { - expect(wrapper.find(GlLoadingIcon).isVisible()).toBe(true); - resolveAction(); - }); + await nextTick(); + expect(wrapper.find(GlLoadingIcon).isVisible()).toBe(true); + resolveAction(); }); - it('hides loading icon when operation finishes', () => { + it('hides loading icon when operation finishes', async () => { findActionButton().trigger('click'); - return actionMock() - .then(() => wrapper.vm.$nextTick()) - .then(() => { - expect(wrapper.find(GlLoadingIcon).isVisible()).toBe(false); - }); + await actionMock(); + await nextTick(); + expect(wrapper.find(GlLoadingIcon).isVisible()).toBe(false); }); }); }); diff --git a/spec/frontend/ide/components/file_row_extra_spec.js b/spec/frontend/ide/components/file_row_extra_spec.js index 641407c7b77..5a7a1fe7db0 100644 --- a/spec/frontend/ide/components/file_row_extra_spec.js +++ b/spec/frontend/ide/components/file_row_extra_spec.js @@ -1,4 +1,4 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; import FileRowExtra from '~/ide/components/file_row_extra.vue'; import { createStore } from '~/ide/stores'; @@ -70,28 +70,22 @@ describe('IDE extra file row component', () => { expect(vm.$el.querySelector('.ide-tree-changes')).toBe(null); }); - it('does not show when tree is open', (done) => { + it('does not show when tree is open', async () => { vm.file.type = 'tree'; vm.file.opened = true; changesCount = 1; - vm.$nextTick(() => { - expect(vm.$el.querySelector('.ide-tree-changes')).toBe(null); - - done(); - }); + await nextTick(); + expect(vm.$el.querySelector('.ide-tree-changes')).toBe(null); }); - it('shows for trees with changes', (done) => { + it('shows for trees with changes', async () => { vm.file.type = 'tree'; vm.file.opened = false; changesCount = 1; - vm.$nextTick(() => { - expect(vm.$el.querySelector('.ide-tree-changes')).not.toBe(null); - - done(); - }); + await nextTick(); + expect(vm.$el.querySelector('.ide-tree-changes')).not.toBe(null); }); }); @@ -100,55 +94,40 @@ describe('IDE extra file row component', () => { expect(vm.$el.querySelector('.file-changed-icon')).toBe(null); }); - it('shows when file is changed', (done) => { + it('shows when file is changed', async () => { vm.file.changed = true; - vm.$nextTick(() => { - expect(vm.$el.querySelector('.file-changed-icon')).not.toBe(null); - - done(); - }); + await nextTick(); + expect(vm.$el.querySelector('.file-changed-icon')).not.toBe(null); }); - it('shows when file is staged', (done) => { + it('shows when file is staged', async () => { vm.file.staged = true; - vm.$nextTick(() => { - expect(vm.$el.querySelector('.file-changed-icon')).not.toBe(null); - - done(); - }); + await nextTick(); + expect(vm.$el.querySelector('.file-changed-icon')).not.toBe(null); }); - it('shows when file is a tempFile', (done) => { + it('shows when file is a tempFile', async () => { vm.file.tempFile = true; - vm.$nextTick(() => { - expect(vm.$el.querySelector('.file-changed-icon')).not.toBe(null); - - done(); - }); + await nextTick(); + expect(vm.$el.querySelector('.file-changed-icon')).not.toBe(null); }); - it('shows when file is renamed', (done) => { + it('shows when file is renamed', async () => { vm.file.prevPath = 'original-file'; - vm.$nextTick(() => { - expect(vm.$el.querySelector('.file-changed-icon')).not.toBe(null); - - done(); - }); + await nextTick(); + expect(vm.$el.querySelector('.file-changed-icon')).not.toBe(null); }); - it('hides when file is renamed', (done) => { + it('hides when file is renamed', async () => { vm.file.prevPath = 'original-file'; vm.file.type = 'tree'; - vm.$nextTick(() => { - expect(vm.$el.querySelector('.file-changed-icon')).toBe(null); - - done(); - }); + await nextTick(); + expect(vm.$el.querySelector('.file-changed-icon')).toBe(null); }); }); @@ -157,14 +136,11 @@ describe('IDE extra file row component', () => { expect(vm.$el.querySelector('[data-testid="git-merge-icon"]')).toBe(null); }); - it('shows when a merge request change', (done) => { + it('shows when a merge request change', async () => { vm.file.mrChange = true; - vm.$nextTick(() => { - expect(vm.$el.querySelector('[data-testid="git-merge-icon"]')).not.toBe(null); - - done(); - }); + await nextTick(); + expect(vm.$el.querySelector('[data-testid="git-merge-icon"]')).not.toBe(null); }); }); }); diff --git a/spec/frontend/ide/components/file_templates/bar_spec.js b/spec/frontend/ide/components/file_templates/bar_spec.js index 4ca99f8d055..e8ebfa78fe9 100644 --- a/spec/frontend/ide/components/file_templates/bar_spec.js +++ b/spec/frontend/ide/components/file_templates/bar_spec.js @@ -1,4 +1,4 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import { mountComponentWithStore } from 'helpers/vue_mount_component_helper'; import Bar from '~/ide/components/file_templates/bar.vue'; import { createStore } from '~/ide/stores'; @@ -46,7 +46,7 @@ describe('IDE file templates bar component', () => { }); describe('template dropdown', () => { - beforeEach((done) => { + beforeEach(async () => { vm.$store.state.fileTemplates.templates = [ { name: 'test', @@ -57,7 +57,7 @@ describe('IDE file templates bar component', () => { key: 'gitlab_ci_ymls', }; - vm.$nextTick(done); + await nextTick(); }); it('renders dropdown component', () => { @@ -75,14 +75,11 @@ describe('IDE file templates bar component', () => { }); }); - it('shows undo button if updateSuccess is true', (done) => { + it('shows undo button if updateSuccess is true', async () => { vm.$store.state.fileTemplates.updateSuccess = true; - vm.$nextTick(() => { - expect(vm.$el.querySelector('.btn-default').style.display).not.toBe('none'); - - done(); - }); + await nextTick(); + expect(vm.$el.querySelector('.btn-default').style.display).not.toBe('none'); }); it('calls undoFileTemplate when clicking undo button', () => { @@ -93,7 +90,7 @@ describe('IDE file templates bar component', () => { expect(vm.undoFileTemplate).toHaveBeenCalled(); }); - it('calls setSelectedTemplateType if activeFile name matches a template', (done) => { + it('calls setSelectedTemplateType if activeFile name matches a template', async () => { const fileName = '.gitlab-ci.yml'; jest.spyOn(vm, 'setSelectedTemplateType').mockImplementation(() => {}); @@ -101,13 +98,10 @@ describe('IDE file templates bar component', () => { vm.setInitialType(); - vm.$nextTick(() => { - expect(vm.setSelectedTemplateType).toHaveBeenCalledWith({ - name: fileName, - key: 'gitlab_ci_ymls', - }); - - done(); + await nextTick(); + expect(vm.setSelectedTemplateType).toHaveBeenCalledWith({ + name: fileName, + key: 'gitlab_ci_ymls', }); }); }); diff --git a/spec/frontend/ide/components/file_templates/dropdown_spec.js b/spec/frontend/ide/components/file_templates/dropdown_spec.js index 44ac9aa954d..e54b322b9db 100644 --- a/spec/frontend/ide/components/file_templates/dropdown_spec.js +++ b/spec/frontend/ide/components/file_templates/dropdown_spec.js @@ -1,11 +1,11 @@ import { GlLoadingIcon } from '@gitlab/ui'; -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; import $ from 'jquery'; import Vuex from 'vuex'; import Dropdown from '~/ide/components/file_templates/dropdown.vue'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('IDE file templates dropdown component', () => { let wrapper; @@ -44,7 +44,6 @@ describe('IDE file templates dropdown component', () => { ...props, }, store: fakeStore, - localVue, }); ({ element } = wrapper); @@ -55,15 +54,14 @@ describe('IDE file templates dropdown component', () => { wrapper = null; }); - it('calls clickItem on click', () => { + it('calls clickItem on click', async () => { const itemData = { name: 'test.yml ' }; createComponent({ props: { data: [itemData] } }); const item = findItemButtons().at(0); item.trigger('click'); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.emitted().click[0][0]).toBe(itemData); - }); + await nextTick(); + expect(wrapper.emitted().click[0][0]).toBe(itemData); }); it('renders dropdown title', () => { @@ -112,7 +110,7 @@ describe('IDE file templates dropdown component', () => { expect(items.wrappers.map((x) => x.text())).toEqual(templates.map((x) => x.name)); }); - it('searches template data', () => { + it('searches template data', async () => { const templates = [{ name: 'match 1' }, { name: 'other' }, { name: 'match 2' }]; const matches = ['match 1', 'match 2']; createComponent({ @@ -120,12 +118,11 @@ describe('IDE file templates dropdown component', () => { state: { templates }, }); findSearch().setValue('match'); - return wrapper.vm.$nextTick().then(() => { - const items = findItemButtons(); + await nextTick(); + const items = findItemButtons(); - expect(items.length).toBe(matches.length); - expect(items.wrappers.map((x) => x.text())).toEqual(matches); - }); + expect(items.length).toBe(matches.length); + expect(items.wrappers.map((x) => x.text())).toEqual(matches); }); it('does not render input when `searchable` is true & `showLoading` is true', () => { @@ -160,17 +157,16 @@ describe('IDE file templates dropdown component', () => { expect(findSearch().exists()).toBe(true); }); - it('searches data', () => { + it('searches data', async () => { const data = [{ name: 'match 1' }, { name: 'other' }, { name: 'match 2' }]; const matches = ['match 1', 'match 2']; createComponent({ props: { searchable: true, data } }); findSearch().setValue('match'); - return wrapper.vm.$nextTick().then(() => { - const items = findItemButtons(); + await nextTick(); + const items = findItemButtons(); - expect(items.length).toBe(matches.length); - expect(items.wrappers.map((x) => x.text())).toEqual(matches); - }); + expect(items.length).toBe(matches.length); + expect(items.wrappers.map((x) => x.text())).toEqual(matches); }); }); }); diff --git a/spec/frontend/ide/components/ide_file_row_spec.js b/spec/frontend/ide/components/ide_file_row_spec.js index 20c105460f2..baf3d7cca9d 100644 --- a/spec/frontend/ide/components/ide_file_row_spec.js +++ b/spec/frontend/ide/components/ide_file_row_spec.js @@ -1,12 +1,12 @@ -import { createLocalVue, mount } from '@vue/test-utils'; +import { mount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import FileRowExtra from '~/ide/components/file_row_extra.vue'; import IdeFileRow from '~/ide/components/ide_file_row.vue'; import { createStore } from '~/ide/stores'; import FileRow from '~/vue_shared/components/file_row.vue'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); const TEST_EXTRA_PROPS = { testattribute: 'abc', @@ -30,7 +30,6 @@ describe('Ide File Row component', () => { ...props, }, store: createStore(), - localVue, ...options, }); }; @@ -44,7 +43,7 @@ describe('Ide File Row component', () => { const findFileRow = () => wrapper.find(FileRow); const hasDropdownOpen = () => findFileRowExtra().props('dropdownOpen'); - it('fileRow component has listeners', () => { + it('fileRow component has listeners', async () => { const toggleTreeOpen = jest.fn(); createComponent( {}, @@ -57,9 +56,8 @@ describe('Ide File Row component', () => { findFileRow().vm.$emit('toggleTreeOpen'); - return wrapper.vm.$nextTick().then(() => { - expect(toggleTreeOpen).toHaveBeenCalled(); - }); + await nextTick(); + expect(toggleTreeOpen).toHaveBeenCalled(); }); describe('default', () => { @@ -86,32 +84,30 @@ describe('Ide File Row component', () => { }); describe('with open dropdown', () => { - beforeEach(() => { + beforeEach(async () => { createComponent(); findFileRowExtra().vm.$emit('toggle', true); - return wrapper.vm.$nextTick(); + await nextTick(); }); it('shows open dropdown', () => { expect(hasDropdownOpen()).toBe(true); }); - it('hides dropdown when mouseleave', () => { + it('hides dropdown when mouseleave', async () => { findFileRow().vm.$emit('mouseleave'); - return wrapper.vm.$nextTick().then(() => { - expect(hasDropdownOpen()).toEqual(false); - }); + await nextTick(); + expect(hasDropdownOpen()).toEqual(false); }); - it('hides dropdown on toggle', () => { + it('hides dropdown on toggle', async () => { findFileRowExtra().vm.$emit('toggle', false); - return wrapper.vm.$nextTick().then(() => { - expect(hasDropdownOpen()).toEqual(false); - }); + await nextTick(); + expect(hasDropdownOpen()).toEqual(false); }); }); }); diff --git a/spec/frontend/ide/components/ide_review_spec.js b/spec/frontend/ide/components/ide_review_spec.js index 7a92f59641f..13d20761263 100644 --- a/spec/frontend/ide/components/ide_review_spec.js +++ b/spec/frontend/ide/components/ide_review_spec.js @@ -1,5 +1,5 @@ -import { createLocalVue, mount } from '@vue/test-utils'; -import Vue from 'vue'; +import { mount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import { keepAlive } from 'helpers/keep_alive_component_helper'; import { trimText } from 'helpers/text_helper'; @@ -9,8 +9,7 @@ import { createStore } from '~/ide/stores'; import { file } from '../helpers'; import { projectData } from '../mock_data'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('IDE review mode', () => { let wrapper; @@ -28,7 +27,6 @@ describe('IDE review mode', () => { wrapper = mount(keepAlive(IdeReview), { store, - localVue, }); }); @@ -76,14 +74,14 @@ describe('IDE review mode', () => { }); describe('merge request', () => { - beforeEach(() => { + beforeEach(async () => { store.state.currentMergeRequestId = '1'; store.state.projects.abcproject.mergeRequests['1'] = { iid: 123, web_url: 'testing123', }; - return wrapper.vm.$nextTick(); + await nextTick(); }); it('renders edit dropdown', () => { @@ -93,7 +91,7 @@ describe('IDE review mode', () => { it('renders merge request link & IID', async () => { store.state.viewer = 'mrdiff'; - await wrapper.vm.$nextTick(); + await nextTick(); expect(trimText(wrapper.text())).toContain('Merge request (!123)'); }); @@ -101,7 +99,7 @@ describe('IDE review mode', () => { it('changes text to latest changes when viewer is not mrdiff', async () => { store.state.viewer = 'diff'; - await wrapper.vm.$nextTick(); + await nextTick(); expect(wrapper.text()).toContain('Latest changes'); }); diff --git a/spec/frontend/ide/components/ide_side_bar_spec.js b/spec/frontend/ide/components/ide_side_bar_spec.js index c683612b142..34f14ef23a4 100644 --- a/spec/frontend/ide/components/ide_side_bar_spec.js +++ b/spec/frontend/ide/components/ide_side_bar_spec.js @@ -1,5 +1,6 @@ import { GlSkeletonLoading } from '@gitlab/ui'; -import { mount, createLocalVue } from '@vue/test-utils'; +import { mount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import waitForPromises from 'helpers/wait_for_promises'; import IdeReview from '~/ide/components/ide_review.vue'; @@ -10,8 +11,7 @@ import { leftSidebarViews } from '~/ide/constants'; import { createStore } from '~/ide/stores'; import { projectData } from '../mock_data'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('IdeSidebar', () => { let wrapper; @@ -26,7 +26,6 @@ describe('IdeSidebar', () => { return mount(IdeSidebar, { store, - localVue, }); } @@ -46,7 +45,7 @@ describe('IdeSidebar', () => { store.state.loading = true; - await wrapper.vm.$nextTick(); + await nextTick(); expect(wrapper.findAll(GlSkeletonLoading)).toHaveLength(3); }); @@ -61,7 +60,7 @@ describe('IdeSidebar', () => { store.state.currentActivityView = leftSidebarViews.review.name; await waitForPromises(); - await wrapper.vm.$nextTick(); + await nextTick(); expect(wrapper.find(IdeTree).exists()).toBe(false); expect(wrapper.find(IdeReview).exists()).toBe(true); @@ -69,7 +68,7 @@ describe('IdeSidebar', () => { store.state.currentActivityView = leftSidebarViews.commit.name; await waitForPromises(); - await wrapper.vm.$nextTick(); + await nextTick(); expect(wrapper.find(IdeTree).exists()).toBe(false); expect(wrapper.find(IdeReview).exists()).toBe(false); @@ -85,7 +84,7 @@ describe('IdeSidebar', () => { view, }); await waitForPromises(); - await wrapper.vm.$nextTick(); + await nextTick(); expect(wrapper.find(IdeTree).exists()).toBe(tree); expect(wrapper.find(IdeReview).exists()).toBe(review); @@ -100,7 +99,7 @@ describe('IdeSidebar', () => { store.state.currentActivityView = leftSidebarViews.commit.name; await waitForPromises(); - await wrapper.vm.$nextTick(); + await nextTick(); expect(wrapper.find(IdeTree).exists()).toBe(false); expect(wrapper.find(RepoCommitSection).exists()).toBe(true); @@ -108,7 +107,7 @@ describe('IdeSidebar', () => { store.state.currentActivityView = leftSidebarViews.edit.name; await waitForPromises(); - await wrapper.vm.$nextTick(); + await nextTick(); // reference to the elements remains the same, meaning the components were kept alive expect(wrapper.find(IdeTree).element).toEqual(ideTreeComponent); diff --git a/spec/frontend/ide/components/ide_spec.js b/spec/frontend/ide/components/ide_spec.js index f8d29fc7b47..37b42001a80 100644 --- a/spec/frontend/ide/components/ide_spec.js +++ b/spec/frontend/ide/components/ide_spec.js @@ -1,4 +1,5 @@ -import { createLocalVue, shallowMount } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; +import Vue from 'vue'; import Vuex from 'vuex'; import waitForPromises from 'helpers/wait_for_promises'; import CannotPushCodeAlert from '~/ide/components/cannot_push_code_alert.vue'; @@ -9,8 +10,7 @@ import { createStore } from '~/ide/stores'; import { file } from '../helpers'; import { projectData } from '../mock_data'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); const TEST_FORK_IDE_PATH = '/test/ide/path'; @@ -34,7 +34,6 @@ describe('WebIDE', () => { wrapper = shallowMount(Ide, { store, - localVue, }); }; diff --git a/spec/frontend/ide/components/ide_status_bar_spec.js b/spec/frontend/ide/components/ide_status_bar_spec.js index f1a0b64caf2..00ef75fcf3a 100644 --- a/spec/frontend/ide/components/ide_status_bar_spec.js +++ b/spec/frontend/ide/components/ide_status_bar_spec.js @@ -1,5 +1,5 @@ import _ from 'lodash'; -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import { TEST_HOST } from 'helpers/test_constants'; import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; import IdeStatusBar from '~/ide/components/ide_status_bar.vue'; @@ -73,7 +73,7 @@ describe('ideStatusBar', () => { }); describe('pipeline status', () => { - it('opens right sidebar on clicking icon', (done) => { + it('opens right sidebar on clicking icon', async () => { jest.spyOn(vm, 'openRightPane').mockImplementation(() => {}); Vue.set(vm.$store.state.pipelines, 'latestPipeline', { details: { @@ -88,14 +88,10 @@ describe('ideStatusBar', () => { }, }); - vm.$nextTick() - .then(() => { - vm.$el.querySelector('.ide-status-pipeline button').click(); + await nextTick(); + vm.$el.querySelector('.ide-status-pipeline button').click(); - expect(vm.openRightPane).toHaveBeenCalledWith(rightSidebarViews.pipelines); - }) - .then(done) - .catch(done.fail); + expect(vm.openRightPane).toHaveBeenCalledWith(rightSidebarViews.pipelines); }); }); diff --git a/spec/frontend/ide/components/ide_status_list_spec.js b/spec/frontend/ide/components/ide_status_list_spec.js index 036edfb3ec1..371fbc6becd 100644 --- a/spec/frontend/ide/components/ide_status_list_spec.js +++ b/spec/frontend/ide/components/ide_status_list_spec.js @@ -1,5 +1,6 @@ import { GlLink } from '@gitlab/ui'; -import { createLocalVue, shallowMount } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; +import Vue from 'vue'; import Vuex from 'vuex'; import IdeStatusList from '~/ide/components/ide_status_list.vue'; import TerminalSyncStatusSafe from '~/ide/components/terminal_sync/terminal_sync_status_safe.vue'; @@ -16,8 +17,7 @@ const TEST_FILE_EDITOR = { }; const TEST_EDITOR_POSITION = `${TEST_FILE_EDITOR.editorRow}:${TEST_FILE_EDITOR.editorColumn}`; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('ide/components/ide_status_list', () => { let activeFileEditor; @@ -42,7 +42,6 @@ describe('ide/components/ide_status_list', () => { }); wrapper = shallowMount(IdeStatusList, { - localVue, store, ...options, }); diff --git a/spec/frontend/ide/components/ide_tree_list_spec.js b/spec/frontend/ide/components/ide_tree_list_spec.js index ace51204374..a85c52f5e86 100644 --- a/spec/frontend/ide/components/ide_tree_list_spec.js +++ b/spec/frontend/ide/components/ide_tree_list_spec.js @@ -1,4 +1,4 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; import IdeTreeList from '~/ide/components/ide_tree_list.vue'; import { createStore } from '~/ide/stores'; @@ -48,15 +48,12 @@ describe('IDE tree list', () => { expect(vm.$emit).toHaveBeenCalledWith('tree-ready'); }); - it('renders loading indicator', (done) => { + it('renders loading indicator', async () => { store.state.trees['abcproject/main'].loading = true; - vm.$nextTick(() => { - expect(vm.$el.querySelector('.multi-file-loading-container')).not.toBeNull(); - expect(vm.$el.querySelectorAll('.multi-file-loading-container').length).toBe(3); - - done(); - }); + await nextTick(); + expect(vm.$el.querySelector('.multi-file-loading-container')).not.toBeNull(); + expect(vm.$el.querySelectorAll('.multi-file-loading-container').length).toBe(3); }); it('renders list of files', () => { diff --git a/spec/frontend/ide/components/ide_tree_spec.js b/spec/frontend/ide/components/ide_tree_spec.js index 0792b88aeb6..8465ef9f5f3 100644 --- a/spec/frontend/ide/components/ide_tree_spec.js +++ b/spec/frontend/ide/components/ide_tree_spec.js @@ -1,4 +1,4 @@ -import { mount, createLocalVue } from '@vue/test-utils'; +import { mount } from '@vue/test-utils'; import Vue from 'vue'; import Vuex from 'vuex'; import { keepAlive } from 'helpers/keep_alive_component_helper'; @@ -7,8 +7,7 @@ import { createStore } from '~/ide/stores'; import { file } from '../helpers'; import { projectData } from '../mock_data'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('IdeTree', () => { let store; @@ -27,7 +26,6 @@ describe('IdeTree', () => { wrapper = mount(keepAlive(IdeTree), { store, - localVue, }); }); diff --git a/spec/frontend/ide/components/jobs/detail_spec.js b/spec/frontend/ide/components/jobs/detail_spec.js index 3634599f328..9122471d421 100644 --- a/spec/frontend/ide/components/jobs/detail_spec.js +++ b/spec/frontend/ide/components/jobs/detail_spec.js @@ -1,4 +1,4 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import { TEST_HOST } from 'helpers/test_constants'; import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; import JobDetail from '~/ide/components/jobs/detail.vue'; @@ -48,14 +48,11 @@ describe('IDE jobs detail view', () => { expect(vm.$el.querySelector('.bash').textContent).toContain('testing'); }); - it('renders empty message output', (done) => { + it('renders empty message output', async () => { vm.$store.state.pipelines.detailJob.output = ''; - vm.$nextTick(() => { - expect(vm.$el.querySelector('.bash').textContent).toContain('No messages were logged'); - - done(); - }); + await nextTick(); + expect(vm.$el.querySelector('.bash').textContent).toContain('No messages were logged'); }); it('renders loading icon', () => { @@ -68,14 +65,11 @@ describe('IDE jobs detail view', () => { expect(vm.$el.querySelector('.bash').style.display).toBe('none'); }); - it('hide loading icon when isLoading is false', (done) => { + it('hide loading icon when isLoading is false', async () => { vm.$store.state.pipelines.detailJob.isLoading = false; - vm.$nextTick(() => { - expect(vm.$el.querySelector('.build-loader-animation').style.display).toBe('none'); - - done(); - }); + await nextTick(); + expect(vm.$el.querySelector('.build-loader-animation').style.display).toBe('none'); }); it('resets detailJob when clicking header button', () => { @@ -107,17 +101,16 @@ describe('IDE jobs detail view', () => { fnName | btnName | scrollPos ${'scrollDown'} | ${'down'} | ${0} ${'scrollUp'} | ${'up'} | ${1} - `('triggers $fnName when clicking $btnName button', ({ fnName, scrollPos }) => { + `('triggers $fnName when clicking $btnName button', async ({ fnName, scrollPos }) => { jest.spyOn(vm, fnName).mockImplementation(); vm = vm.$mount(); vm.scrollPos = scrollPos; - return vm.$nextTick().then(() => { - vm.$el.querySelector('.btn-scroll:not([disabled])').click(); - expect(vm[fnName]).toHaveBeenCalled(); - }); + await nextTick(); + vm.$el.querySelector('.btn-scroll:not([disabled])').click(); + expect(vm[fnName]).toHaveBeenCalled(); }); }); diff --git a/spec/frontend/ide/components/jobs/item_spec.js b/spec/frontend/ide/components/jobs/item_spec.js index 7343fc80a03..c76760a5522 100644 --- a/spec/frontend/ide/components/jobs/item_spec.js +++ b/spec/frontend/ide/components/jobs/item_spec.js @@ -1,4 +1,4 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import mountComponent from 'helpers/vue_mount_component_helper'; import JobItem from '~/ide/components/jobs/item.vue'; import { jobs } from '../../mock_data'; @@ -27,13 +27,10 @@ describe('IDE jobs item', () => { expect(vm.$el.querySelector('[data-testid="status_success_borderless-icon"]')).not.toBe(null); }); - it('does not render view logs button if not started', (done) => { + it('does not render view logs button if not started', async () => { vm.job.started = false; - vm.$nextTick(() => { - expect(vm.$el.querySelector('.btn')).toBe(null); - - done(); - }); + await nextTick(); + expect(vm.$el.querySelector('.btn')).toBe(null); }); }); diff --git a/spec/frontend/ide/components/jobs/list_spec.js b/spec/frontend/ide/components/jobs/list_spec.js index 8797e07aef1..cb2c9f8f04f 100644 --- a/spec/frontend/ide/components/jobs/list_spec.js +++ b/spec/frontend/ide/components/jobs/list_spec.js @@ -1,11 +1,11 @@ import { GlLoadingIcon } from '@gitlab/ui'; -import { shallowMount, mount, createLocalVue } from '@vue/test-utils'; +import { shallowMount, mount } from '@vue/test-utils'; +import Vue from 'vue'; import Vuex from 'vuex'; import StageList from '~/ide/components/jobs/list.vue'; import Stage from '~/ide/components/jobs/stage.vue'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); const storeActions = { fetchJobs: jest.fn(), toggleStageCollapsed: jest.fn(), @@ -42,7 +42,6 @@ describe('IDE stages list', () => { ...defaultProps, ...props, }, - localVue, store, }); }; @@ -92,7 +91,6 @@ describe('IDE stages list', () => { wrapper = mount(StageList, { propsData: { ...defaultProps, stages }, store, - localVue, }); }); diff --git a/spec/frontend/ide/components/jobs/stage_spec.js b/spec/frontend/ide/components/jobs/stage_spec.js index 9accd81a2ba..f158c59cd32 100644 --- a/spec/frontend/ide/components/jobs/stage_spec.js +++ b/spec/frontend/ide/components/jobs/stage_spec.js @@ -1,5 +1,6 @@ import { GlLoadingIcon } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; +import { nextTick } from 'vue'; import Item from '~/ide/components/jobs/item.vue'; import Stage from '~/ide/components/jobs/stage.vue'; import { stages, jobs } from '../../mock_data'; @@ -47,23 +48,21 @@ describe('IDE pipeline stage', () => { expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); }); - it('emits toggleCollaped event with stage id when clicking header', () => { + it('emits toggleCollaped event with stage id when clicking header', async () => { const id = 5; createComponent({ stage: { ...defaultProps.stage, id } }); findHeader().trigger('click'); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.emitted().toggleCollapsed[0][0]).toBe(id); - }); + await nextTick(); + expect(wrapper.emitted().toggleCollapsed[0][0]).toBe(id); }); - it('emits clickViewLog entity with job', () => { + it('emits clickViewLog entity with job', async () => { const [job] = defaultProps.stage.jobs; createComponent(); wrapper.findAll(Item).at(0).vm.$emit('clickViewLog', job); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.emitted().clickViewLog[0][0]).toBe(job); - }); + await nextTick(); + expect(wrapper.emitted().clickViewLog[0][0]).toBe(job); }); it('renders stage details & icon', () => { diff --git a/spec/frontend/ide/components/merge_requests/item_spec.js b/spec/frontend/ide/components/merge_requests/item_spec.js index f0a97a0b10a..d6cf8127b53 100644 --- a/spec/frontend/ide/components/merge_requests/item_spec.js +++ b/spec/frontend/ide/components/merge_requests/item_spec.js @@ -1,4 +1,5 @@ -import { mount, createLocalVue } from '@vue/test-utils'; +import { mount } from '@vue/test-utils'; +import Vue from 'vue'; import Vuex from 'vuex'; import Item from '~/ide/components/merge_requests/item.vue'; import { createRouter } from '~/ide/ide_router'; @@ -11,8 +12,7 @@ const TEST_ITEM = { }; describe('IDE merge request item', () => { - const localVue = createLocalVue(); - localVue.use(Vuex); + Vue.use(Vuex); let wrapper; let store; @@ -28,7 +28,6 @@ describe('IDE merge request item', () => { currentProjectId: TEST_ITEM.projectPathWithNamespace, ...props, }, - localVue, router, store, }); diff --git a/spec/frontend/ide/components/merge_requests/list_spec.js b/spec/frontend/ide/components/merge_requests/list_spec.js index 610e20d5868..583671a0af6 100644 --- a/spec/frontend/ide/components/merge_requests/list_spec.js +++ b/spec/frontend/ide/components/merge_requests/list_spec.js @@ -1,13 +1,13 @@ import { GlLoadingIcon } from '@gitlab/ui'; -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import Item from '~/ide/components/merge_requests/item.vue'; import List from '~/ide/components/merge_requests/list.vue'; import TokenedInput from '~/ide/components/shared/tokened_input.vue'; import { mergeRequests as mergeRequestsMock } from '../../mock_data'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('IDE merge requests list', () => { let wrapper; @@ -41,7 +41,6 @@ describe('IDE merge requests list', () => { wrapper = shallowMount(List, { store: fakeStore, - localVue, }); }; @@ -67,33 +66,28 @@ describe('IDE merge requests list', () => { expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); }); - it('renders no search results text when search is not empty', () => { + it('renders no search results text when search is not empty', async () => { createComponent(); findTokenedInput().vm.$emit('input', 'something'); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.text()).toContain('No merge requests found'); - }); + await nextTick(); + expect(wrapper.text()).toContain('No merge requests found'); }); - it('clicking on search type, sets currentSearchType and loads merge requests', () => { + it('clicking on search type, sets currentSearchType and loads merge requests', async () => { createComponent(); findTokenedInput().vm.$emit('focus'); - return wrapper.vm - .$nextTick() - .then(() => { - findSearchTypeButtons().at(0).trigger('click'); - return wrapper.vm.$nextTick(); - }) - .then(() => { - const searchType = wrapper.vm.$options.searchTypes[0]; + await nextTick(); + findSearchTypeButtons().at(0).trigger('click'); - expect(findTokenedInput().props('tokens')).toEqual([searchType]); - expect(fetchMergeRequestsMock).toHaveBeenCalledWith(expect.any(Object), { - type: searchType.type, - search: '', - }); - }); + await nextTick(); + const searchType = wrapper.vm.$options.searchTypes[0]; + + expect(findTokenedInput().props('tokens')).toEqual([searchType]); + expect(fetchMergeRequestsMock).toHaveBeenCalledWith(expect.any(Object), { + type: searchType.type, + search: '', + }); }); describe('with merge requests', () => { @@ -120,16 +114,15 @@ describe('IDE merge requests list', () => { }); describe('when searching merge requests', () => { - it('calls `loadMergeRequests` on input in search field', () => { + it('calls `loadMergeRequests` on input in search field', async () => { createComponent(defaultStateWithMergeRequests); const input = findTokenedInput(); input.vm.$emit('input', 'something'); - return wrapper.vm.$nextTick().then(() => { - expect(fetchMergeRequestsMock).toHaveBeenCalledWith(expect.any(Object), { - search: 'something', - type: '', - }); + await nextTick(); + expect(fetchMergeRequestsMock).toHaveBeenCalledWith(expect.any(Object), { + search: 'something', + type: '', }); }); }); @@ -144,9 +137,9 @@ describe('IDE merge requests list', () => { }); describe('without search value', () => { - beforeEach(() => { + beforeEach(async () => { input.vm.$emit('focus'); - return wrapper.vm.$nextTick(); + await nextTick(); }); it('shows search types', () => { @@ -156,22 +149,20 @@ describe('IDE merge requests list', () => { ); }); - it('hides search types when search changes', () => { + it('hides search types when search changes', async () => { input.vm.$emit('input', 'something'); - return wrapper.vm.$nextTick().then(() => { - expect(findSearchTypeButtons().exists()).toBe(false); - }); + await nextTick(); + expect(findSearchTypeButtons().exists()).toBe(false); }); describe('with search type', () => { - beforeEach(() => { + beforeEach(async () => { findSearchTypeButtons().at(0).trigger('click'); - return wrapper.vm - .$nextTick() - .then(() => input.vm.$emit('focus')) - .then(() => wrapper.vm.$nextTick()); + await nextTick(); + await input.vm.$emit('focus'); + await nextTick(); }); it('does not show search types', () => { @@ -181,10 +172,10 @@ describe('IDE merge requests list', () => { }); describe('with search value', () => { - beforeEach(() => { + beforeEach(async () => { input.vm.$emit('input', 'something'); input.vm.$emit('focus'); - return wrapper.vm.$nextTick(); + await nextTick(); }); it('does not show search types', () => { diff --git a/spec/frontend/ide/components/nav_dropdown_button_spec.js b/spec/frontend/ide/components/nav_dropdown_button_spec.js index a02bfa5c391..1c14685df68 100644 --- a/spec/frontend/ide/components/nav_dropdown_button_spec.js +++ b/spec/frontend/ide/components/nav_dropdown_button_spec.js @@ -1,4 +1,4 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import { trimText } from 'helpers/text_helper'; import { mountComponentWithStore } from 'helpers/vue_mount_component_helper'; import NavDropdownButton from '~/ide/components/nav_dropdown_button.vue'; @@ -36,38 +36,26 @@ describe('NavDropdown', () => { expect(trimText(vm.$el.textContent)).toEqual('- -'); }); - it('renders branch name, if state has currentBranchId', (done) => { + it('renders branch name, if state has currentBranchId', async () => { vm.$store.state.currentBranchId = TEST_BRANCH_ID; - vm.$nextTick() - .then(() => { - expect(trimText(vm.$el.textContent)).toEqual(`${TEST_BRANCH_ID} -`); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(trimText(vm.$el.textContent)).toEqual(`${TEST_BRANCH_ID} -`); }); - it('renders mr id, if state has currentMergeRequestId', (done) => { + it('renders mr id, if state has currentMergeRequestId', async () => { vm.$store.state.currentMergeRequestId = TEST_MR_ID; - vm.$nextTick() - .then(() => { - expect(trimText(vm.$el.textContent)).toEqual(`- !${TEST_MR_ID}`); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(trimText(vm.$el.textContent)).toEqual(`- !${TEST_MR_ID}`); }); - it('renders branch and mr, if state has both', (done) => { + it('renders branch and mr, if state has both', async () => { vm.$store.state.currentBranchId = TEST_BRANCH_ID; vm.$store.state.currentMergeRequestId = TEST_MR_ID; - vm.$nextTick() - .then(() => { - expect(trimText(vm.$el.textContent)).toEqual(`${TEST_BRANCH_ID} !${TEST_MR_ID}`); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(trimText(vm.$el.textContent)).toEqual(`${TEST_BRANCH_ID} !${TEST_MR_ID}`); }); it('shows icons', () => { diff --git a/spec/frontend/ide/components/nav_dropdown_spec.js b/spec/frontend/ide/components/nav_dropdown_spec.js index 6a1be7ee964..33e638843f5 100644 --- a/spec/frontend/ide/components/nav_dropdown_spec.js +++ b/spec/frontend/ide/components/nav_dropdown_spec.js @@ -1,5 +1,6 @@ import { mount } from '@vue/test-utils'; import $ from 'jquery'; +import { nextTick } from 'vue'; import NavDropdown from '~/ide/components/nav_dropdown.vue'; import { PERMISSION_READ_MR } from '~/ide/constants'; import { createStore } from '~/ide/stores'; @@ -58,29 +59,19 @@ describe('IDE NavDropdown', () => { expect(findNavForm().exists()).toBe(false); }); - it('renders nav form when show.bs.dropdown', (done) => { + it('renders nav form when show.bs.dropdown', async () => { showDropdown(); - wrapper.vm - .$nextTick() - .then(() => { - expect(findNavForm().exists()).toBe(true); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(findNavForm().exists()).toBe(true); }); - it('destroys nav form when closed', (done) => { + it('destroys nav form when closed', async () => { showDropdown(); hideDropdown(); - wrapper.vm - .$nextTick() - .then(() => { - expect(findNavForm().exists()).toBe(false); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(findNavForm().exists()).toBe(false); }); it('renders merge request icon', () => { diff --git a/spec/frontend/ide/components/new_dropdown/button_spec.js b/spec/frontend/ide/components/new_dropdown/button_spec.js index 32fa2babcdb..298d7b810e1 100644 --- a/spec/frontend/ide/components/new_dropdown/button_spec.js +++ b/spec/frontend/ide/components/new_dropdown/button_spec.js @@ -1,4 +1,4 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import mountComponent from 'helpers/vue_mount_component_helper'; import Button from '~/ide/components/new_dropdown/button.vue'; @@ -37,14 +37,11 @@ describe('IDE new entry dropdown button component', () => { expect(vm.$emit).toHaveBeenCalledWith('click'); }); - it('hides label if showLabel is false', (done) => { + it('hides label if showLabel is false', async () => { vm.showLabel = false; - vm.$nextTick(() => { - expect(vm.$el.textContent).not.toContain('Testing'); - - done(); - }); + await nextTick(); + expect(vm.$el.textContent).not.toContain('Testing'); }); describe('tooltipTitle', () => { @@ -52,14 +49,11 @@ describe('IDE new entry dropdown button component', () => { expect(vm.tooltipTitle).toBe(''); }); - it('returns label', (done) => { + it('returns label', async () => { vm.showLabel = false; - vm.$nextTick(() => { - expect(vm.tooltipTitle).toBe('Testing'); - - done(); - }); + await nextTick(); + expect(vm.tooltipTitle).toBe('Testing'); }); }); }); diff --git a/spec/frontend/ide/components/new_dropdown/index_spec.js b/spec/frontend/ide/components/new_dropdown/index_spec.js index fa34d1b257f..19dcd9569b3 100644 --- a/spec/frontend/ide/components/new_dropdown/index_spec.js +++ b/spec/frontend/ide/components/new_dropdown/index_spec.js @@ -1,4 +1,4 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; import newDropdown from '~/ide/components/new_dropdown/index.vue'; import { createStore } from '~/ide/stores'; @@ -57,17 +57,15 @@ describe('new dropdown component', () => { }); describe('isOpen', () => { - it('scrolls dropdown into view', (done) => { + it('scrolls dropdown into view', async () => { jest.spyOn(vm.$refs.dropdownMenu, 'scrollIntoView').mockImplementation(() => {}); vm.isOpen = true; - setImmediate(() => { - expect(vm.$refs.dropdownMenu.scrollIntoView).toHaveBeenCalledWith({ - block: 'nearest', - }); + await nextTick(); - done(); + expect(vm.$refs.dropdownMenu.scrollIntoView).toHaveBeenCalledWith({ + block: 'nearest', }); }); }); diff --git a/spec/frontend/ide/components/new_dropdown/modal_spec.js b/spec/frontend/ide/components/new_dropdown/modal_spec.js index 41111f5dbb4..8134248bbf4 100644 --- a/spec/frontend/ide/components/new_dropdown/modal_spec.js +++ b/spec/frontend/ide/components/new_dropdown/modal_spec.js @@ -1,4 +1,4 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; import createFlash from '~/flash'; import modal from '~/ide/components/new_dropdown/modal.vue'; @@ -19,14 +19,14 @@ describe('new file modal component', () => { ${'tree'} | ${'Create new directory'} | ${'Create directory'} | ${false} ${'blob'} | ${'Create new file'} | ${'Create file'} | ${true} `('$entryType', ({ entryType, modalTitle, btnTitle, showsFileTemplates }) => { - beforeEach((done) => { + beforeEach(async () => { const store = createStore(); vm = createComponentWithStore(Component, store).$mount(); vm.open(entryType); vm.name = 'testing'; - vm.$nextTick(done); + await nextTick(); }); afterEach(() => { @@ -71,16 +71,13 @@ describe('new file modal component', () => { ${'blob'} | ${'Rename file'} | ${'Rename file'} `( 'renders title and button for renaming $entryType', - ({ entryType, modalTitle, btnTitle }, done) => { + async ({ entryType, modalTitle, btnTitle }) => { vm.$store.state.entries['test-path'].type = entryType; vm.open('rename', 'test-path'); - vm.$nextTick(() => { - expect(document.querySelector('.modal-title').textContent.trim()).toBe(modalTitle); - expect(document.querySelector('.btn-success').textContent.trim()).toBe(btnTitle); - - done(); - }); + await nextTick(); + expect(document.querySelector('.modal-title').textContent.trim()).toBe(modalTitle); + expect(document.querySelector('.btn-success').textContent.trim()).toBe(btnTitle); }, ); diff --git a/spec/frontend/ide/components/panes/collapsible_sidebar_spec.js b/spec/frontend/ide/components/panes/collapsible_sidebar_spec.js index 7216f50b05c..7f2ee0fe7d9 100644 --- a/spec/frontend/ide/components/panes/collapsible_sidebar_spec.js +++ b/spec/frontend/ide/components/panes/collapsible_sidebar_spec.js @@ -1,12 +1,12 @@ -import { createLocalVue, shallowMount } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; +import Vue from 'vue'; import Vuex from 'vuex'; import IdeSidebarNav from '~/ide/components/ide_sidebar_nav.vue'; import CollapsibleSidebar from '~/ide/components/panes/collapsible_sidebar.vue'; import { createStore } from '~/ide/stores'; import paneModule from '~/ide/stores/modules/pane'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('ide/components/panes/collapsible_sidebar.vue', () => { let wrapper; @@ -17,7 +17,6 @@ describe('ide/components/panes/collapsible_sidebar.vue', () => { const createComponent = (props) => { wrapper = shallowMount(CollapsibleSidebar, { - localVue, store, propsData: { extensionTabs: [], @@ -46,7 +45,7 @@ describe('ide/components/panes/collapsible_sidebar.vue', () => { let extensionTabs; beforeEach(() => { - const FakeComponent = localVue.component(fakeComponentName, { + const FakeComponent = Vue.component(fakeComponentName, { render: () => null, }); diff --git a/spec/frontend/ide/components/panes/right_spec.js b/spec/frontend/ide/components/panes/right_spec.js index c6231d129ff..d12acd6dc4c 100644 --- a/spec/frontend/ide/components/panes/right_spec.js +++ b/spec/frontend/ide/components/panes/right_spec.js @@ -1,5 +1,5 @@ -import { createLocalVue, shallowMount } from '@vue/test-utils'; -import Vue from 'vue'; +import { shallowMount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import CollapsibleSidebar from '~/ide/components/panes/collapsible_sidebar.vue'; import RightPane from '~/ide/components/panes/right.vue'; @@ -7,8 +7,7 @@ import { rightSidebarViews } from '~/ide/constants'; import { createStore } from '~/ide/stores'; import extendStore from '~/ide/stores/extend'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('ide/components/panes/right.vue', () => { let wrapper; @@ -18,7 +17,6 @@ describe('ide/components/panes/right.vue', () => { extendStore(store, document.createElement('div')); wrapper = shallowMount(RightPane, { - localVue, store, propsData: { ...props, @@ -88,19 +86,18 @@ describe('ide/components/panes/right.vue', () => { createComponent(); }); - it('adds terminal tab', () => { + it('adds terminal tab', async () => { store.state.terminal.isVisible = true; - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.find(CollapsibleSidebar).props('extensionTabs')).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - show: true, - title: 'Terminal', - }), - ]), - ); - }); + await nextTick(); + expect(wrapper.find(CollapsibleSidebar).props('extensionTabs')).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + show: true, + title: 'Terminal', + }), + ]), + ); }); it('hides terminal tab when not visible', () => { diff --git a/spec/frontend/ide/components/preview/clientside_spec.js b/spec/frontend/ide/components/preview/clientside_spec.js index b168eec0f16..426fbd5c04c 100644 --- a/spec/frontend/ide/components/preview/clientside_spec.js +++ b/spec/frontend/ide/components/preview/clientside_spec.js @@ -1,16 +1,19 @@ import { GlLoadingIcon } from '@gitlab/ui'; -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; +import { dispatch } from 'codesandbox-api'; import smooshpack from 'smooshpack'; import Vuex from 'vuex'; +import waitForPromises from 'helpers/wait_for_promises'; import Clientside from '~/ide/components/preview/clientside.vue'; +import { PING_USAGE_PREVIEW_KEY, PING_USAGE_PREVIEW_SUCCESS_KEY } from '~/ide/constants'; import eventHub from '~/ide/eventhub'; jest.mock('smooshpack', () => ({ Manager: jest.fn(), })); -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); const dummyPackageJson = () => ({ raw: JSON.stringify({ @@ -39,8 +42,7 @@ describe('IDE clientside preview', () => { const storeClientsideActions = { pingUsage: jest.fn().mockReturnValue(Promise.resolve({})), }; - - const waitForCalls = () => new Promise(setImmediate); + const dispatchCodesandboxReady = () => dispatch({ type: 'done' }); const createComponent = ({ state, getters } = {}) => { store = new Vuex.Store({ @@ -67,7 +69,6 @@ describe('IDE clientside preview', () => { wrapper = shallowMount(Clientside, { store, - localVue, }); }; @@ -98,7 +99,7 @@ describe('IDE clientside preview', () => { beforeEach(() => { createComponent({ getters: { packageJson: dummyPackageJson } }); - return waitForCalls(); + return waitForPromises(); }); it('creates sandpack manager', () => { @@ -111,6 +112,20 @@ describe('IDE clientside preview', () => { it('pings usage', () => { expect(storeClientsideActions.pingUsage).toHaveBeenCalledTimes(1); + expect(storeClientsideActions.pingUsage).toHaveBeenCalledWith( + expect.anything(), + PING_USAGE_PREVIEW_KEY, + ); + }); + + it('pings usage success', async () => { + dispatchCodesandboxReady(); + await nextTick(); + expect(storeClientsideActions.pingUsage).toHaveBeenCalledTimes(2); + expect(storeClientsideActions.pingUsage).toHaveBeenCalledWith( + expect.anything(), + PING_USAGE_PREVIEW_SUCCESS_KEY, + ); }); }); @@ -123,7 +138,7 @@ describe('IDE clientside preview', () => { state: { codesandboxBundlerUrl: TEST_BUNDLER_URL }, }); - return waitForCalls(); + return waitForPromises(); }); it('creates sandpack manager with bundlerURL', () => { @@ -138,7 +153,7 @@ describe('IDE clientside preview', () => { beforeEach(() => { createComponent({ getters: { packageJson: dummyPackageJson } }); - return waitForCalls(); + return waitForPromises(); }); it('creates sandpack manager', () => { @@ -324,7 +339,7 @@ describe('IDE clientside preview', () => { wrapper.setData({ sandpackReady: true }); wrapper.vm.update(); - return waitForCalls().then(() => { + return waitForPromises().then(() => { expect(smooshpack.Manager).toHaveBeenCalled(); }); }); @@ -352,39 +367,36 @@ describe('IDE clientside preview', () => { }); describe('template', () => { - it('renders ide-preview element when showPreview is true', () => { + it('renders ide-preview element when showPreview is true', async () => { createComponent({ getters: { packageJson: dummyPackageJson } }); // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details // eslint-disable-next-line no-restricted-syntax wrapper.setData({ loading: false }); - return wrapper.vm.$nextTick(() => { - expect(wrapper.find('#ide-preview').exists()).toBe(true); - }); + await nextTick(); + expect(wrapper.find('#ide-preview').exists()).toBe(true); }); - it('renders empty state', () => { + it('renders empty state', async () => { createComponent(); // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details // eslint-disable-next-line no-restricted-syntax wrapper.setData({ loading: false }); - return wrapper.vm.$nextTick(() => { - expect(wrapper.text()).toContain( - 'Preview your web application using Web IDE client-side evaluation.', - ); - }); + await nextTick(); + expect(wrapper.text()).toContain( + 'Preview your web application using Web IDE client-side evaluation.', + ); }); - it('renders loading icon', () => { + it('renders loading icon', async () => { createComponent(); // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details // eslint-disable-next-line no-restricted-syntax wrapper.setData({ loading: true }); - return wrapper.vm.$nextTick(() => { - expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); - }); + await nextTick(); + expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); }); }); diff --git a/spec/frontend/ide/components/preview/navigator_spec.js b/spec/frontend/ide/components/preview/navigator_spec.js index ee760364c7e..a199f4704f7 100644 --- a/spec/frontend/ide/components/preview/navigator_spec.js +++ b/spec/frontend/ide/components/preview/navigator_spec.js @@ -1,6 +1,7 @@ import { GlLoadingIcon } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; import { listen } from 'codesandbox-api'; +import { nextTick } from 'vue'; import { TEST_HOST } from 'helpers/test_constants'; import ClientsideNavigator from '~/ide/components/preview/navigator.vue'; @@ -29,31 +30,28 @@ describe('IDE clientside preview navigator', () => { wrapper.destroy(); }); - it('renders readonly URL bar', () => { + it('renders readonly URL bar', async () => { listenHandler({ type: 'urlchange', url: manager.bundlerURL }); - return wrapper.vm.$nextTick(() => { - expect(wrapper.find('input[readonly]').element.value).toBe('/'); - }); + await nextTick(); + expect(wrapper.find('input[readonly]').element.value).toBe('/'); }); it('renders loading icon by default', () => { expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); }); - it('removes loading icon when done event is fired', () => { + it('removes loading icon when done event is fired', async () => { listenHandler({ type: 'done' }); - return wrapper.vm.$nextTick(() => { - expect(wrapper.find(GlLoadingIcon).exists()).toBe(false); - }); + await nextTick(); + expect(wrapper.find(GlLoadingIcon).exists()).toBe(false); }); - it('does not count visiting same url multiple times', () => { + it('does not count visiting same url multiple times', async () => { listenHandler({ type: 'done' }); listenHandler({ type: 'done', url: `${TEST_HOST}/url1` }); listenHandler({ type: 'done', url: `${TEST_HOST}/url1` }); - return wrapper.vm.$nextTick().then(() => { - expect(findBackButton().attributes('disabled')).toBe('disabled'); - }); + await nextTick(); + expect(findBackButton().attributes('disabled')).toBe('disabled'); }); it('unsubscribes from listen on destroy', () => { @@ -64,107 +62,93 @@ describe('IDE clientside preview navigator', () => { }); describe('back button', () => { - beforeEach(() => { + beforeEach(async () => { listenHandler({ type: 'done' }); listenHandler({ type: 'urlchange', url: TEST_HOST }); - return wrapper.vm.$nextTick(); + await nextTick(); }); it('is disabled by default', () => { expect(findBackButton().attributes('disabled')).toBe('disabled'); }); - it('is enabled when there is previous entry', () => { + it('is enabled when there is previous entry', async () => { listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` }); - return wrapper.vm.$nextTick().then(() => { - findBackButton().trigger('click'); - expect(findBackButton().attributes('disabled')).toBeFalsy(); - }); + await nextTick(); + findBackButton().trigger('click'); + expect(findBackButton().attributes('disabled')).toBeFalsy(); }); - it('is disabled when there is no previous entry', () => { + it('is disabled when there is no previous entry', async () => { listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` }); - return wrapper.vm - .$nextTick() - .then(() => { - findBackButton().trigger('click'); - - return wrapper.vm.$nextTick(); - }) - .then(() => { - expect(findBackButton().attributes('disabled')).toBe('disabled'); - }); + + await nextTick(); + findBackButton().trigger('click'); + + await nextTick(); + expect(findBackButton().attributes('disabled')).toBe('disabled'); }); - it('updates manager iframe src', () => { + it('updates manager iframe src', async () => { listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` }); listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url2` }); - return wrapper.vm.$nextTick().then(() => { - findBackButton().trigger('click'); + await nextTick(); + findBackButton().trigger('click'); - expect(manager.iframe.src).toBe(`${TEST_HOST}/url1`); - }); + expect(manager.iframe.src).toBe(`${TEST_HOST}/url1`); }); }); describe('forward button', () => { - beforeEach(() => { + beforeEach(async () => { listenHandler({ type: 'done' }); listenHandler({ type: 'urlchange', url: TEST_HOST }); - return wrapper.vm.$nextTick(); + await nextTick(); }); it('is disabled by default', () => { expect(findForwardButton().attributes('disabled')).toBe('disabled'); }); - it('is enabled when there is next entry', () => { + it('is enabled when there is next entry', async () => { listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` }); - return wrapper.vm - .$nextTick() - .then(() => { - findBackButton().trigger('click'); - return wrapper.vm.$nextTick(); - }) - .then(() => { - expect(findForwardButton().attributes('disabled')).toBeFalsy(); - }); + + await nextTick(); + findBackButton().trigger('click'); + + await nextTick(); + expect(findForwardButton().attributes('disabled')).toBeFalsy(); }); - it('is disabled when there is no next entry', () => { + it('is disabled when there is no next entry', async () => { listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` }); - return wrapper.vm - .$nextTick() - .then(() => { - findBackButton().trigger('click'); - return wrapper.vm.$nextTick(); - }) - .then(() => { - findForwardButton().trigger('click'); - return wrapper.vm.$nextTick(); - }) - .then(() => { - expect(findForwardButton().attributes('disabled')).toBe('disabled'); - }); + + await nextTick(); + findBackButton().trigger('click'); + + await nextTick(); + findForwardButton().trigger('click'); + + await nextTick(); + expect(findForwardButton().attributes('disabled')).toBe('disabled'); }); - it('updates manager iframe src', () => { + it('updates manager iframe src', async () => { listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` }); listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url2` }); - return wrapper.vm.$nextTick().then(() => { - findBackButton().trigger('click'); + await nextTick(); + findBackButton().trigger('click'); - expect(manager.iframe.src).toBe(`${TEST_HOST}/url1`); - }); + expect(manager.iframe.src).toBe(`${TEST_HOST}/url1`); }); }); describe('refresh button', () => { const url = `${TEST_HOST}/some_url`; - beforeEach(() => { + beforeEach(async () => { listenHandler({ type: 'done' }); listenHandler({ type: 'urlchange', url }); - return wrapper.vm.$nextTick(); + await nextTick(); }); it('calls refresh with current path', () => { diff --git a/spec/frontend/ide/components/repo_editor_spec.js b/spec/frontend/ide/components/repo_editor_spec.js index 15af2d03704..96c9baeb328 100644 --- a/spec/frontend/ide/components/repo_editor_spec.js +++ b/spec/frontend/ide/components/repo_editor_spec.js @@ -1,7 +1,7 @@ import { shallowMount } from '@vue/test-utils'; import MockAdapter from 'axios-mock-adapter'; import { editor as monacoEditor, Range } from 'monaco-editor'; -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import '~/behaviors/markdown/render_gfm'; import waitForPromises from 'helpers/wait_for_promises'; @@ -367,17 +367,17 @@ describe('RepoEditor', () => { expect(vm.$store.state.panelResizing).toBe(false); // default value vm.$store.state.panelResizing = true; - await vm.$nextTick(); + await nextTick(); expect(updateDimensionsSpy).not.toHaveBeenCalled(); vm.$store.state.panelResizing = false; - await vm.$nextTick(); + await nextTick(); expect(updateDimensionsSpy).toHaveBeenCalledTimes(1); vm.$store.state.panelResizing = true; - await vm.$nextTick(); + await nextTick(); expect(updateDimensionsSpy).toHaveBeenCalledTimes(1); }); @@ -387,12 +387,12 @@ describe('RepoEditor', () => { expect(vm.$store.state.rightPane.isOpen).toBe(false); // default value vm.$store.state.rightPane.isOpen = true; - await vm.$nextTick(); + await nextTick(); expect(updateDimensionsSpy).toHaveBeenCalledTimes(1); vm.$store.state.rightPane.isOpen = false; - await vm.$nextTick(); + await nextTick(); expect(updateDimensionsSpy).toHaveBeenCalledTimes(2); }); @@ -411,7 +411,7 @@ describe('RepoEditor', () => { `('tabs in $mode are $isVisible', async ({ mode, isVisible } = {}) => { vm.$store.state.currentActivityView = leftSidebarViews[mode].name; - await vm.$nextTick(); + await nextTick(); expect(wrapper.find('.nav-links').exists()).toBe(isVisible); }); }); @@ -436,7 +436,7 @@ describe('RepoEditor', () => { }); changeViewMode(FILE_VIEW_MODE_PREVIEW); - await vm.$nextTick(); + await nextTick(); }); it('do not show the editor', () => { @@ -448,7 +448,7 @@ describe('RepoEditor', () => { expect(updateDimensionsSpy).not.toHaveBeenCalled(); changeViewMode(FILE_VIEW_MODE_EDITOR); - await vm.$nextTick(); + await nextTick(); expect(updateDimensionsSpy).toHaveBeenCalled(); }); @@ -460,7 +460,7 @@ describe('RepoEditor', () => { jest.spyOn(vm, 'shouldHideEditor', 'get').mockReturnValue(true); vm.initEditor(); - await vm.$nextTick(); + await nextTick(); }; it('does not fetch file information for temp entries', async () => { @@ -511,20 +511,20 @@ describe('RepoEditor', () => { const origFile = vm.file; vm.file.pending = true; - await vm.$nextTick(); + await nextTick(); wrapper.setProps({ file: file('testing'), }); vm.file.content = 'foo'; // need to prevent full cycle of initEditor - await vm.$nextTick(); + await nextTick(); expect(vm.removePendingTab).toHaveBeenCalledWith(origFile); }); it('does not call initEditor if the file did not change', async () => { Vue.set(vm, 'file', vm.file); - await vm.$nextTick(); + await nextTick(); expect(vm.initEditor).not.toHaveBeenCalled(); }); @@ -538,7 +538,7 @@ describe('RepoEditor', () => { key: 'new', }, }); - await vm.$nextTick(); + await nextTick(); expect(vm.initEditor).toHaveBeenCalled(); }); diff --git a/spec/frontend/ide/components/repo_tab_spec.js b/spec/frontend/ide/components/repo_tab_spec.js index 95d52e8f7a9..b16fd8f80ba 100644 --- a/spec/frontend/ide/components/repo_tab_spec.js +++ b/spec/frontend/ide/components/repo_tab_spec.js @@ -1,5 +1,6 @@ import { GlTab } from '@gitlab/ui'; -import { mount, createLocalVue } from '@vue/test-utils'; +import { mount } from '@vue/test-utils'; +import Vue from 'vue'; import Vuex from 'vuex'; import { stubComponent } from 'helpers/stub_component'; import RepoTab from '~/ide/components/repo_tab.vue'; @@ -7,8 +8,7 @@ import { createRouter } from '~/ide/ide_router'; import { createStore } from '~/ide/stores'; import { file } from '../helpers'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); const GlTabStub = stubComponent(GlTab, { template: '<li><slot name="title" /></li>', @@ -23,7 +23,6 @@ describe('RepoTab', () => { function createComponent(propsData) { wrapper = mount(RepoTab, { - localVue, store, propsData, stubs: { diff --git a/spec/frontend/ide/components/repo_tabs_spec.js b/spec/frontend/ide/components/repo_tabs_spec.js index 6ee73b0a437..1cfc1f12745 100644 --- a/spec/frontend/ide/components/repo_tabs_spec.js +++ b/spec/frontend/ide/components/repo_tabs_spec.js @@ -1,11 +1,11 @@ -import { mount, createLocalVue } from '@vue/test-utils'; +import { mount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import RepoTabs from '~/ide/components/repo_tabs.vue'; import { createStore } from '~/ide/stores'; import { file } from '../helpers'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('RepoTabs', () => { let wrapper; @@ -22,7 +22,6 @@ describe('RepoTabs', () => { activeFile: file('activeFile'), }, store, - localVue, }); }); @@ -30,17 +29,14 @@ describe('RepoTabs', () => { wrapper.destroy(); }); - it('renders a list of tabs', (done) => { + it('renders a list of tabs', async () => { store.state.openFiles[0].active = true; - wrapper.vm.$nextTick(() => { - const tabs = [...wrapper.vm.$el.querySelectorAll('.multi-file-tab')]; + await nextTick(); + const tabs = [...wrapper.vm.$el.querySelectorAll('.multi-file-tab')]; - expect(tabs.length).toEqual(2); - expect(tabs[0].parentNode.classList.contains('active')).toEqual(true); - expect(tabs[1].parentNode.classList.contains('active')).toEqual(false); - - done(); - }); + expect(tabs.length).toEqual(2); + expect(tabs[0].parentNode.classList.contains('active')).toEqual(true); + expect(tabs[1].parentNode.classList.contains('active')).toEqual(false); }); }); diff --git a/spec/frontend/ide/components/resizable_panel_spec.js b/spec/frontend/ide/components/resizable_panel_spec.js index 6a5af52ea35..55b9423aba8 100644 --- a/spec/frontend/ide/components/resizable_panel_spec.js +++ b/spec/frontend/ide/components/resizable_panel_spec.js @@ -1,4 +1,5 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import ResizablePanel from '~/ide/components/resizable_panel.vue'; import { SIDE_LEFT, SIDE_RIGHT } from '~/ide/constants'; @@ -8,8 +9,7 @@ const TEST_WIDTH = 500; const TEST_MIN_WIDTH = 400; describe('~/ide/components/resizable_panel', () => { - const localVue = createLocalVue(); - localVue.use(Vuex); + Vue.use(Vuex); let wrapper; let store; @@ -33,7 +33,6 @@ describe('~/ide/components/resizable_panel', () => { ...props, }, store, - localVue, }); }; const findResizer = () => wrapper.find(PanelResizer); @@ -100,15 +99,14 @@ describe('~/ide/components/resizable_panel', () => { }); }); - it('when resizer emits update:size, changes inline width', () => { + it('when resizer emits update:size, changes inline width', async () => { const newSize = TEST_WIDTH - 100; const resizer = findResizer(); resizer.vm.$emit('update:size', newSize); - return wrapper.vm.$nextTick().then(() => { - expect(findInlineStyle()).toBe(createInlineStyle(newSize)); - }); + await nextTick(); + expect(findInlineStyle()).toBe(createInlineStyle(newSize)); }); }); }); diff --git a/spec/frontend/ide/components/shared/tokened_input_spec.js b/spec/frontend/ide/components/shared/tokened_input_spec.js index 837bfe6b574..a37c08af0a1 100644 --- a/spec/frontend/ide/components/shared/tokened_input_spec.js +++ b/spec/frontend/ide/components/shared/tokened_input_spec.js @@ -1,4 +1,4 @@ -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import mountComponent from 'helpers/vue_mount_component_helper'; import TokenedInput from '~/ide/components/shared/tokened_input.vue'; @@ -54,15 +54,11 @@ describe('IDE shared/TokenedInput', () => { expect(vm.$refs.input).toHaveValue(TEST_VALUE); }); - it('renders placeholder, when tokens are empty', (done) => { + it('renders placeholder, when tokens are empty', async () => { vm.tokens = []; - vm.$nextTick() - .then(() => { - expect(vm.$refs.input).toHaveAttr('placeholder', TEST_PLACEHOLDER); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(vm.$refs.input).toHaveAttr('placeholder', TEST_PLACEHOLDER); }); it('triggers "removeToken" on token click', () => { diff --git a/spec/frontend/ide/components/terminal/session_spec.js b/spec/frontend/ide/components/terminal/session_spec.js index 5659a7d15da..6a70ddb46a8 100644 --- a/spec/frontend/ide/components/terminal/session_spec.js +++ b/spec/frontend/ide/components/terminal/session_spec.js @@ -1,5 +1,6 @@ import { GlButton } from '@gitlab/ui'; -import { createLocalVue, shallowMount } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import TerminalSession from '~/ide/components/terminal/session.vue'; import Terminal from '~/ide/components/terminal/terminal.vue'; @@ -13,8 +14,7 @@ import { const TEST_TERMINAL_PATH = 'terminal/path'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('IDE TerminalSession', () => { let wrapper; @@ -33,7 +33,6 @@ describe('IDE TerminalSession', () => { }); wrapper = shallowMount(TerminalSession, { - localVue, store, ...options, }); @@ -68,32 +67,30 @@ describe('IDE TerminalSession', () => { }); [STARTING, PENDING, RUNNING].forEach((status) => { - it(`show stop button when status is ${status}`, () => { + it(`show stop button when status is ${status}`, async () => { state.session = { status }; factory(); const button = findButton(); button.vm.$emit('click'); - return wrapper.vm.$nextTick().then(() => { - expect(button.text()).toEqual('Stop Terminal'); - expect(actions.stopSession).toHaveBeenCalled(); - }); + await nextTick(); + expect(button.text()).toEqual('Stop Terminal'); + expect(actions.stopSession).toHaveBeenCalled(); }); }); [STOPPING, STOPPED].forEach((status) => { - it(`show stop button when status is ${status}`, () => { + it(`show stop button when status is ${status}`, async () => { state.session = { status }; factory(); const button = findButton(); button.vm.$emit('click'); - return wrapper.vm.$nextTick().then(() => { - expect(button.text()).toEqual('Restart Terminal'); - expect(actions.restartSession).toHaveBeenCalled(); - }); + await nextTick(); + expect(button.text()).toEqual('Restart Terminal'); + expect(actions.restartSession).toHaveBeenCalled(); }); }); }); diff --git a/spec/frontend/ide/components/terminal/terminal_controls_spec.js b/spec/frontend/ide/components/terminal/terminal_controls_spec.js index 416096083f0..71ec0dca89d 100644 --- a/spec/frontend/ide/components/terminal/terminal_controls_spec.js +++ b/spec/frontend/ide/components/terminal/terminal_controls_spec.js @@ -1,4 +1,5 @@ import { shallowMount } from '@vue/test-utils'; +import { nextTick } from 'vue'; import ScrollButton from '~/ide/components/jobs/detail/scroll_button.vue'; import TerminalControls from '~/ide/components/terminal/terminal_controls.vue'; @@ -39,27 +40,25 @@ describe('IDE TerminalControls', () => { ); }); - it('emits "scroll-up" when click up button', () => { + it('emits "scroll-up" when click up button', async () => { factory({ propsData: { canScrollUp: true } }); expect(wrapper.emitted()).toEqual({}); buttons.at(0).vm.$emit('click'); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.emitted('scroll-up')).toEqual([[]]); - }); + await nextTick(); + expect(wrapper.emitted('scroll-up')).toEqual([[]]); }); - it('emits "scroll-down" when click down button', () => { + it('emits "scroll-down" when click down button', async () => { factory({ propsData: { canScrollDown: true } }); expect(wrapper.emitted()).toEqual({}); buttons.at(1).vm.$emit('click'); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.emitted('scroll-down')).toEqual([[]]); - }); + await nextTick(); + expect(wrapper.emitted('scroll-down')).toEqual([[]]); }); }); diff --git a/spec/frontend/ide/components/terminal/view_spec.js b/spec/frontend/ide/components/terminal/view_spec.js index e97d4d8a73b..49f9513d2ac 100644 --- a/spec/frontend/ide/components/terminal/view_spec.js +++ b/spec/frontend/ide/components/terminal/view_spec.js @@ -1,4 +1,5 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; +import Vue from 'vue'; import Vuex from 'vuex'; import waitForPromises from 'helpers/wait_for_promises'; import { TEST_HOST } from 'spec/test_constants'; @@ -9,8 +10,7 @@ import TerminalView from '~/ide/components/terminal/view.vue'; const TEST_HELP_PATH = `${TEST_HOST}/help`; const TEST_SVG_PATH = `${TEST_HOST}/illustration.svg`; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('IDE TerminalView', () => { let state; @@ -30,7 +30,7 @@ describe('IDE TerminalView', () => { }, }); - wrapper = shallowMount(TerminalView, { localVue, store }); + wrapper = shallowMount(TerminalView, { store }); // Uses deferred components, so wait for those to load... await waitForPromises(); diff --git a/spec/frontend/ide/components/terminal_sync/terminal_sync_status_safe_spec.js b/spec/frontend/ide/components/terminal_sync/terminal_sync_status_safe_spec.js index 69077ef2c68..f921037d744 100644 --- a/spec/frontend/ide/components/terminal_sync/terminal_sync_status_safe_spec.js +++ b/spec/frontend/ide/components/terminal_sync/terminal_sync_status_safe_spec.js @@ -1,10 +1,10 @@ -import { createLocalVue, shallowMount } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; +import Vue from 'vue'; import Vuex from 'vuex'; import TerminalSyncStatus from '~/ide/components/terminal_sync/terminal_sync_status.vue'; import TerminalSyncStatusSafe from '~/ide/components/terminal_sync/terminal_sync_status_safe.vue'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('ide/components/terminal_sync/terminal_sync_status_safe', () => { let store; @@ -16,7 +16,6 @@ describe('ide/components/terminal_sync/terminal_sync_status_safe', () => { }); wrapper = shallowMount(TerminalSyncStatusSafe, { - localVue, store, }); }; diff --git a/spec/frontend/ide/components/terminal_sync/terminal_sync_status_spec.js b/spec/frontend/ide/components/terminal_sync/terminal_sync_status_spec.js index c916c43d1e2..3a326b08fff 100644 --- a/spec/frontend/ide/components/terminal_sync/terminal_sync_status_spec.js +++ b/spec/frontend/ide/components/terminal_sync/terminal_sync_status_spec.js @@ -1,5 +1,6 @@ import { GlLoadingIcon, GlIcon } from '@gitlab/ui'; -import { createLocalVue, shallowMount } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; +import Vue from 'vue'; import Vuex from 'vuex'; import TerminalSyncStatus from '~/ide/components/terminal_sync/terminal_sync_status.vue'; import { @@ -11,8 +12,7 @@ import { const TEST_MESSAGE = 'lorem ipsum dolar sit'; const START_LOADING = 'START_LOADING'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('ide/components/terminal_sync/terminal_sync_status', () => { let moduleState; @@ -35,7 +35,6 @@ describe('ide/components/terminal_sync/terminal_sync_status', () => { }); wrapper = shallowMount(TerminalSyncStatus, { - localVue, store, }); }; diff --git a/spec/frontend/ide/lib/common/model_spec.js b/spec/frontend/ide/lib/common/model_spec.js index 51df1e2e42f..5d1623429c0 100644 --- a/spec/frontend/ide/lib/common/model_spec.js +++ b/spec/frontend/ide/lib/common/model_spec.js @@ -81,16 +81,13 @@ describe('Multi-file editor library model', () => { }); describe('onChange', () => { - it('calls callback on change', (done) => { + it('calls callback on change', () => { const spy = jest.fn(); model.onChange(spy); model.getModel().setValue('123'); - setImmediate(() => { - expect(spy).toHaveBeenCalledWith(model, expect.anything()); - done(); - }); + expect(spy).toHaveBeenCalledWith(model, expect.anything()); }); }); diff --git a/spec/frontend/ide/stores/actions/file_spec.js b/spec/frontend/ide/stores/actions/file_spec.js index 6b94d7cf6f1..45d1beea3f8 100644 --- a/spec/frontend/ide/stores/actions/file_spec.js +++ b/spec/frontend/ide/stores/actions/file_spec.js @@ -1,5 +1,5 @@ import MockAdapter from 'axios-mock-adapter'; -import Vue from 'vue'; +import { nextTick } from 'vue'; import eventHub from '~/ide/eventhub'; import { createRouter } from '~/ide/ide_router'; import service from '~/ide/services'; @@ -68,7 +68,7 @@ describe('IDE store file actions', () => { return store .dispatch('closeFile', localFile) - .then(Vue.nextTick) + .then(nextTick) .then(() => { expect(store.state.openFiles.length).toBe(0); expect(store.state.changedFiles.length).toBe(1); @@ -83,7 +83,7 @@ describe('IDE store file actions', () => { return store .dispatch('closeFile', localFile) - .then(Vue.nextTick) + .then(nextTick) .then(() => { expect(router.push).toHaveBeenCalledWith('/project/test/test/tree/main/-/newOpenFile/'); }); diff --git a/spec/frontend/ide/stores/actions_spec.js b/spec/frontend/ide/stores/actions_spec.js index e575667b8c6..be43c618095 100644 --- a/spec/frontend/ide/stores/actions_spec.js +++ b/spec/frontend/ide/stores/actions_spec.js @@ -274,24 +274,17 @@ describe('Multi-file store actions', () => { }); describe('scrollToTab', () => { - it('focuses the current active element', (done) => { + it('focuses the current active element', () => { document.body.innerHTML += '<div id="tabs"><div class="active"><div class="repo-tab"></div></div></div>'; const el = document.querySelector('.repo-tab'); jest.spyOn(el, 'focus').mockImplementation(); - store - .dispatch('scrollToTab') - .then(() => { - setImmediate(() => { - expect(el.focus).toHaveBeenCalled(); + return store.dispatch('scrollToTab').then(() => { + expect(el.focus).toHaveBeenCalled(); - document.getElementById('tabs').remove(); - - done(); - }); - }) - .catch(done.fail); + document.getElementById('tabs').remove(); + }); }); }); diff --git a/spec/frontend/ide/stores/modules/clientside/actions_spec.js b/spec/frontend/ide/stores/modules/clientside/actions_spec.js index 88d7a630a90..d2777623b0d 100644 --- a/spec/frontend/ide/stores/modules/clientside/actions_spec.js +++ b/spec/frontend/ide/stores/modules/clientside/actions_spec.js @@ -1,11 +1,12 @@ import MockAdapter from 'axios-mock-adapter'; import { TEST_HOST } from 'helpers/test_constants'; import testAction from 'helpers/vuex_action_helper'; +import { PING_USAGE_PREVIEW_KEY } from '~/ide/constants'; import * as actions from '~/ide/stores/modules/clientside/actions'; import axios from '~/lib/utils/axios_utils'; const TEST_PROJECT_URL = `${TEST_HOST}/lorem/ipsum`; -const TEST_USAGE_URL = `${TEST_PROJECT_URL}/service_ping/web_ide_clientside_preview`; +const TEST_USAGE_URL = `${TEST_PROJECT_URL}/service_ping/${PING_USAGE_PREVIEW_KEY}`; describe('IDE store module clientside actions', () => { let rootGetters; @@ -30,7 +31,7 @@ describe('IDE store module clientside actions', () => { mock.onPost(TEST_USAGE_URL).reply(() => usageSpy()); - testAction(actions.pingUsage, null, rootGetters, [], [], () => { + testAction(actions.pingUsage, PING_USAGE_PREVIEW_KEY, rootGetters, [], [], () => { expect(usageSpy).toHaveBeenCalled(); done(); }); diff --git a/spec/frontend/ide/stores/plugins/terminal_spec.js b/spec/frontend/ide/stores/plugins/terminal_spec.js index d4cdad16ecb..912de88cb39 100644 --- a/spec/frontend/ide/stores/plugins/terminal_spec.js +++ b/spec/frontend/ide/stores/plugins/terminal_spec.js @@ -1,4 +1,4 @@ -import { createLocalVue } from '@vue/test-utils'; +import Vue from 'vue'; import Vuex from 'vuex'; import { TEST_HOST } from 'helpers/test_constants'; import terminalModule from '~/ide/stores/modules/terminal'; @@ -11,8 +11,7 @@ const TEST_DATASET = { eeWebTerminalConfigHelpPath: `${TEST_HOST}/web/terminal/config/help`, eeWebTerminalRunnersHelpPath: `${TEST_HOST}/web/terminal/runners/help`, }; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('ide/stores/extend', () => { let store; |