summaryrefslogtreecommitdiff
path: root/spec/frontend_integration
diff options
context:
space:
mode:
authorRobert Speicher <rspeicher@gmail.com>2021-01-20 13:34:23 -0600
committerRobert Speicher <rspeicher@gmail.com>2021-01-20 13:34:23 -0600
commit6438df3a1e0fb944485cebf07976160184697d72 (patch)
tree00b09bfd170e77ae9391b1a2f5a93ef6839f2597 /spec/frontend_integration
parent42bcd54d971da7ef2854b896a7b34f4ef8601067 (diff)
downloadgitlab-ce-6438df3a1e0fb944485cebf07976160184697d72.tar.gz
Add latest changes from gitlab-org/gitlab@13-8-stable-eev13.8.0-rc42
Diffstat (limited to 'spec/frontend_integration')
-rw-r--r--spec/frontend_integration/ide/helpers/ide_helper.js66
-rw-r--r--spec/frontend_integration/ide/helpers/start.js14
-rw-r--r--spec/frontend_integration/ide/ide_integration_spec.js25
-rw-r--r--spec/frontend_integration/ide/user_opens_file_spec.js4
-rw-r--r--spec/frontend_integration/test_helpers/factories/commit_id.js4
-rw-r--r--spec/frontend_integration/test_helpers/fixtures.js6
-rw-r--r--spec/frontend_integration/test_helpers/mock_server/index.js2
-rw-r--r--spec/frontend_integration/test_helpers/mock_server/routes/404.js4
-rw-r--r--spec/frontend_integration/test_helpers/mock_server/routes/ci.js2
-rw-r--r--spec/frontend_integration/test_helpers/mock_server/routes/graphql.js2
-rw-r--r--spec/frontend_integration/test_helpers/mock_server/routes/index.js2
-rw-r--r--spec/frontend_integration/test_helpers/mock_server/routes/projects.js2
-rw-r--r--spec/frontend_integration/test_helpers/mock_server/routes/repository.js20
-rw-r--r--spec/frontend_integration/test_helpers/setup/index.js1
-rw-r--r--spec/frontend_integration/test_helpers/setup/setup_testing_library.js3
-rw-r--r--spec/frontend_integration/test_helpers/snapshot_serializer.js2
-rw-r--r--spec/frontend_integration/test_helpers/utils/obj_spec.js6
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' });
});
});