diff options
author | Robert Speicher <rspeicher@gmail.com> | 2021-01-20 13:34:23 -0600 |
---|---|---|
committer | Robert Speicher <rspeicher@gmail.com> | 2021-01-20 13:34:23 -0600 |
commit | 6438df3a1e0fb944485cebf07976160184697d72 (patch) | |
tree | 00b09bfd170e77ae9391b1a2f5a93ef6839f2597 /spec/frontend_integration | |
parent | 42bcd54d971da7ef2854b896a7b34f4ef8601067 (diff) | |
download | gitlab-ce-6438df3a1e0fb944485cebf07976160184697d72.tar.gz |
Add latest changes from gitlab-org/gitlab@13-8-stable-eev13.8.0-rc42
Diffstat (limited to 'spec/frontend_integration')
17 files changed, 118 insertions, 47 deletions
diff --git a/spec/frontend_integration/ide/helpers/ide_helper.js b/spec/frontend_integration/ide/helpers/ide_helper.js index fe8d5f93794..8d5d047b146 100644 --- a/spec/frontend_integration/ide/helpers/ide_helper.js +++ b/spec/frontend_integration/ide/helpers/ide_helper.js @@ -8,11 +8,11 @@ import { findByText, } from '@testing-library/dom'; -const isFolderRowOpen = row => row.matches('.folder.is-open'); +const isFolderRowOpen = (row) => row.matches('.folder.is-open'); const getLeftSidebar = () => screen.getByTestId('left-sidebar'); -export const switchLeftSidebarTab = name => { +export const switchLeftSidebarTab = (name) => { const sidebar = getLeftSidebar(); const button = getByLabelText(sidebar, name); @@ -23,7 +23,7 @@ export const switchLeftSidebarTab = name => { export const getStatusBar = () => document.querySelector('.ide-status-bar'); export const waitForMonacoEditor = () => - new Promise(resolve => window.monaco.editor.onDidCreateEditor(resolve)); + new Promise((resolve) => window.monaco.editor.onDidCreateEditor(resolve)); export const findMonacoEditor = () => screen.findAllByLabelText(/Editor content;/).then(([x]) => x.closest('.monaco-editor')); @@ -31,7 +31,7 @@ export const findMonacoEditor = () => export const findMonacoDiffEditor = () => screen.findAllByLabelText(/Editor content;/).then(([x]) => x.closest('.monaco-diff-editor')); -export const findAndSetEditorValue = async value => { +export const findAndSetEditorValue = async (value) => { const editor = await findMonacoEditor(); const uri = editor.getAttribute('data-uri'); @@ -45,9 +45,9 @@ export const getEditorValue = async () => { return window.monaco.editor.getModel(uri).getValue(); }; -const findTreeBody = () => screen.findByTestId('ide-tree-body', {}, { timeout: 5000 }); +const findTreeBody = () => screen.findByTestId('ide-tree-body'); -const findRootActions = () => screen.findByTestId('ide-root-actions', {}, { timeout: 7000 }); +const findRootActions = () => screen.findByTestId('ide-root-actions'); const findFileRowContainer = (row = null) => row ? Promise.resolve(row.parentElement) : findTreeBody(); @@ -56,10 +56,12 @@ const findFileChild = async (row, name, index = 0) => { const container = await findFileRowContainer(row); const children = await findAllByText(container, name, { selector: '.file-row-name' }); - return children.map(x => x.closest('.file-row')).find(x => x.dataset.level === index.toString()); + return children + .map((x) => x.closest('.file-row')) + .find((x) => x.dataset.level === index.toString()); }; -const openFileRow = row => { +const openFileRow = (row) => { if (!row || isFolderRowOpen(row)) { return; } @@ -101,7 +103,7 @@ const fillFileNameModal = async (value, submitText = 'Create file') => { createButton.click(); }; -const findAndClickRootAction = async name => { +const findAndClickRootAction = async (name) => { const container = await findRootActions(); const button = getByLabelText(container, name); @@ -112,20 +114,17 @@ export const clickPreviewMarkdown = () => { screen.getByText('Preview Markdown').click(); }; -export const openFile = async path => { +export const openFile = async (path) => { const row = await findAndTraverseToPath(path); openFileRow(row); }; -export const waitForTabToOpen = fileName => +export const waitForTabToOpen = (fileName) => findByText(document.querySelector('.multi-file-edit-pane'), fileName); export const createFile = async (path, content) => { - const parentPath = path - .split('/') - .slice(0, -1) - .join('/'); + const parentPath = path.split('/').slice(0, -1).join('/'); const parentRow = await findAndTraverseToPath(parentPath); @@ -139,11 +138,16 @@ export const createFile = async (path, content) => { await findAndSetEditorValue(content); }; +export const updateFile = async (path, content) => { + await openFile(path); + await findAndSetEditorValue(content); +}; + export const getFilesList = () => { - return screen.getAllByTestId('file-row-name-container').map(e => e.textContent.trim()); + return screen.getAllByTestId('file-row-name-container').map((e) => e.textContent.trim()); }; -export const deleteFile = async path => { +export const deleteFile = async (path) => { const row = await findAndTraverseToPath(path); clickFileRowAction(row, 'Delete'); }; @@ -155,7 +159,7 @@ export const renameFile = async (path, newPath) => { await fillFileNameModal(newPath, 'Rename file'); }; -export const closeFile = async path => { +export const closeFile = async (path) => { const button = await screen.getByLabelText(`Close ${path}`, { selector: '.multi-file-tabs button', }); @@ -163,11 +167,33 @@ export const closeFile = async path => { button.click(); }; -export const commit = async () => { +/** + * Fill out and submit the commit form in the Web IDE + * + * @param {Object} options - Used to fill out the commit form in the IDE + * @param {Boolean} options.newBranch - Flag for the "Create a new branch" radio. + * @param {Boolean} options.newMR - Flag for the "Start a new merge request" checkbox. + * @param {String} options.newBranchName - Value to put in the new branch name input field. The Web IDE supports leaving this field blank. + */ +export const commit = async ({ newBranch = false, newMR = false, newBranchName = '' } = {}) => { switchLeftSidebarTab('Commit'); screen.getByTestId('begin-commit-button').click(); - await screen.findByLabelText(/Commit to .+ branch/).then(x => x.click()); + if (!newBranch) { + const option = await screen.findByLabelText(/Commit to .+ branch/); + option.click(); + } else { + const option = await screen.findByLabelText('Create a new branch'); + option.click(); + + const branchNameInput = await screen.findByTestId('ide-new-branch-name'); + fireEvent.input(branchNameInput, { target: { value: newBranchName } }); + + const mrCheck = await screen.findByLabelText('Start a new merge request'); + if (Boolean(mrCheck.checked) !== newMR) { + mrCheck.click(); + } + } screen.getByText('Commit').click(); }; diff --git a/spec/frontend_integration/ide/helpers/start.js b/spec/frontend_integration/ide/helpers/start.js index 9dc9649e1bf..43a996286e7 100644 --- a/spec/frontend_integration/ide/helpers/start.js +++ b/spec/frontend_integration/ide/helpers/start.js @@ -2,6 +2,7 @@ import { TEST_HOST } from 'helpers/test_constants'; import extendStore from '~/ide/stores/extend'; import { IDE_DATASET } from './mock_data'; import { initIde } from '~/ide'; +import Editor from '~/ide/lib/editor'; export default (container, { isRepoEmpty = false, path = '' } = {}) => { global.jsdom.reconfigure({ @@ -13,5 +14,16 @@ export default (container, { isRepoEmpty = false, path = '' } = {}) => { const el = document.createElement('div'); Object.assign(el.dataset, IDE_DATASET); container.appendChild(el); - return initIde(el, { extendStore }); + const vm = initIde(el, { extendStore }); + + // We need to dispose of editor Singleton things or tests will bump into eachother + vm.$on('destroy', () => { + if (Editor.editorInstance) { + Editor.editorInstance.modelManager.dispose(); + Editor.editorInstance.dispose(); + Editor.editorInstance = null; + } + }); + + return vm; }; diff --git a/spec/frontend_integration/ide/ide_integration_spec.js b/spec/frontend_integration/ide/ide_integration_spec.js index dacc538d5ba..00a73661d14 100644 --- a/spec/frontend_integration/ide/ide_integration_spec.js +++ b/spec/frontend_integration/ide/ide_integration_spec.js @@ -1,5 +1,6 @@ import { waitForText } from 'helpers/wait_for_text'; import waitForPromises from 'helpers/wait_for_promises'; +import { setTestTimeout } from 'helpers/timeout'; import { useOverclockTimers } from 'test_helpers/utils/overclock_timers'; import { createCommitId } from 'test_helpers/factories/commit_id'; import * as ideHelper from './helpers/ide_helper'; @@ -12,6 +13,9 @@ describe('WebIDE', () => { let container; beforeEach(() => { + // For some reason these tests were timing out in CI. + // We will investigate in https://gitlab.com/gitlab-org/gitlab/-/issues/298714 + setTestTimeout(20000); setFixtures('<div class="webide-container"></div>'); container = document.querySelector('.webide-container'); }); @@ -55,6 +59,25 @@ describe('WebIDE', () => { }); }); + it('user commits changes to new branch', async () => { + vm = startWebIDE(container); + + expect(window.location.pathname).toBe('/-/ide/project/gitlab-test/lorem-ipsum/tree/master/-/'); + + await ideHelper.updateFile('README.md', 'Lorem dolar si amit\n'); + await ideHelper.commit({ newBranch: true, newMR: false, newBranchName: 'test-hello-world' }); + + await waitForText('All changes are committed'); + + // Wait for IDE to load new commit + await waitForText('10000000', document.querySelector('.ide-status-bar')); + + // It's important that the new branch is now in the route + expect(window.location.pathname).toBe( + '/-/ide/project/gitlab-test/lorem-ipsum/blob/test-hello-world/-/README.md', + ); + }); + it('user adds file that starts with +', async () => { vm = startWebIDE(container); @@ -66,7 +89,7 @@ describe('WebIDE', () => { // Assert that +test is the only open tab const tabs = Array.from(document.querySelectorAll('.multi-file-tab')); - expect(tabs.map(x => x.textContent.trim())).toEqual(['+test']); + expect(tabs.map((x) => x.textContent.trim())).toEqual(['+test']); }); describe('editor info', () => { diff --git a/spec/frontend_integration/ide/user_opens_file_spec.js b/spec/frontend_integration/ide/user_opens_file_spec.js index 98a73c7a029..7fa6dcecc9e 100644 --- a/spec/frontend_integration/ide/user_opens_file_spec.js +++ b/spec/frontend_integration/ide/user_opens_file_spec.js @@ -3,9 +3,7 @@ import { screen } from '@testing-library/dom'; import * as ideHelper from './helpers/ide_helper'; import startWebIDE from './helpers/start'; -// https://gitlab.com/gitlab-org/gitlab/-/issues/293654#note_466432769 -// eslint-disable-next-line jest/no-disabled-tests -describe.skip('IDE: User opens a file in the Web IDE', () => { +describe('IDE: User opens a file in the Web IDE', () => { useOverclockTimers(); let vm; diff --git a/spec/frontend_integration/test_helpers/factories/commit_id.js b/spec/frontend_integration/test_helpers/factories/commit_id.js index 9fa278c9dde..815da19a2d9 100644 --- a/spec/frontend_integration/test_helpers/factories/commit_id.js +++ b/spec/frontend_integration/test_helpers/factories/commit_id.js @@ -1,7 +1,5 @@ const COMMIT_ID_LENGTH = 40; -const DEFAULT_COMMIT_ID = Array(COMMIT_ID_LENGTH) - .fill('0') - .join(''); +const DEFAULT_COMMIT_ID = Array(COMMIT_ID_LENGTH).fill('0').join(''); export const createCommitId = (index = 0) => `${index}${DEFAULT_COMMIT_ID}`.substr(0, COMMIT_ID_LENGTH); diff --git a/spec/frontend_integration/test_helpers/fixtures.js b/spec/frontend_integration/test_helpers/fixtures.js index 46946ed71f2..fde3fd8cb63 100644 --- a/spec/frontend_integration/test_helpers/fixtures.js +++ b/spec/frontend_integration/test_helpers/fixtures.js @@ -10,9 +10,9 @@ const createFactoryWithDefault = (fn, defaultValue) => () => { }; const factory = { - json: fn => createFactoryWithDefault(fn, { error: 'fixture not found' }), - text: fn => createFactoryWithDefault(fn, 'Hello world\nHow are you today?\n'), - binary: fn => createFactoryWithDefault(fn, ''), + json: (fn) => createFactoryWithDefault(fn, { error: 'fixture not found' }), + text: (fn) => createFactoryWithDefault(fn, 'Hello world\nHow are you today?\n'), + binary: (fn) => createFactoryWithDefault(fn, ''), }; export const getProject = factory.json(() => require('test_fixtures/api/projects/get.json')); diff --git a/spec/frontend_integration/test_helpers/mock_server/index.js b/spec/frontend_integration/test_helpers/mock_server/index.js index 6f090565635..2aebdefaafb 100644 --- a/spec/frontend_integration/test_helpers/mock_server/index.js +++ b/spec/frontend_integration/test_helpers/mock_server/index.js @@ -26,7 +26,7 @@ export const createMockServerOptions = () => ({ }, seeds(schema) { schema.db.loadData({ - files: getRepositoryFiles().map(path => ({ path })), + files: getRepositoryFiles().map((path) => ({ path })), projects: [getProject(), getEmptyProject()], branches: [getBranch()], mergeRequests: getMergeRequests(), diff --git a/spec/frontend_integration/test_helpers/mock_server/routes/404.js b/spec/frontend_integration/test_helpers/mock_server/routes/404.js index 9e08016577b..bc8edba927e 100644 --- a/spec/frontend_integration/test_helpers/mock_server/routes/404.js +++ b/spec/frontend_integration/test_helpers/mock_server/routes/404.js @@ -1,5 +1,5 @@ -export default server => { - ['get', 'post', 'put', 'delete', 'patch'].forEach(method => { +export default (server) => { + ['get', 'post', 'put', 'delete', 'patch'].forEach((method) => { server[method]('*', () => { return new Response(404); }); diff --git a/spec/frontend_integration/test_helpers/mock_server/routes/ci.js b/spec/frontend_integration/test_helpers/mock_server/routes/ci.js index 83951f09c56..6f1593a2cf9 100644 --- a/spec/frontend_integration/test_helpers/mock_server/routes/ci.js +++ b/spec/frontend_integration/test_helpers/mock_server/routes/ci.js @@ -1,6 +1,6 @@ import { getPipelinesEmptyResponse } from 'test_helpers/fixtures'; -export default server => { +export default (server) => { server.get('*/commit/:id/pipelines', () => { return getPipelinesEmptyResponse(); }); diff --git a/spec/frontend_integration/test_helpers/mock_server/routes/graphql.js b/spec/frontend_integration/test_helpers/mock_server/routes/graphql.js index ebb5415ba97..a22763dcb45 100644 --- a/spec/frontend_integration/test_helpers/mock_server/routes/graphql.js +++ b/spec/frontend_integration/test_helpers/mock_server/routes/graphql.js @@ -1,6 +1,6 @@ import { graphqlQuery } from '../graphql'; -export default server => { +export default (server) => { server.post('/api/graphql', (schema, request) => { const batches = JSON.parse(request.requestBody); diff --git a/spec/frontend_integration/test_helpers/mock_server/routes/index.js b/spec/frontend_integration/test_helpers/mock_server/routes/index.js index eea196b5158..e30fecf2f06 100644 --- a/spec/frontend_integration/test_helpers/mock_server/routes/index.js +++ b/spec/frontend_integration/test_helpers/mock_server/routes/index.js @@ -1,5 +1,5 @@ /* eslint-disable global-require */ -export default server => { +export default (server) => { [ require('./graphql'), require('./projects'), diff --git a/spec/frontend_integration/test_helpers/mock_server/routes/projects.js b/spec/frontend_integration/test_helpers/mock_server/routes/projects.js index f4d8ce4b23d..de37aa98eee 100644 --- a/spec/frontend_integration/test_helpers/mock_server/routes/projects.js +++ b/spec/frontend_integration/test_helpers/mock_server/routes/projects.js @@ -1,6 +1,6 @@ import { withKeys } from 'test_helpers/utils/obj'; -export default server => { +export default (server) => { server.get('/api/v4/projects/:id', (schema, request) => { const { id } = request.params; diff --git a/spec/frontend_integration/test_helpers/mock_server/routes/repository.js b/spec/frontend_integration/test_helpers/mock_server/routes/repository.js index 166c0cc32db..ba36463cad8 100644 --- a/spec/frontend_integration/test_helpers/mock_server/routes/repository.js +++ b/spec/frontend_integration/test_helpers/mock_server/routes/repository.js @@ -1,9 +1,9 @@ import { createNewCommit, createCommitIdGenerator } from 'test_helpers/factories'; -export default server => { +export default (server) => { const commitIdGenerator = createCommitIdGenerator(); - server.get('/api/v4/projects/:id/repository/branches', schema => { + server.get('/api/v4/projects/:id/repository/branches', (schema) => { return schema.db.branches; }); @@ -15,7 +15,7 @@ export default server => { return branch.attrs; }); - server.get('*/-/files/:id', schema => { + server.get('*/-/files/:id', (schema) => { return schema.db.files.map(({ path }) => path); }); @@ -37,13 +37,23 @@ export default server => { ); const branch = schema.branches.findBy({ name: branchName }); + const prevCommit = branch + ? branch.attrs.commit + : schema.branches.findBy({ name: 'master' }).attrs.commit; const commit = { - ...createNewCommit({ id: commitIdGenerator.next(), message }, branch.attrs.commit), + ...createNewCommit({ id: commitIdGenerator.next(), message }, prevCommit), __actions: actions, }; - branch.update({ commit }); + if (branch) { + branch.update({ commit }); + } else { + schema.branches.create({ + name: branchName, + commit, + }); + } return commit; }); diff --git a/spec/frontend_integration/test_helpers/setup/index.js b/spec/frontend_integration/test_helpers/setup/index.js index ba1d256e16e..946ccbec00c 100644 --- a/spec/frontend_integration/test_helpers/setup/index.js +++ b/spec/frontend_integration/test_helpers/setup/index.js @@ -3,3 +3,4 @@ import './setup_globals'; import './setup_axios'; import './setup_serializers'; import './setup_mock_server'; +import './setup_testing_library'; diff --git a/spec/frontend_integration/test_helpers/setup/setup_testing_library.js b/spec/frontend_integration/test_helpers/setup/setup_testing_library.js new file mode 100644 index 00000000000..5081b1c3b62 --- /dev/null +++ b/spec/frontend_integration/test_helpers/setup/setup_testing_library.js @@ -0,0 +1,3 @@ +import { configure } from '@testing-library/dom'; + +configure({ asyncUtilTimeout: 10000 }); diff --git a/spec/frontend_integration/test_helpers/snapshot_serializer.js b/spec/frontend_integration/test_helpers/snapshot_serializer.js index 8c4f95a9156..aacd144217f 100644 --- a/spec/frontend_integration/test_helpers/snapshot_serializer.js +++ b/spec/frontend_integration/test_helpers/snapshot_serializer.js @@ -4,7 +4,7 @@ export default { }, print(element, serialize) { element.$_hit = true; - element.querySelectorAll('[style]').forEach(el => { + element.querySelectorAll('[style]').forEach((el) => { el.$_hit = true; if (el.style.display === 'none') { el.textContent = '(jest: contents hidden)'; diff --git a/spec/frontend_integration/test_helpers/utils/obj_spec.js b/spec/frontend_integration/test_helpers/utils/obj_spec.js index 0ad7b4a1a4c..614250ccddc 100644 --- a/spec/frontend_integration/test_helpers/utils/obj_spec.js +++ b/spec/frontend_integration/test_helpers/utils/obj_spec.js @@ -3,9 +3,9 @@ import { withKeys, withValues } from './obj'; describe('frontend_integration/test_helpers/utils/obj', () => { describe('withKeys', () => { it('picks and maps keys', () => { - expect(withKeys({ a: '123', b: 456, c: 'd' }, { b: 'lorem', c: 'ipsum', z: 'zed ' })).toEqual( - { lorem: 456, ipsum: 'd' }, - ); + expect( + withKeys({ a: '123', b: 456, c: 'd' }, { b: 'lorem', c: 'ipsum', z: 'zed ' }), + ).toEqual({ lorem: 456, ipsum: 'd' }); }); }); |