Add puppeteer types and use TS in driver

This commit is contained in:
Daniel Imms 2019-07-15 11:50:15 -07:00
parent f784f5fd7f
commit f7b8079f21
5 changed files with 78 additions and 76 deletions

View file

@ -64,6 +64,7 @@
"@types/minimist": "^1.2.0",
"@types/mocha": "2.2.39",
"@types/node": "^10.12.12",
"@types/puppeteer": "^1.12.4",
"@types/semver": "^5.5.0",
"@types/sinon": "^1.16.36",
"@types/webpack": "^4.4.10",
@ -156,4 +157,4 @@
"windows-mutex": "0.2.1",
"windows-process-tree": "0.2.4"
}
}
}

View file

@ -14,19 +14,19 @@ import { ncp } from 'ncp';
import { Application, Quality, ApplicationOptions } 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';
import { setup as setupDataSearchTests } from './areas/search/search.test';
import { setup as setupDataCSSTests } from './areas/css/css.test';
import { setup as setupDataEditorTests } from './areas/editor/editor.test';
import { setup as setupDataDebugTests } from './areas/debug/debug.test';
import { setup as setupDataGitTests } from './areas/git/git.test';
import { setup as setupDataStatusbarTests } from './areas/statusbar/statusbar.test';
import { setup as setupDataExtensionTests } from './areas/extensions/extensions.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';
// import { setup as setupDataSearchTests } from './areas/search/search.test';
// import { setup as setupDataCSSTests } from './areas/css/css.test';
// import { setup as setupDataEditorTests } from './areas/editor/editor.test';
// import { setup as setupDataDebugTests } from './areas/debug/debug.test';
// import { setup as setupDataGitTests } from './areas/git/git.test';
// import { setup as setupDataStatusbarTests } from './areas/statusbar/statusbar.test';
// import { setup as setupDataExtensionTests } from './areas/extensions/extensions.test';
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 setupDataMultirootTests } from './areas/multiroot/multiroot.test';
// import { setup as setupDataLocalizationTests } from './areas/workbench/localization.test';
import { setup as setupLaunchTests } from './areas/workbench/launch.test';
import { MultiLogger, Logger, ConsoleLogger, FileLogger } from './logger';

View file

@ -1,56 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/**
* Thenable is a common denominator between ES6 promises, Q, jquery.Deferred, WinJS.Promise,
* and others. This API makes no assumption about what promise library is being used which
* enables reusing existing code without migrating to a specific promise implementation. Still,
* we recommend the use of native promises which are available in this editor.
*/
interface Thenable<T> {
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of which ever callback is executed.
*/
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Thenable<TResult>;
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Thenable<TResult>;
}
export interface IElement {
tagName: string;
className: string;
textContent: string;
attributes: { [name: string]: string; };
children: IElement[];
top: number;
left: number;
}
export interface IDriver {
_serviceBrand: any;
getWindowIds(): Promise<number[]>;
capturePage(windowId: number): Promise<string>;
reloadWindow(windowId: number): Promise<void>;
exitApplication(): Promise<void>;
dispatchKeybinding(windowId: number, keybinding: string): Promise<void>;
click(windowId: number, selector: string, xoffset?: number | undefined, yoffset?: number | undefined): Promise<void>;
doubleClick(windowId: number, selector: string): Promise<void>;
setValue(windowId: number, selector: string, text: string): Promise<void>;
getTitle(windowId: number): Promise<string>;
isActiveElement(windowId: number, selector: string): Promise<boolean>;
getElements(windowId: number, selector: string, recursive?: boolean): Promise<IElement[]>;
typeInEditor(windowId: number, selector: string, text: string): Promise<void>;
getTerminalBuffer(windowId: number, selector: string): Promise<string[]>;
writeInTerminal(windowId: number, selector: string, text: string): Promise<void>;
}
export interface IDisposable {
dispose(): void;
}
export function connect(outPath: string, handle: string): Promise<{ client: IDisposable, driver: IDriver }>;

View file

@ -22,12 +22,12 @@ function buildDriver(browser, page) {
getWindowIds: () => {
return Promise.resolve([1]);
},
capturePage: () => Promise.result(''),
capturePage: () => Promise.resolve(''),
reloadWindow: (windowId) => Promise.resolve(),
exitApplication: () => browser.close(),
dispatchKeybinding: async (windowId, keybinding) => {
const keys = keybinding.split('+');
const keysDown = [];
const keysDown: string[] = [];
for (let i = 0; i < keys.length; i++) {
if (keys[i] in vscodeToPuppeteerKey) {
keys[i] = vscodeToPuppeteerKey[keys[i]];
@ -314,10 +314,10 @@ function buildDriver(browser, page) {
})();
`);
}
}
};
}
exports.connect = function (outPath, handle) {
export function connect(outPath: string, handle: string): Promise<{ client: IDisposable, driver: IDriver }> {
return new Promise(async (c) => {
const browser = await puppeteer.launch({
// Run in Edge dev on macOS
@ -330,9 +330,59 @@ exports.connect = function (outPath, handle) {
await page.setViewport({ width, height });
await page.goto('http://127.0.0.1:9888');
const result = {
client: { dispose: () => {} },
client: { dispose: () => { } },
driver: buildDriver(browser, page)
}
};
c(result);
});
};
}
/**
* Thenable is a common denominator between ES6 promises, Q, jquery.Deferred, WinJS.Promise,
* and others. This API makes no assumption about what promise library is being used which
* enables reusing existing code without migrating to a specific promise implementation. Still,
* we recommend the use of native promises which are available in this editor.
*/
export interface Thenable<T> {
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of which ever callback is executed.
*/
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Thenable<TResult>;
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Thenable<TResult>;
}
export interface IElement {
tagName: string;
className: string;
textContent: string;
attributes: { [name: string]: string; };
children: IElement[];
top: number;
left: number;
}
export interface IDriver {
_serviceBrand: any;
getWindowIds(): Promise<number[]>;
capturePage(windowId: number): Promise<string>;
reloadWindow(windowId: number): Promise<void>;
exitApplication(): Promise<void>;
dispatchKeybinding(windowId: number, keybinding: string): Promise<void>;
click(windowId: number, selector: string, xoffset?: number | undefined, yoffset?: number | undefined): Promise<void>;
doubleClick(windowId: number, selector: string): Promise<void>;
setValue(windowId: number, selector: string, text: string): Promise<void>;
getTitle(windowId: number): Promise<string>;
isActiveElement(windowId: number, selector: string): Promise<boolean>;
getElements(windowId: number, selector: string, recursive?: boolean): Promise<IElement[]>;
typeInEditor(windowId: number, selector: string, text: string): Promise<void>;
getTerminalBuffer(windowId: number, selector: string): Promise<string[]>;
writeInTerminal(windowId: number, selector: string, text: string): Promise<void>;
}
export interface IDisposable {
dispose(): void;
}

View file

@ -65,6 +65,13 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.12.tgz#e15a9d034d9210f00320ef718a50c4a799417c47"
integrity sha512-Pr+6JRiKkfsFvmU/LK68oBRCQeEg36TyAbPhc2xpez24OOZZCuoIhWGTd39VZy6nGafSbxzGouFPTFD/rR1A0A==
"@types/puppeteer@^1.12.4":
version "1.12.4"
resolved "https://registry.yarnpkg.com/@types/puppeteer/-/puppeteer-1.12.4.tgz#8388efdb0b30a54a7e7c4831ca0d709191d77ff1"
integrity sha512-aaGbJaJ9TuF9vZfTeoh876sBa+rYJWPwtsmHmYr28pGr42ewJnkDTq2aeSKEmS39SqUdkwLj73y/d7rBSp7mDQ==
dependencies:
"@types/node" "*"
"@types/semver@^5.4.0", "@types/semver@^5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45"