From 038e24c08940c34c315df6896e8611f1eb7c695a Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Mon, 25 Nov 2019 15:06:52 -0800 Subject: [PATCH] chore: common types for evaluate functions (#72) --- src/chromium/DOMWorld.ts | 19 ++++++++++--------- src/chromium/ExecutionContext.ts | 9 +++++---- src/chromium/Frame.ts | 17 +++++++++-------- src/chromium/JSHandle.ts | 17 +++++++++-------- src/chromium/Page.ts | 17 +++++++++-------- src/chromium/features/workers.ts | 9 +++++---- src/types.ts | 22 ++++++++++++++++++++++ 7 files changed, 69 insertions(+), 41 deletions(-) create mode 100644 src/types.ts diff --git a/src/chromium/DOMWorld.ts b/src/chromium/DOMWorld.ts index f065aa790cbe3..93764ed67dbc4 100644 --- a/src/chromium/DOMWorld.ts +++ b/src/chromium/DOMWorld.ts @@ -16,6 +16,7 @@ */ import * as fs from 'fs'; +import * as types from '../types'; import { TimeoutError } from '../Errors'; import { ExecutionContext } from './ExecutionContext'; import { Frame } from './Frame'; @@ -79,14 +80,14 @@ export class DOMWorld { return this._contextPromise; } - async evaluateHandle(pageFunction: Function | string, ...args: any[]): Promise { + evaluateHandle: types.EvaluateHandle = async (pageFunction, ...args) => { const context = await this.executionContext(); - return context.evaluateHandle(pageFunction, ...args); + return context.evaluateHandle(pageFunction, ...args as any); } - async evaluate(pageFunction: Function | string, ...args: any[]): Promise { + evaluate: types.Evaluate = async (pageFunction, ...args) => { const context = await this.executionContext(); - return context.evaluate(pageFunction, ...args); + return context.evaluate(pageFunction, ...args as any); } async $(selector: string): Promise { @@ -111,14 +112,14 @@ export class DOMWorld { return value; } - async $eval(selector: string, pageFunction: Function | string, ...args: any[]): Promise { + $eval: types.$Eval = async (selector, pageFunction, ...args) => { const document = await this._document(); - return document.$eval(selector, pageFunction, ...args); + return document.$eval(selector, pageFunction, ...args as any); } - async $$eval(selector: string, pageFunction: Function | string, ...args: any[]): Promise { + $$eval: types.$$Eval = async (selector, pageFunction, ...args) => { const document = await this._document(); - const value = await document.$$eval(selector, pageFunction, ...args); + const value = await document.$$eval(selector, pageFunction, ...args as any); return value; } @@ -439,7 +440,7 @@ class WaitTask { } } -async function waitForPredicatePageFunction(predicateBody: string, polling: string, timeout: number, ...args): Promise { +async function waitForPredicatePageFunction(predicateBody: string, polling: string | number, timeout: number, ...args): Promise { const predicate = new Function('...args', predicateBody); let timedOut = false; if (timeout) diff --git a/src/chromium/ExecutionContext.ts b/src/chromium/ExecutionContext.ts index 9f111fef03cc4..f45a185bd63e2 100644 --- a/src/chromium/ExecutionContext.ts +++ b/src/chromium/ExecutionContext.ts @@ -25,11 +25,12 @@ import { Protocol } from './protocol'; import * as injectedSource from '../generated/injectedSource'; import * as cssSelectorEngineSource from '../generated/cssSelectorEngineSource'; import * as xpathSelectorEngineSource from '../generated/xpathSelectorEngineSource'; +import * as types from '../types'; export const EVALUATION_SCRIPT_URL = '__playwright_evaluation_script__'; const SOURCE_URL_REGEX = /^[\040\t]*\/\/[@#] sourceURL=\s*(\S*?)\s*$/m; -export class ExecutionContext { +export class ExecutionContext implements types.EvaluationContext { _client: CDPSession; _world: DOMWorld; private _injectedPromise: Promise | null = null; @@ -45,11 +46,11 @@ export class ExecutionContext { return this._world ? this._world.frame() : null; } - async evaluate(pageFunction: Function | string, ...args: any[]): Promise { - return await this._evaluateInternal(true /* returnByValue */, pageFunction, ...args); + evaluate: types.Evaluate = (pageFunction, ...args) => { + return this._evaluateInternal(true /* returnByValue */, pageFunction, ...args); } - async evaluateHandle(pageFunction: Function | string, ...args: any[]): Promise { + evaluateHandle: types.EvaluateHandle = (pageFunction, ...args) => { return this._evaluateInternal(false /* returnByValue */, pageFunction, ...args); } diff --git a/src/chromium/Frame.ts b/src/chromium/Frame.ts index 719d0d7eddc8f..94524202ccae3 100644 --- a/src/chromium/Frame.ts +++ b/src/chromium/Frame.ts @@ -15,6 +15,7 @@ * limitations under the License. */ +import * as types from '../types'; import { helper, assert } from '../helper'; import { ClickOptions, MultiClickOptions, PointerActionOptions, SelectOption } from '../input'; import { CDPSession } from './Connection'; @@ -68,12 +69,12 @@ export class Frame { return this._mainWorld.executionContext(); } - async evaluateHandle(pageFunction: Function | string, ...args: any[]): Promise { - return this._mainWorld.evaluateHandle(pageFunction, ...args); + evaluateHandle: types.EvaluateHandle = (pageFunction, ...args) => { + return this._mainWorld.evaluateHandle(pageFunction, ...args as any); } - async evaluate(pageFunction: Function | string, ...args: any[]): Promise { - return this._mainWorld.evaluate(pageFunction, ...args); + evaluate: types.Evaluate = (pageFunction, ...args) => { + return this._mainWorld.evaluate(pageFunction, ...args as any); } async $(selector: string): Promise { @@ -84,12 +85,12 @@ export class Frame { return this._mainWorld.$x(expression); } - async $eval(selector: string, pageFunction: Function | string, ...args: any[]): Promise<(object | undefined)> { - return this._mainWorld.$eval(selector, pageFunction, ...args); + $eval: types.$Eval = (selector, pageFunction, ...args) => { + return this._mainWorld.$eval(selector, pageFunction, ...args as any); } - async $$eval(selector: string, pageFunction: Function | string, ...args: any[]): Promise<(object | undefined)> { - return this._mainWorld.$$eval(selector, pageFunction, ...args); + $$eval: types.$$Eval = (selector, pageFunction, ...args) => { + return this._mainWorld.$$eval(selector, pageFunction, ...args as any); } async $$(selector: string): Promise { diff --git a/src/chromium/JSHandle.ts b/src/chromium/JSHandle.ts index 370e8691174b4..da6d9932595aa 100644 --- a/src/chromium/JSHandle.ts +++ b/src/chromium/JSHandle.ts @@ -16,6 +16,7 @@ */ import * as path from 'path'; +import * as types from '../types'; import { assert, debugError, helper } from '../helper'; import { ClickOptions, Modifier, MultiClickOptions, PointerActionOptions, SelectOption, selectFunction, fillFunction } from '../input'; import { CDPSession } from './Connection'; @@ -59,12 +60,12 @@ export class JSHandle { return this._context; } - async evaluate(pageFunction: Function | string, ...args: any[]): Promise { - return await this.executionContext().evaluate(pageFunction, this, ...args); + evaluate: types.EvaluateOn = (pageFunction, ...args) => { + return this.executionContext().evaluate(pageFunction, this, ...args); } - async evaluateHandle(pageFunction: Function | string, ...args: any[]): Promise { - return await this.executionContext().evaluateHandle(pageFunction, this, ...args); + evaluateHandle: types.EvaluateHandleOn = (pageFunction, ...args) => { + return this.executionContext().evaluateHandle(pageFunction, this, ...args); } async getProperty(propertyName: string): Promise { @@ -432,22 +433,22 @@ export class ElementHandle extends JSHandle { return result; } - async $eval(selector: string, pageFunction: Function | string, ...args: any[]): Promise { + $eval: types.$Eval = async (selector, pageFunction, ...args) => { const elementHandle = await this.$(selector); if (!elementHandle) throw new Error(`Error: failed to find element matching selector "${selector}"`); - const result = await elementHandle.evaluate(pageFunction, ...args); + const result = await elementHandle.evaluate(pageFunction, ...args as any); await elementHandle.dispose(); return result; } - async $$eval(selector: string, pageFunction: Function | string, ...args: any[]): Promise { + $$eval: types.$$Eval = async (selector, pageFunction, ...args) => { const arrayHandle = await this.evaluateHandle( (root: SelectorRoot, selector: string, injected: Injected) => injected.querySelectorAll('css=' + selector, root), selector, await this._context._injected() ); - const result = await arrayHandle.evaluate(pageFunction, ...args); + const result = await arrayHandle.evaluate(pageFunction, ...args as any); await arrayHandle.dispose(); return result; } diff --git a/src/chromium/Page.ts b/src/chromium/Page.ts index 357043266fb6b..8f4745c560c66 100644 --- a/src/chromium/Page.ts +++ b/src/chromium/Page.ts @@ -44,6 +44,7 @@ import { getExceptionMessage, releaseObject, valueFromRemoteObject } from './pro import { Target } from './Target'; import { TaskQueue } from './TaskQueue'; import * as input from '../input'; +import * as types from '../types'; const writeFileAsync = helper.promisify(fs.writeFile); @@ -232,17 +233,17 @@ export class Page extends EventEmitter { return this.mainFrame().$(selector); } - async evaluateHandle(pageFunction: Function | string, ...args: any[]): Promise { + evaluateHandle: types.EvaluateHandle = async (pageFunction, ...args) => { const context = await this.mainFrame().executionContext(); - return context.evaluateHandle(pageFunction, ...args); + return context.evaluateHandle(pageFunction, ...args as any); } - async $eval(selector: string, pageFunction: Function | string, ...args: any[]): Promise<(object | undefined)> { - return this.mainFrame().$eval(selector, pageFunction, ...args); + $eval: types.$Eval = (selector, pageFunction, ...args) => { + return this.mainFrame().$eval(selector, pageFunction, ...args as any); } - async $$eval(selector: string, pageFunction: Function | string, ...args: any[]): Promise<(object | undefined)> { - return this.mainFrame().$$eval(selector, pageFunction, ...args); + $$eval: types.$$Eval = (selector, pageFunction, ...args) => { + return this.mainFrame().$$eval(selector, pageFunction, ...args as any); } async $$(selector: string): Promise { @@ -567,8 +568,8 @@ export class Page extends EventEmitter { return this._viewport; } - async evaluate(pageFunction: Function | string, ...args: any[]): Promise { - return this._frameManager.mainFrame().evaluate(pageFunction, ...args); + evaluate: types.Evaluate = (pageFunction, ...args) => { + return this._frameManager.mainFrame().evaluate(pageFunction, ...args as any); } async evaluateOnNewDocument(pageFunction: Function | string, ...args: any[]) { diff --git a/src/chromium/features/workers.ts b/src/chromium/features/workers.ts index e5de3d7276ce3..c67d64c6867ab 100644 --- a/src/chromium/features/workers.ts +++ b/src/chromium/features/workers.ts @@ -21,6 +21,7 @@ import { debugError } from '../../helper'; import { JSHandle } from '../JSHandle'; import { Protocol } from '../protocol'; import { Events } from '../events'; +import * as types from '../../types'; type AddToConsoleCallback = (type: string, args: JSHandle[], stackTrace: Protocol.Runtime.StackTrace | undefined) => void; type HandleExceptionCallback = (exceptionDetails: Protocol.Runtime.ExceptionDetails) => void; @@ -85,11 +86,11 @@ export class Worker extends EventEmitter { return this._executionContextPromise; } - async evaluate(pageFunction: Function | string, ...args: any[]): Promise { - return (await this._executionContextPromise).evaluate(pageFunction, ...args); + evaluate: types.Evaluate = async (pageFunction, ...args) => { + return (await this._executionContextPromise).evaluate(pageFunction, ...args as any); } - async evaluateHandle(pageFunction: Function | string, ...args: any[]): Promise { - return (await this._executionContextPromise).evaluateHandle(pageFunction, ...args); + evaluateHandle: types.EvaluateHandle = async (pageFunction, ...args) => { + return (await this._executionContextPromise).evaluateHandle(pageFunction, ...args as any); } } diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000000000..5268432c81b22 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +type Boxed = { [Index in keyof Args]: Args[Index] | Handle }; +type PageFunction = string | ((...args: Args) => R | Promise); +type PageFunctionOn = string | ((on: On, ...args: Args) => R | Promise); + +export type Evaluate = (fn: PageFunction, ...args: Boxed) => Promise; +export type EvaluateHandle = (fn: PageFunction, ...args: Boxed) => Promise; +export type $Eval = (selector: string, fn: PageFunctionOn, ...args: Boxed) => Promise; +export type $$Eval = (selector: string, fn: PageFunctionOn, ...args: Boxed) => Promise; +export type EvaluateOn = (fn: PageFunctionOn, ...args: Boxed) => Promise; +export type EvaluateHandleOn = (fn: PageFunctionOn, ...args: Boxed) => Promise; + +export interface EvaluationContext { + evaluate: Evaluate; + evaluateHandle: EvaluateHandle; +} + +export interface Handle { + dispose(): Promise; +}