From dbef7de42a7b78b6db546361170609f4a62daa12 Mon Sep 17 00:00:00 2001 From: Joel Einbinder Date: Wed, 13 May 2020 20:51:53 -0700 Subject: [PATCH] feat(electron): types (#2231) --- packages/playwright-electron/index.d.ts | 38 +++++++++++++++++++++++-- src/server/electron.ts | 20 ++++++++----- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/packages/playwright-electron/index.d.ts b/packages/playwright-electron/index.d.ts index e87c71ad84..a39028e11c 100644 --- a/packages/playwright-electron/index.d.ts +++ b/packages/playwright-electron/index.d.ts @@ -14,7 +14,41 @@ * limitations under the License. */ -import * as types from 'playwright-core/types/types'; +import { Logger, Page, JSHandle, ChromiumBrowserContext } from 'playwright-core/types/types'; +import { BrowserWindow, BrowserWindowConstructorOptions } from 'electron'; export * from 'playwright-core/types/types'; -export const electron: types.BrowserType; +export type ElectronLaunchOptions = { + args?: string[], + cwd?: string, + env?: {[key: string]: string|number|boolean}, + handleSIGINT?: boolean, + handleSIGTERM?: boolean, + handleSIGHUP?: boolean, + timeout?: number, + logger?: Logger, +}; +export interface ElectronLauncher { + launch(executablePath: string, options?: ElectronLaunchOptions): Promise; +} +export interface ElectronApplication { + on(event: 'window', listener: (page : ElectronPage) => void): this; + addListener(event: 'window', listener: (page : ElectronPage) => void): this; + waitForEvent(event: 'window', optionsOrPredicate?: { predicate?: (page : ElectronPage) => boolean, timeout?: number }): Promise; + + on(event: 'close', listener: (exitCode? : number) => void): this; + addListener(event: 'close', listener: (exitCode? : number) => void): this; + waitForEvent(event: 'close', optionsOrPredicate?: { predicate?: (exitCode? : number) => boolean, timeout?: number }): Promise; + + context(): ChromiumBrowserContext; + windows(): ElectronPage[]; + firstWindow(): Promise; + newBrowserWindow(options?: BrowserWindowConstructorOptions): Promise; + close(): Promise; + evaluate: JSHandle['evaluate']; + evaluateHandle: JSHandle['evaluateHandle']; +} +export interface ElectronPage extends Page { + browserWindow: JSHandle; +} +export const electron: ElectronLauncher; diff --git a/src/server/electron.ts b/src/server/electron.ts index e2d50ba539..a9172d87c9 100644 --- a/src/server/electron.ts +++ b/src/server/electron.ts @@ -31,6 +31,7 @@ import * as types from '../types'; import { BrowserServer } from './browserServer'; import { launchProcess, waitForLine } from './processLauncher'; import { BrowserContext } from '../browserContext'; +import type {BrowserWindow} from 'electron'; type ElectronLaunchOptions = { args?: string[], @@ -50,6 +51,11 @@ export const ElectronEvents = { } }; +interface ElectronPage extends Page { + browserWindow: js.JSHandle; + _browserWindowId: number; +} + export class ElectronApplication extends ExtendedEventEmitter { private _logger: InnerLogger; private _browserContext: CRBrowserContext; @@ -57,7 +63,7 @@ export class ElectronApplication extends ExtendedEventEmitter { private _nodeSession: CRSession; private _nodeExecutionContext: js.ExecutionContext | undefined; private _nodeElectronHandle: js.JSHandle | undefined; - private _windows = new Set(); + private _windows = new Set(); private _lastWindowId = 0; readonly _timeoutSettings = new TimeoutSettings(); @@ -71,17 +77,17 @@ export class ElectronApplication extends ExtendedEventEmitter { this._nodeSession = nodeConnection.rootSession; } - private async _onPage(page: Page) { + private async _onPage(page: ElectronPage) { // Needs to be sync. const windowId = ++this._lastWindowId; // Can be async. const handle = await this._nodeElectronHandle!.evaluateHandle(({ BrowserWindow }, windowId) => BrowserWindow.fromId(windowId), windowId).catch(e => {}); if (!handle) return; - (page as any).browserWindow = handle; - (page as any)._browserWindowId = windowId; + page.browserWindow = handle; + page._browserWindowId = windowId; page.on(Events.Page.Close, () => { - (page as any).browserWindow.dispose(); + page.browserWindow.dispose(); this._windows.delete(page); }); this._windows.add(page); @@ -107,11 +113,11 @@ export class ElectronApplication extends ExtendedEventEmitter { }, options); for (const page of this._windows) { - if ((page as any)._browserWindowId === windowId) + if (page._browserWindowId === windowId) return page; } - return await this.waitForEvent(ElectronEvents.ElectronApplication.Window, (page: Page) => (page as any)._browserWindowId === windowId); + return await this.waitForEvent(ElectronEvents.ElectronApplication.Window, (page: ElectronPage) => page._browserWindowId === windowId); } context(): BrowserContext {