Commit c34a9aa3 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents c8df8fec fdc1d6a8
3154e9cb4c1df03c5405e2bd8a429838ebde03f2
cb5c003584e180415fe33d1712e0d5aee2a22b0c
......@@ -137,6 +137,7 @@ export default {
ref="modal"
modal-id="ide-new-entry"
data-qa-selector="new_file_modal"
data-testid="ide-new-entry"
:title="modalTitle"
:ok-title="buttonLabel"
ok-variant="success"
......
......@@ -109,7 +109,7 @@ export default {
</script>
<template>
<div ref="markdownPreview" class="md-previewer">
<div ref="markdownPreview" class="md-previewer" data-testid="md-previewer">
<gl-skeleton-loading v-if="isLoading" />
<div v-else class="md" v-html="previewContent"></div>
</div>
......
......@@ -75,7 +75,9 @@ Let's consider the following scenario:
A unique job token is generated for each job and provides the user read
access all projects that would be normally accessible to the user creating that
job. The unique job token does not have any write permissions, but there
is a [proposal to add support](https://gitlab.com/gitlab-org/gitlab/-/issues/35067).
is a [proposal to add support](https://gitlab.com/groups/gitlab-org/-/epics/3559).
If you need your CI pipeline to push to the Package Registry, consider using [deploy tokens](deploy_tokens/index.md).
We try to make sure that this token doesn't leak by:
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'IDE user sees editor info', :js do
include WebIdeSpecHelpers
let_it_be(:project) { create(:project, :public, :repository) }
let_it_be(:user) { project.owner }
before do
sign_in(user)
ide_visit(project)
end
it 'shows line position' do
ide_open_file('README.md')
within find('.ide-status-bar') do
expect(page).to have_content('1:1')
end
ide_set_editor_position(4, 10)
within find('.ide-status-bar') do
expect(page).not_to have_content('1:1')
expect(page).to have_content('4:10')
end
end
it 'updates after rename' do
ide_open_file('README.md')
ide_set_editor_position(4, 10)
within find('.ide-status-bar') do
expect(page).to have_content('markdown')
expect(page).to have_content('4:10')
end
ide_rename_file('README.md', 'READMEZ.txt')
within find('.ide-status-bar') do
expect(page).to have_content('plaintext')
expect(page).to have_content('1:1')
end
end
it 'persists position after rename' do
ide_open_file('README.md')
ide_set_editor_position(4, 10)
ide_open_file('files/js/application.js')
ide_rename_file('README.md', 'READING_RAINBOW.md')
ide_open_file('READING_RAINBOW.md')
within find('.ide-status-bar') do
expect(page).to have_content('4:10')
end
end
it 'persists position' do
ide_open_file('README.md')
ide_set_editor_position(4, 10)
ide_close_file('README.md')
ide_open_file('README.md')
within find('.ide-status-bar') do
expect(page).to have_content('markdown')
expect(page).to have_content('4:10')
end
end
it 'persists viewer' do
ide_open_file('README.md')
click_link('Preview Markdown')
within find('.md-previewer') do
expect(page).to have_content('testme')
end
# Switch away from and back to the file
ide_open_file('.gitignore')
ide_open_file('README.md')
# Preview is still enabled
within find('.md-previewer') do
expect(page).to have_content('testme')
end
end
end
import { findAllByText, fireEvent, getByLabelText, screen } from '@testing-library/dom';
import {
findAllByText,
fireEvent,
getByLabelText,
findByTestId,
getByText,
screen,
} from '@testing-library/dom';
const isFolderRowOpen = row => row.matches('.folder.is-open');
......@@ -12,6 +19,11 @@ const clickOnLeftSidebarTab = name => {
button.click();
};
export const getStatusBar = () => document.querySelector('.ide-status-bar');
export const waitForMonacoEditor = () =>
new Promise(resolve => window.monaco.editor.onDidCreateEditor(resolve));
export const findMonacoEditor = () =>
screen.findByLabelText(/Editor content;/).then(x => x.closest('.monaco-editor'));
......@@ -75,11 +87,13 @@ const clickFileRowAction = (row, name) => {
dropdownAction.click();
};
const findAndSetFileName = async value => {
const nameField = await screen.findByTestId('file-name-field');
const fillFileNameModal = async (value, submitText = 'Create file') => {
const modal = await screen.findByTestId('ide-new-entry');
const nameField = await findByTestId(modal, 'file-name-field');
fireEvent.input(nameField, { target: { value } });
const createButton = screen.getByText('Create file');
const createButton = getByText(modal, submitText, { selector: 'button' });
createButton.click();
};
......@@ -90,6 +104,10 @@ const findAndClickRootAction = async name => {
button.click();
};
export const clickPreviewMarkdown = () => {
screen.getByText('Preview Markdown').click();
};
export const openFile = async path => {
const row = await findAndTraverseToPath(path);
......@@ -110,7 +128,7 @@ export const createFile = async (path, content) => {
await findAndClickRootAction('New file');
}
await findAndSetFileName(path);
await fillFileNameModal(path);
await findAndSetEditorValue(content);
};
......@@ -123,6 +141,21 @@ export const deleteFile = async path => {
clickFileRowAction(row, 'Delete');
};
export const renameFile = async (path, newPath) => {
const row = await findAndTraverseToPath(path);
clickFileRowAction(row, 'Rename/Move');
await fillFileNameModal(newPath, 'Rename file');
};
export const closeFile = async path => {
const button = await screen.getByLabelText(`Close ${path}`, {
selector: '.multi-file-tabs button',
});
button.click();
};
export const commit = async () => {
clickOnLeftSidebarTab('Commit');
screen.getByTestId('begin-commit-button').click();
......
......@@ -68,4 +68,93 @@ describe('WebIDE', () => {
const tabs = Array.from(document.querySelectorAll('.multi-file-tab'));
expect(tabs.map(x => x.textContent.trim())).toEqual(['+test']);
});
describe('editor info', () => {
let statusBar;
let editor;
const waitForEditor = async () => {
editor = await ideHelper.waitForMonacoEditor();
};
const changeEditorPosition = async (lineNumber, column) => {
editor.setPosition({ lineNumber, column });
await vm.$nextTick();
};
beforeEach(async () => {
vm = startWebIDE(container);
await ideHelper.openFile('README.md');
editor = await ideHelper.waitForMonacoEditor();
statusBar = ideHelper.getStatusBar();
});
it('shows line position and type', () => {
expect(statusBar).toHaveText('1:1');
expect(statusBar).toHaveText('markdown');
});
it('persists viewer', async () => {
const markdownPreview = 'test preview_markdown result';
mockServer.post('/:namespace/:project/preview_markdown', () => ({
body: markdownPreview,
}));
await ideHelper.openFile('README.md');
ideHelper.clickPreviewMarkdown();
const el = await waitForText(markdownPreview);
expect(el).toHaveText(markdownPreview);
// Need to wait for monaco editor to load so it doesn't through errors on dispose
await ideHelper.openFile('.gitignore');
await ideHelper.waitForMonacoEditor();
await ideHelper.openFile('README.md');
await ideHelper.waitForMonacoEditor();
expect(el).toHaveText(markdownPreview);
});
describe('when editor position changes', () => {
beforeEach(async () => {
await changeEditorPosition(4, 10);
});
it('shows new line position', () => {
expect(statusBar).not.toHaveText('1:1');
expect(statusBar).toHaveText('4:10');
});
it('updates after rename', async () => {
await ideHelper.renameFile('README.md', 'READMEZ.txt');
await waitForEditor();
expect(statusBar).toHaveText('1:1');
expect(statusBar).toHaveText('plaintext');
});
it('persists position after opening then rename', async () => {
await ideHelper.openFile('files/js/application.js');
await waitForEditor();
await ideHelper.renameFile('README.md', 'READING_RAINBOW.md');
await ideHelper.openFile('READING_RAINBOW.md');
await waitForEditor();
expect(statusBar).toHaveText('4:10');
expect(statusBar).toHaveText('markdown');
});
it('persists position after closing', async () => {
await ideHelper.closeFile('README.md');
await ideHelper.openFile('README.md');
await waitForEditor();
expect(statusBar).toHaveText('4:10');
expect(statusBar).toHaveText('markdown');
});
});
});
});
......@@ -22,8 +22,6 @@ module WebIdeSpecHelpers
click_link('Web IDE')
wait_for_requests
save_monaco_editor_reference
end
def ide_tree_body
......@@ -65,17 +63,6 @@ module WebIdeSpecHelpers
ide_set_editor_value(content)
end
def ide_rename_file(path, new_path)
container = ide_traverse_to_file(path)
click_file_action(container, 'Rename/Move')
within '#ide-new-entry' do
find('input').fill_in(with: new_path)
click_button('Rename file')
end
end
# Deletes a file by traversing to `path`
# then clicking the 'Delete' action.
#
......@@ -103,20 +90,6 @@ module WebIdeSpecHelpers
container
end
def ide_close_file(name)
within page.find('.multi-file-tabs') do
click_button("Close #{name}")
end
end
def ide_open_file(path)
row = ide_traverse_to_file(path)
ide_open_file_row(row)
wait_for_requests
end
def ide_open_file_row(row)
return if ide_folder_row_open?(row)
......@@ -130,10 +103,6 @@ module WebIdeSpecHelpers
execute_script("monaco.editor.getModel('#{uri}').setValue('#{escape_javascript(value)}')")
end
def ide_set_editor_position(line, col)
execute_script("TEST_EDITOR.setPosition(#{{ lineNumber: line, column: col }.to_json})")
end
def ide_editor_value
editor = find('.monaco-editor')
uri = editor['data-uri']
......@@ -180,8 +149,4 @@ module WebIdeSpecHelpers
wait_for_requests
end
end
def save_monaco_editor_reference
evaluate_script("monaco.editor.onDidCreateEditor(editor => { window.TEST_EDITOR = editor; })")
end
end
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