mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-22 12:50:29 -04:00
Refresh master with initial release/0.24 snapshot (#332)
* Initial port of release/0.24 source code * Fix additional headers * Fix a typo in launch.json
This commit is contained in:
194
test/smoke/src/areas/editor/editor.ts
Normal file
194
test/smoke/src/areas/editor/editor.ts
Normal file
@@ -0,0 +1,194 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { SpectronApplication } from '../../spectron/application';
|
||||
import { QuickOutline } from './quickoutline';
|
||||
import { References } from './peek';
|
||||
|
||||
const RENAME_BOX = '.monaco-editor .monaco-editor.rename-box';
|
||||
const RENAME_INPUT = `${RENAME_BOX} .rename-input`;
|
||||
|
||||
export class Editor {
|
||||
|
||||
private static VIEW_LINES = '.monaco-editor .view-lines';
|
||||
private static LINE_NUMBERS = '.monaco-editor .margin .margin-view-overlays .line-numbers';
|
||||
private static FOLDING_EXPANDED = '.monaco-editor .margin .margin-view-overlays>:nth-child(${INDEX}) .folding';
|
||||
private static FOLDING_COLLAPSED = `${Editor.FOLDING_EXPANDED}.collapsed`;
|
||||
|
||||
constructor(private spectron: SpectronApplication) {
|
||||
}
|
||||
|
||||
async openOutline(): Promise<QuickOutline> {
|
||||
const outline = new QuickOutline(this.spectron);
|
||||
await outline.open();
|
||||
return outline;
|
||||
}
|
||||
|
||||
async findReferences(term: string, line: number): Promise<References> {
|
||||
await this.clickOnTerm(term, line);
|
||||
await this.spectron.workbench.quickopen.runCommand('Find All References');
|
||||
const references = new References(this.spectron);
|
||||
await references.waitUntilOpen();
|
||||
return references;
|
||||
}
|
||||
|
||||
async rename(filename: string, line: number, from: string, to: string): Promise<void> {
|
||||
await this.clickOnTerm(from, line);
|
||||
await this.spectron.workbench.quickopen.runCommand('Rename Symbol');
|
||||
|
||||
await this.spectron.client.waitForActiveElement(RENAME_INPUT);
|
||||
await this.spectron.client.setValue(RENAME_INPUT, to);
|
||||
|
||||
await this.spectron.client.keys(['Enter', 'NULL']);
|
||||
}
|
||||
|
||||
async gotoDefinition(term: string, line: number): Promise<void> {
|
||||
await this.clickOnTerm(term, line);
|
||||
await this.spectron.workbench.quickopen.runCommand('Go to Definition');
|
||||
}
|
||||
|
||||
async peekDefinition(term: string, line: number): Promise<References> {
|
||||
await this.clickOnTerm(term, line);
|
||||
await this.spectron.workbench.quickopen.runCommand('Peek Definition');
|
||||
const peek = new References(this.spectron);
|
||||
await peek.waitUntilOpen();
|
||||
return peek;
|
||||
}
|
||||
|
||||
async waitForHighlightingLine(line: number): Promise<void> {
|
||||
const currentLineIndex = await this.getViewLineIndex(line);
|
||||
if (currentLineIndex) {
|
||||
await this.spectron.client.waitForElement(`.monaco-editor .view-overlays>:nth-child(${currentLineIndex}) .current-line`);
|
||||
return;
|
||||
}
|
||||
throw new Error('Cannot find line ' + line);
|
||||
}
|
||||
|
||||
async getSelector(term: string, line: number): Promise<string> {
|
||||
const lineIndex = await this.getViewLineIndex(line);
|
||||
const classNames = await this.spectron.client.waitFor(() => this.getClassSelectors(term, lineIndex), classNames => classNames && !!classNames.length, 'Getting class names for editor lines');
|
||||
return `${Editor.VIEW_LINES}>:nth-child(${lineIndex}) span span.${classNames[0]}`;
|
||||
}
|
||||
|
||||
async foldAtLine(line: number): Promise<any> {
|
||||
const lineIndex = await this.getViewLineIndex(line);
|
||||
await this.spectron.client.waitAndClick(Editor.FOLDING_EXPANDED.replace('${INDEX}', '' + lineIndex));
|
||||
await this.spectron.client.waitForElement(Editor.FOLDING_COLLAPSED.replace('${INDEX}', '' + lineIndex));
|
||||
}
|
||||
|
||||
async unfoldAtLine(line: number): Promise<any> {
|
||||
const lineIndex = await this.getViewLineIndex(line);
|
||||
await this.spectron.client.waitAndClick(Editor.FOLDING_COLLAPSED.replace('${INDEX}', '' + lineIndex));
|
||||
await this.spectron.client.waitForElement(Editor.FOLDING_EXPANDED.replace('${INDEX}', '' + lineIndex));
|
||||
}
|
||||
|
||||
async waitUntilHidden(line: number): Promise<void> {
|
||||
await this.spectron.client.waitFor<number>(() => this.getViewLineIndexWithoutWait(line), lineNumber => lineNumber === undefined, 'Waiting until line number is hidden');
|
||||
}
|
||||
|
||||
async waitUntilShown(line: number): Promise<void> {
|
||||
await this.getViewLineIndex(line);
|
||||
}
|
||||
|
||||
async clickOnTerm(term: string, line: number): Promise<void> {
|
||||
const selector = await this.getSelector(term, line);
|
||||
await this.spectron.client.waitAndClick(selector);
|
||||
}
|
||||
|
||||
async waitForTypeInEditor(filename: string, text: string, selectorPrefix = ''): Promise<any> {
|
||||
const editor = [
|
||||
selectorPrefix || '',
|
||||
`.monaco-editor[data-uri$="${filename}"]`
|
||||
].join(' ');
|
||||
|
||||
await this.spectron.client.element(editor);
|
||||
|
||||
const textarea = `${editor} textarea`;
|
||||
await this.spectron.client.waitForActiveElement(textarea);
|
||||
|
||||
// https://github.com/Microsoft/vscode/issues/34203#issuecomment-334441786
|
||||
await this.spectron.client.spectron.client.selectorExecute(textarea, (elements, text) => {
|
||||
const textarea = (Array.isArray(elements) ? elements : [elements])[0] as HTMLTextAreaElement;
|
||||
const start = textarea.selectionStart;
|
||||
const newStart = start + text.length;
|
||||
const value = textarea.value;
|
||||
const newValue = value.substr(0, start) + text + value.substr(start);
|
||||
|
||||
textarea.value = newValue;
|
||||
textarea.setSelectionRange(newStart, newStart);
|
||||
|
||||
const event = new Event('input', { 'bubbles': true, 'cancelable': true });
|
||||
textarea.dispatchEvent(event);
|
||||
}, text);
|
||||
|
||||
await this.waitForEditorContents(filename, c => c.indexOf(text) > -1, selectorPrefix);
|
||||
}
|
||||
|
||||
async waitForEditorContents(filename: string, accept: (contents: string) => boolean, selectorPrefix = ''): Promise<any> {
|
||||
const selector = [
|
||||
selectorPrefix || '',
|
||||
`.monaco-editor[data-uri$="${filename}"] .view-lines`
|
||||
].join(' ');
|
||||
|
||||
return this.spectron.client.waitForTextContent(selector, undefined, c => accept(c.replace(/\u00a0/g, ' ')));
|
||||
}
|
||||
|
||||
async waitForActiveEditor(filename: string): Promise<any> {
|
||||
const selector = `.editor-container .monaco-editor[data-uri$="${filename}"] textarea`;
|
||||
return this.spectron.client.waitForActiveElement(selector);
|
||||
}
|
||||
|
||||
// async waitForActiveEditorFirstLineText(filename: string): Promise<string> {
|
||||
// const selector = `.editor-container .monaco-editor[data-uri$="${filename}"] textarea`;
|
||||
// const result = await this.spectron.client.waitFor(
|
||||
// () => this.spectron.client.spectron.client.execute(s => {
|
||||
// if (!document.activeElement.matches(s)) {
|
||||
// return undefined;
|
||||
// }
|
||||
|
||||
// let element: Element | null = document.activeElement;
|
||||
// while (element && !/monaco-editor/.test(element.className) && element !== document.body) {
|
||||
// element = element.parentElement;
|
||||
// }
|
||||
|
||||
// if (element && /monaco-editor/.test(element.className)) {
|
||||
// const firstLine = element.querySelector('.view-lines span span:nth-child(1)');
|
||||
|
||||
// if (firstLine) {
|
||||
// return (firstLine.textContent || '').replace(/\u00a0/g, ' '); // DAMN
|
||||
// }
|
||||
// }
|
||||
|
||||
// return undefined;
|
||||
// }, selector),
|
||||
// r => typeof r.value === 'string',
|
||||
// `wait for active editor first line: ${selector}`
|
||||
// );
|
||||
|
||||
// return result.value;
|
||||
// }
|
||||
|
||||
private async getClassSelectors(term: string, viewline: number): Promise<string[]> {
|
||||
const result: { text: string, className: string }[] = await this.spectron.webclient.selectorExecute(`${Editor.VIEW_LINES}>:nth-child(${viewline}) span span`,
|
||||
elements => (Array.isArray(elements) ? elements : [elements])
|
||||
.map(element => ({ text: element.textContent, className: element.className })));
|
||||
return result.filter(r => r.text === term).map(({ className }) => className);
|
||||
}
|
||||
|
||||
private async getViewLineIndex(line: number): Promise<number> {
|
||||
return await this.spectron.client.waitFor<number>(() => this.getViewLineIndexWithoutWait(line), void 0, 'Getting line index');
|
||||
}
|
||||
|
||||
private async getViewLineIndexWithoutWait(line: number): Promise<number | undefined> {
|
||||
const lineNumbers = await this.spectron.webclient.selectorExecute(Editor.LINE_NUMBERS,
|
||||
elements => (Array.isArray(elements) ? elements : [elements]).map(element => element.textContent));
|
||||
for (let index = 0; index < lineNumbers.length; index++) {
|
||||
if (lineNumbers[index] === `${line}`) {
|
||||
return index + 1;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user