提交 1ebb0dd2 编写于 作者: J Joao Moreno

remove spectron references

上级 1b2f1980
......@@ -29,10 +29,9 @@
"ncp": "^2.0.0",
"portastic": "^1.0.1",
"rimraf": "^2.6.1",
"spectron": "^3.7.2",
"strip-json-comments": "^2.0.1",
"tmp": "0.0.33",
"typescript": "2.5.2",
"watch": "^1.0.2"
}
}
\ No newline at end of file
}
......@@ -3,7 +3,149 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Driver, Element } from './driver';
import { IDriver, IElement } from './vscode/driver';
export class CodeDriver {
constructor(
private driver: IDriver,
private verbose: boolean
) { }
private _activeWindowId: number | undefined = undefined;
async dispatchKeybinding(keybinding: string): Promise<void> {
if (this.verbose) {
console.log('- dispatchKeybinding:', keybinding);
}
const windowId = await this.getWindowId();
await this.driver.dispatchKeybinding(windowId, keybinding);
}
async click(selector: string, xoffset?: number | undefined, yoffset?: number | undefined): Promise<any> {
if (this.verbose) {
console.log('- click:', selector);
}
const windowId = await this.getWindowId();
await this.driver.click(windowId, selector, xoffset, yoffset);
}
async doubleClick(selector: string): Promise<any> {
if (this.verbose) {
console.log('- doubleClick:', selector);
}
const windowId = await this.getWindowId();
await this.driver.doubleClick(windowId, selector);
}
async move(selector: string): Promise<any> {
if (this.verbose) {
console.log('- move:', selector);
}
const windowId = await this.getWindowId();
await this.driver.move(windowId, selector);
}
async setValue(selector: string, text: string): Promise<void> {
if (this.verbose) {
console.log('- setValue:', selector, text);
}
const windowId = await this.getWindowId();
await this.driver.setValue(windowId, selector, text);
}
async getTitle(): Promise<string> {
if (this.verbose) {
console.log('- getTitle:');
}
const windowId = await this.getWindowId();
return await this.driver.getTitle(windowId);
}
async isActiveElement(selector: string): Promise<boolean> {
if (this.verbose) {
console.log('- isActiveElement:', selector);
}
const windowId = await this.getWindowId();
return await this.driver.isActiveElement(windowId, selector);
}
async getElements(selector: string, recursive = false): Promise<IElement[]> {
if (this.verbose) {
console.log('- getElements:', selector);
}
const windowId = await this.getWindowId();
return await this.driver.getElements(windowId, selector, recursive);
}
async typeInEditor(selector: string, text: string): Promise<void> {
if (this.verbose) {
console.log('- typeInEditor:', selector, text);
}
const windowId = await this.getWindowId();
return await this.driver.typeInEditor(windowId, selector, text);
}
async getTerminalBuffer(selector: string): Promise<string[]> {
if (this.verbose) {
console.log('- getTerminalBuffer:', selector);
}
const windowId = await this.getWindowId();
return await this.driver.getTerminalBuffer(windowId, selector);
}
private async getWindowId(): Promise<number> {
if (typeof this._activeWindowId !== 'number') {
const windows = await this.driver.getWindowIds();
this._activeWindowId = windows[0];
}
return this._activeWindowId;
}
}
export function findElement(element: IElement, fn: (element: IElement) => boolean): IElement | null {
const queue = [element];
while (queue.length > 0) {
const element = queue.shift()!;
if (fn(element)) {
return element;
}
queue.push(...element.children);
}
return null;
}
export function findElements(element: IElement, fn: (element: IElement) => boolean): IElement[] {
const result: IElement[] = [];
const queue = [element];
while (queue.length > 0) {
const element = queue.shift()!;
if (fn(element)) {
result.push(element);
}
queue.push(...element.children);
}
return result;
}
export class API {
......@@ -13,7 +155,7 @@ export class API {
private readonly retryDuration = 100; // in milliseconds
constructor(
private driver: Driver,
private driver: CodeDriver,
waitTime: number
) {
this.retryCount = (waitTime * 1000) / this.retryDuration;
......@@ -58,11 +200,11 @@ export class API {
return elements.length;
}
waitForElements(selector: string, recursive: boolean, accept: (result: Element[]) => boolean = result => result.length > 0): Promise<Element[]> {
waitForElements(selector: string, recursive: boolean, accept: (result: IElement[]) => boolean = result => result.length > 0): Promise<IElement[]> {
return this.waitFor(() => this.driver.getElements(selector, recursive), accept, `elements with selector ${selector}`) as Promise<any>;
}
waitForElement(selector: string, accept: (result: Element | undefined) => boolean = result => !!result): Promise<void> {
waitForElement(selector: string, accept: (result: IElement | undefined) => boolean = result => !!result): Promise<void> {
return this.waitFor(() => this.driver.getElements(selector).then(els => els[0]), accept, `element with selector ${selector}`) as Promise<any>;
}
......
......@@ -3,11 +3,10 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { API } from './api';
import { API, CodeDriver } from './api';
import { Workbench } from './areas/workbench/workbench';
import * as fs from 'fs';
import * as cp from 'child_process';
import { CodeDriver } from './driver';
import { Code, spawn, SpawnOptions } from './vscode/code';
export enum Quality {
......@@ -16,22 +15,15 @@ export enum Quality {
Stable
}
export interface SpectronApplicationOptions extends SpawnOptions {
export interface ApplicationOptions extends SpawnOptions {
quality: Quality;
electronPath: string;
workspacePath: string;
artifactsPath: string;
workspaceFilePath: string;
waitTime: number;
verbose: boolean;
}
/**
* Wraps Spectron's Application instance with its used methods.
*/
export class SpectronApplication {
// private static count = 0;
export class Application {
private _api: API;
private _workbench: Workbench;
......@@ -39,9 +31,7 @@ export class SpectronApplication {
private keybindings: any[];
private stopLogCollection: (() => Promise<void>) | undefined;
constructor(
private options: SpectronApplicationOptions
) { }
constructor(private options: ApplicationOptions) { }
get quality(): Quality {
return this.options.quality;
......
......@@ -3,13 +3,13 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { SpectronApplication } from '../../application';
import { Application } from '../../application';
import { ProblemSeverity, Problems } from '../problems/problems';
export function setup() {
describe('CSS', () => {
it('verifies quick outline', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.quickopen.openFile('style.css');
await app.workbench.quickopen.openQuickOutline();
......@@ -17,7 +17,7 @@ export function setup() {
});
it('verifies warnings for the empty rule', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.quickopen.openFile('style.css');
await app.workbench.editor.waitForTypeInEditor('style.css', '.foo{}');
......@@ -29,7 +29,7 @@ export function setup() {
});
it('verifies that warning becomes an error once setting changed', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.settingsEditor.addUserSetting('css.lint.emptyRules', '"error"');
await app.workbench.quickopen.openFile('style.css');
await app.workbench.editor.waitForTypeInEditor('style.css', '.foo{}');
......
......@@ -8,12 +8,12 @@ import * as http from 'http';
import * as path from 'path';
import * as fs from 'fs';
import * as stripJsonComments from 'strip-json-comments';
import { SpectronApplication } from '../../application';
import { Application } from '../../application';
export function setup() {
describe('Debug', () => {
it('configure launch json', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.debug.openDebugViewlet();
await app.workbench.quickopen.openFile('app.js');
......@@ -37,7 +37,7 @@ export function setup() {
});
it('breakpoints', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.quickopen.openFile('index.js');
await app.workbench.debug.setBreakpointOnLine(6);
......@@ -45,7 +45,7 @@ export function setup() {
let port: number;
it('start debugging', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
// TODO@isidor
await new Promise(c => setTimeout(c, 100));
......@@ -60,7 +60,7 @@ export function setup() {
});
it('focus stack frames and variables', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.api.waitFor(() => app.workbench.debug.getLocalVariableCount(), c => c === 4, 'there should be 4 local variables');
......@@ -75,7 +75,7 @@ export function setup() {
});
it('stepOver, stepIn, stepOut', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.debug.stepIn();
......@@ -89,7 +89,7 @@ export function setup() {
});
it('continue', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.debug.continue();
......@@ -102,13 +102,13 @@ export function setup() {
});
it('debug console', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.debug.waitForReplCommand('2 + 2', r => r === '4');
});
it('stop debugging', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.debug.stopDebugging();
});
......
......@@ -5,10 +5,10 @@
import { Viewlet } from '../workbench/viewlet';
import { Commands } from '../workbench/workbench';
import { API } from '../../api';
import { API, findElement } from '../../api';
import { Editors } from '../editor/editors';
import { Editor } from '../editor/editor';
import { findElement, Element } from '../../driver';
import { IElement } from '../../vscode/driver';
const VIEWLET = 'div[id="workbench.view.debug"]';
const DEBUG_VIEW = `${VIEWLET} .debug-view-content`;
......@@ -37,7 +37,7 @@ export interface IStackFrame {
lineNumber: number;
}
function toStackFrame(element: Element): IStackFrame {
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;
......
......@@ -3,12 +3,12 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { SpectronApplication } from '../../application';
import { Application } from '../../application';
export function setup() {
describe('Editor', () => {
it('shows correct quick outline', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.quickopen.openFile('www');
await app.workbench.quickopen.openQuickOutline();
......@@ -16,7 +16,7 @@ export function setup() {
});
it(`finds 'All References' to 'app'`, async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.quickopen.openFile('www');
const references = await app.workbench.editor.findReferences('app', 7);
......@@ -27,7 +27,7 @@ export function setup() {
});
it(`renames local 'app' variable`, async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.quickopen.openFile('www');
await app.workbench.editor.rename('www', 7, 'app', 'newApp');
await app.workbench.editor.waitForEditorContents('www', contents => contents.indexOf('newApp') > -1);
......@@ -50,7 +50,7 @@ export function setup() {
// });
it(`verifies that 'Go To Definition' works`, async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.quickopen.openFile('app.js');
await app.workbench.editor.gotoDefinition('express', 11);
......@@ -59,7 +59,7 @@ export function setup() {
});
it(`verifies that 'Peek Definition' works`, async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.quickopen.openFile('app.js');
const peek = await app.workbench.editor.peekDefinition('express', 11);
......
......@@ -3,12 +3,12 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { SpectronApplication } from '../../application';
import { Application } from '../../application';
export function setup() {
describe('Explorer', () => {
it('quick open search produces correct result', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
const expectedNames = [
'.eslintrc.json',
'tasks.json',
......@@ -25,7 +25,7 @@ export function setup() {
});
it('quick open respects fuzzy matching', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
const expectedNames = [
'tasks.json',
'app.js',
......
......@@ -4,12 +4,12 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { SpectronApplication, Quality } from '../../application';
import { Application, Quality } from '../../application';
export function setup() {
describe('Extensions', () => {
it(`install and activate vscode-smoketest-check extension`, async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
if (app.quality === Quality.Dev) {
this.skip();
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as cp from 'child_process';
import { SpectronApplication } from '../../application';
import { Application } from '../../application';
const DIFF_EDITOR_LINE_INSERT = '.monaco-diff-editor .editor.modified .line-insert';
const SYNC_STATUSBAR = 'div[id="workbench.parts.statusbar"] .statusbar-entry a[title$="Synchronize Changes"]';
......@@ -12,7 +12,7 @@ const SYNC_STATUSBAR = 'div[id="workbench.parts.statusbar"] .statusbar-entry a[t
export function setup() {
describe('Git', () => {
it('reflects working tree changes', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.scm.openSCMViewlet();
......@@ -30,7 +30,7 @@ export function setup() {
});
it('opens diff editor', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.scm.openSCMViewlet();
await app.workbench.scm.openChange('app.js');
......@@ -38,7 +38,7 @@ export function setup() {
});
it('stages correctly', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.scm.openSCMViewlet();
......@@ -52,7 +52,7 @@ export function setup() {
});
it(`stages, commits changes and verifies outgoing change`, async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.scm.openSCMViewlet();
......
......@@ -4,9 +4,9 @@
*--------------------------------------------------------------------------------------------*/
import { Viewlet } from '../workbench/viewlet';
import { API } from '../../api';
import { API, findElement, findElements } from '../../api';
import { Commands } from '../workbench/workbench';
import { Element, findElement, findElements } from '../../driver';
import { IElement } from '../../vscode/driver';
const VIEWLET = 'div[id="workbench.view.scm"]';
const SCM_INPUT = `${VIEWLET} .scm-editor textarea`;
......@@ -24,7 +24,7 @@ interface Change {
actions: string[];
}
function toChange(element: Element): Change {
function toChange(element: IElement): Change {
const name = findElement(element, e => /\blabel-name\b/.test(e.className))!;
const type = element.attributes['data-tooltip'] || '';
......
......@@ -4,13 +4,13 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { SpectronApplication } from '../../application';
import { Application } from '../../application';
export function setup() {
describe('Multiroot', () => {
before(async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
// restart with preventing additional windows from restoring
// to ensure the window after restart is the multi-root workspace
......@@ -18,7 +18,7 @@ export function setup() {
});
it('shows results from all folders', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.quickopen.openQuickOpen('*.*');
await app.workbench.quickopen.waitForQuickOpenElements(names => names.length === 6);
......@@ -26,7 +26,7 @@ export function setup() {
});
it('shows workspace name in title', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
const title = await app.api.getTitle();
assert.ok(title.indexOf('smoketest (Workspace)') >= 0);
});
......
......@@ -5,13 +5,13 @@
import * as assert from 'assert';
import { SpectronApplication } from '../../application';
import { Application } from '../../application';
import { ActivityBarPosition } from '../activitybar/activityBar';
export function setup() {
describe('Preferences', () => {
it('turns off editor line numbers and verifies the live change', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.explorer.openFile('app.js');
await app.api.waitForElements('.line-numbers', false, elements => !!elements.length);
......@@ -22,7 +22,7 @@ export function setup() {
});
it(`changes 'workbench.action.toggleSidebarPosition' command key binding and verifies it`, async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
assert.ok(await app.workbench.activitybar.getActivityBar(ActivityBarPosition.LEFT), 'Activity bar should be positioned on the left.');
await app.workbench.keybindingsEditor.updateKeybinding('workbench.action.toggleSidebarPosition', 'ctrl+u', 'Control+U');
......@@ -32,7 +32,7 @@ export function setup() {
});
after(async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.settingsEditor.clearUserSettings();
});
});
......
......@@ -3,12 +3,12 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { SpectronApplication } from '../../application';
import { Application } from '../../application';
export function setup() {
describe('Search', () => {
it('searches for body & checks for correct result number', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.search.openSearchViewlet();
await app.workbench.search.searchFor('body');
......@@ -16,7 +16,7 @@ export function setup() {
});
it('searches only for *.js files & checks for correct result number', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.search.searchFor('body');
await app.workbench.search.showQueryDetails();
await app.workbench.search.setFilesToIncludeText('*.js');
......@@ -28,14 +28,14 @@ export function setup() {
});
it('dismisses result & checks for correct result number', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.search.searchFor('body');
await app.workbench.search.removeFileMatch(1);
await app.workbench.search.waitForResultText('10 results in 4 files');
});
it('replaces first search result with a replace term', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.search.searchFor('body');
await app.workbench.search.expandReplace();
......
......@@ -3,13 +3,13 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { SpectronApplication, Quality } from '../../application';
import { Application, Quality } from '../../application';
import { StatusBarElement } from './statusbar';
export function setup() {
describe('Statusbar', () => {
it('verifies presence of all default status bar elements', async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.statusbar.waitForStatusbarElement(StatusBarElement.BRANCH_STATUS);
if (app.quality !== Quality.Dev) {
......@@ -27,7 +27,7 @@ export function setup() {
});
it(`verifies that 'quick open' opens when clicking on status bar elements`, async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.statusbar.clickOn(StatusBarElement.BRANCH_STATUS);
await app.workbench.quickopen.waitForQuickOpenOpened();
......@@ -49,14 +49,14 @@ export function setup() {
});
it(`verifies that 'Problems View' appears when clicking on 'Problems' status element`, async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.statusbar.clickOn(StatusBarElement.PROBLEMS_STATUS);
await app.workbench.problems.waitForProblemsView();
});
it(`verifies that 'Tweet us feedback' pop-up appears when clicking on 'Feedback' icon`, async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
if (app.quality === Quality.Dev) {
return this.skip();
......@@ -67,7 +67,7 @@ export function setup() {
});
it(`checks if 'Go to Line' works if called from the status bar`, async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.quickopen.openFile('app.js');
await app.workbench.statusbar.clickOn(StatusBarElement.SELECTION_STATUS);
......@@ -79,7 +79,7 @@ export function setup() {
});
it(`verifies if changing EOL is reflected in the status bar`, async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.quickopen.openFile('app.js');
await app.workbench.statusbar.clickOn(StatusBarElement.EOL_STATUS);
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// import { SpectronApplication } from '../../application';
describe('Terminal', () => {
// let app: SpectronApplication;
// before(() => { app = new SpectronApplication(); return app.start('Terminal'); });
// after(() => app.stop());
// it(`opens terminal, runs 'echo' and verifies the output`, async function () {
// const expected = new Date().getTime().toString();
// await app.workbench.terminal.showTerminal();
// await app.workbench.terminal.runCommand(`echo ${expected}`);
// await app.workbench.terminal.waitForTerminalText(terminalText => {
// // Last line will not contain the output
// for (let index = terminalText.length - 2; index >= 0; index--) {
// if (!!terminalText[index] && terminalText[index].trim() === expected) {
// return true;
// }
// }
// return false;
// });
// });
});
\ No newline at end of file
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { API } from '../../api';
import { Commands } from '../workbench/workbench';
const PANEL_SELECTOR = 'div[id="workbench.panel.terminal"]';
const XTERM_SELECTOR = `${PANEL_SELECTOR} .terminal-wrapper`;
export class Terminal {
constructor(private api: API, private commands: Commands) { }
async showTerminal(): Promise<void> {
if (!await this.isVisible()) {
await this.commands.runCommand('View: Toggle Integrated Terminal');
await this.api.waitForElement(XTERM_SELECTOR);
await this.waitForTerminalText(text => text.length > 0, 'Waiting for Terminal to be ready');
}
}
isVisible(): Promise<boolean> {
return this.api.doesElementExist(PANEL_SELECTOR);
}
async runCommand(commandText: string): Promise<void> {
// TODO@Tyriar fix this. we should not use type but setValue
// await this.spectron.client.type(commandText);
await this.api.dispatchKeybinding('enter');
}
async waitForTerminalText(fn: (text: string[]) => boolean, timeOutDescription: string = 'Getting Terminal Text'): Promise<void> {
await this.api.waitFor(async () => {
const terminalText = await this.api.getTerminalBuffer(XTERM_SELECTOR);
return fn(terminalText);
}, void 0, timeOutDescription);
}
async getCurrentLineNumber(): Promise<number> {
const terminalText = await this.api.getTerminalBuffer(XTERM_SELECTOR);
return terminalText.length;
}
}
\ No newline at end of file
......@@ -3,12 +3,12 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { SpectronApplication } from '../../application';
import { Application } from '../../application';
export function setup() {
describe('Dataloss', () => {
it(`verifies that 'hot exit' works for dirty files`, async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
await app.workbench.editors.newUntitledFile();
const untitled = 'Untitled-1';
......
......@@ -5,11 +5,11 @@
import * as assert from 'assert';
import { SpectronApplication, Quality } from '../../application';
import { Application, Quality } from '../../application';
import * as rimraf from 'rimraf';
export interface ICreateAppFn {
(quality: Quality): SpectronApplication | null;
(quality: Quality): Application | null;
}
export function setup(userDataDir: string, createApp: ICreateAppFn) {
......
......@@ -5,12 +5,12 @@
import * as assert from 'assert';
import { SpectronApplication, Quality } from '../../application';
import { Application, Quality } from '../../application';
export function setup() {
describe('Localization', () => {
before(async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
if (app.quality === Quality.Dev) {
return;
......@@ -20,7 +20,7 @@ export function setup() {
});
it(`starts with 'DE' locale and verifies title and viewlets text is in German`, async function () {
const app = this.app as SpectronApplication;
const app = this.app as Application;
if (app.quality === Quality.Dev) {
this.skip();
......
......@@ -15,7 +15,6 @@ import { StatusBar } from '../statusbar/statusbar';
import { Problems } from '../problems/problems';
import { SettingsEditor } from '../preferences/settings';
import { KeybindingsEditor } from '../preferences/keybindings';
import { Terminal } from '../terminal/terminal';
import { API } from '../../api';
import { Editors } from '../editor/editors';
......@@ -38,7 +37,6 @@ export class Workbench implements Commands {
readonly problems: Problems;
readonly settingsEditor: SettingsEditor;
readonly keybindingsEditor: KeybindingsEditor;
readonly terminal: Terminal;
constructor(private api: API, private keybindings: any[], userDataPath: string) {
this.editors = new Editors(api, this);
......@@ -54,7 +52,6 @@ export class Workbench implements Commands {
this.problems = new Problems(api, this);
this.settingsEditor = new SettingsEditor(api, userDataPath, this, this.editors, this.editor);
this.keybindingsEditor = new KeybindingsEditor(api, this);
this.terminal = new Terminal(api, this);
}
/**
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { SpectronClient } from 'spectron';
import { IDriver } from './vscode/driver';
export interface Element {
tagName: string;
className: string;
textContent: string;
attributes: { [name: string]: string };
children: Element[];
}
export interface Driver {
dispatchKeybinding(keybinding: string): Promise<void>;
click(selector: string, xoffset?: number, yoffset?: number): Promise<any>;
doubleClick(selector: string): Promise<any>;
move(selector: string): Promise<any>;
setValue(selector: string, text: string): Promise<void>;
getTitle(): Promise<string>;
isActiveElement(selector: string): Promise<boolean>;
getElements(selector: string, recursive?: boolean): Promise<Element[]>;
typeInEditor(selector: string, text: string): Promise<void>;
getTerminalBuffer(selector: string): Promise<string[]>;
}
export class SpectronDriver implements Driver {
constructor(
private spectronClient: SpectronClient,
private verbose: boolean
) { }
dispatchKeybinding(keybinding: string): Promise<void> {
return Promise.reject(new Error('not implemented'));
}
async click(selector: string, xoffset?: number | undefined, yoffset?: number | undefined): Promise<void> {
if (this.verbose) {
console.log('- click:', selector, xoffset, yoffset);
}
await this.spectronClient.leftClick(selector, xoffset, yoffset);
if (this.verbose) {
console.log('- click DONE');
}
}
async doubleClick(selector: string): Promise<void> {
if (this.verbose) {
console.log('- doubleClick:', selector);
}
await this.spectronClient.doubleClick(selector);
}
async move(selector: string): Promise<void> {
if (this.verbose) {
console.log('- move:', selector);
}
await this.spectronClient.moveToObject(selector);
}
async setValue(selector: string, text: string): Promise<void> {
if (this.verbose) {
console.log('- setValue:', selector, text);
}
await this.spectronClient.setValue(selector, text);
}
async getTitle(): Promise<string> {
if (this.verbose) {
console.log('- getTitle');
}
return await this.spectronClient.getTitle();
}
async isActiveElement(selector: string): Promise<boolean> {
if (this.verbose) {
console.log('- isActiveElement:', selector);
}
const result = await (this.spectronClient.execute(s => document.activeElement.matches(s), selector) as any as Promise<{ value: boolean; }>);
return result.value;
}
async getElements(selector: string): Promise<Element[]> {
if (this.verbose) {
console.log('- getElements:', selector);
}
const result = await (this.spectronClient.execute(selector => {
const query = document.querySelectorAll(selector);
const result: Element[] = [];
for (let i = 0; i < query.length; i++) {
const element: HTMLElement = query.item(i);
result.push({
tagName: element.tagName,
className: element.className,
textContent: element.textContent || '',
attributes: {},
children: []
});
}
return result;
}, selector) as any as Promise<{ value: Element[]; }>);
return result.value;
}
typeInEditor(selector: string, text: string): Promise<void> {
throw new Error('Method not implemented.');
}
getTerminalBuffer(selector: string): Promise<string[]> {
throw new Error('Method not implemented.');
}
}
export class CodeDriver implements Driver {
constructor(
private driver: IDriver,
private verbose: boolean
) { }
private _activeWindowId: number | undefined = undefined;
async dispatchKeybinding(keybinding: string): Promise<void> {
if (this.verbose) {
console.log('- dispatchKeybinding:', keybinding);
}
const windowId = await this.getWindowId();
await this.driver.dispatchKeybinding(windowId, keybinding);
}
async click(selector: string, xoffset?: number | undefined, yoffset?: number | undefined): Promise<any> {
if (this.verbose) {
console.log('- click:', selector);
}
const windowId = await this.getWindowId();
await this.driver.click(windowId, selector, xoffset, yoffset);
}
async doubleClick(selector: string): Promise<any> {
if (this.verbose) {
console.log('- doubleClick:', selector);
}
const windowId = await this.getWindowId();
await this.driver.doubleClick(windowId, selector);
}
async move(selector: string): Promise<any> {
if (this.verbose) {
console.log('- move:', selector);
}
const windowId = await this.getWindowId();
await this.driver.move(windowId, selector);
}
async setValue(selector: string, text: string): Promise<void> {
if (this.verbose) {
console.log('- setValue:', selector, text);
}
const windowId = await this.getWindowId();
await this.driver.setValue(windowId, selector, text);
}
async getTitle(): Promise<string> {
if (this.verbose) {
console.log('- getTitle:');
}
const windowId = await this.getWindowId();
return await this.driver.getTitle(windowId);
}
async isActiveElement(selector: string): Promise<boolean> {
if (this.verbose) {
console.log('- isActiveElement:', selector);
}
const windowId = await this.getWindowId();
return await this.driver.isActiveElement(windowId, selector);
}
async getElements(selector: string, recursive = false): Promise<Element[]> {
if (this.verbose) {
console.log('- getElements:', selector);
}
const windowId = await this.getWindowId();
return await this.driver.getElements(windowId, selector, recursive);
}
async typeInEditor(selector: string, text: string): Promise<void> {
if (this.verbose) {
console.log('- typeInEditor:', selector, text);
}
const windowId = await this.getWindowId();
return await this.driver.typeInEditor(windowId, selector, text);
}
async getTerminalBuffer(selector: string): Promise<string[]> {
if (this.verbose) {
console.log('- getTerminalBuffer:', selector);
}
const windowId = await this.getWindowId();
return await this.driver.getTerminalBuffer(windowId, selector);
}
private async getWindowId(): Promise<number> {
if (typeof this._activeWindowId !== 'number') {
const windows = await this.driver.getWindowIds();
this._activeWindowId = windows[0];
}
return this._activeWindowId;
}
}
export function findElement(element: Element, fn: (element: Element) => boolean): Element | null {
const queue = [element];
while (queue.length > 0) {
const element = queue.shift()!;
if (fn(element)) {
return element;
}
queue.push(...element.children);
}
return null;
}
export function findElements(element: Element, fn: (element: Element) => boolean): Element[] {
const result: Element[] = [];
const queue = [element];
while (queue.length > 0) {
const element = queue.shift()!;
if (fn(element)) {
result.push(element);
}
queue.push(...element.children);
}
return result;
}
\ No newline at end of file
......@@ -11,9 +11,9 @@ import * as minimist from 'minimist';
import * as tmp from 'tmp';
import * as rimraf from 'rimraf';
import * as mkdirp from 'mkdirp';
import { SpectronApplication, Quality } from './application';
import { setup as setupDataMigrationTests } from './areas/workbench/data-migration.test';
import { Application, Quality } from './application';
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';
......@@ -26,7 +26,6 @@ import { setup as setupDataStatusbarTests } from './areas/statusbar/statusbar.te
import { setup as setupDataExtensionTests } from './areas/extensions/extensions.test';
import { setup as setupDataMultirootTests } from './areas/multiroot/multiroot.test';
import { setup as setupDataLocalizationTests } from './areas/workbench/localization.test';
// import './areas/terminal/terminal.test';
const tmpDir = tmp.dirSync({ prefix: 't' }) as { name: string; removeCallback: Function; };
const testDataPath = tmpDir.name;
......@@ -37,7 +36,6 @@ const opts = minimist(args, {
string: [
'build',
'stable-build',
'log',
'wait-time',
'test-repo',
'keybindings'
......@@ -50,8 +48,6 @@ const opts = minimist(args, {
}
});
const artifactsPath = opts.log || '';
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');
......@@ -232,41 +228,19 @@ async function setup(): Promise<void> {
console.log('*** Smoketest setup done!\n');
}
/**
* WebDriverIO 4.8.0 outputs all kinds of "deprecation" warnings
* for common commands like `keys` and `moveToObject`.
* According to https://github.com/Codeception/CodeceptJS/issues/531,
* these deprecation warnings are for Firefox, and have no alternative replacements.
* Since we can't downgrade WDIO as suggested (it's Spectron's dep, not ours),
* we must suppress the warning with a classic monkey-patch.
*
* @see webdriverio/lib/helpers/depcrecationWarning.js
* @see https://github.com/webdriverio/webdriverio/issues/2076
*/
// Filter out the following messages:
const wdioDeprecationWarning = /^WARNING: the "\w+" command will be deprecated soon../; // [sic]
// Monkey patch:
const warn = console.warn;
console.warn = function suppressWebdriverWarnings(message) {
if (wdioDeprecationWarning.test(message)) { return; }
warn.apply(console, arguments);
};
function createApp(quality: Quality): SpectronApplication | null {
function createApp(quality: Quality): Application | null {
const path = quality === Quality.Stable ? stablePath : electronPath;
if (!path) {
return null;
}
return new SpectronApplication({
return new Application({
quality,
codePath: opts.build,
electronPath: path,
workspacePath,
userDataDir,
extensionsPath,
artifactsPath,
workspaceFilePath,
waitTime: parseInt(opts['wait-time'] || '0') || 20,
verbose: opts.verbose
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册