diff --git a/src/client/accessibility.ts b/src/client/accessibility.ts index 63c938a316dad..4af1336ccc41d 100644 --- a/src/client/accessibility.ts +++ b/src/client/accessibility.ts @@ -17,6 +17,7 @@ import * as channels from '../protocol/channels'; import { ElementHandle } from './elementHandle'; +import * as api from '../../types/types'; type SerializedAXNode = Omit & { value?: string|number, @@ -38,7 +39,7 @@ function axNodeFromProtocol(axNode: channels.AXNode): SerializedAXNode { return result; } -export class Accessibility { +export class Accessibility implements api.Accessibility { private _channel: channels.PageChannel; constructor(channel: channels.PageChannel) { diff --git a/src/client/browser.ts b/src/client/browser.ts index 1af06ba248579..52f24ee270138 100644 --- a/src/client/browser.ts +++ b/src/client/browser.ts @@ -21,8 +21,9 @@ import { ChannelOwner } from './channelOwner'; import { Events } from './events'; import { BrowserContextOptions } from './types'; import { isSafeCloseError } from '../utils/errors'; +import * as api from '../../types/types'; -export class Browser extends ChannelOwner { +export class Browser extends ChannelOwner implements api.Browser { readonly _contexts = new Set(); private _isConnected = true; private _closedPromise: Promise; diff --git a/src/client/browserContext.ts b/src/client/browserContext.ts index ea6ef97a988a7..456476f4f51a2 100644 --- a/src/client/browserContext.ts +++ b/src/client/browserContext.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { Page, BindingCall, FunctionWithSource } from './page'; +import { Page, BindingCall } from './page'; import * as network from './network'; import * as channels from '../protocol/channels'; import * as util from 'util'; @@ -30,16 +30,18 @@ import { URLMatch, Headers, WaitForEventOptions, BrowserContextOptions, StorageS import { isUnderTest, headersObjectToArray, mkdirIfNeeded } from '../utils/utils'; import { isSafeCloseError } from '../utils/errors'; import { serializeArgument } from './jsHandle'; +import * as api from '../../types/types'; +import * as structs from '../../types/structs'; const fsWriteFileAsync = util.promisify(fs.writeFile.bind(fs)); const fsReadFileAsync = util.promisify(fs.readFile.bind(fs)); -export class BrowserContext extends ChannelOwner { +export class BrowserContext extends ChannelOwner implements api.BrowserContext { _pages = new Set(); private _routes: { url: URLMatch, handler: network.RouteHandler }[] = []; readonly _browser: Browser | null = null; readonly _browserName: string; - readonly _bindings = new Map(); + readonly _bindings = new Map any>(); _timeoutSettings = new TimeoutSettings(); _ownerPage: Page | undefined; private _closedPromise: Promise; @@ -182,7 +184,7 @@ export class BrowserContext extends ChannelOwner { + async exposeBinding(name: string, playwrightBinding: (source: structs.BindingSource, ...args: any[]) => any, options: { handle?: boolean } = {}): Promise { return this._wrapApiCall('browserContext.exposeBinding', async () => { await this._channel.exposeBinding({ name, needsHandle: options.handle }); this._bindings.set(name, playwrightBinding); @@ -192,7 +194,7 @@ export class BrowserContext extends ChannelOwner { return this._wrapApiCall('browserContext.exposeFunction', async () => { await this._channel.exposeBinding({ name }); - const binding: FunctionWithSource = (source, ...args) => playwrightFunction(...args); + const binding = (source: structs.BindingSource, ...args: any[]) => playwrightFunction(...args); this._bindings.set(name, binding); }); } diff --git a/src/client/browserType.ts b/src/client/browserType.ts index fb79d7a0917ac..4966101e66332 100644 --- a/src/client/browserType.ts +++ b/src/client/browserType.ts @@ -32,19 +32,21 @@ import { assert, makeWaitForNextTask, mkdirIfNeeded } from '../utils/utils'; import { SelectorsOwner, sharedSelectors } from './selectors'; import { kBrowserClosedError } from '../utils/errors'; import { Stream } from './stream'; +import * as api from '../../types/types'; export interface BrowserServerLauncher { - launchServer(options?: LaunchServerOptions): Promise; + launchServer(options?: LaunchServerOptions): Promise; } -export interface BrowserServer { +// This is here just for api generation and checking. +export interface BrowserServer extends api.BrowserServer { process(): ChildProcess; wsEndpoint(): string; close(): Promise; kill(): Promise; } -export class BrowserType extends ChannelOwner { +export class BrowserType extends ChannelOwner implements api.BrowserType { private _timeoutSettings = new TimeoutSettings(); _serverLauncher?: BrowserServerLauncher; @@ -83,7 +85,7 @@ export class BrowserType extends ChannelOwner { + async launchServer(options: LaunchServerOptions = {}): Promise { if (!this._serverLauncher) throw new Error('Launching server is not supported'); return this._serverLauncher.launchServer(options); diff --git a/src/client/cdpSession.ts b/src/client/cdpSession.ts index c3b792395030e..739a5e1c4e53e 100644 --- a/src/client/cdpSession.ts +++ b/src/client/cdpSession.ts @@ -17,8 +17,9 @@ import * as channels from '../protocol/channels'; import { ChannelOwner } from './channelOwner'; import { Protocol } from '../server/chromium/protocol'; +import * as api from '../../types/types'; -export class CDPSession extends ChannelOwner { +export class CDPSession extends ChannelOwner implements api.CDPSession { static from(cdpSession: channels.CDPSessionChannel): CDPSession { return (cdpSession as any)._object; } diff --git a/src/client/chromiumBrowser.ts b/src/client/chromiumBrowser.ts index d6646da93ba85..6441477768290 100644 --- a/src/client/chromiumBrowser.ts +++ b/src/client/chromiumBrowser.ts @@ -17,8 +17,19 @@ import { Page } from './page'; import { CDPSession } from './cdpSession'; import { Browser } from './browser'; +import * as api from '../../types/types'; +import { ChromiumBrowserContext } from './chromiumBrowserContext'; +import { BrowserContextOptions } from './types'; + +export class ChromiumBrowser extends Browser implements api.ChromiumBrowser { + contexts(): ChromiumBrowserContext[] { + return super.contexts() as ChromiumBrowserContext[]; + } + + newContext(options?: BrowserContextOptions): Promise { + return super.newContext(options) as Promise; + } -export class ChromiumBrowser extends Browser { async newBrowserCDPSession(): Promise { return this._wrapApiCall('chromiumBrowser.newBrowserCDPSession', async () => { return CDPSession.from((await this._channel.crNewBrowserCDPSession()).session); diff --git a/src/client/chromiumBrowserContext.ts b/src/client/chromiumBrowserContext.ts index 1f9b0ccb68001..a7bc1ae3f1d0c 100644 --- a/src/client/chromiumBrowserContext.ts +++ b/src/client/chromiumBrowserContext.ts @@ -22,8 +22,9 @@ import { CDPSession } from './cdpSession'; import { Events } from './events'; import { Worker } from './worker'; import { BrowserContext } from './browserContext'; +import * as api from '../../types/types'; -export class ChromiumBrowserContext extends BrowserContext { +export class ChromiumBrowserContext extends BrowserContext implements api.ChromiumBrowserContext { _backgroundPages = new Set(); _serviceWorkers = new Set(); diff --git a/src/client/chromiumCoverage.ts b/src/client/chromiumCoverage.ts index 472e0ac6d1b4f..1420eaf0528e1 100644 --- a/src/client/chromiumCoverage.ts +++ b/src/client/chromiumCoverage.ts @@ -15,8 +15,9 @@ */ import * as channels from '../protocol/channels'; +import * as api from '../../types/types'; -export class ChromiumCoverage { +export class ChromiumCoverage implements api.ChromiumCoverage { private _channel: channels.PageChannel; constructor(channel: channels.PageChannel) { diff --git a/src/client/consoleMessage.ts b/src/client/consoleMessage.ts index 5032d1557647a..9c6d5afeb2b67 100644 --- a/src/client/consoleMessage.ts +++ b/src/client/consoleMessage.ts @@ -18,10 +18,11 @@ import * as util from 'util'; import { JSHandle } from './jsHandle'; import * as channels from '../protocol/channels'; import { ChannelOwner } from './channelOwner'; +import * as api from '../../types/types'; type ConsoleMessageLocation = channels.ConsoleMessageInitializer['location']; -export class ConsoleMessage extends ChannelOwner { +export class ConsoleMessage extends ChannelOwner implements api.ConsoleMessage { static from(message: channels.ConsoleMessageChannel): ConsoleMessage { return (message as any)._object; } diff --git a/src/client/dialog.ts b/src/client/dialog.ts index 458fcfd4e8201..b0e50df60b9e6 100644 --- a/src/client/dialog.ts +++ b/src/client/dialog.ts @@ -16,8 +16,9 @@ import * as channels from '../protocol/channels'; import { ChannelOwner } from './channelOwner'; +import * as api from '../../types/types'; -export class Dialog extends ChannelOwner { +export class Dialog extends ChannelOwner implements api.Dialog { static from(dialog: channels.DialogChannel): Dialog { return (dialog as any)._object; } diff --git a/src/client/download.ts b/src/client/download.ts index 47da0a009a3f3..5f51c4ed05c7d 100644 --- a/src/client/download.ts +++ b/src/client/download.ts @@ -22,8 +22,9 @@ import { Browser } from './browser'; import { BrowserContext } from './browserContext'; import * as fs from 'fs'; import { mkdirIfNeeded } from '../utils/utils'; +import * as api from '../../types/types'; -export class Download extends ChannelOwner { +export class Download extends ChannelOwner implements api.Download { private _browser: Browser | null; static from(download: channels.DownloadChannel): Download { diff --git a/src/client/electron.ts b/src/client/electron.ts index 73689adfd8a95..31ec467e5f888 100644 --- a/src/client/electron.ts +++ b/src/client/electron.ts @@ -18,12 +18,13 @@ import * as channels from '../protocol/channels'; import { BrowserContext } from './browserContext'; import { ChannelOwner } from './channelOwner'; import { Page } from './page'; -import { serializeArgument, FuncOn, parseResult, SmartHandle, JSHandle } from './jsHandle'; +import { serializeArgument, parseResult, JSHandle } from './jsHandle'; import { TimeoutSettings } from '../utils/timeoutSettings'; import { Waiter } from './waiter'; import { Events } from './events'; import { WaitForEventOptions, Env, Logger } from './types'; import { envObjectToArray } from './clientHelper'; +import * as structs from '../../types/structs'; type ElectronOptions = Omit & { env?: Env, @@ -110,17 +111,13 @@ export class ElectronApplication extends ChannelOwner(pageFunction: FuncOn, arg: Arg): Promise; - async evaluate(pageFunction: FuncOn, arg?: any): Promise; - async evaluate(pageFunction: FuncOn, arg: Arg): Promise { + async evaluate(pageFunction: structs.PageFunctionOn, arg: Arg): Promise { const result = await this._channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) }); return parseResult(result.value); } - async evaluateHandle(pageFunction: FuncOn, arg: Arg): Promise>; - async evaluateHandle(pageFunction: FuncOn, arg?: any): Promise>; - async evaluateHandle(pageFunction: FuncOn, arg: Arg): Promise> { + async evaluateHandle(pageFunction: structs.PageFunctionOn, arg: Arg): Promise> { const result = await this._channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) }); - return JSHandle.from(result.handle) as SmartHandle; + return JSHandle.from(result.handle) as any as structs.SmartHandle; } } diff --git a/src/client/elementHandle.ts b/src/client/elementHandle.ts index ec1726320e22d..64c3ac4aea561 100644 --- a/src/client/elementHandle.ts +++ b/src/client/elementHandle.ts @@ -16,7 +16,7 @@ import * as channels from '../protocol/channels'; import { Frame } from './frame'; -import { FuncOn, JSHandle, serializeArgument, parseResult } from './jsHandle'; +import { JSHandle, serializeArgument, parseResult } from './jsHandle'; import { ChannelOwner } from './channelOwner'; import { SelectOption, FilePayload, Rect, SelectOptionOptions } from './types'; import * as fs from 'fs'; @@ -24,10 +24,12 @@ import * as mime from 'mime'; import * as path from 'path'; import * as util from 'util'; import { assert, isString, mkdirIfNeeded } from '../utils/utils'; +import * as api from '../../types/types'; +import * as structs from '../../types/structs'; const fsWriteFileAsync = util.promisify(fs.writeFile.bind(fs)); -export class ElementHandle extends JSHandle { +export class ElementHandle extends JSHandle implements api.ElementHandle { readonly _elementChannel: channels.ElementHandleChannel; static from(handle: channels.ElementHandleChannel): ElementHandle { @@ -43,8 +45,8 @@ export class ElementHandle extends JSHandle { this._elementChannel = this._channel as channels.ElementHandleChannel; } - asElement(): ElementHandle | null { - return this; + asElement(): T extends Node ? ElementHandle : null { + return this as any; } async ownerFrame(): Promise { @@ -121,7 +123,7 @@ export class ElementHandle extends JSHandle { }); } - async selectOption(values: string | ElementHandle | SelectOption | string[] | ElementHandle[] | SelectOption[] | null, options: SelectOptionOptions = {}): Promise { + async selectOption(values: string | api.ElementHandle | SelectOption | string[] | api.ElementHandle[] | SelectOption[] | null, options: SelectOptionOptions = {}): Promise { return this._wrapApiCall('elementHandle.selectOption', async () => { const result = await this._elementChannel.selectOption({ ...convertSelectOptionValues(values), ...options }); return result.values; @@ -198,31 +200,27 @@ export class ElementHandle extends JSHandle { }); } - async $(selector: string): Promise | null> { + async $(selector: string): Promise | null> { return this._wrapApiCall('elementHandle.$', async () => { - return ElementHandle.fromNullable((await this._elementChannel.querySelector({ selector })).element) as ElementHandle | null; + return ElementHandle.fromNullable((await this._elementChannel.querySelector({ selector })).element) as ElementHandle | null; }); } - async $$(selector: string): Promise[]> { + async $$(selector: string): Promise[]> { return this._wrapApiCall('elementHandle.$$', async () => { const result = await this._elementChannel.querySelectorAll({ selector }); - return result.elements.map(h => ElementHandle.from(h) as ElementHandle); + return result.elements.map(h => ElementHandle.from(h) as ElementHandle); }); } - async $eval(selector: string, pageFunction: FuncOn, arg: Arg): Promise; - async $eval(selector: string, pageFunction: FuncOn, arg?: any): Promise; - async $eval(selector: string, pageFunction: FuncOn, arg: Arg): Promise { + async $eval(selector: string, pageFunction: structs.PageFunctionOn, arg?: Arg): Promise { return this._wrapApiCall('elementHandle.$eval', async () => { const result = await this._elementChannel.evalOnSelector({ selector, expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) }); return parseResult(result.value); }); } - async $$eval(selector: string, pageFunction: FuncOn, arg: Arg): Promise; - async $$eval(selector: string, pageFunction: FuncOn, arg?: any): Promise; - async $$eval(selector: string, pageFunction: FuncOn, arg: Arg): Promise { + async $$eval(selector: string, pageFunction: structs.PageFunctionOn, arg?: Arg): Promise { return this._wrapApiCall('elementHandle.$$eval', async () => { const result = await this._elementChannel.evalOnSelectorAll({ selector, expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) }); return parseResult(result.value); @@ -235,15 +233,17 @@ export class ElementHandle extends JSHandle { }); } - async waitForSelector(selector: string, options: channels.ElementHandleWaitForSelectorOptions = {}): Promise | null> { + waitForSelector(selector: string, options: channels.ElementHandleWaitForSelectorOptions & { state: 'attached' | 'visible' }): Promise>; + waitForSelector(selector: string, options?: channels.ElementHandleWaitForSelectorOptions): Promise | null>; + async waitForSelector(selector: string, options: channels.ElementHandleWaitForSelectorOptions = {}): Promise | null> { return this._wrapApiCall('elementHandle.waitForSelector', async () => { const result = await this._elementChannel.waitForSelector({ selector, ...options }); - return ElementHandle.fromNullable(result.element) as ElementHandle | null; + return ElementHandle.fromNullable(result.element) as ElementHandle | null; }); } } -export function convertSelectOptionValues(values: string | ElementHandle | SelectOption | string[] | ElementHandle[] | SelectOption[] | null): { elements?: channels.ElementHandleChannel[], options?: SelectOption[] } { +export function convertSelectOptionValues(values: string | api.ElementHandle | SelectOption | string[] | api.ElementHandle[] | SelectOption[] | null): { elements?: channels.ElementHandleChannel[], options?: SelectOption[] } { if (values === null) return {}; if (!Array.isArray(values)) diff --git a/src/client/fileChooser.ts b/src/client/fileChooser.ts index 923c39e02d519..6f39c30c8c7b6 100644 --- a/src/client/fileChooser.ts +++ b/src/client/fileChooser.ts @@ -18,8 +18,9 @@ import { ElementHandle } from './elementHandle'; import { Page } from './page'; import { FilePayload } from './types'; import * as channels from '../protocol/channels'; +import * as api from '../../types/types'; -export class FileChooser { +export class FileChooser implements api.FileChooser { private _page: Page; private _elementHandle: ElementHandle; private _isMultiple: boolean; diff --git a/src/client/firefoxBrowser.ts b/src/client/firefoxBrowser.ts index a55e0f059b115..477b55d9b9378 100644 --- a/src/client/firefoxBrowser.ts +++ b/src/client/firefoxBrowser.ts @@ -15,6 +15,7 @@ */ import { Browser } from './browser'; +import * as api from '../../types/types'; -export class FirefoxBrowser extends Browser { +export class FirefoxBrowser extends Browser implements api.FirefoxBrowser { } diff --git a/src/client/frame.ts b/src/client/frame.ts index 17fd0f46b0055..7ff7a0d85d49b 100644 --- a/src/client/frame.ts +++ b/src/client/frame.ts @@ -19,7 +19,7 @@ import { assert } from '../utils/utils'; import * as channels from '../protocol/channels'; import { ChannelOwner } from './channelOwner'; import { ElementHandle, convertSelectOptionValues, convertInputFiles } from './elementHandle'; -import { assertMaxArguments, JSHandle, Func1, FuncOn, SmartHandle, serializeArgument, parseResult } from './jsHandle'; +import { assertMaxArguments, JSHandle, serializeArgument, parseResult } from './jsHandle'; import * as fs from 'fs'; import * as network from './network'; import * as util from 'util'; @@ -29,6 +29,8 @@ import { Waiter } from './waiter'; import { Events } from './events'; import { LifecycleEvent, URLMatch, SelectOption, SelectOptionOptions, FilePayload, WaitForFunctionOptions, kLifecycleEvents } from './types'; import { urlMatches } from './clientHelper'; +import * as api from '../../types/types'; +import * as structs from '../../types/structs'; const fsReadFileAsync = util.promisify(fs.readFile.bind(fs)); @@ -38,7 +40,7 @@ export type WaitForNavigationOptions = { url?: URLMatch, }; -export class Frame extends ChannelOwner { +export class Frame extends ChannelOwner implements api.Frame { _eventEmitter: EventEmitter; _loadStates: Set; _parentFrame: Frame | null = null; @@ -164,29 +166,25 @@ export class Frame extends ChannelOwner(pageFunction: Func1, arg: Arg): Promise>; - async evaluateHandle(pageFunction: Func1, arg?: any): Promise>; - async evaluateHandle(pageFunction: Func1, arg: Arg): Promise> { + async evaluateHandle(pageFunction: structs.PageFunction, arg?: Arg): Promise> { assertMaxArguments(arguments.length, 2); return this._wrapApiCall(this._apiName('evaluateHandle'), async () => { const result = await this._channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) }); - return JSHandle.from(result.handle) as SmartHandle; + return JSHandle.from(result.handle) as any as structs.SmartHandle; }); } - async _evaluateHandleInUtility(pageFunction: Func1, arg: Arg): Promise>; - async _evaluateHandleInUtility(pageFunction: Func1, arg?: any): Promise>; - async _evaluateHandleInUtility(pageFunction: Func1, arg: Arg): Promise> { + async _evaluateHandleInUtility(pageFunction: structs.PageFunction, arg: Arg): Promise>; + async _evaluateHandleInUtility(pageFunction: structs.PageFunction, arg?: any): Promise>; + async _evaluateHandleInUtility(pageFunction: structs.PageFunction, arg?: Arg): Promise> { assertMaxArguments(arguments.length, 2); return this._wrapApiCall(this._apiName('_evaluateHandleInUtility'), async () => { const result = await this._channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg), world: 'utility' }); - return JSHandle.from(result.handle) as SmartHandle; + return JSHandle.from(result.handle) as any as structs.SmartHandle; }); } - async evaluate(pageFunction: Func1, arg: Arg): Promise; - async evaluate(pageFunction: Func1, arg?: any): Promise; - async evaluate(pageFunction: Func1, arg: Arg): Promise { + async evaluate(pageFunction: structs.PageFunction, arg?: Arg): Promise { assertMaxArguments(arguments.length, 2); return this._wrapApiCall(this._apiName('evaluate'), async () => { const result = await this._channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) }); @@ -194,9 +192,9 @@ export class Frame extends ChannelOwner(pageFunction: Func1, arg: Arg): Promise; - async _evaluateInUtility(pageFunction: Func1, arg?: any): Promise; - async _evaluateInUtility(pageFunction: Func1, arg: Arg): Promise { + async _evaluateInUtility(pageFunction: structs.PageFunction, arg: Arg): Promise; + async _evaluateInUtility(pageFunction: structs.PageFunction, arg?: any): Promise; + async _evaluateInUtility(pageFunction: structs.PageFunction, arg?: Arg): Promise { assertMaxArguments(arguments.length, 2); return this._wrapApiCall(this._apiName('evaluate'), async () => { const result = await this._channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg), world: 'utility' }); @@ -204,21 +202,23 @@ export class Frame extends ChannelOwner | null> { + async $(selector: string): Promise | null> { return this._wrapApiCall(this._apiName('$'), async () => { const result = await this._channel.querySelector({ selector }); - return ElementHandle.fromNullable(result.element) as ElementHandle | null; + return ElementHandle.fromNullable(result.element) as ElementHandle | null; }); } - async waitForSelector(selector: string, options: channels.FrameWaitForSelectorOptions = {}): Promise | null> { + waitForSelector(selector: string, options: channels.FrameWaitForSelectorOptions & { state: 'attached' | 'visible' }): Promise>; + waitForSelector(selector: string, options?: channels.FrameWaitForSelectorOptions): Promise | null>; + async waitForSelector(selector: string, options: channels.FrameWaitForSelectorOptions = {}): Promise | null> { return this._wrapApiCall(this._apiName('waitForSelector'), async () => { if ((options as any).visibility) throw new Error('options.visibility is not supported, did you mean options.state?'); if ((options as any).waitFor && (options as any).waitFor !== 'visible') throw new Error('options.waitFor is not supported, did you mean options.state?'); const result = await this._channel.waitForSelector({ selector, ...options }); - return ElementHandle.fromNullable(result.element) as ElementHandle | null; + return ElementHandle.fromNullable(result.element) as ElementHandle | null; }); } @@ -228,9 +228,7 @@ export class Frame extends ChannelOwner(selector: string, pageFunction: FuncOn, arg: Arg): Promise; - async $eval(selector: string, pageFunction: FuncOn, arg?: any): Promise; - async $eval(selector: string, pageFunction: FuncOn, arg: Arg): Promise { + async $eval(selector: string, pageFunction: structs.PageFunctionOn, arg?: Arg): Promise { assertMaxArguments(arguments.length, 3); return this._wrapApiCall(this._apiName('$eval'), async () => { const result = await this._channel.evalOnSelector({ selector, expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) }); @@ -238,9 +236,7 @@ export class Frame extends ChannelOwner(selector: string, pageFunction: FuncOn, arg: Arg): Promise; - async $$eval(selector: string, pageFunction: FuncOn, arg?: any): Promise; - async $$eval(selector: string, pageFunction: FuncOn, arg: Arg): Promise { + async $$eval(selector: string, pageFunction: structs.PageFunctionOn, arg?: Arg): Promise { assertMaxArguments(arguments.length, 3); return this._wrapApiCall(this._apiName('$$eval'), async () => { const result = await this._channel.evalOnSelectorAll({ selector, expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) }); @@ -248,10 +244,10 @@ export class Frame extends ChannelOwner[]> { + async $$(selector: string): Promise[]> { return this._wrapApiCall(this._apiName('$$'), async () => { const result = await this._channel.querySelectorAll({ selector }); - return result.elements.map(e => ElementHandle.from(e) as ElementHandle); + return result.elements.map(e => ElementHandle.from(e) as ElementHandle); }); } @@ -372,7 +368,7 @@ export class Frame extends ChannelOwner { + async selectOption(selector: string, values: string | api.ElementHandle | SelectOption | string[] | api.ElementHandle[] | SelectOption[] | null, options: SelectOptionOptions = {}): Promise { return this._wrapApiCall(this._apiName('selectOption'), async () => { return (await this._channel.selectOption({ selector, ...convertSelectOptionValues(values), ...options })).values; }); @@ -412,9 +408,7 @@ export class Frame extends ChannelOwner setTimeout(fulfill, timeout)); } - async waitForFunction(pageFunction: Func1, arg: Arg, options?: WaitForFunctionOptions): Promise>; - async waitForFunction(pageFunction: Func1, arg?: any, options?: WaitForFunctionOptions): Promise>; - async waitForFunction(pageFunction: Func1, arg: Arg, options: WaitForFunctionOptions = {}): Promise> { + async waitForFunction(pageFunction: structs.PageFunction, arg?: Arg, options: WaitForFunctionOptions = {}): Promise> { return this._wrapApiCall(this._apiName('waitForFunction'), async () => { if (typeof options.polling === 'string') assert(options.polling === 'raf', 'Unknown polling option: ' + options.polling); @@ -425,7 +419,7 @@ export class Frame extends ChannelOwner; + return JSHandle.from(result.handle) as any as structs.SmartHandle; }); } diff --git a/src/client/input.ts b/src/client/input.ts index ef0a567415050..11ad5ba776141 100644 --- a/src/client/input.ts +++ b/src/client/input.ts @@ -16,8 +16,9 @@ */ import * as channels from '../protocol/channels'; +import * as api from '../../types/types'; -export class Keyboard { +export class Keyboard implements api.Keyboard { private _channel: channels.PageChannel; constructor(channel: channels.PageChannel) { @@ -45,7 +46,7 @@ export class Keyboard { } } -export class Mouse { +export class Mouse implements api.Mouse { private _channel: channels.PageChannel; constructor(channel: channels.PageChannel) { @@ -73,7 +74,7 @@ export class Mouse { } } -export class Touchscreen { +export class Touchscreen implements api.Touchscreen { private _channel: channels.PageChannel; constructor(channel: channels.PageChannel) { diff --git a/src/client/jsHandle.ts b/src/client/jsHandle.ts index 55ff3e7c36013..5c2c410e909a0 100644 --- a/src/client/jsHandle.ts +++ b/src/client/jsHandle.ts @@ -15,27 +15,12 @@ */ import * as channels from '../protocol/channels'; -import { ElementHandle } from './elementHandle'; import { ChannelOwner } from './channelOwner'; import { parseSerializedValue, serializeValue } from '../protocol/serializers'; +import * as api from '../../types/types'; +import * as structs from '../../types/structs'; -type NoHandles = Arg extends JSHandle ? never : (Arg extends object ? { [Key in keyof Arg]: NoHandles } : Arg); -type Unboxed = - Arg extends ElementHandle ? T : - Arg extends JSHandle ? T : - Arg extends NoHandles ? Arg : - Arg extends [infer A0] ? [Unboxed] : - Arg extends [infer A0, infer A1] ? [Unboxed, Unboxed] : - Arg extends [infer A0, infer A1, infer A2] ? [Unboxed, Unboxed, Unboxed] : - Arg extends Array ? Array> : - Arg extends object ? { [Key in keyof Arg]: Unboxed } : - Arg; -export type Func0 = string | (() => R | Promise); -export type Func1 = string | ((arg: Unboxed) => R | Promise); -export type FuncOn = string | ((on: On, arg2: Unboxed) => R | Promise); -export type SmartHandle = T extends Node ? ElementHandle : JSHandle; - -export class JSHandle extends ChannelOwner { +export class JSHandle extends ChannelOwner implements api.JSHandle { private _preview: string; static from(handle: channels.JSHandleChannel): JSHandle { @@ -48,18 +33,14 @@ export class JSHandle extends ChannelOwner this._preview = preview); } - async evaluate(pageFunction: FuncOn, arg: Arg): Promise; - async evaluate(pageFunction: FuncOn, arg?: any): Promise; - async evaluate(pageFunction: FuncOn, arg: Arg): Promise { + async evaluate(pageFunction: structs.PageFunctionOn, arg?: Arg): Promise { const result = await this._channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) }); return parseResult(result.value); } - async evaluateHandle(pageFunction: FuncOn, arg: Arg): Promise>; - async evaluateHandle(pageFunction: FuncOn, arg?: any): Promise>; - async evaluateHandle(pageFunction: FuncOn, arg: Arg): Promise> { + async evaluateHandle(pageFunction: structs.PageFunctionOn, arg?: Arg): Promise> { const result = await this._channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) }); - return JSHandle.from(result.handle) as SmartHandle; + return JSHandle.from(result.handle) as any as structs.SmartHandle; } async getProperty(propertyName: string): Promise { @@ -78,8 +59,8 @@ export class JSHandle extends ChannelOwner : null { + return null as any; } async dispose() { diff --git a/src/client/network.ts b/src/client/network.ts index 91a97b8cf9a00..e9595b8e0cde9 100644 --- a/src/client/network.ts +++ b/src/client/network.ts @@ -26,6 +26,7 @@ import { isString, headersObjectToArray, headersArrayToObject } from '../utils/u import { Events } from './events'; import { Page } from './page'; import { Waiter } from './waiter'; +import * as api from '../../types/types'; export type NetworkCookie = { name: string, @@ -50,7 +51,7 @@ export type SetNetworkCookieParam = { sameSite?: 'Strict' | 'Lax' | 'None' }; -export class Request extends ChannelOwner { +export class Request extends ChannelOwner implements api.Request { private _redirectedFrom: Request | null = null; private _redirectedTo: Request | null = null; _failureText: string | null = null; @@ -167,7 +168,7 @@ export class Request extends ChannelOwner { +export class Route extends ChannelOwner implements api.Route { static from(route: channels.RouteChannel): Route { return (route as any)._object; } @@ -246,7 +247,7 @@ export type ResourceTiming = { responseEnd: number; }; -export class Response extends ChannelOwner { +export class Response extends ChannelOwner implements api.Response { private _headers: Headers; private _request: Request; @@ -316,7 +317,7 @@ export class Response extends ChannelOwner { +export class WebSocket extends ChannelOwner implements api.WebSocket { private _page: Page; private _isClosed: boolean; diff --git a/src/client/page.ts b/src/client/page.ts index 2a00a20698b71..894ca08c5e2b5 100644 --- a/src/client/page.ts +++ b/src/client/page.ts @@ -30,13 +30,14 @@ import { ElementHandle, determineScreenshotType } from './elementHandle'; import { Worker } from './worker'; import { Frame, verifyLoadState, WaitForNavigationOptions } from './frame'; import { Keyboard, Mouse, Touchscreen } from './input'; -import { assertMaxArguments, Func1, FuncOn, SmartHandle, serializeArgument, parseResult, JSHandle } from './jsHandle'; +import { assertMaxArguments, serializeArgument, parseResult, JSHandle } from './jsHandle'; import { Request, Response, Route, RouteHandler, WebSocket, validateHeaders } from './network'; import { FileChooser } from './fileChooser'; import { Buffer } from 'buffer'; import { ChromiumCoverage } from './chromiumCoverage'; import { Waiter } from './waiter'; - +import * as api from '../../types/types'; +import * as structs from '../../types/structs'; import * as fs from 'fs'; import * as path from 'path'; import * as util from 'util'; @@ -61,9 +62,8 @@ type PDFOptions = Omit & path?: string, }; type Listener = (...args: any[]) => void; -export type FunctionWithSource = (source: { context: BrowserContext, page: Page, frame: Frame }, ...args: any) => any; -export class Page extends ChannelOwner { +export class Page extends ChannelOwner implements api.Page { private _browserContext: BrowserContext; _ownedContext: BrowserContext | undefined; @@ -79,9 +79,9 @@ export class Page extends ChannelOwner Promise; + pdf: (options?: PDFOptions) => Promise; - readonly _bindings = new Map(); + readonly _bindings = new Map any>(); readonly _timeoutSettings: TimeoutSettings; _isPageCall = false; private _video: Video | null = null; @@ -136,6 +136,8 @@ export class Page extends ChannelOwner this._pdf(options); + } else { + this.pdf = undefined as any; } } @@ -261,11 +263,13 @@ export class Page extends ChannelOwner | null> { + async $(selector: string): Promise | null> { return this._attributeToPage(() => this._mainFrame.$(selector)); } - async waitForSelector(selector: string, options?: channels.FrameWaitForSelectorOptions): Promise | null> { + waitForSelector(selector: string, options: channels.FrameWaitForSelectorOptions & { state: 'attached' | 'visible' }): Promise>; + waitForSelector(selector: string, options?: channels.FrameWaitForSelectorOptions): Promise | null>; + async waitForSelector(selector: string, options?: channels.FrameWaitForSelectorOptions): Promise | null> { return this._attributeToPage(() => this._mainFrame.waitForSelector(selector, options)); } @@ -273,28 +277,22 @@ export class Page extends ChannelOwner this._mainFrame.dispatchEvent(selector, type, eventInit, options)); } - async evaluateHandle(pageFunction: Func1, arg: Arg): Promise>; - async evaluateHandle(pageFunction: Func1, arg?: any): Promise>; - async evaluateHandle(pageFunction: Func1, arg: Arg): Promise> { + async evaluateHandle(pageFunction: structs.PageFunction, arg?: Arg): Promise> { assertMaxArguments(arguments.length, 2); return this._attributeToPage(() => this._mainFrame.evaluateHandle(pageFunction, arg)); } - async $eval(selector: string, pageFunction: FuncOn, arg: Arg): Promise; - async $eval(selector: string, pageFunction: FuncOn, arg?: any): Promise; - async $eval(selector: string, pageFunction: FuncOn, arg: Arg): Promise { + async $eval(selector: string, pageFunction: structs.PageFunctionOn, arg?: Arg): Promise { assertMaxArguments(arguments.length, 3); return this._attributeToPage(() => this._mainFrame.$eval(selector, pageFunction, arg)); } - async $$eval(selector: string, pageFunction: FuncOn, arg: Arg): Promise; - async $$eval(selector: string, pageFunction: FuncOn, arg?: any): Promise; - async $$eval(selector: string, pageFunction: FuncOn, arg: Arg): Promise { + async $$eval(selector: string, pageFunction: structs.PageFunctionOn, arg?: Arg): Promise { assertMaxArguments(arguments.length, 3); return this._attributeToPage(() => this._mainFrame.$$eval(selector, pageFunction, arg)); } - async $$(selector: string): Promise[]> { + async $$(selector: string): Promise[]> { return this._attributeToPage(() => this._mainFrame.$$(selector)); } @@ -309,12 +307,12 @@ export class Page extends ChannelOwner { await this._channel.exposeBinding({ name }); - const binding: FunctionWithSource = (source, ...args) => playwrightFunction(...args); + const binding = (source: structs.BindingSource, ...args: any[]) => playwrightFunction(...args); this._bindings.set(name, binding); }); } - async exposeBinding(name: string, playwrightBinding: FunctionWithSource, options: { handle?: boolean } = {}) { + async exposeBinding(name: string, playwrightBinding: (source: structs.BindingSource, ...args: any[]) => any, options: { handle?: boolean } = {}) { return this._wrapApiCall('page.exposeBinding', async () => { await this._channel.exposeBinding({ name, needsHandle: options.handle }); this._bindings.set(name, playwrightBinding); @@ -425,9 +423,7 @@ export class Page extends ChannelOwner(pageFunction: Func1, arg: Arg): Promise; - async evaluate(pageFunction: Func1, arg?: any): Promise; - async evaluate(pageFunction: Func1, arg: Arg): Promise { + async evaluate(pageFunction: structs.PageFunction, arg?: Arg): Promise { assertMaxArguments(arguments.length, 2); return this._attributeToPage(() => this._mainFrame.evaluate(pageFunction, arg)); } @@ -538,7 +534,7 @@ export class Page extends ChannelOwner this._mainFrame.hover(selector, options)); } - async selectOption(selector: string, values: string | ElementHandle | SelectOption | string[] | ElementHandle[] | SelectOption[] | null, options?: SelectOptionOptions): Promise { + async selectOption(selector: string, values: string | api.ElementHandle | SelectOption | string[] | api.ElementHandle[] | SelectOption[] | null, options?: SelectOptionOptions): Promise { return this._attributeToPage(() => this._mainFrame.selectOption(selector, values, options)); } @@ -566,9 +562,7 @@ export class Page extends ChannelOwner(pageFunction: Func1, arg: Arg, options?: WaitForFunctionOptions): Promise>; - async waitForFunction(pageFunction: Func1, arg?: any, options?: WaitForFunctionOptions): Promise>; - async waitForFunction(pageFunction: Func1, arg: Arg, options?: WaitForFunctionOptions): Promise> { + async waitForFunction(pageFunction: structs.PageFunction, arg?: Arg, options?: WaitForFunctionOptions): Promise> { return this._attributeToPage(() => this._mainFrame.waitForFunction(pageFunction, arg, options)); } @@ -636,7 +630,7 @@ export class BindingCall extends ChannelOwner any) { try { const frame = Frame.from(this._initializer.frame); const source = { diff --git a/src/client/selectors.ts b/src/client/selectors.ts index 9819f3ad6a442..65b5086fa119c 100644 --- a/src/client/selectors.ts +++ b/src/client/selectors.ts @@ -18,8 +18,9 @@ import { evaluationScript } from './clientHelper'; import * as channels from '../protocol/channels'; import { ChannelOwner } from './channelOwner'; import { SelectorEngine } from './types'; +import * as api from '../../types/types'; -export class Selectors { +export class Selectors implements api.Selectors { private _channels = new Set(); private _registrations: channels.SelectorsRegisterParams[] = []; diff --git a/src/client/video.ts b/src/client/video.ts index f8358de3cf8c2..4ac2826b6ae39 100644 --- a/src/client/video.ts +++ b/src/client/video.ts @@ -16,8 +16,9 @@ import * as path from 'path'; import { Page } from './page'; +import * as api from '../../types/types'; -export class Video { +export class Video implements api.Video { private _page: Page; private _pathCallback: ((path: string) => void) | undefined; private _pathPromise: Promise; diff --git a/src/client/webkitBrowser.ts b/src/client/webkitBrowser.ts index 15a25a07afd1b..98a0d16f97b98 100644 --- a/src/client/webkitBrowser.ts +++ b/src/client/webkitBrowser.ts @@ -15,6 +15,7 @@ */ import { Browser } from './browser'; +import * as api from '../../types/types'; -export class WebKitBrowser extends Browser { +export class WebKitBrowser extends Browser implements api.WebKitBrowser { } diff --git a/src/client/worker.ts b/src/client/worker.ts index cbd14378b6b08..0d5d12dff9942 100644 --- a/src/client/worker.ts +++ b/src/client/worker.ts @@ -17,12 +17,14 @@ import { Events } from './events'; import * as channels from '../protocol/channels'; import { ChannelOwner } from './channelOwner'; -import { assertMaxArguments, Func1, JSHandle, parseResult, serializeArgument, SmartHandle } from './jsHandle'; +import { assertMaxArguments, JSHandle, parseResult, serializeArgument } from './jsHandle'; import { Page } from './page'; import { BrowserContext } from './browserContext'; import { ChromiumBrowserContext } from './chromiumBrowserContext'; +import * as api from '../../types/types'; +import * as structs from '../../types/structs'; -export class Worker extends ChannelOwner { +export class Worker extends ChannelOwner implements api.Worker { _page: Page | undefined; // Set for web workers. _context: BrowserContext | undefined; // Set for service workers. @@ -45,19 +47,15 @@ export class Worker extends ChannelOwner(pageFunction: Func1, arg: Arg): Promise; - async evaluate(pageFunction: Func1, arg?: any): Promise; - async evaluate(pageFunction: Func1, arg: Arg): Promise { + async evaluate(pageFunction: structs.PageFunction, arg?: Arg): Promise { assertMaxArguments(arguments.length, 2); const result = await this._channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) }); return parseResult(result.value); } - async evaluateHandle(pageFunction: Func1, arg: Arg): Promise>; - async evaluateHandle(pageFunction: Func1, arg?: any): Promise>; - async evaluateHandle(pageFunction: Func1, arg: Arg): Promise> { + async evaluateHandle(pageFunction: structs.PageFunction, arg?: Arg): Promise> { assertMaxArguments(arguments.length, 2); const result = await this._channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) }); - return JSHandle.from(result.handle) as SmartHandle; + return JSHandle.from(result.handle) as any as structs.SmartHandle; } } diff --git a/types/structs.d.ts b/types/structs.d.ts new file mode 100644 index 0000000000000..7d1e981d74601 --- /dev/null +++ b/types/structs.d.ts @@ -0,0 +1,45 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { JSHandle, ElementHandle, Frame, Page, BrowserContext } from './types'; + +/** + * Can be converted to JSON + */ +export type Serializable = {}; +/** + * Can be converted to JSON, but may also contain JSHandles. + */ +export type EvaluationArgument = {}; + +export type NoHandles = Arg extends JSHandle ? never : (Arg extends object ? { [Key in keyof Arg]: NoHandles } : Arg); +export type Unboxed = + Arg extends ElementHandle ? T : + Arg extends JSHandle ? T : + Arg extends NoHandles ? Arg : + Arg extends [infer A0] ? [Unboxed] : + Arg extends [infer A0, infer A1] ? [Unboxed, Unboxed] : + Arg extends [infer A0, infer A1, infer A2] ? [Unboxed, Unboxed, Unboxed] : + Arg extends [infer A0, infer A1, infer A2, infer A3] ? [Unboxed, Unboxed, Unboxed, Unboxed] : + Arg extends Array ? Array> : + Arg extends object ? { [Key in keyof Arg]: Unboxed } : + Arg; +export type PageFunction0 = string | (() => R | Promise); +export type PageFunction = string | ((arg: Unboxed) => R | Promise); +export type PageFunctionOn = string | ((on: On, arg2: Unboxed) => R | Promise); +export type SmartHandle = T extends Node ? ElementHandle : JSHandle; +export type ElementHandleForTag = ElementHandle; +export type BindingSource = { context: BrowserContext, page: Page, frame: Frame }; diff --git a/types/types.d.ts b/types/types.d.ts index d190f110ecaf9..5efd82e60e8b1 100644 --- a/types/types.d.ts +++ b/types/types.d.ts @@ -18,32 +18,7 @@ import { Protocol } from './protocol'; import { ChildProcess } from 'child_process'; import { EventEmitter } from 'events'; import { Readable } from 'stream'; - -/** - * Can be converted to JSON - */ -type Serializable = {}; -/** - * Can be converted to JSON, but may also contain JSHandles. - */ -type EvaluationArgument = {}; - -type NoHandles = Arg extends JSHandle ? never : (Arg extends object ? { [Key in keyof Arg]: NoHandles } : Arg); -type Unboxed = - Arg extends ElementHandle ? T : - Arg extends JSHandle ? T : - Arg extends NoHandles ? Arg : - Arg extends [infer A0] ? [Unboxed] : - Arg extends [infer A0, infer A1] ? [Unboxed, Unboxed] : - Arg extends [infer A0, infer A1, infer A2] ? [Unboxed, Unboxed, Unboxed] : - Arg extends [infer A0, infer A1, infer A2, infer A3] ? [Unboxed, Unboxed, Unboxed, Unboxed] : - Arg extends Array ? Array> : - Arg extends object ? { [Key in keyof Arg]: Unboxed } : - Arg; -type PageFunction = string | ((arg: Unboxed) => R | Promise); -type PageFunctionOn = string | ((on: On, arg2: Unboxed) => R | Promise); -type SmartHandle = T extends Node ? ElementHandle : JSHandle; -type ElementHandleForTag = ElementHandle; +import { Serializable, EvaluationArgument, PageFunction, PageFunctionOn, SmartHandle, ElementHandleForTag, BindingSource } from './structs'; type PageWaitForSelectorOptionsNotHidden = PageWaitForSelectorOptions & { state: 'visible'|'attached'; @@ -52,8 +27,6 @@ type ElementHandleWaitForSelectorOptionsNotHidden = ElementHandleWaitForSelector state: 'visible'|'attached'; }; -type BindingSource = { context: BrowserContext, page: Page, frame: Frame }; - /** * Page provides methods to interact with a single tab in a Browser, or an extension background page in Chromium. One Browser instance might have multiple Page instances. * This example creates a page, navigates it to a URL, and then saves a screenshot: diff --git a/utils/doclint/check_public_api/index.js b/utils/doclint/check_public_api/index.js index b1565d4891c86..2cd21039393db 100644 --- a/utils/doclint/check_public_api/index.js +++ b/utils/doclint/check_public_api/index.js @@ -200,7 +200,8 @@ function compareDocumentations(actual, expected) { [/Handle\/g, 'JSHandle'], [/JSHandle\/g, 'JSHandle'], [/object/g, 'Object'], - [/Promise\/, 'Promise'] + [/Promise\/, 'Promise'], + [/TextendsNode\?ElementHandle:null/, 'null|ElementHandle'] ] let actualName = actual.name; for (const replacer of mdReplacers) diff --git a/utils/generate_types/overrides.d.ts b/utils/generate_types/overrides.d.ts index 07c03931bbf1e..38c4487877651 100644 --- a/utils/generate_types/overrides.d.ts +++ b/utils/generate_types/overrides.d.ts @@ -17,32 +17,7 @@ import { Protocol } from './protocol'; import { ChildProcess } from 'child_process'; import { EventEmitter } from 'events'; import { Readable } from 'stream'; - -/** - * Can be converted to JSON - */ -type Serializable = {}; -/** - * Can be converted to JSON, but may also contain JSHandles. - */ -type EvaluationArgument = {}; - -type NoHandles = Arg extends JSHandle ? never : (Arg extends object ? { [Key in keyof Arg]: NoHandles } : Arg); -type Unboxed = - Arg extends ElementHandle ? T : - Arg extends JSHandle ? T : - Arg extends NoHandles ? Arg : - Arg extends [infer A0] ? [Unboxed] : - Arg extends [infer A0, infer A1] ? [Unboxed, Unboxed] : - Arg extends [infer A0, infer A1, infer A2] ? [Unboxed, Unboxed, Unboxed] : - Arg extends [infer A0, infer A1, infer A2, infer A3] ? [Unboxed, Unboxed, Unboxed, Unboxed] : - Arg extends Array ? Array> : - Arg extends object ? { [Key in keyof Arg]: Unboxed } : - Arg; -type PageFunction = string | ((arg: Unboxed) => R | Promise); -type PageFunctionOn = string | ((on: On, arg2: Unboxed) => R | Promise); -type SmartHandle = T extends Node ? ElementHandle : JSHandle; -type ElementHandleForTag = ElementHandle; +import { Serializable, EvaluationArgument, PageFunction, PageFunctionOn, SmartHandle, ElementHandleForTag, BindingSource } from './structs'; type PageWaitForSelectorOptionsNotHidden = PageWaitForSelectorOptions & { state: 'visible'|'attached'; @@ -51,8 +26,6 @@ type ElementHandleWaitForSelectorOptionsNotHidden = ElementHandleWaitForSelector state: 'visible'|'attached'; }; -type BindingSource = { context: BrowserContext, page: Page, frame: Frame }; - export interface Page { evaluate(pageFunction: PageFunction, arg: Arg): Promise; evaluate(pageFunction: PageFunction, arg?: any): Promise;