Commit c419f753 authored by Paul Slaughter's avatar Paul Slaughter

Merge branch '254254-web-ide-fe-integration-spec' into 'master'

Add integration spec "user commits changes"

See merge request gitlab-org/gitlab!42885
parents 41b74fd2 c8d14fb8
......@@ -32,7 +32,7 @@ export default {
</script>
<template>
<nav class="ide-activity-bar">
<nav class="ide-activity-bar" data-testid="left-sidebar">
<ul class="list-unstyled">
<li>
<button
......
......@@ -44,7 +44,7 @@ export default {
<nav-dropdown />
<slot name="header"></slot>
</header>
<div class="ide-tree-body h-100">
<div class="ide-tree-body h-100" data-testid="ide-tree-body">
<template v-if="currentTree.tree.length">
<file-tree
v-for="file in currentTree.tree"
......
......@@ -152,6 +152,7 @@ export default {
v-model.trim="entryName"
type="text"
class="form-control"
data-testid="file-name-field"
data-qa-selector="file_name_field"
:placeholder="placeholder"
/>
......
import { findByText } from '@testing-library/dom';
export const waitForText = async (text, container = document) => findByText(container, text);
......@@ -4,3 +4,5 @@ settings:
import/resolver:
jest:
jestConfigFile: 'jest.config.integration.js'
globals:
mockServer: false
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();
};
/**
* 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',
},
],
});
});
});
import { createMockServer } from '../mock_server';
beforeEach(() => {
if (global.mockServer) {
global.mockServer.shutdown();
}
const server = createMockServer();
server.logging = false;
global.mockServer = server;
});
afterEach(() => {
global.mockServer.shutdown();
global.mockServer = null;
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment