Merge from vscode 64980ea1f3f532c82bb6c28d27bba9ef2c5b4463 (#7206)

* Merge from vscode 64980ea1f3f532c82bb6c28d27bba9ef2c5b4463

* fix config changes

* fix strictnull checks
This commit is contained in:
Anthony Dresser
2019-09-15 22:38:26 -07:00
committed by GitHub
parent fa6c52699e
commit ea0f9e6ce9
1226 changed files with 21541 additions and 17633 deletions

View File

@@ -1,30 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Code } from '../../vscode/code';
export const enum ActivityBarPosition {
LEFT = 0,
RIGHT = 1
}
export class ActivityBar {
constructor(private code: Code) { }
async waitForActivityBar(position: ActivityBarPosition): Promise<void> {
let positionClass: string;
if (position === ActivityBarPosition.LEFT) {
positionClass = 'left';
} else if (position === ActivityBarPosition.RIGHT) {
positionClass = 'right';
} else {
throw new Error('No such position for activity bar defined.');
}
await this.code.waitForElement(`.part.activitybar.${positionClass}`);
}
}

View File

@@ -3,8 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Application } from '../../application';
import { ProblemSeverity, Problems } from '../problems/problems';
import { Application, ProblemSeverity, Problems } from '../../../../automation';
export function setup() {
describe('CSS', () => {
@@ -44,4 +43,4 @@ export function setup() {
await problems.hideProblemsView();
});
});
}
}

View File

@@ -8,7 +8,7 @@ import * as http from 'http';
import * as path from 'path';
import * as fs from 'fs';
import * as stripJsonComments from 'strip-json-comments';
import { Application } from '../../application';
import { Application } from '../../../../automation';
export function setup() {
describe('Debug', () => {

View File

@@ -1,148 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Viewlet } from '../workbench/viewlet';
import { Commands } from '../workbench/workbench';
import { Code, findElement } from '../../vscode/code';
import { Editors } from '../editor/editors';
import { Editor } from '../editor/editor';
import { IElement } from '../../vscode/driver';
const VIEWLET = 'div[id="workbench.view.debug"]';
const DEBUG_VIEW = `${VIEWLET} .debug-view-content`;
const CONFIGURE = `div[id="workbench.parts.sidebar"] .actions-container .configure`;
const STOP = `.debug-toolbar .action-label[title*="Stop"]`;
const STEP_OVER = `.debug-toolbar .action-label[title*="Step Over"]`;
const STEP_IN = `.debug-toolbar .action-label[title*="Step Into"]`;
const STEP_OUT = `.debug-toolbar .action-label[title*="Step Out"]`;
const CONTINUE = `.debug-toolbar .action-label[title*="Continue"]`;
const GLYPH_AREA = '.margin-view-overlays>:nth-child';
const BREAKPOINT_GLYPH = '.debug-breakpoint';
const PAUSE = `.debug-toolbar .action-label[title*="Pause"]`;
const DEBUG_STATUS_BAR = `.statusbar.debugging`;
const NOT_DEBUG_STATUS_BAR = `.statusbar:not(debugging)`;
const TOOLBAR_HIDDEN = `.debug-toolbar[aria-hidden="true"]`;
const STACK_FRAME = `${VIEWLET} .monaco-list-row .stack-frame`;
const SPECIFIC_STACK_FRAME = filename => `${STACK_FRAME} .file[title*="${filename}"]`;
const VARIABLE = `${VIEWLET} .debug-variables .monaco-list-row .expression`;
const CONSOLE_OUTPUT = `.repl .output.expression .value`;
const CONSOLE_INPUT_OUTPUT = `.repl .input-output-pair .output.expression .value`;
const REPL_FOCUSED = '.repl-input-wrapper .monaco-editor textarea';
export interface IStackFrame {
name: string;
lineNumber: number;
}
function toStackFrame(element: IElement): IStackFrame {
const name = findElement(element, e => /\bfile-name\b/.test(e.className))!;
const line = findElement(element, e => /\bline-number\b/.test(e.className))!;
const lineNumber = line.textContent ? parseInt(line.textContent.split(':').shift() || '0') : 0;
return {
name: name.textContent || '',
lineNumber
};
}
export class Debug extends Viewlet {
constructor(code: Code, private commands: Commands, private editors: Editors, private editor: Editor) {
super(code);
}
async openDebugViewlet(): Promise<any> {
if (process.platform === 'darwin') {
await this.code.dispatchKeybinding('cmd+shift+d');
} else {
await this.code.dispatchKeybinding('ctrl+shift+d');
}
await this.code.waitForElement(DEBUG_VIEW);
}
async configure(): Promise<any> {
await this.code.waitAndClick(CONFIGURE);
await this.editors.waitForEditorFocus('launch.json');
}
async setBreakpointOnLine(lineNumber: number): Promise<any> {
await this.code.waitForElement(`${GLYPH_AREA}(${lineNumber})`);
await this.code.waitAndClick(`${GLYPH_AREA}(${lineNumber})`, 5, 5);
await this.code.waitForElement(BREAKPOINT_GLYPH);
}
async startDebugging(): Promise<number> {
await this.code.dispatchKeybinding('f5');
await this.code.waitForElement(PAUSE);
await this.code.waitForElement(DEBUG_STATUS_BAR);
const portPrefix = 'Port: ';
const output = await this.waitForOutput(output => output.some(line => line.indexOf(portPrefix) >= 0));
const lastOutput = output.filter(line => line.indexOf(portPrefix) >= 0)[0];
return lastOutput ? parseInt(lastOutput.substr(portPrefix.length)) : 3000;
}
async stepOver(): Promise<any> {
await this.code.waitAndClick(STEP_OVER);
}
async stepIn(): Promise<any> {
await this.code.waitAndClick(STEP_IN);
}
async stepOut(): Promise<any> {
await this.code.waitAndClick(STEP_OUT);
}
async continue(): Promise<any> {
await this.code.waitAndClick(CONTINUE);
await this.waitForStackFrameLength(0);
}
async stopDebugging(): Promise<any> {
await this.code.waitAndClick(STOP);
await this.code.waitForElement(TOOLBAR_HIDDEN);
await this.code.waitForElement(NOT_DEBUG_STATUS_BAR);
}
async waitForStackFrame(func: (stackFrame: IStackFrame) => boolean, message: string): Promise<IStackFrame> {
const elements = await this.code.waitForElements(STACK_FRAME, true, elements => elements.some(e => func(toStackFrame(e))));
return elements.map(toStackFrame).filter(s => func(s))[0];
}
async waitForStackFrameLength(length: number): Promise<any> {
await this.code.waitForElements(STACK_FRAME, false, result => result.length === length);
}
async focusStackFrame(name: string, message: string): Promise<any> {
await this.code.waitAndClick(SPECIFIC_STACK_FRAME(name), 0, 0);
await this.editors.waitForTab(name);
}
async waitForReplCommand(text: string, accept: (result: string) => boolean): Promise<void> {
await this.commands.runCommand('Debug: Focus on Debug Console View');
await this.code.waitForActiveElement(REPL_FOCUSED);
await this.code.waitForSetValue(REPL_FOCUSED, text);
// Wait for the keys to be picked up by the editor model such that repl evalutes what just got typed
await this.editor.waitForEditorContents('debug:replinput', s => s.indexOf(text) >= 0);
await this.code.dispatchKeybinding('enter');
await this.code.waitForElement(CONSOLE_INPUT_OUTPUT);
await this.waitForOutput(output => accept(output[output.length - 1] || ''));
}
// Different node versions give different number of variables. As a workaround be more relaxed when checking for variable count
async waitForVariableCount(count: number, alternativeCount: number): Promise<void> {
await this.code.waitForElements(VARIABLE, false, els => els.length === count || els.length === alternativeCount);
}
private async waitForOutput(fn: (output: string[]) => boolean): Promise<string[]> {
const elements = await this.code.waitForElements(CONSOLE_OUTPUT, false, elements => fn(elements.map(e => e.textContent)));
return elements.map(e => e.textContent);
}
}

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Application } from '../../application';
import { Application } from '../../../../automation';
export function setup() {
describe('Editor', () => {
@@ -67,4 +67,4 @@ export function setup() {
await peek.waitForFile('app.js');
});
});
}
}

View File

@@ -1,133 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { References } from './peek';
import { Commands } from '../workbench/workbench';
import { Code } from '../../vscode/code';
const RENAME_BOX = '.monaco-editor .monaco-editor.rename-box';
const RENAME_INPUT = `${RENAME_BOX} .rename-input`;
const EDITOR = filename => `.monaco-editor[data-uri$="${filename}"]`;
const VIEW_LINES = filename => `${EDITOR(filename)} .view-lines`;
const LINE_NUMBERS = filename => `${EDITOR(filename)} .margin .margin-view-overlays .line-numbers`;
export class Editor {
private static readonly FOLDING_EXPANDED = '.monaco-editor .margin .margin-view-overlays>:nth-child(${INDEX}) .folding';
private static readonly FOLDING_COLLAPSED = `${Editor.FOLDING_EXPANDED}.collapsed`;
constructor(private code: Code, private commands: Commands) { }
async findReferences(filename: string, term: string, line: number): Promise<References> {
await this.clickOnTerm(filename, term, line);
await this.commands.runCommand('Peek References');
const references = new References(this.code);
await references.waitUntilOpen();
return references;
}
async rename(filename: string, line: number, from: string, to: string): Promise<void> {
await this.clickOnTerm(filename, from, line);
await this.commands.runCommand('Rename Symbol');
await this.code.waitForActiveElement(RENAME_INPUT);
await this.code.waitForSetValue(RENAME_INPUT, to);
await this.code.dispatchKeybinding('enter');
}
async gotoDefinition(filename: string, term: string, line: number): Promise<void> {
await this.clickOnTerm(filename, term, line);
await this.commands.runCommand('Go to Implementation');
}
async peekDefinition(filename: string, term: string, line: number): Promise<References> {
await this.clickOnTerm(filename, term, line);
await this.commands.runCommand('Peek Definition');
const peek = new References(this.code);
await peek.waitUntilOpen();
return peek;
}
async waitForHighlightingLine(filename: string, line: number): Promise<void> {
const currentLineIndex = await this.getViewLineIndex(filename, line);
if (currentLineIndex) {
await this.code.waitForElement(`.monaco-editor .view-overlays>:nth-child(${currentLineIndex}) .current-line`);
return;
}
throw new Error('Cannot find line ' + line);
}
private async getSelector(filename: string, term: string, line: number): Promise<string> {
const lineIndex = await this.getViewLineIndex(filename, line);
const classNames = await this.getClassSelectors(filename, term, lineIndex);
return `${VIEW_LINES(filename)}>:nth-child(${lineIndex}) span span.${classNames[0]}`;
}
async foldAtLine(filename: string, line: number): Promise<any> {
const lineIndex = await this.getViewLineIndex(filename, line);
await this.code.waitAndClick(Editor.FOLDING_EXPANDED.replace('${INDEX}', '' + lineIndex));
await this.code.waitForElement(Editor.FOLDING_COLLAPSED.replace('${INDEX}', '' + lineIndex));
}
async unfoldAtLine(filename: string, line: number): Promise<any> {
const lineIndex = await this.getViewLineIndex(filename, line);
await this.code.waitAndClick(Editor.FOLDING_COLLAPSED.replace('${INDEX}', '' + lineIndex));
await this.code.waitForElement(Editor.FOLDING_EXPANDED.replace('${INDEX}', '' + lineIndex));
}
private async clickOnTerm(filename: string, term: string, line: number): Promise<void> {
const selector = await this.getSelector(filename, term, line);
await this.code.waitAndClick(selector);
}
async waitForEditorFocus(filename: string, lineNumber: number, selectorPrefix = ''): Promise<void> {
const editor = [selectorPrefix || '', EDITOR(filename)].join(' ');
const line = `${editor} .view-lines > .view-line:nth-child(${lineNumber})`;
const textarea = `${editor} textarea`;
await this.code.waitAndClick(line, 0, 0);
await this.code.waitForActiveElement(textarea);
}
async waitForTypeInEditor(filename: string, text: string, selectorPrefix = ''): Promise<any> {
const editor = [selectorPrefix || '', EDITOR(filename)].join(' ');
await this.code.waitForElement(editor);
const textarea = `${editor} textarea`;
await this.code.waitForActiveElement(textarea);
await this.code.waitForTypeInEditor(textarea, 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 || '', `${EDITOR(filename)} .view-lines`].join(' ');
return this.code.waitForTextContent(selector, undefined, c => accept(c.replace(/\u00a0/g, ' ')));
}
private async getClassSelectors(filename: string, term: string, viewline: number): Promise<string[]> {
const elements = await this.code.waitForElements(`${VIEW_LINES(filename)}>:nth-child(${viewline}) span span`, false, els => els.some(el => el.textContent === term));
const { className } = elements.filter(r => r.textContent === term)[0];
return className.split(/\s/g);
}
private async getViewLineIndex(filename: string, line: number): Promise<number> {
const elements = await this.code.waitForElements(LINE_NUMBERS(filename), false, els => {
return els.some(el => el.textContent === `${line}`);
});
for (let index = 0; index < elements.length; index++) {
if (elements[index].textContent === `${line}`) {
return index + 1;
}
}
throw new Error('Line not found');
}
}

View File

@@ -1,52 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Code } from '../../vscode/code';
export class Editors {
constructor(private code: Code) { }
async saveOpenedFile(): Promise<any> {
if (process.platform === 'darwin') {
await this.code.dispatchKeybinding('cmd+s');
} else {
await this.code.dispatchKeybinding('ctrl+s');
}
}
async selectTab(tabName: string, untitled: boolean = false): Promise<void> {
await this.code.waitAndClick(`.tabs-container div.tab[aria-label="${tabName}, tab"]`);
await this.waitForEditorFocus(tabName, untitled);
}
async waitForActiveEditor(filename: string): Promise<any> {
const selector = `.editor-instance .monaco-editor[data-uri$="${filename}"] textarea`;
return this.code.waitForActiveElement(selector);
}
async waitForEditorFocus(fileName: string, untitled: boolean = false): Promise<void> {
await this.waitForActiveTab(fileName);
await this.waitForActiveEditor(fileName);
}
async waitForActiveTab(fileName: string, isDirty: boolean = false): Promise<void> {
await this.code.waitForElement(`.tabs-container div.tab.active${isDirty ? '.dirty' : ''}[aria-selected="true"][aria-label="${fileName}, tab"]`);
}
async waitForTab(fileName: string, isDirty: boolean = false): Promise<void> {
await this.code.waitForElement(`.tabs-container div.tab${isDirty ? '.dirty' : ''}[aria-label="${fileName}, tab"]`);
}
async newUntitledFile(): Promise<void> {
if (process.platform === 'darwin') {
await this.code.dispatchKeybinding('cmd+n');
} else {
await this.code.dispatchKeybinding('ctrl+n');
}
await this.waitForEditorFocus('Untitled-1', true);
}
}

View File

@@ -1,52 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Code } from '../../vscode/code';
export class References {
private static readonly REFERENCES_WIDGET = '.monaco-editor .zone-widget .zone-widget-container.peekview-widget.reference-zone-widget.results-loaded';
private static readonly REFERENCES_TITLE_FILE_NAME = `${References.REFERENCES_WIDGET} .head .peekview-title .filename`;
private static readonly REFERENCES_TITLE_COUNT = `${References.REFERENCES_WIDGET} .head .peekview-title .meta`;
private static readonly REFERENCES = `${References.REFERENCES_WIDGET} .body .ref-tree.inline .monaco-list-row .highlight`;
constructor(private code: Code) { }
async waitUntilOpen(): Promise<void> {
await this.code.waitForElement(References.REFERENCES_WIDGET);
}
async waitForReferencesCountInTitle(count: number): Promise<void> {
await this.code.waitForTextContent(References.REFERENCES_TITLE_COUNT, undefined, titleCount => {
const matches = titleCount.match(/\d+/);
return matches ? parseInt(matches[0]) === count : false;
});
}
async waitForReferencesCount(count: number): Promise<void> {
await this.code.waitForElements(References.REFERENCES, false, result => result && result.length === count);
}
async waitForFile(file: string): Promise<void> {
await this.code.waitForTextContent(References.REFERENCES_TITLE_FILE_NAME, file);
}
async close(): Promise<void> {
// Sometimes someone else eats up the `Escape` key
let count = 0;
while (true) {
await this.code.dispatchKeybinding('escape');
try {
await this.code.waitForElement(References.REFERENCES_WIDGET, el => !el, 10);
return;
} catch (err) {
if (++count > 5) {
throw err;
}
}
}
}
}

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Application } from '../../application';
import { Application } from '../../../../automation';
export function setup() {
describe('Explorer', () => {
@@ -37,4 +37,4 @@ export function setup() {
await app.code.dispatchKeybinding('escape');
});
});
}
}

View File

@@ -1,48 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Viewlet } from '../workbench/viewlet';
import { Editors } from '../editor/editors';
import { Code } from '../../vscode/code';
export class Explorer extends Viewlet {
private static readonly EXPLORER_VIEWLET = 'div[id="workbench.view.explorer"]';
private static readonly OPEN_EDITORS_VIEW = `${Explorer.EXPLORER_VIEWLET} .split-view-view:nth-child(1) .title`;
constructor(code: Code, private editors: Editors) {
super(code);
}
async openExplorerView(): Promise<any> {
if (process.platform === 'darwin') {
await this.code.dispatchKeybinding('cmd+shift+e');
} else {
await this.code.dispatchKeybinding('ctrl+shift+e');
}
}
async waitForOpenEditorsViewTitle(fn: (title: string) => boolean): Promise<void> {
await this.code.waitForTextContent(Explorer.OPEN_EDITORS_VIEW, undefined, fn);
}
async openFile(fileName: string): Promise<any> {
await this.code.waitAndDoubleClick(`div[class="monaco-icon-label file-icon ${fileName}-name-file-icon ${this.getExtensionSelector(fileName)} explorer-item"]`);
await this.editors.waitForEditorFocus(fileName);
}
getExtensionSelector(fileName: string): string {
const extension = fileName.split('.')[1];
if (extension === 'js') {
return 'js-ext-file-icon ext-file-icon javascript-lang-file-icon';
} else if (extension === 'json') {
return 'json-ext-file-icon ext-file-icon json-lang-file-icon';
} else if (extension === 'md') {
return 'md-ext-file-icon ext-file-icon markdown-lang-file-icon';
}
throw new Error('No class defined for this file extension');
}
}

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Application, Quality } from '../../application';
import { Application, Quality } from '../../../../automation';
export function setup() {
describe('Extensions', () => {
@@ -28,4 +28,4 @@ export function setup() {
await app.workbench.statusbar.waitForStatusbarText('smoke test', 'VS Code Smoke Test Check');
});
});
}
}

View File

@@ -1,43 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Viewlet } from '../workbench/viewlet';
import { Code } from '../../vscode/code';
const SEARCH_BOX = 'div.extensions-viewlet[id="workbench.view.extensions"] .monaco-editor textarea';
export class Extensions extends Viewlet {
constructor(code: Code) {
super(code);
}
async openExtensionsViewlet(): Promise<any> {
if (process.platform === 'darwin') {
await this.code.dispatchKeybinding('cmd+shift+x');
} else {
await this.code.dispatchKeybinding('ctrl+shift+x');
}
await this.code.waitForActiveElement(SEARCH_BOX);
}
async waitForExtensionsViewlet(): Promise<any> {
await this.code.waitForElement(SEARCH_BOX);
}
async searchForExtension(id: string): Promise<any> {
await this.code.waitAndClick(SEARCH_BOX);
await this.code.waitForActiveElement(SEARCH_BOX);
await this.code.waitForTypeInEditor(SEARCH_BOX, `@id:${id}`);
}
async installExtension(id: string, name: string): Promise<void> {
await this.searchForExtension(id);
const ariaLabel = `${name}. Press enter for extension details.`;
await this.code.waitAndClick(`div.extensions-viewlet[id="workbench.view.extensions"] .monaco-list-row[aria-label="${ariaLabel}"] .extension li[class='action-item'] .extension-action.install`);
await this.code.waitForElement(`.extension-editor .monaco-action-bar .action-item:not(.disabled) .extension-action.uninstall`);
}
}

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as cp from 'child_process';
import { Application } from '../../application';
import { Application } from '../../../../automation';
const DIFF_EDITOR_LINE_INSERT = '.monaco-diff-editor .editor.modified .line-insert';
const SYNC_STATUSBAR = 'div[id="workbench.parts.statusbar"] .statusbar-item[title$="Synchronize Changes"]';
@@ -74,4 +74,4 @@ export function setup() {
cp.execSync('git reset --hard origin/master', { cwd: app.workspacePathOrFolder });
});
});
}
}

View File

@@ -1,79 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Viewlet } from '../workbench/viewlet';
import { IElement } from '../../vscode/driver';
import { findElement, findElements, Code } from '../../vscode/code';
const VIEWLET = 'div[id="workbench.view.scm"]';
const SCM_INPUT = `${VIEWLET} .scm-editor textarea`;
const SCM_RESOURCE = `${VIEWLET} .monaco-list-row > .resource`;
const REFRESH_COMMAND = `div[id="workbench.parts.sidebar"] .actions-container a.action-label[title="Refresh"]`;
const COMMIT_COMMAND = `div[id="workbench.parts.sidebar"] .actions-container a.action-label[title="Commit"]`;
const SCM_RESOURCE_CLICK = (name: string) => `${SCM_RESOURCE} .monaco-icon-label[title*="${name}"] .label-name`;
const SCM_RESOURCE_ACTION_CLICK = (name: string, actionName: string) => `${SCM_RESOURCE} .monaco-icon-label[title*="${name}"] .actions .action-label[title="${actionName}"]`;
interface Change {
name: string;
type: string;
actions: string[];
}
function toChange(element: IElement): Change {
const name = findElement(element, e => /\blabel-name\b/.test(e.className))!;
const type = element.attributes['data-tooltip'] || '';
const actionElementList = findElements(element, e => /\baction-label\b/.test(e.className));
const actions = actionElementList.map(e => e.attributes['title']);
return {
name: name.textContent || '',
type,
actions
};
}
export class SCM extends Viewlet {
constructor(code: Code) {
super(code);
}
async openSCMViewlet(): Promise<any> {
await this.code.dispatchKeybinding('ctrl+shift+g');
await this.code.waitForElement(SCM_INPUT);
}
async waitForChange(name: string, type?: string): Promise<void> {
const func = (change: Change) => change.name === name && (!type || change.type === type);
await this.code.waitForElements(SCM_RESOURCE, true, elements => elements.some(e => func(toChange(e))));
}
async refreshSCMViewlet(): Promise<any> {
await this.code.waitAndClick(REFRESH_COMMAND);
}
async openChange(name: string): Promise<void> {
await this.code.waitAndClick(SCM_RESOURCE_CLICK(name));
}
async stage(name: string): Promise<void> {
await this.code.waitAndClick(SCM_RESOURCE_ACTION_CLICK(name, 'Stage Changes'));
await this.waitForChange(name, 'Index Modified');
}
async unstage(name: string): Promise<void> {
await this.code.waitAndClick(SCM_RESOURCE_ACTION_CLICK(name, 'Unstage Changes'));
await this.waitForChange('app.js', 'Modified');
}
async commit(message: string): Promise<void> {
await this.code.waitAndClick(SCM_INPUT);
await this.code.waitForActiveElement(SCM_INPUT);
await this.code.waitForSetValue(SCM_INPUT, message);
await this.code.waitAndClick(COMMIT_COMMAND);
}
}

View File

@@ -5,7 +5,7 @@
import * as fs from 'fs';
import * as path from 'path';
import { Application } from '../../application';
import { Application } from '../../../../automation';
function toUri(path: string): string {
if (process.platform === 'win32') {
@@ -47,8 +47,7 @@ export function setup() {
const app = this.app as Application;
await app.workbench.quickopen.openQuickOpen('*.*');
// TODO roblourens: Go to files finds welcome page: issue 74875
await app.workbench.quickopen.waitForQuickOpenElements(names => names.length === 6 || names.length === 7);
await app.workbench.quickopen.waitForQuickOpenElements(names => names.length === 6);
await app.workbench.quickopen.closeQuickOpen();
});
@@ -57,4 +56,4 @@ export function setup() {
await app.code.waitForTitle(title => /smoketest \(Workspace\)/i.test(title));
});
});
}
}

View File

@@ -1,34 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Code } from '../../vscode/code';
const SEARCH_INPUT = '.keybindings-header .settings-search-input input';
export class KeybindingsEditor {
constructor(private code: Code) { }
async updateKeybinding(command: string, keybinding: string, ariaLabel: string): Promise<any> {
if (process.platform === 'darwin') {
await this.code.dispatchKeybinding('cmd+k cmd+s');
} else {
await this.code.dispatchKeybinding('ctrl+k ctrl+s');
}
await this.code.waitForActiveElement(SEARCH_INPUT);
await this.code.waitForSetValue(SEARCH_INPUT, command);
await this.code.waitAndClick('.keybindings-list-container .monaco-list-row.keybinding-item');
await this.code.waitForElement('.keybindings-list-container .monaco-list-row.keybinding-item.focused.selected');
await this.code.waitAndClick('.keybindings-list-container .monaco-list-row.keybinding-item .action-item .icon.add');
await this.code.waitForActiveElement('.defineKeybindingWidget .monaco-inputbox input');
await this.code.dispatchKeybinding(keybinding);
await this.code.dispatchKeybinding('enter');
await this.code.waitForElement(`.keybindings-list-container div[aria-label="Keybinding is ${ariaLabel}."]`);
}
}

View File

@@ -3,8 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Application } from '../../application';
import { ActivityBarPosition } from '../activitybar/activityBar';
import { Application, ActivityBarPosition } from '../../../../automation';
export function setup() {
describe('Preferences', () => {

View File

@@ -1,42 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as fs from 'fs';
import * as path from 'path';
import { Editor } from '../editor/editor';
import { Editors } from '../editor/editors';
import { Code } from '../../vscode/code';
import { QuickOpen } from '../quickopen/quickopen';
export const enum ActivityBarPosition {
LEFT = 0,
RIGHT = 1
}
export class SettingsEditor {
constructor(private code: Code, private userDataPath: string, private editors: Editors, private editor: Editor, private quickopen: QuickOpen) { }
async addUserSetting(setting: string, value: string): Promise<void> {
await this.openSettings();
await this.editor.waitForEditorFocus('settings.json', 1);
await this.code.dispatchKeybinding('right');
await this.editor.waitForTypeInEditor('settings.json', `"${setting}": ${value}`);
await this.editors.saveOpenedFile();
}
async clearUserSettings(): Promise<void> {
const settingsPath = path.join(this.userDataPath, 'User', 'settings.json');
await new Promise((c, e) => fs.writeFile(settingsPath, '{\n}', 'utf8', err => err ? e(err) : c()));
await this.openSettings();
await this.editor.waitForEditorContents('settings.json', c => c === '{}');
}
private async openSettings(): Promise<void> {
await this.quickopen.runCommand('Preferences: Open Settings (JSON)');
}
}

View File

@@ -1,50 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Code } from '../../vscode/code';
export const enum ProblemSeverity {
WARNING = 0,
ERROR = 1
}
export class Problems {
static PROBLEMS_VIEW_SELECTOR = '.panel.markers-panel';
constructor(private code: Code) { }
public async showProblemsView(): Promise<any> {
await this.toggleProblemsView();
await this.waitForProblemsView();
}
public async hideProblemsView(): Promise<any> {
await this.toggleProblemsView();
await this.code.waitForElement(Problems.PROBLEMS_VIEW_SELECTOR, el => !el);
}
private async toggleProblemsView(): Promise<void> {
if (process.platform === 'darwin') {
await this.code.dispatchKeybinding('cmd+shift+m');
} else {
await this.code.dispatchKeybinding('ctrl+shift+m');
}
}
public async waitForProblemsView(): Promise<void> {
await this.code.waitForElement(Problems.PROBLEMS_VIEW_SELECTOR);
}
public static getSelectorInProblemsView(problemType: ProblemSeverity): string {
let selector = problemType === ProblemSeverity.WARNING ? 'severity-warning' : 'severity-error';
return `div[id="workbench.panel.markers"] .monaco-tl-contents .marker-icon.${selector}`;
}
public static getSelectorInEditor(problemType: ProblemSeverity): string {
let selector = problemType === ProblemSeverity.WARNING ? 'squiggly-warning' : 'squiggly-error';
return `.view-overlays .cdr.${selector}`;
}
}

View File

@@ -1,37 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Code } from '../../vscode/code';
export class QuickInput {
static QUICK_INPUT = '.quick-input-widget';
static QUICK_INPUT_INPUT = `${QuickInput.QUICK_INPUT} .quick-input-box input`;
static QUICK_INPUT_FOCUSED_ELEMENT = `${QuickInput.QUICK_INPUT} .quick-open-tree .monaco-tree-row.focused .monaco-highlighted-label`;
constructor(private code: Code) { }
async closeQuickInput(): Promise<void> {
await this.code.dispatchKeybinding('escape');
await this.waitForQuickInputClosed();
}
async waitForQuickInputOpened(retryCount?: number): Promise<void> {
await this.code.waitForActiveElement(QuickInput.QUICK_INPUT_INPUT, retryCount);
}
private async waitForQuickInputClosed(): Promise<void> {
await this.code.waitForElement(QuickInput.QUICK_INPUT, r => !!r && r.attributes.style.indexOf('display: none;') !== -1);
}
async selectQuickInputElement(index: number): Promise<void> {
await this.waitForQuickInputOpened();
for (let from = 0; from < index; from++) {
await this.code.dispatchKeybinding('down');
}
await this.code.dispatchKeybinding('enter');
await this.waitForQuickInputClosed();
}
}

View File

@@ -1,119 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Editors } from '../editor/editors';
import { Code } from '../../vscode/code';
export class QuickOpen {
static QUICK_OPEN = 'div.monaco-quick-open-widget';
static QUICK_OPEN_HIDDEN = 'div.monaco-quick-open-widget[aria-hidden="true"]';
static QUICK_OPEN_INPUT = `${QuickOpen.QUICK_OPEN} .quick-open-input input`;
static QUICK_OPEN_FOCUSED_ELEMENT = `${QuickOpen.QUICK_OPEN} .quick-open-tree .monaco-tree-row.focused .monaco-highlighted-label`;
static QUICK_OPEN_ENTRY_SELECTOR = 'div[aria-label="Quick Picker"] .monaco-tree-rows.show-twisties .monaco-tree-row .quick-open-entry';
static QUICK_OPEN_ENTRY_LABEL_SELECTOR = 'div[aria-label="Quick Picker"] .monaco-tree-rows.show-twisties .monaco-tree-row .quick-open-entry .label-name';
constructor(private code: Code, private editors: Editors) { }
async openQuickOpen(value: string): Promise<void> {
let retries = 0;
// other parts of code might steal focus away from quickopen :(
while (retries < 5) {
if (process.platform === 'darwin') {
await this.code.dispatchKeybinding('cmd+p');
} else {
await this.code.dispatchKeybinding('ctrl+p');
}
try {
await this.waitForQuickOpenOpened(10);
break;
} catch (err) {
if (++retries > 5) {
throw err;
}
await this.code.dispatchKeybinding('escape');
}
}
if (value) {
await this.code.waitForSetValue(QuickOpen.QUICK_OPEN_INPUT, value);
}
}
async closeQuickOpen(): Promise<void> {
await this.code.dispatchKeybinding('escape');
await this.waitForQuickOpenClosed();
}
async openFile(fileName: string): Promise<void> {
await this.openQuickOpen(fileName);
await this.waitForQuickOpenElements(names => names[0] === fileName);
await this.code.dispatchKeybinding('enter');
await this.editors.waitForActiveTab(fileName);
await this.editors.waitForEditorFocus(fileName);
}
async waitForQuickOpenOpened(retryCount?: number): Promise<void> {
await this.code.waitForActiveElement(QuickOpen.QUICK_OPEN_INPUT, retryCount);
}
private async waitForQuickOpenClosed(): Promise<void> {
await this.code.waitForElement(QuickOpen.QUICK_OPEN_HIDDEN);
}
async submit(text: string): Promise<void> {
await this.code.waitForSetValue(QuickOpen.QUICK_OPEN_INPUT, text);
await this.code.dispatchKeybinding('enter');
await this.waitForQuickOpenClosed();
}
async selectQuickOpenElement(index: number): Promise<void> {
await this.waitForQuickOpenOpened();
for (let from = 0; from < index; from++) {
await this.code.dispatchKeybinding('down');
}
await this.code.dispatchKeybinding('enter');
await this.waitForQuickOpenClosed();
}
async waitForQuickOpenElements(accept: (names: string[]) => boolean): Promise<void> {
await this.code.waitForElements(QuickOpen.QUICK_OPEN_ENTRY_LABEL_SELECTOR, false, els => accept(els.map(e => e.textContent)));
}
async runCommand(command: string): Promise<void> {
await this.openQuickOpen(`> ${command}`);
// wait for best choice to be focused
await this.code.waitForTextContent(QuickOpen.QUICK_OPEN_FOCUSED_ELEMENT, command);
// wait and click on best choice
await this.code.waitAndClick(QuickOpen.QUICK_OPEN_FOCUSED_ELEMENT);
}
async openQuickOutline(): Promise<void> {
let retries = 0;
while (++retries < 10) {
if (process.platform === 'darwin') {
await this.code.dispatchKeybinding('cmd+shift+o');
} else {
await this.code.dispatchKeybinding('ctrl+shift+o');
}
const text = await this.code.waitForTextContent('div[aria-label="Quick Picker"] .monaco-tree-rows.show-twisties div.monaco-tree-row .quick-open-entry .monaco-icon-label .label-name .monaco-highlighted-label span');
if (text !== 'No symbol information for the file') {
return;
}
await this.closeQuickOpen();
await new Promise(c => setTimeout(c, 250));
}
}
}

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as cp from 'child_process';
import { Application } from '../../application';
import { Application } from '../../../../automation';
export function setup() {
describe('Search', () => {
@@ -56,4 +56,4 @@ export function setup() {
await app.workbench.search.waitForNoResultText();
});
});
}
}

View File

@@ -1,136 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Viewlet } from '../workbench/viewlet';
import { Code } from '../../vscode/code';
const VIEWLET = '.search-view';
const INPUT = `${VIEWLET} .search-widget .search-container .monaco-inputbox textarea`;
const INCLUDE_INPUT = `${VIEWLET} .query-details .file-types.includes .monaco-inputbox input`;
const FILE_MATCH = filename => `${VIEWLET} .results .filematch[data-resource$="${filename}"]`;
async function retry(setup: () => Promise<any>, attempt: () => Promise<any>) {
let count = 0;
while (true) {
await setup();
try {
await attempt();
return;
} catch (err) {
if (++count > 5) {
throw err;
}
}
}
}
export class Search extends Viewlet {
constructor(code: Code) {
super(code);
}
async openSearchViewlet(): Promise<any> {
if (process.platform === 'darwin') {
await this.code.dispatchKeybinding('cmd+shift+f');
} else {
await this.code.dispatchKeybinding('ctrl+shift+f');
}
await this.waitForInputFocus(INPUT);
}
async searchFor(text: string): Promise<void> {
await this.waitForInputFocus(INPUT);
await this.code.waitForSetValue(INPUT, text);
await this.submitSearch();
}
async submitSearch(): Promise<void> {
await this.waitForInputFocus(INPUT);
await this.code.dispatchKeybinding('enter');
await this.code.waitForElement(`${VIEWLET} .messages`);
}
async setFilesToIncludeText(text: string): Promise<void> {
await this.waitForInputFocus(INCLUDE_INPUT);
await this.code.waitForSetValue(INCLUDE_INPUT, text || '');
}
async showQueryDetails(): Promise<void> {
await this.code.waitAndClick(`${VIEWLET} .query-details .more`);
}
async hideQueryDetails(): Promise<void> {
await this.code.waitAndClick(`${VIEWLET} .query-details.more .more`);
}
async removeFileMatch(filename: string): Promise<void> {
const fileMatch = FILE_MATCH(filename);
await retry(
() => this.code.waitAndClick(fileMatch),
() => this.code.waitForElement(`${fileMatch} .action-label.icon.action-remove`, el => !!el && el.top > 0 && el.left > 0, 10)
);
// ¯\_(ツ)_/¯
await new Promise(c => setTimeout(c, 500));
await this.code.waitAndClick(`${fileMatch} .action-label.icon.action-remove`);
await this.code.waitForElement(fileMatch, el => !el);
}
async expandReplace(): Promise<void> {
await this.code.waitAndClick(`${VIEWLET} .search-widget .monaco-button.toggle-replace-button.collapse`);
}
async collapseReplace(): Promise<void> {
await this.code.waitAndClick(`${VIEWLET} .search-widget .monaco-button.toggle-replace-button.expand`);
}
async setReplaceText(text: string): Promise<void> {
await this.code.waitForSetValue(`${VIEWLET} .search-widget .replace-container .monaco-inputbox textarea[title="Replace"]`, text);
}
async replaceFileMatch(filename: string): Promise<void> {
const fileMatch = FILE_MATCH(filename);
await retry(
() => this.code.waitAndClick(fileMatch),
() => this.code.waitForElement(`${fileMatch} .action-label.icon.action-replace-all`, el => !!el && el.top > 0 && el.left > 0, 10)
);
// ¯\_(ツ)_/¯
await new Promise(c => setTimeout(c, 500));
await this.code.waitAndClick(`${fileMatch} .action-label.icon.action-replace-all`);
}
async waitForResultText(text: string): Promise<void> {
await this.code.waitForTextContent(`${VIEWLET} .messages .message>p`, text);
}
async waitForNoResultText(): Promise<void> {
await this.code.waitForElement(`${VIEWLET} .messages[aria-hidden="true"] .message>p`);
}
private async waitForInputFocus(selector: string): Promise<void> {
let retries = 0;
// other parts of code might steal focus away from input boxes :(
while (retries < 5) {
await this.code.waitAndClick(INPUT, 2, 2);
try {
await this.code.waitForActiveElement(INPUT, 10);
break;
} catch (err) {
if (++retries > 5) {
throw err;
}
}
}
}
}

View File

@@ -3,8 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Application, Quality } from '../../application';
import { StatusBarElement } from './statusbar';
import { Application, Quality, StatusBarElement } from '../../../../automation';
export function setup() {
describe('Statusbar', () => {
@@ -90,4 +89,4 @@ export function setup() {
await app.workbench.statusbar.waitForEOL('CRLF');
});
});
}
}

View File

@@ -1,68 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Code } from '../../vscode/code';
export const enum StatusBarElement {
BRANCH_STATUS = 0,
SYNC_STATUS = 1,
PROBLEMS_STATUS = 2,
SELECTION_STATUS = 3,
INDENTATION_STATUS = 4,
ENCODING_STATUS = 5,
EOL_STATUS = 6,
LANGUAGE_STATUS = 7,
FEEDBACK_ICON = 8
}
export class StatusBar {
private readonly mainSelector = 'div[id="workbench.parts.statusbar"]';
private readonly leftSelector = '.statusbar-item.left';
private readonly rightSelector = '.statusbar-item.right';
constructor(private code: Code) { }
async waitForStatusbarElement(element: StatusBarElement): Promise<void> {
await this.code.waitForElement(this.getSelector(element));
}
async clickOn(element: StatusBarElement): Promise<void> {
await this.code.waitAndClick(this.getSelector(element));
}
async waitForEOL(eol: string): Promise<string> {
return this.code.waitForTextContent(this.getSelector(StatusBarElement.EOL_STATUS), eol);
}
async waitForStatusbarText(title: string, text: string): Promise<void> {
await this.code.waitForTextContent(`${this.mainSelector} .statusbar-item[title="${title}"]`, text);
}
private getSelector(element: StatusBarElement): string {
switch (element) {
case StatusBarElement.BRANCH_STATUS:
return `${this.mainSelector} ${this.leftSelector} .octicon.octicon-git-branch`;
case StatusBarElement.SYNC_STATUS:
return `${this.mainSelector} ${this.leftSelector} .octicon.octicon-sync`;
case StatusBarElement.PROBLEMS_STATUS:
return `${this.mainSelector} ${this.leftSelector} .octicon.octicon-error`;
case StatusBarElement.SELECTION_STATUS:
return `${this.mainSelector} ${this.rightSelector}[title="Go to Line"]`;
case StatusBarElement.INDENTATION_STATUS:
return `${this.mainSelector} ${this.rightSelector}[title="Select Indentation"]`;
case StatusBarElement.ENCODING_STATUS:
return `${this.mainSelector} ${this.rightSelector}[title="Select Encoding"]`;
case StatusBarElement.EOL_STATUS:
return `${this.mainSelector} ${this.rightSelector}[title="Select End of Line Sequence"]`;
case StatusBarElement.LANGUAGE_STATUS:
return `${this.mainSelector} ${this.rightSelector}[title="Select Language Mode"]`;
case StatusBarElement.FEEDBACK_ICON:
return `${this.mainSelector} .statusbar-item.right[id="status.feedback"]`;
default:
throw new Error(element);
}
}
}

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Application } from '../../application';
import { Application } from '../../../../automation';
export function setup() {
describe('Terminal', () => {

View File

@@ -1,33 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Code } from '../../vscode/code';
import { QuickOpen } from '../quickopen/quickopen';
const PANEL_SELECTOR = 'div[id="workbench.panel.terminal"]';
const XTERM_SELECTOR = `${PANEL_SELECTOR} .terminal-wrapper`;
const XTERM_TEXTAREA = `${XTERM_SELECTOR} textarea.xterm-helper-textarea`;
export class Terminal {
constructor(private code: Code, private quickopen: QuickOpen) { }
async showTerminal(): Promise<void> {
await this.quickopen.runCommand('View: Toggle Integrated Terminal');
await this.code.waitForActiveElement(XTERM_TEXTAREA);
await this.code.waitForTerminalBuffer(XTERM_SELECTOR, lines => lines.some(line => line.length > 0));
}
async runCommand(commandText: string): Promise<void> {
await this.code.writeInTerminal(XTERM_SELECTOR, commandText);
// hold your horses
await new Promise(c => setTimeout(c, 500));
await this.code.dispatchKeybinding('enter');
}
async waitForTerminalText(accept: (buffer: string[]) => boolean): Promise<void> {
await this.code.waitForTerminalBuffer(XTERM_SELECTOR, accept);
}
}

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Application } from '../../application';
import { Application } from '../../../../automation';
export function setup() {
describe('Dataloss', () => {

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Application, ApplicationOptions } from '../../application';
import { Application, ApplicationOptions } from '../../../../automation';
import { join } from 'path';
export function setup(stableCodePath: string, testDataPath: string) {

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as path from 'path';
import { Application, ApplicationOptions } from '../../application';
import { Application, ApplicationOptions } from '../../../../automation';
export function setup() {
@@ -35,4 +35,4 @@ export function setup() {
});
});
}
}

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Application, Quality } from '../../application';
import { Application, Quality } from '../../../../automation';
export function setup() {
describe('Localization', () => {

View File

@@ -1,15 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Code } from '../../vscode/code';
export abstract class Viewlet {
constructor(protected code: Code) { }
async waitForTitle(fn: (title: string) => boolean): Promise<void> {
await this.code.waitForTextContent('.monaco-workbench .part.sidebar > .title > .title-label > h2', undefined, fn);
}
}

View File

@@ -1,79 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Explorer } from '../explorer/explorer';
import { ActivityBar } from '../activitybar/activityBar';
import { QuickOpen } from '../quickopen/quickopen';
import { QuickInput } from '../quickinput/quickinput';
import { Extensions } from '../extensions/extensions';
import { Search } from '../search/search';
import { Editor } from '../editor/editor';
import { SCM } from '../git/scm';
import { Debug } from '../debug/debugSmoke';
import { StatusBar } from '../statusbar/statusbar';
import { Problems } from '../problems/problems';
import { SettingsEditor } from '../preferences/settings';
import { KeybindingsEditor } from '../preferences/keybindings';
import { Editors } from '../editor/editors';
import { Code } from '../../vscode/code';
import { Terminal } from '../terminal/terminal';
// {{SQL CARBON EDIT}}
import { ConnectionDialog } from '../../sql/connectionDialog/connectionDialog';
import { Profiler } from '../../sql/profiler/profiler';
import { QueryEditors } from '../../sql/queryEditor/queryEditors';
// {{END}}
export interface Commands {
runCommand(command: string): Promise<any>;
}
export class Workbench {
readonly quickopen: QuickOpen;
readonly quickinput: QuickInput;
readonly editors: Editors;
readonly explorer: Explorer;
readonly activitybar: ActivityBar;
readonly search: Search;
readonly extensions: Extensions;
readonly editor: Editor;
readonly scm: SCM;
readonly debug: Debug;
readonly statusbar: StatusBar;
readonly problems: Problems;
readonly settingsEditor: SettingsEditor;
readonly keybindingsEditor: KeybindingsEditor;
readonly terminal: Terminal;
// {{SQL CARBON EDIT}}
readonly connectionDialog: ConnectionDialog;
readonly profiler: Profiler;
readonly queryEditors: QueryEditors;
// {{END}}
constructor(code: Code, userDataPath: string) {
this.editors = new Editors(code);
this.quickopen = new QuickOpen(code, this.editors);
this.quickinput = new QuickInput(code);
this.explorer = new Explorer(code, this.editors);
this.activitybar = new ActivityBar(code);
this.search = new Search(code);
this.extensions = new Extensions(code);
this.editor = new Editor(code, this.quickopen);
this.scm = new SCM(code);
this.debug = new Debug(code, this.quickopen, this.editors, this.editor);
this.statusbar = new StatusBar(code);
this.problems = new Problems(code);
this.settingsEditor = new SettingsEditor(code, userDataPath, this.editors, this.editor, this.quickopen);
this.keybindingsEditor = new KeybindingsEditor(code);
this.terminal = new Terminal(code, this.quickopen);
// {{SQL CARBON EDIT}}
this.connectionDialog = new ConnectionDialog(code);
this.profiler = new Profiler(code, this.quickopen);
this.queryEditors = new QueryEditors(code, this.quickopen);
// {{END}}
}
}