diff options
Diffstat (limited to 'spec/frontend_integration/ide')
3 files changed, 140 insertions, 10 deletions
diff --git a/spec/frontend_integration/ide/__snapshots__/ide_integration_spec.js.snap b/spec/frontend_integration/ide/__snapshots__/ide_integration_spec.js.snap index 6beb5eab6db..6c120898f01 100644 --- a/spec/frontend_integration/ide/__snapshots__/ide_integration_spec.js.snap +++ b/spec/frontend_integration/ide/__snapshots__/ide_integration_spec.js.snap @@ -20,6 +20,7 @@ exports[`WebIDE runs 1`] = ` > <div class="multi-file-commit-panel-inner" + data-testid="ide-side-bar-inner" > <div class="multi-file-loading-container" diff --git a/spec/frontend_integration/ide/ide_helper.js b/spec/frontend_integration/ide/ide_helper.js new file mode 100644 index 00000000000..a43695fea8f --- /dev/null +++ b/spec/frontend_integration/ide/ide_helper.js @@ -0,0 +1,102 @@ +import { findAllByText, fireEvent, getByLabelText, screen } from '@testing-library/dom'; + +const isFileRowOpen = row => row.matches('.is-open'); + +const getLeftSidebar = () => screen.getByTestId('left-sidebar'); + +const clickOnLeftSidebarTab = name => { + const sidebar = getLeftSidebar(); + + const button = getByLabelText(sidebar, name); + + button.click(); +}; + +const findMonacoEditor = () => + screen.findByLabelText(/Editor content;/).then(x => x.closest('.monaco-editor')); + +const findAndSetEditorValue = async value => { + const editor = await findMonacoEditor(); + const uri = editor.getAttribute('data-uri'); + + window.monaco.editor.getModel(uri).setValue(value); +}; + +const findTreeBody = () => screen.findByTestId('ide-tree-body', {}, { timeout: 5000 }); + +const findFileRowContainer = (row = null) => + row ? Promise.resolve(row.parentElement) : findTreeBody(); + +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()); +}; + +const openFileRow = row => { + if (!row || isFileRowOpen(row)) { + return; + } + + row.click(); +}; + +const findAndTraverseToPath = async (path, index = 0, row = null) => { + if (!path) { + return row; + } + + const [name, ...restOfPath] = path.split('/'); + + openFileRow(row); + + const child = await findFileChild(row, name, index); + + return findAndTraverseToPath(restOfPath.join('/'), index + 1, child); +}; + +const clickFileRowAction = (row, name) => { + fireEvent.mouseOver(row); + + const dropdownButton = getByLabelText(row, 'Create new file or directory'); + dropdownButton.click(); + + const dropdownAction = getByLabelText(dropdownButton.parentNode, name); + dropdownAction.click(); +}; + +const findAndSetFileName = async value => { + const nameField = await screen.findByTestId('file-name-field'); + fireEvent.input(nameField, { target: { value } }); + + const createButton = screen.getByText('Create file'); + createButton.click(); +}; + +export const createFile = async (path, content) => { + const parentPath = path + .split('/') + .slice(0, -1) + .join('/'); + + const parentRow = await findAndTraverseToPath(parentPath); + clickFileRowAction(parentRow, 'New file'); + + await findAndSetFileName(path); + await findAndSetEditorValue(content); +}; + +export const deleteFile = async path => { + const row = await findAndTraverseToPath(path); + clickFileRowAction(row, 'Delete'); +}; + +export const commit = async () => { + clickOnLeftSidebarTab('Commit'); + screen.getByTestId('begin-commit-button').click(); + + await screen.findByLabelText(/Commit to .+ branch/).then(x => x.click()); + + screen.getByText('Commit').click(); +}; diff --git a/spec/frontend_integration/ide/ide_integration_spec.js b/spec/frontend_integration/ide/ide_integration_spec.js index 91d89c26ec1..c4d0c4df8de 100644 --- a/spec/frontend_integration/ide/ide_integration_spec.js +++ b/spec/frontend_integration/ide/ide_integration_spec.js @@ -1,17 +1,10 @@ -/** - * WARNING: WIP - * - * Please do not copy from this spec or use it as an example for anything. - * - * This is in place to iteratively set up the frontend integration testing environment - * and will be improved upon in a later iteration. - * - * See https://gitlab.com/gitlab-org/gitlab/-/issues/208800 for more information. - */ import { TEST_HOST } from 'helpers/test_constants'; +import { waitForText } from 'helpers/wait_for_text'; import { useOverclockTimers } from 'test_helpers/utils/overclock_timers'; +import { createCommitId } from 'test_helpers/factories/commit_id'; import { initIde } from '~/ide'; import extendStore from '~/ide/stores/extend'; +import * as ideHelper from './ide_helper'; const TEST_DATASET = { emptyStateSvgPath: '/test/empty_state.svg', @@ -59,4 +52,38 @@ describe('WebIDE', () => { expect(root).toMatchSnapshot(); }); + + it('user commits changes', async () => { + createComponent(); + + await ideHelper.createFile('foo/bar/test.txt', 'Lorem ipsum dolar sit'); + await ideHelper.deleteFile('foo/bar/.gitkeep'); + await ideHelper.commit(); + + const commitId = createCommitId(1); + const commitShortId = commitId.slice(0, 8); + + await waitForText('All changes are committed'); + await waitForText(commitShortId); + + expect(mockServer.db.branches.findBy({ name: 'master' }).commit).toMatchObject({ + short_id: commitShortId, + id: commitId, + message: 'Update foo/bar/test.txt\nDeleted foo/bar/.gitkeep', + __actions: [ + { + action: 'create', + content: 'Lorem ipsum dolar sit\n', + encoding: 'text', + file_path: 'foo/bar/test.txt', + last_commit_id: '', + }, + { + action: 'delete', + encoding: 'text', + file_path: 'foo/bar/.gitkeep', + }, + ], + }); + }); }); |