mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Merge from master
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
### Run
|
||||
|
||||
```
|
||||
```bash
|
||||
# Dev
|
||||
yarn smoketest
|
||||
|
||||
@@ -14,7 +14,7 @@ yarn smoketest --build PATH_TO_BUILD
|
||||
|
||||
You must always run the smoketest version which matches the release you are testing. So, if you want to run the smoketest for a release build (eg `release/1.22`), you need that version of the smoke tests too:
|
||||
|
||||
```
|
||||
```bash
|
||||
git checkout release/1.22
|
||||
yarn
|
||||
yarn smoketest --build PATH_TO_RELEASE_BUILD
|
||||
@@ -30,7 +30,7 @@ yarn smoketest --build PATH_TO_RELEASE_BUILD
|
||||
|
||||
Start a watch task in `test/smoke`:
|
||||
|
||||
```
|
||||
```bash
|
||||
cd test/smoke
|
||||
yarn watch
|
||||
```
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"copy-driver": "cpx src/vscode/driver.js out/vscode",
|
||||
"watch-driver": "cpx src/vscode/driver.js out/vscode -w",
|
||||
"copy-driver-definition": "node tools/copy-driver-definition.js",
|
||||
"watch-driver-definition": "watch \"node tools/copy-driver-definition.js\" ../../src/vs/platform/driver/common",
|
||||
"watch-driver-definition": "watch \"node tools/copy-driver-definition.js\" ../../src/vs/platform/driver/node",
|
||||
"mocha": "mocha"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -22,7 +22,7 @@
|
||||
"@types/webdriverio": "4.6.1",
|
||||
"concurrently": "^3.5.1",
|
||||
"cpx": "^1.5.0",
|
||||
"electron": "^2.0.6",
|
||||
"electron": "^2.0.12",
|
||||
"htmlparser2": "^3.9.2",
|
||||
"mkdirp": "^0.5.1",
|
||||
"mocha": "^5.2.0",
|
||||
@@ -33,7 +33,7 @@
|
||||
"rimraf": "^2.6.1",
|
||||
"strip-json-comments": "^2.0.1",
|
||||
"tmp": "0.0.33",
|
||||
"typescript": "2.5.2",
|
||||
"typescript": "2.9.2",
|
||||
"watch": "^1.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
* 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 { Workbench } from './areas/workbench/workbench';
|
||||
import * as cp from 'child_process';
|
||||
import { Code, spawn, SpawnOptions } from './vscode/code';
|
||||
import { Logger } from './logger';
|
||||
|
||||
export enum Quality {
|
||||
export const enum Quality {
|
||||
Dev,
|
||||
Insiders,
|
||||
Stable
|
||||
@@ -17,8 +18,8 @@ export enum Quality {
|
||||
export interface ApplicationOptions extends SpawnOptions {
|
||||
quality: Quality;
|
||||
workspacePath: string;
|
||||
workspaceFilePath: string;
|
||||
waitTime: number;
|
||||
screenshotsPath: string | null;
|
||||
}
|
||||
|
||||
export class Application {
|
||||
@@ -26,7 +27,9 @@ export class Application {
|
||||
private _code: Code | undefined;
|
||||
private _workbench: Workbench;
|
||||
|
||||
constructor(private options: ApplicationOptions) { }
|
||||
constructor(private options: ApplicationOptions) {
|
||||
this._workspacePathOrFolder = options.workspacePath;
|
||||
}
|
||||
|
||||
get quality(): Quality {
|
||||
return this.options.quality;
|
||||
@@ -44,8 +47,9 @@ export class Application {
|
||||
return this.options.logger;
|
||||
}
|
||||
|
||||
get workspacePath(): string {
|
||||
return this.options.workspacePath;
|
||||
private _workspacePathOrFolder: string;
|
||||
get workspacePathOrFolder(): string {
|
||||
return this._workspacePathOrFolder;
|
||||
}
|
||||
|
||||
get extensionsPath(): string {
|
||||
@@ -56,10 +60,6 @@ export class Application {
|
||||
return this.options.userDataDir;
|
||||
}
|
||||
|
||||
get workspaceFilePath(): string {
|
||||
return this.options.workspaceFilePath;
|
||||
}
|
||||
|
||||
async start(): Promise<any> {
|
||||
await this._start();
|
||||
//{{SQL CARBON EDIT}}
|
||||
@@ -79,9 +79,9 @@ export class Application {
|
||||
await this._start(options.workspaceOrFolder, options.extraArgs);
|
||||
}
|
||||
|
||||
private async _start(workspaceOrFolder = this.options.workspacePath, extraArgs: string[] = []): Promise<any> {
|
||||
cp.execSync('git checkout .', { cwd: this.options.workspacePath });
|
||||
await this.startApplication(workspaceOrFolder, extraArgs);
|
||||
private async _start(workspaceOrFolder = this.workspacePathOrFolder, extraArgs: string[] = []): Promise<any> {
|
||||
this._workspacePathOrFolder = workspaceOrFolder;
|
||||
await this.startApplication(extraArgs);
|
||||
await this.checkWindowReady();
|
||||
}
|
||||
|
||||
@@ -101,14 +101,22 @@ export class Application {
|
||||
}
|
||||
}
|
||||
|
||||
async capturePage(): Promise<string> {
|
||||
return this.code.capturePage();
|
||||
async captureScreenshot(name: string): Promise<void> {
|
||||
if (this.options.screenshotsPath) {
|
||||
const raw = await this.code.capturePage();
|
||||
const buffer = Buffer.from(raw, 'base64');
|
||||
const screenshotPath = path.join(this.options.screenshotsPath, `${name}.png`);
|
||||
if (this.options.log) {
|
||||
this.logger.log('*** Screenshot recorded:', screenshotPath);
|
||||
}
|
||||
fs.writeFileSync(screenshotPath, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private async startApplication(workspaceOrFolder: string, extraArgs: string[] = []): Promise<any> {
|
||||
private async startApplication(extraArgs: string[] = []): Promise<any> {
|
||||
this._code = await spawn({
|
||||
codePath: this.options.codePath,
|
||||
workspacePath: workspaceOrFolder,
|
||||
workspacePath: this.workspacePathOrFolder,
|
||||
userDataDir: this.options.userDataDir,
|
||||
extensionsPath: this.options.extensionsPath,
|
||||
logger: this.options.logger,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Code } from '../../vscode/code';
|
||||
|
||||
export enum ActivityBarPosition {
|
||||
export const enum ActivityBarPosition {
|
||||
LEFT = 0,
|
||||
RIGHT = 1
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ export function setup() {
|
||||
await app.workbench.quickopen.openFile('app.js');
|
||||
await app.workbench.debug.configure();
|
||||
|
||||
const launchJsonPath = path.join(app.workspacePath, '.vscode', 'launch.json');
|
||||
const launchJsonPath = path.join(app.workspacePathOrFolder, '.vscode', 'launch.json');
|
||||
const content = fs.readFileSync(launchJsonPath, 'utf8');
|
||||
const config = JSON.parse(stripJsonComments(content));
|
||||
config.configurations[0].protocol = 'inspector';
|
||||
|
||||
@@ -13,19 +13,19 @@ 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-actions-widget .debug-action.stop`;
|
||||
const STEP_OVER = `.debug-actions-widget .debug-action.step-over`;
|
||||
const STEP_IN = `.debug-actions-widget .debug-action.step-into`;
|
||||
const STEP_OUT = `.debug-actions-widget .debug-action.step-out`;
|
||||
const CONTINUE = `.debug-actions-widget .debug-action.continue`;
|
||||
const STOP = `.debug-toolbar .debug-action.stop`;
|
||||
const STEP_OVER = `.debug-toolbar .debug-action.step-over`;
|
||||
const STEP_IN = `.debug-toolbar .debug-action.step-into`;
|
||||
const STEP_OUT = `.debug-toolbar .debug-action.step-out`;
|
||||
const CONTINUE = `.debug-toolbar .debug-action.continue`;
|
||||
const GLYPH_AREA = '.margin-view-overlays>:nth-child';
|
||||
const BREAKPOINT_GLYPH = '.debug-breakpoint';
|
||||
const PAUSE = `.debug-actions-widget .debug-action.pause`;
|
||||
const PAUSE = `.debug-toolbar .debug-action.pause`;
|
||||
const DEBUG_STATUS_BAR = `.statusbar.debugging`;
|
||||
const NOT_DEBUG_STATUS_BAR = `.statusbar:not(debugging)`;
|
||||
const TOOLBAR_HIDDEN = `.debug-actions-widget.monaco-builder-hidden`;
|
||||
const TOOLBAR_HIDDEN = `.debug-toolbar[aria-hidden="true"]`;
|
||||
const STACK_FRAME = `${VIEWLET} .monaco-tree-row .stack-frame`;
|
||||
const SPECIFIC_STACK_FRAME = filename => `${STACK_FRAME} .file[title$="${filename}"]`;
|
||||
const SPECIFIC_STACK_FRAME = filename => `${STACK_FRAME} .file[title*="${filename}"]`;
|
||||
const VARIABLE = `${VIEWLET} .debug-variables .monaco-tree-row .expression`;
|
||||
const CONSOLE_OUTPUT = `.repl .output.expression .value`;
|
||||
const CONSOLE_INPUT_OUTPUT = `.repl .input-output-pair .output.expression .value`;
|
||||
@@ -125,7 +125,7 @@ export class Debug extends Viewlet {
|
||||
}
|
||||
|
||||
async waitForReplCommand(text: string, accept: (result: string) => boolean): Promise<void> {
|
||||
await this.commands.runCommand('Debug: Focus Debug Console');
|
||||
await this.commands.runCommand('Debug: Focus on Debug Console View');
|
||||
await this.code.waitForActiveElement(REPL_FOCUSED);
|
||||
await this.code.waitForSetValue(REPL_FOCUSED, text);
|
||||
|
||||
@@ -22,7 +22,7 @@ export class Editor {
|
||||
|
||||
async findReferences(filename: string, term: string, line: number): Promise<References> {
|
||||
await this.clickOnTerm(filename, term, line);
|
||||
await this.commands.runCommand('Find All References');
|
||||
await this.commands.runCommand('Peek References');
|
||||
const references = new References(this.code);
|
||||
await references.waitUntilOpen();
|
||||
return references;
|
||||
@@ -40,7 +40,7 @@ export class Editor {
|
||||
|
||||
async gotoDefinition(filename: string, term: string, line: number): Promise<void> {
|
||||
await this.clickOnTerm(filename, term, line);
|
||||
await this.commands.runCommand('Go to Definition');
|
||||
await this.commands.runCommand('Go to Implementation');
|
||||
}
|
||||
|
||||
async peekDefinition(filename: string, term: string, line: number): Promise<References> {
|
||||
|
||||
@@ -34,6 +34,6 @@ export class Extensions extends Viewlet {
|
||||
await this.searchForExtension(name);
|
||||
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(`div.extensions-viewlet[id="workbench.view.extensions"] .monaco-list-row[aria-label="${ariaLabel}"] .extension li[class='action-item'] .extension-action.reload`);
|
||||
await this.code.waitForElement(`.extension-editor .monaco-action-bar .action-item:not(.disabled) .extension-action.uninstall`);
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,8 @@ export function setup() {
|
||||
before(async function () {
|
||||
const app = this.app as Application;
|
||||
|
||||
cp.execSync('git config user.name testuser', { cwd: app.workspacePath });
|
||||
cp.execSync('git config user.email monacotools@microsoft.com', { cwd: app.workspacePath });
|
||||
cp.execSync('git config user.name testuser', { cwd: app.workspacePathOrFolder });
|
||||
cp.execSync('git config user.email monacotools@microsoft.com', { cwd: app.workspacePathOrFolder });
|
||||
});
|
||||
|
||||
it('reflects working tree changes', async function () {
|
||||
@@ -71,7 +71,7 @@ export function setup() {
|
||||
await app.workbench.scm.commit('second commit');
|
||||
await app.code.waitForTextContent(SYNC_STATUSBAR, ' 0↓ 2↑');
|
||||
|
||||
cp.execSync('git reset --hard origin/master', { cwd: app.workspacePath });
|
||||
cp.execSync('git reset --hard origin/master', { cwd: app.workspacePathOrFolder });
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -3,17 +3,44 @@
|
||||
* 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 { Application } from '../../application';
|
||||
|
||||
function toUri(path: string): string {
|
||||
if (process.platform === 'win32') {
|
||||
return `${path.replace(/\\/g, '/')}`;
|
||||
}
|
||||
|
||||
return `${path}`;
|
||||
}
|
||||
|
||||
async function createWorkspaceFile(workspacePath: string): Promise<string> {
|
||||
const workspaceFilePath = path.join(path.dirname(workspacePath), 'smoketest.code-workspace');
|
||||
const workspace = {
|
||||
folders: [
|
||||
{ path: toUri(path.join(workspacePath, 'public')) },
|
||||
{ path: toUri(path.join(workspacePath, 'routes')) },
|
||||
{ path: toUri(path.join(workspacePath, 'views')) }
|
||||
]
|
||||
};
|
||||
|
||||
fs.writeFileSync(workspaceFilePath, JSON.stringify(workspace, null, '\t'));
|
||||
|
||||
return workspaceFilePath;
|
||||
}
|
||||
|
||||
export function setup() {
|
||||
describe('Multiroot', () => {
|
||||
|
||||
before(async function () {
|
||||
const app = this.app as Application;
|
||||
|
||||
const workspaceFilePath = await createWorkspaceFile(app.workspacePathOrFolder);
|
||||
|
||||
// restart with preventing additional windows from restoring
|
||||
// to ensure the window after restart is the multi-root workspace
|
||||
await app.restart({ workspaceOrFolder: app.workspaceFilePath, extraArgs: ['--disable-restore-windows'] });
|
||||
await app.restart({ workspaceOrFolder: workspaceFilePath, extraArgs: ['--disable-restore-windows'] });
|
||||
});
|
||||
|
||||
it('shows results from all folders', async function () {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Code } from '../../vscode/code';
|
||||
|
||||
const SEARCH_INPUT = '.settings-search-input input';
|
||||
const SEARCH_INPUT = '.keybindings-header .settings-search-input input';
|
||||
|
||||
export class KeybindingsEditor {
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Editors } from '../editor/editors';
|
||||
import { Code } from '../../vscode/code';
|
||||
import { QuickOpen } from '../quickopen/quickopen';
|
||||
|
||||
export enum ActivityBarPosition {
|
||||
export const enum ActivityBarPosition {
|
||||
LEFT = 0,
|
||||
RIGHT = 1
|
||||
}
|
||||
@@ -42,6 +42,6 @@ export class SettingsEditor {
|
||||
}
|
||||
|
||||
private async openSettings(): Promise<void> {
|
||||
await this.quickopen.runCommand('Preferences: Open User Settings');
|
||||
await this.quickopen.runCommand('Preferences: Open Settings (JSON)');
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Code } from '../../vscode/code';
|
||||
|
||||
export enum ProblemSeverity {
|
||||
export const enum ProblemSeverity {
|
||||
WARNING = 0,
|
||||
ERROR = 1
|
||||
}
|
||||
@@ -40,7 +40,7 @@ export class Problems {
|
||||
|
||||
public static getSelectorInProblemsView(problemType: ProblemSeverity): string {
|
||||
let selector = problemType === ProblemSeverity.WARNING ? 'warning' : 'error';
|
||||
return `div[aria-label="Problems grouped by files"] .icon.${selector}`;
|
||||
return `div[id="workbench.panel.markers"] .monaco-tl-contents .icon.${selector}`;
|
||||
}
|
||||
|
||||
public static getSelectorInEditor(problemType: ProblemSeverity): string {
|
||||
|
||||
@@ -25,4 +25,13 @@ export class QuickInput {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ 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 = 'div.monaco-quick-open-widget[aria-hidden="false"]';
|
||||
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';
|
||||
|
||||
@@ -10,8 +10,8 @@ export function setup() {
|
||||
describe('Search', () => {
|
||||
after(function () {
|
||||
const app = this.app as Application;
|
||||
cp.execSync('git checkout .', { cwd: app.workspacePath });
|
||||
cp.execSync('git reset --hard origin/master', { cwd: app.workspacePath });
|
||||
cp.execSync('git checkout .', { cwd: app.workspacePathOrFolder });
|
||||
cp.execSync('git reset --hard origin/master', { cwd: app.workspacePathOrFolder });
|
||||
});
|
||||
|
||||
it('searches for body & checks for correct result number', async function () {
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
import { Viewlet } from '../workbench/viewlet';
|
||||
import { Code } from '../../vscode/code';
|
||||
|
||||
const VIEWLET = 'div[id="workbench.view.search"] .search-view';
|
||||
const INPUT = `${VIEWLET} .search-widget .search-container .monaco-inputbox input`;
|
||||
const VIEWLET = 'div[id="workbench.view.search"].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}"]`;
|
||||
|
||||
@@ -53,7 +53,7 @@ export class Search extends Viewlet {
|
||||
await this.waitForInputFocus(INPUT);
|
||||
|
||||
await this.code.dispatchKeybinding('enter');
|
||||
await this.code.waitForElement(`${VIEWLET} .messages[aria-hidden="false"]`);
|
||||
await this.code.waitForElement(`${VIEWLET} .messages`);
|
||||
}
|
||||
|
||||
async setFilesToIncludeText(text: string): Promise<void> {
|
||||
@@ -92,7 +92,7 @@ export class Search extends Viewlet {
|
||||
}
|
||||
|
||||
async setReplaceText(text: string): Promise<void> {
|
||||
await this.code.waitForSetValue(`${VIEWLET} .search-widget .replace-container .monaco-inputbox input[title="Replace"]`, text);
|
||||
await this.code.waitForSetValue(`${VIEWLET} .search-widget .replace-container .monaco-inputbox textarea[title="Replace"]`, text);
|
||||
}
|
||||
|
||||
async replaceFileMatch(filename: string): Promise<void> {
|
||||
@@ -109,11 +109,11 @@ export class Search extends Viewlet {
|
||||
}
|
||||
|
||||
async waitForResultText(text: string): Promise<void> {
|
||||
await this.code.waitForTextContent(`${VIEWLET} .messages[aria-hidden="false"] .message>p`, text);
|
||||
await this.code.waitForTextContent(`${VIEWLET} .messages .message>p`, text);
|
||||
}
|
||||
|
||||
async waitForNoResultText(): Promise<void> {
|
||||
await this.code.waitForElement(`${VIEWLET} .messages[aria-hidden="false"] .message>p`, el => !el);
|
||||
await this.code.waitForElement(`${VIEWLET} .messages[aria-hidden="true"] .message>p`);
|
||||
}
|
||||
|
||||
private async waitForInputFocus(selector: string): Promise<void> {
|
||||
|
||||
@@ -35,17 +35,17 @@ export function setup() {
|
||||
|
||||
await app.workbench.quickopen.openFile('app.js');
|
||||
await app.workbench.statusbar.clickOn(StatusBarElement.INDENTATION_STATUS);
|
||||
await app.workbench.quickopen.waitForQuickOpenOpened();
|
||||
await app.workbench.quickopen.closeQuickOpen();
|
||||
await app.workbench.quickinput.waitForQuickInputOpened();
|
||||
await app.workbench.quickinput.closeQuickInput();
|
||||
await app.workbench.statusbar.clickOn(StatusBarElement.ENCODING_STATUS);
|
||||
await app.workbench.quickopen.waitForQuickOpenOpened();
|
||||
await app.workbench.quickopen.closeQuickOpen();
|
||||
await app.workbench.quickinput.waitForQuickInputOpened();
|
||||
await app.workbench.quickinput.closeQuickInput();
|
||||
await app.workbench.statusbar.clickOn(StatusBarElement.EOL_STATUS);
|
||||
await app.workbench.quickopen.waitForQuickOpenOpened();
|
||||
await app.workbench.quickopen.closeQuickOpen();
|
||||
await app.workbench.quickinput.waitForQuickInputOpened();
|
||||
await app.workbench.quickinput.closeQuickInput();
|
||||
await app.workbench.statusbar.clickOn(StatusBarElement.LANGUAGE_STATUS);
|
||||
await app.workbench.quickopen.waitForQuickOpenOpened();
|
||||
await app.workbench.quickopen.closeQuickOpen();
|
||||
await app.workbench.quickinput.waitForQuickInputOpened();
|
||||
await app.workbench.quickinput.closeQuickInput();
|
||||
});
|
||||
|
||||
it(`verifies that 'Problems View' appears when clicking on 'Problems' status element`, async function () {
|
||||
@@ -84,8 +84,8 @@ export function setup() {
|
||||
await app.workbench.quickopen.openFile('app.js');
|
||||
await app.workbench.statusbar.clickOn(StatusBarElement.EOL_STATUS);
|
||||
|
||||
await app.workbench.quickopen.waitForQuickOpenOpened();
|
||||
await app.workbench.quickopen.selectQuickOpenElement(1);
|
||||
await app.workbench.quickinput.waitForQuickInputOpened();
|
||||
await app.workbench.quickinput.selectQuickInputElement(1);
|
||||
|
||||
await app.workbench.statusbar.waitForEOL('CRLF');
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Code } from '../../vscode/code';
|
||||
|
||||
export enum StatusBarElement {
|
||||
export const enum StatusBarElement {
|
||||
BRANCH_STATUS = 0,
|
||||
SYNC_STATUS = 1,
|
||||
PROBLEMS_STATUS = 2,
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
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`;
|
||||
@@ -11,10 +12,10 @@ const XTERM_TEXTAREA = `${XTERM_SELECTOR} textarea.xterm-helper-textarea`;
|
||||
|
||||
export class Terminal {
|
||||
|
||||
constructor(private code: Code) { }
|
||||
constructor(private code: Code, private quickopen: QuickOpen) { }
|
||||
|
||||
async showTerminal(): Promise<void> {
|
||||
await this.code.dispatchKeybinding('ctrl+`');
|
||||
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));
|
||||
}
|
||||
|
||||
38
test/smoke/src/areas/workbench/launch.test.ts
Normal file
38
test/smoke/src/areas/workbench/launch.test.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as path from 'path';
|
||||
import { Application, ApplicationOptions } from '../../application';
|
||||
|
||||
export function setup() {
|
||||
|
||||
describe('Launch', () => {
|
||||
|
||||
let app: Application;
|
||||
|
||||
after(async function () {
|
||||
if (app) {
|
||||
await app.stop();
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(async function () {
|
||||
if (app) {
|
||||
if (this.currentTest.state === 'failed') {
|
||||
const name = this.currentTest.fullTitle().replace(/[^a-z0-9\-]/ig, '_');
|
||||
await app.captureScreenshot(name);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it(`verifies that application launches when user data directory has non-ascii characters`, async function () {
|
||||
const defaultOptions = this.defaultOptions as ApplicationOptions;
|
||||
const options: ApplicationOptions = { ...defaultOptions, userDataDir: path.join(defaultOptions.userDataDir, 'abcdø') };
|
||||
app = new Application(options);
|
||||
await app.start();
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
@@ -3,8 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { Code } from '../../vscode/code';
|
||||
|
||||
export abstract class Viewlet {
|
||||
|
||||
@@ -11,7 +11,7 @@ import { Extensions } from '../extensions/extensions';
|
||||
import { Search } from '../search/search';
|
||||
import { Editor } from '../editor/editor';
|
||||
import { SCM } from '../git/scm';
|
||||
import { Debug } from '../debug/debug';
|
||||
import { Debug } from '../debug/debugSmoke';
|
||||
import { StatusBar } from '../statusbar/statusbar';
|
||||
import { Problems } from '../problems/problems';
|
||||
import { SettingsEditor } from '../preferences/settings';
|
||||
@@ -67,11 +67,10 @@ export class Workbench {
|
||||
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.terminal = new Terminal(code, this.quickopen);
|
||||
// {{SQL CARBON EDIT}}
|
||||
this.connectionDialog = new ConnectionDialog(code);
|
||||
this.profiler = new Profiler(code, this.quickopen);
|
||||
// {{END}}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,12 +11,12 @@ import * as tmp from 'tmp';
|
||||
import * as rimraf from 'rimraf';
|
||||
import * as mkdirp from 'mkdirp';
|
||||
import { ncp } from 'ncp';
|
||||
import { Application, Quality } from './application';
|
||||
import { Application, Quality, ApplicationOptions } from './application';
|
||||
//{{SQL CARBON EDIT}}
|
||||
import { setup as runProfilerTests } from './sql/profiler/profiler.test';
|
||||
//Original
|
||||
/*
|
||||
import { setup as setupDataMigrationTests } from './areas/workbench/data-migration.test';
|
||||
// import { setup as setupDataMigrationTests } from './areas/workbench/data-migration.test';
|
||||
import { setup as setupDataLossTests } from './areas/workbench/data-loss.test';
|
||||
import { setup as setupDataExplorerTests } from './areas/explorer/explorer.test';
|
||||
import { setup as setupDataPreferencesTests } from './areas/preferences/preferences.test';
|
||||
@@ -30,6 +30,7 @@ import { setup as setupDataExtensionTests } from './areas/extensions/extensions.
|
||||
import { setup as setupTerminalTests } from './areas/terminal/terminal.test';
|
||||
import { setup as setupDataMultirootTests } from './areas/multiroot/multiroot.test';
|
||||
import { setup as setupDataLocalizationTests } from './areas/workbench/localization.test';
|
||||
import { setup as setupLaunchTests } from './areas/workbench/launch.test';
|
||||
*/
|
||||
//{{END}}
|
||||
import { MultiLogger, Logger, ConsoleLogger, FileLogger } from './logger';
|
||||
@@ -56,7 +57,6 @@ const opts = minimist(args, {
|
||||
}
|
||||
});
|
||||
|
||||
const workspaceFilePath = path.join(testDataPath, 'smoketest.code-workspace');
|
||||
const testRepoUrl = 'https://github.com/Microsoft/vscode-smoketest-express';
|
||||
const workspacePath = path.join(testDataPath, 'vscode-smoketest-express');
|
||||
const extensionsPath = path.join(testDataPath, 'extensions-dir');
|
||||
@@ -146,37 +146,6 @@ if (process.env.VSCODE_DEV === '1') {
|
||||
quality = Quality.Stable;
|
||||
}
|
||||
|
||||
function toUri(path: string): string {
|
||||
if (process.platform === 'win32') {
|
||||
return `${path.replace(/\\/g, '/')}`;
|
||||
}
|
||||
|
||||
return `${path}`;
|
||||
}
|
||||
|
||||
async function createWorkspaceFile(): Promise<void> {
|
||||
if (fs.existsSync(workspaceFilePath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('*** Creating workspace file...');
|
||||
const workspace = {
|
||||
folders: [
|
||||
{
|
||||
path: toUri(path.join(workspacePath, 'public'))
|
||||
},
|
||||
{
|
||||
path: toUri(path.join(workspacePath, 'routes'))
|
||||
},
|
||||
{
|
||||
path: toUri(path.join(workspacePath, 'views'))
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
fs.writeFileSync(workspaceFilePath, JSON.stringify(workspace, null, '\t'));
|
||||
}
|
||||
|
||||
async function setupRepository(): Promise<void> {
|
||||
if (opts['test-repo']) {
|
||||
console.log('*** Copying test project repository:', opts['test-repo']);
|
||||
@@ -203,13 +172,12 @@ async function setup(): Promise<void> {
|
||||
console.log('*** Test data:', testDataPath);
|
||||
console.log('*** Preparing smoketest setup...');
|
||||
|
||||
await createWorkspaceFile();
|
||||
await setupRepository();
|
||||
|
||||
console.log('*** Smoketest setup done!\n');
|
||||
}
|
||||
|
||||
function createApp(quality: Quality): Application {
|
||||
function createOptions(): ApplicationOptions {
|
||||
const loggers: Logger[] = [];
|
||||
|
||||
if (opts.verbose) {
|
||||
@@ -222,25 +190,25 @@ function createApp(quality: Quality): Application {
|
||||
loggers.push(new FileLogger(opts.log));
|
||||
log = 'trace';
|
||||
}
|
||||
|
||||
return new Application({
|
||||
return {
|
||||
quality,
|
||||
codePath: opts.build,
|
||||
workspacePath,
|
||||
userDataDir,
|
||||
extensionsPath,
|
||||
workspaceFilePath,
|
||||
waitTime: parseInt(opts['wait-time'] || '0') || 20,
|
||||
logger: new MultiLogger(loggers),
|
||||
verbose: opts.verbose,
|
||||
log
|
||||
});
|
||||
log,
|
||||
screenshotsPath
|
||||
};
|
||||
}
|
||||
|
||||
before(async function () {
|
||||
// allow two minutes for setup
|
||||
this.timeout(2 * 60 * 1000);
|
||||
await setup();
|
||||
this.defaultOptions = createOptions();
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
@@ -255,17 +223,13 @@ after(async function () {
|
||||
await new Promise((c, e) => rimraf(testDataPath, { maxBusyTries: 10 }, err => err ? e(err) : c()));
|
||||
});
|
||||
|
||||
//{{SQL CARBON EDIT}}
|
||||
/*
|
||||
describe('Data Migration', () => {
|
||||
setupDataMigrationTests(userDataDir, createApp);
|
||||
});
|
||||
*/
|
||||
//{{END}}
|
||||
// describe('Data Migration', () => {
|
||||
// setupDataMigrationTests(userDataDir, createApp);
|
||||
// });
|
||||
|
||||
describe('Smoke Test', () => {
|
||||
describe('Running Code', () => {
|
||||
before(async function () {
|
||||
const app = createApp(quality);
|
||||
const app = new Application(this.defaultOptions);
|
||||
await app!.start();
|
||||
//{{SQL CARBON EDIT}}
|
||||
const testExtLoadedText = 'Test Extension Loaded';
|
||||
@@ -293,19 +257,10 @@ describe('Smoke Test', () => {
|
||||
if (this.currentTest.state !== 'failed') {
|
||||
return;
|
||||
}
|
||||
|
||||
const app = this.app as Application;
|
||||
const raw = await app.capturePage();
|
||||
const buffer = new Buffer(raw, 'base64');
|
||||
|
||||
const name = this.currentTest.fullTitle().replace(/[^a-z0-9\-]/ig, '_');
|
||||
const screenshotPath = path.join(screenshotsPath, `${name}.png`);
|
||||
|
||||
if (opts.log) {
|
||||
app.logger.log('*** Screenshot recorded:', screenshotPath);
|
||||
}
|
||||
|
||||
fs.writeFileSync(screenshotPath, buffer);
|
||||
await app.captureScreenshot(name);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -338,3 +293,6 @@ describe('Smoke Test', () => {
|
||||
*/
|
||||
//{{END}}
|
||||
});
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
// setupLaunchTests();
|
||||
@@ -7,6 +7,6 @@ const path = require('path');
|
||||
|
||||
exports.connect = function (outPath, handle) {
|
||||
const bootstrapPath = path.join(outPath, 'bootstrap-amd.js');
|
||||
const { bootstrap } = require(bootstrapPath);
|
||||
return new Promise((c, e) => bootstrap('vs/platform/driver/node/driver', ({ connect }) => connect(handle).then(c, e), e));
|
||||
const { load } = require(bootstrapPath);
|
||||
return new Promise((c, e) => load('vs/platform/driver/node/driver', ({ connect }) => connect(handle).then(c, e), e));
|
||||
};
|
||||
@@ -7,7 +7,7 @@ const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const root = path.dirname(path.dirname(path.dirname(__dirname)));
|
||||
const driverPath = path.join(root, 'src/vs/platform/driver/common/driver.ts');
|
||||
const driverPath = path.join(root, 'src/vs/platform/driver/node/driver.ts');
|
||||
|
||||
let contents = fs.readFileSync(driverPath, 'utf8');
|
||||
contents = /\/\/\*START([\s\S]*)\/\/\*END/mi.exec(contents)[1].trim();
|
||||
|
||||
@@ -584,10 +584,10 @@ electron-download@^3.0.1:
|
||||
semver "^5.3.0"
|
||||
sumchecker "^1.2.0"
|
||||
|
||||
electron@^2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/electron/-/electron-2.0.6.tgz#8e5c1bd2ebc08fa7a6ee906de3753c1ece9d7300"
|
||||
integrity sha512-1UHBWHF2EMjjVyTvcdcUBmISnoxElY4cUgkFVslw5pM1HxTVzi2vev+8NBohdLLFGbIbPyNua5vcBg+bxo1rqw==
|
||||
electron@^2.0.12:
|
||||
version "2.0.12"
|
||||
resolved "https://registry.yarnpkg.com/electron/-/electron-2.0.12.tgz#04b11ef3246cd2a5839a8f16314051341dc5c449"
|
||||
integrity sha512-mw8hoM/GPtFPP8FGiJcVNe8Rx63YJ7O8bf7McQj21HAvrXGAwReGFrpIe5xN6ec10fDXNSNyfzRucjFXtOtLcg==
|
||||
dependencies:
|
||||
"@types/node" "^8.0.24"
|
||||
electron-download "^3.0.1"
|
||||
@@ -2132,10 +2132,10 @@ typedarray@^0.0.6:
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||
|
||||
typescript@2.5.2:
|
||||
version "2.5.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.5.2.tgz#038a95f7d9bbb420b1bf35ba31d4c5c1dd3ffe34"
|
||||
integrity sha1-A4qV99m7tCCxvzW6MdTFwd0//jQ=
|
||||
typescript@2.9.2:
|
||||
version "2.9.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c"
|
||||
integrity sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==
|
||||
|
||||
uid-number@^0.0.6:
|
||||
version "0.0.6"
|
||||
|
||||
Reference in New Issue
Block a user