feat(inspector): send api names along with metainfo (#5518)

This commit is contained in:
Pavel Feldman 2021-02-19 16:21:39 -08:00 committed by GitHub
parent 46c8c29f7a
commit f154a827c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 354 additions and 347 deletions

View file

@ -50,8 +50,8 @@ export class Android extends ChannelOwner<channels.AndroidChannel, channels.Andr
}
async devices(): Promise<AndroidDevice[]> {
return this._wrapApiCall('android.devices', async () => {
const { devices } = await this._channel.devices();
return this._wrapApiCall('android.devices', async (channel: channels.AndroidChannel) => {
const { devices } = await channel.devices();
return devices.map(d => AndroidDevice.from(d));
});
}
@ -116,14 +116,14 @@ export class AndroidDevice extends ChannelOwner<channels.AndroidDeviceChannel, c
}
async wait(selector: api.AndroidSelector, options?: { state?: 'gone' } & types.TimeoutOptions) {
await this._wrapApiCall('androidDevice.wait', async () => {
await this._channel.wait({ selector: toSelectorChannel(selector), ...options });
await this._wrapApiCall('androidDevice.wait', async (channel: channels.AndroidDeviceChannel) => {
await channel.wait({ selector: toSelectorChannel(selector), ...options });
});
}
async fill(selector: api.AndroidSelector, text: string, options?: types.TimeoutOptions) {
await this._wrapApiCall('androidDevice.fill', async () => {
await this._channel.fill({ selector: toSelectorChannel(selector), text, ...options });
await this._wrapApiCall('androidDevice.fill', async (channel: channels.AndroidDeviceChannel) => {
await channel.fill({ selector: toSelectorChannel(selector), text, ...options });
});
}
@ -133,62 +133,62 @@ export class AndroidDevice extends ChannelOwner<channels.AndroidDeviceChannel, c
}
async tap(selector: api.AndroidSelector, options?: { duration?: number } & types.TimeoutOptions) {
await this._wrapApiCall('androidDevice.tap', async () => {
await this._channel.tap({ selector: toSelectorChannel(selector), ...options });
await this._wrapApiCall('androidDevice.tap', async (channel: channels.AndroidDeviceChannel) => {
await channel.tap({ selector: toSelectorChannel(selector), ...options });
});
}
async drag(selector: api.AndroidSelector, dest: types.Point, options?: SpeedOptions & types.TimeoutOptions) {
await this._wrapApiCall('androidDevice.drag', async () => {
await this._channel.drag({ selector: toSelectorChannel(selector), dest, ...options });
await this._wrapApiCall('androidDevice.drag', async (channel: channels.AndroidDeviceChannel) => {
await channel.drag({ selector: toSelectorChannel(selector), dest, ...options });
});
}
async fling(selector: api.AndroidSelector, direction: Direction, options?: SpeedOptions & types.TimeoutOptions) {
await this._wrapApiCall('androidDevice.fling', async () => {
await this._channel.fling({ selector: toSelectorChannel(selector), direction, ...options });
await this._wrapApiCall('androidDevice.fling', async (channel: channels.AndroidDeviceChannel) => {
await channel.fling({ selector: toSelectorChannel(selector), direction, ...options });
});
}
async longTap(selector: api.AndroidSelector, options?: types.TimeoutOptions) {
await this._wrapApiCall('androidDevice.longTap', async () => {
await this._channel.longTap({ selector: toSelectorChannel(selector), ...options });
await this._wrapApiCall('androidDevice.longTap', async (channel: channels.AndroidDeviceChannel) => {
await channel.longTap({ selector: toSelectorChannel(selector), ...options });
});
}
async pinchClose(selector: api.AndroidSelector, percent: number, options?: SpeedOptions & types.TimeoutOptions) {
await this._wrapApiCall('androidDevice.pinchClose', async () => {
await this._channel.pinchClose({ selector: toSelectorChannel(selector), percent, ...options });
await this._wrapApiCall('androidDevice.pinchClose', async (channel: channels.AndroidDeviceChannel) => {
await channel.pinchClose({ selector: toSelectorChannel(selector), percent, ...options });
});
}
async pinchOpen(selector: api.AndroidSelector, percent: number, options?: SpeedOptions & types.TimeoutOptions) {
await this._wrapApiCall('androidDevice.pinchOpen', async () => {
await this._channel.pinchOpen({ selector: toSelectorChannel(selector), percent, ...options });
await this._wrapApiCall('androidDevice.pinchOpen', async (channel: channels.AndroidDeviceChannel) => {
await channel.pinchOpen({ selector: toSelectorChannel(selector), percent, ...options });
});
}
async scroll(selector: api.AndroidSelector, direction: Direction, percent: number, options?: SpeedOptions & types.TimeoutOptions) {
await this._wrapApiCall('androidDevice.scroll', async () => {
await this._channel.scroll({ selector: toSelectorChannel(selector), direction, percent, ...options });
await this._wrapApiCall('androidDevice.scroll', async (channel: channels.AndroidDeviceChannel) => {
await channel.scroll({ selector: toSelectorChannel(selector), direction, percent, ...options });
});
}
async swipe(selector: api.AndroidSelector, direction: Direction, percent: number, options?: SpeedOptions & types.TimeoutOptions) {
await this._wrapApiCall('androidDevice.swipe', async () => {
await this._channel.swipe({ selector: toSelectorChannel(selector), direction, percent, ...options });
await this._wrapApiCall('androidDevice.swipe', async (channel: channels.AndroidDeviceChannel) => {
await channel.swipe({ selector: toSelectorChannel(selector), direction, percent, ...options });
});
}
async info(selector: api.AndroidSelector): Promise<api.AndroidElementInfo> {
return await this._wrapApiCall('androidDevice.info', async () => {
return (await this._channel.info({ selector: toSelectorChannel(selector) })).info;
return await this._wrapApiCall('androidDevice.info', async (channel: channels.AndroidDeviceChannel) => {
return (await channel.info({ selector: toSelectorChannel(selector) })).info;
});
}
async screenshot(options: { path?: string } = {}): Promise<Buffer> {
return await this._wrapApiCall('androidDevice.screenshot', async () => {
const { binary } = await this._channel.screenshot();
return await this._wrapApiCall('androidDevice.screenshot', async (channel: channels.AndroidDeviceChannel) => {
const { binary } = await channel.screenshot();
const buffer = Buffer.from(binary, 'base64');
if (options.path)
await util.promisify(fs.writeFile)(options.path, buffer);
@ -197,41 +197,41 @@ export class AndroidDevice extends ChannelOwner<channels.AndroidDeviceChannel, c
}
async close() {
return this._wrapApiCall('androidDevice.close', async () => {
await this._channel.close();
return this._wrapApiCall('androidDevice.close', async (channel: channels.AndroidDeviceChannel) => {
await channel.close();
this.emit(Events.AndroidDevice.Close);
});
}
async shell(command: string): Promise<Buffer> {
return this._wrapApiCall('androidDevice.shell', async () => {
const { result } = await this._channel.shell({ command });
return this._wrapApiCall('androidDevice.shell', async (channel: channels.AndroidDeviceChannel) => {
const { result } = await channel.shell({ command });
return Buffer.from(result, 'base64');
});
}
async open(command: string): Promise<AndroidSocket> {
return this._wrapApiCall('androidDevice.open', async () => {
return AndroidSocket.from((await this._channel.open({ command })).socket);
return this._wrapApiCall('androidDevice.open', async (channel: channels.AndroidDeviceChannel) => {
return AndroidSocket.from((await channel.open({ command })).socket);
});
}
async installApk(file: string | Buffer, options?: { args: string[] }): Promise<void> {
return this._wrapApiCall('androidDevice.installApk', async () => {
await this._channel.installApk({ file: await loadFile(file), args: options && options.args });
return this._wrapApiCall('androidDevice.installApk', async (channel: channels.AndroidDeviceChannel) => {
await channel.installApk({ file: await loadFile(file), args: options && options.args });
});
}
async push(file: string | Buffer, path: string, options?: { mode: number }): Promise<void> {
return this._wrapApiCall('androidDevice.push', async () => {
await this._channel.push({ file: await loadFile(file), path, mode: options ? options.mode : undefined });
return this._wrapApiCall('androidDevice.push', async (channel: channels.AndroidDeviceChannel) => {
await channel.push({ file: await loadFile(file), path, mode: options ? options.mode : undefined });
});
}
async launchBrowser(options: types.BrowserContextOptions & { pkg?: string } = {}): Promise<ChromiumBrowserContext> {
return this._wrapApiCall('androidDevice.launchBrowser', async () => {
return this._wrapApiCall('androidDevice.launchBrowser', async (channel: channels.AndroidDeviceChannel) => {
const contextOptions = await prepareBrowserContextParams(options);
const { context } = await this._channel.launchBrowser(contextOptions);
const { context } = await channel.launchBrowser(contextOptions);
return BrowserContext.from(context) as ChromiumBrowserContext;
});
}
@ -261,14 +261,14 @@ export class AndroidSocket extends ChannelOwner<channels.AndroidSocketChannel, c
}
async write(data: Buffer): Promise<void> {
return this._wrapApiCall('androidDevice.write', async () => {
await this._channel.write({ data: data.toString('base64') });
return this._wrapApiCall('androidDevice.write', async (channel: channels.AndroidSocketChannel) => {
await channel.write({ data: data.toString('base64') });
});
}
async close(): Promise<void> {
return this._wrapApiCall('androidDevice.close', async () => {
await this._channel.close();
return this._wrapApiCall('androidDevice.close', async (channel: channels.AndroidSocketChannel) => {
await channel.close();
});
}
}
@ -287,32 +287,32 @@ export class AndroidInput implements api.AndroidInput {
}
async type(text: string) {
return this._device._wrapApiCall('androidDevice.inputType', async () => {
await this._device._channel.inputType({ text });
return this._device._wrapApiCall('androidDevice.inputType', async (channel: channels.AndroidDeviceChannel) => {
await channel.inputType({ text });
});
}
async press(key: api.AndroidKey) {
return this._device._wrapApiCall('androidDevice.inputPress', async () => {
await this._device._channel.inputPress({ key });
return this._device._wrapApiCall('androidDevice.inputPress', async (channel: channels.AndroidDeviceChannel) => {
await channel.inputPress({ key });
});
}
async tap(point: types.Point) {
return this._device._wrapApiCall('androidDevice.inputTap', async () => {
await this._device._channel.inputTap({ point });
return this._device._wrapApiCall('androidDevice.inputTap', async (channel: channels.AndroidDeviceChannel) => {
await channel.inputTap({ point });
});
}
async swipe(from: types.Point, segments: types.Point[], steps: number) {
return this._device._wrapApiCall('androidDevice.inputSwipe', async () => {
await this._device._channel.inputSwipe({ segments, steps });
return this._device._wrapApiCall('androidDevice.inputSwipe', async (channel: channels.AndroidDeviceChannel) => {
await channel.inputSwipe({ segments, steps });
});
}
async drag(from: types.Point, to: types.Point, steps: number) {
return this._device._wrapApiCall('androidDevice.inputDragAndDrop', async () => {
await this._device._channel.inputDrag({ from, to, steps });
return this._device._wrapApiCall('androidDevice.inputDragAndDrop', async (channel: channels.AndroidDeviceChannel) => {
await channel.inputDrag({ from, to, steps });
});
}
}
@ -393,8 +393,8 @@ export class AndroidWebView extends EventEmitter implements api.AndroidWebView {
}
private async _fetchPage(): Promise<Page> {
return this._device._wrapApiCall('androidWebView.page', async () => {
const { context } = await this._device._channel.connectToWebView({ pid: this._data.pid, sdkLanguage: 'javascript' });
return this._device._wrapApiCall('androidWebView.page', async (channel: channels.AndroidDeviceChannel) => {
const { context } = await channel.connectToWebView({ pid: this._data.pid, sdkLanguage: 'javascript' });
return BrowserContext.from(context).pages()[0];
});
}

View file

@ -44,11 +44,11 @@ export class Browser extends ChannelOwner<channels.BrowserChannel, channels.Brow
}
async newContext(options: BrowserContextOptions = {}): Promise<BrowserContext> {
return this._wrapApiCall('browser.newContext', async () => {
return this._wrapApiCall('browser.newContext', async (channel: channels.BrowserChannel) => {
if (this._isRemote && options._traceDir)
throw new Error(`"_traceDir" is not supported in connected browser`);
const contextOptions = await prepareBrowserContextParams(options);
const context = BrowserContext.from((await this._channel.newContext(contextOptions)).context);
const context = BrowserContext.from((await channel.newContext(contextOptions)).context);
context._options = contextOptions;
this._contexts.add(context);
context._logger = options.logger || this._logger;
@ -78,8 +78,8 @@ export class Browser extends ChannelOwner<channels.BrowserChannel, channels.Brow
async close(): Promise<void> {
try {
await this._wrapApiCall('browser.close', async () => {
await this._channel.close();
await this._wrapApiCall('browser.close', async (channel: channels.BrowserChannel) => {
await channel.close();
await this._closedPromise;
});
} catch (e) {

View file

@ -108,10 +108,10 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel,
}
async newPage(): Promise<Page> {
return this._wrapApiCall('browserContext.newPage', async () => {
return this._wrapApiCall('browserContext.newPage', async (channel: channels.BrowserContextChannel) => {
if (this._ownerPage)
throw new Error('Please use browser.newContext()');
return Page.from((await this._channel.newPage()).page);
return Page.from((await channel.newPage()).page);
});
}
@ -120,97 +120,97 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel,
urls = [];
if (urls && typeof urls === 'string')
urls = [ urls ];
return this._wrapApiCall('browserContext.cookies', async () => {
return (await this._channel.cookies({ urls: urls as string[] })).cookies;
return this._wrapApiCall('browserContext.cookies', async (channel: channels.BrowserContextChannel) => {
return (await channel.cookies({ urls: urls as string[] })).cookies;
});
}
async addCookies(cookies: network.SetNetworkCookieParam[]): Promise<void> {
return this._wrapApiCall('browserContext.addCookies', async () => {
await this._channel.addCookies({ cookies });
return this._wrapApiCall('browserContext.addCookies', async (channel: channels.BrowserContextChannel) => {
await channel.addCookies({ cookies });
});
}
async clearCookies(): Promise<void> {
return this._wrapApiCall('browserContext.clearCookies', async () => {
await this._channel.clearCookies();
return this._wrapApiCall('browserContext.clearCookies', async (channel: channels.BrowserContextChannel) => {
await channel.clearCookies();
});
}
async grantPermissions(permissions: string[], options?: { origin?: string }): Promise<void> {
return this._wrapApiCall('browserContext.grantPermissions', async () => {
await this._channel.grantPermissions({ permissions, ...options });
return this._wrapApiCall('browserContext.grantPermissions', async (channel: channels.BrowserContextChannel) => {
await channel.grantPermissions({ permissions, ...options });
});
}
async clearPermissions(): Promise<void> {
return this._wrapApiCall('browserContext.clearPermissions', async () => {
await this._channel.clearPermissions();
return this._wrapApiCall('browserContext.clearPermissions', async (channel: channels.BrowserContextChannel) => {
await channel.clearPermissions();
});
}
async setGeolocation(geolocation: { longitude: number, latitude: number, accuracy?: number } | null): Promise<void> {
return this._wrapApiCall('browserContext.setGeolocation', async () => {
await this._channel.setGeolocation({ geolocation: geolocation || undefined });
return this._wrapApiCall('browserContext.setGeolocation', async (channel: channels.BrowserContextChannel) => {
await channel.setGeolocation({ geolocation: geolocation || undefined });
});
}
async setExtraHTTPHeaders(headers: Headers): Promise<void> {
return this._wrapApiCall('browserContext.setExtraHTTPHeaders', async () => {
return this._wrapApiCall('browserContext.setExtraHTTPHeaders', async (channel: channels.BrowserContextChannel) => {
network.validateHeaders(headers);
await this._channel.setExtraHTTPHeaders({ headers: headersObjectToArray(headers) });
await channel.setExtraHTTPHeaders({ headers: headersObjectToArray(headers) });
});
}
async setOffline(offline: boolean): Promise<void> {
return this._wrapApiCall('browserContext.setOffline', async () => {
await this._channel.setOffline({ offline });
return this._wrapApiCall('browserContext.setOffline', async (channel: channels.BrowserContextChannel) => {
await channel.setOffline({ offline });
});
}
async setHTTPCredentials(httpCredentials: { username: string, password: string } | null): Promise<void> {
if (!isUnderTest())
deprecate(`context.setHTTPCredentials`, `warning: method |context.setHTTPCredentials()| is deprecated. Instead of changing credentials, create another browser context with new credentials.`);
return this._wrapApiCall('browserContext.setHTTPCredentials', async () => {
await this._channel.setHTTPCredentials({ httpCredentials: httpCredentials || undefined });
return this._wrapApiCall('browserContext.setHTTPCredentials', async (channel: channels.BrowserContextChannel) => {
await channel.setHTTPCredentials({ httpCredentials: httpCredentials || undefined });
});
}
async addInitScript(script: Function | string | { path?: string, content?: string }, arg?: any): Promise<void> {
return this._wrapApiCall('browserContext.addInitScript', async () => {
return this._wrapApiCall('browserContext.addInitScript', async (channel: channels.BrowserContextChannel) => {
const source = await evaluationScript(script, arg);
await this._channel.addInitScript({ source });
await channel.addInitScript({ source });
});
}
async exposeBinding(name: string, callback: (source: structs.BindingSource, ...args: any[]) => any, options: { handle?: boolean } = {}): Promise<void> {
return this._wrapApiCall('browserContext.exposeBinding', async () => {
await this._channel.exposeBinding({ name, needsHandle: options.handle });
return this._wrapApiCall('browserContext.exposeBinding', async (channel: channels.BrowserContextChannel) => {
await channel.exposeBinding({ name, needsHandle: options.handle });
this._bindings.set(name, callback);
});
}
async exposeFunction(name: string, callback: Function): Promise<void> {
return this._wrapApiCall('browserContext.exposeFunction', async () => {
await this._channel.exposeBinding({ name });
return this._wrapApiCall('browserContext.exposeFunction', async (channel: channels.BrowserContextChannel) => {
await channel.exposeBinding({ name });
const binding = (source: structs.BindingSource, ...args: any[]) => callback(...args);
this._bindings.set(name, binding);
});
}
async route(url: URLMatch, handler: network.RouteHandler): Promise<void> {
return this._wrapApiCall('browserContext.route', async () => {
return this._wrapApiCall('browserContext.route', async (channel: channels.BrowserContextChannel) => {
this._routes.push({ url, handler });
if (this._routes.length === 1)
await this._channel.setNetworkInterceptionEnabled({ enabled: true });
await channel.setNetworkInterceptionEnabled({ enabled: true });
});
}
async unroute(url: URLMatch, handler?: network.RouteHandler): Promise<void> {
return this._wrapApiCall('browserContext.unroute', async () => {
return this._wrapApiCall('browserContext.unroute', async (channel: channels.BrowserContextChannel) => {
this._routes = this._routes.filter(route => route.url !== url || (handler && route.handler !== handler));
if (this._routes.length === 0)
await this._channel.setNetworkInterceptionEnabled({ enabled: false });
await channel.setNetworkInterceptionEnabled({ enabled: false });
});
}
@ -227,8 +227,8 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel,
}
async storageState(options: { path?: string } = {}): Promise<StorageState> {
return await this._wrapApiCall('browserContext.storageState', async () => {
const state = await this._channel.storageState();
return await this._wrapApiCall('browserContext.storageState', async (channel: channels.BrowserContextChannel) => {
const state = await channel.storageState();
if (options.path) {
await mkdirIfNeeded(options.path);
await fsWriteFileAsync(options.path, JSON.stringify(state), 'utf8');
@ -245,8 +245,8 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel,
async close(): Promise<void> {
try {
await this._wrapApiCall('browserContext.close', async () => {
await this._channel.close();
await this._wrapApiCall('browserContext.close', async (channel: channels.BrowserContextChannel) => {
await channel.close();
await this._closedPromise;
});
} catch (e) {
@ -257,8 +257,8 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel,
}
async _pause() {
return this._wrapApiCall('browserContext.pause', async () => {
await this._channel.pause();
return this._wrapApiCall('browserContext.pause', async (channel: channels.BrowserContextChannel) => {
await channel.pause();
});
}

View file

@ -70,7 +70,7 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel, chann
async launch(options: LaunchOptions = {}): Promise<Browser> {
const logger = options.logger;
return this._wrapApiCall('browserType.launch', async () => {
return this._wrapApiCall('browserType.launch', async (channel: channels.BrowserTypeChannel) => {
assert(!(options as any).userDataDir, 'userDataDir option is not supported in `browserType.launch`. Use `browserType.launchPersistentContext` instead');
assert(!(options as any).port, 'Cannot specify a port without launching as a server.');
const launchOptions: channels.BrowserTypeLaunchParams = {
@ -79,7 +79,7 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel, chann
ignoreAllDefaultArgs: !!options.ignoreDefaultArgs && !Array.isArray(options.ignoreDefaultArgs),
env: options.env ? envObjectToArray(options.env) : undefined,
};
const browser = Browser.from((await this._channel.launch(launchOptions)).browser);
const browser = Browser.from((await channel.launch(launchOptions)).browser);
browser._logger = logger;
return browser;
}, logger);
@ -92,7 +92,7 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel, chann
}
async launchPersistentContext(userDataDir: string, options: LaunchPersistentContextOptions = {}): Promise<BrowserContext> {
return this._wrapApiCall('browserType.launchPersistentContext', async () => {
return this._wrapApiCall('browserType.launchPersistentContext', async (channel: channels.BrowserTypeChannel) => {
assert(!(options as any).port, 'Cannot specify a port without launching as a server.');
const contextParams = await prepareBrowserContextParams(options);
const persistentParams: channels.BrowserTypeLaunchPersistentContextParams = {
@ -102,7 +102,7 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel, chann
env: options.env ? envObjectToArray(options.env) : undefined,
userDataDir,
};
const result = await this._channel.launchPersistentContext(persistentParams);
const result = await channel.launchPersistentContext(persistentParams);
const context = BrowserContext.from(result.context);
context._options = contextParams;
context._logger = options.logger;
@ -190,8 +190,8 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel, chann
if (this.name() !== 'chromium')
throw new Error('Connecting over CDP is only supported in Chromium.');
const logger = params.logger;
return this._wrapApiCall('browserType.connectOverCDP', async () => {
const result = await this._channel.connectOverCDP({
return this._wrapApiCall('browserType.connectOverCDP', async (channel: channels.BrowserTypeChannel) => {
const result = await channel.connectOverCDP({
sdkLanguage: 'javascript',
wsEndpoint: params.wsEndpoint,
slowMo: params.slowMo,

View file

@ -48,15 +48,15 @@ export class CDPSession extends ChannelOwner<channels.CDPSessionChannel, channel
method: T,
params?: Protocol.CommandParameters[T]
): Promise<Protocol.CommandReturnValues[T]> {
return this._wrapApiCall('cdpSession.send', async () => {
const result = await this._channel.send({ method, params });
return this._wrapApiCall('cdpSession.send', async (channel: channels.CDPSessionChannel) => {
const result = await channel.send({ method, params });
return result.result as Protocol.CommandReturnValues[T];
});
}
async detach() {
return this._wrapApiCall('cdpSession.detach', async () => {
return this._channel.detach();
return this._wrapApiCall('cdpSession.detach', async (channel: channels.CDPSessionChannel) => {
return channel.detach();
});
}
}

View file

@ -84,11 +84,11 @@ export abstract class ChannelOwner<T extends channels.Channel = channels.Channel
};
}
async _wrapApiCall<T>(apiName: string, func: () => Promise<T>, logger?: Logger): Promise<T> {
async _wrapApiCall<T, K extends channels.Channel>(apiName: string, func: (channel: K) => Promise<T>, logger?: Logger): Promise<T> {
logger = logger || this._logger;
try {
logApiCall(logger, `=> ${apiName} started`);
const result = await func();
const result = await func(this._channel as any);
logApiCall(logger, `<= ${apiName} succeeded`);
return result;
} catch (e) {

View file

@ -14,6 +14,7 @@
* limitations under the License.
*/
import * as channels from '../protocol/channels';
import { Page } from './page';
import { CDPSession } from './cdpSession';
import { Browser } from './browser';
@ -31,20 +32,20 @@ export class ChromiumBrowser extends Browser implements api.ChromiumBrowser {
}
async newBrowserCDPSession(): Promise<CDPSession> {
return this._wrapApiCall('chromiumBrowser.newBrowserCDPSession', async () => {
return CDPSession.from((await this._channel.crNewBrowserCDPSession()).session);
return this._wrapApiCall('chromiumBrowser.newBrowserCDPSession', async (channel: channels.BrowserChannel) => {
return CDPSession.from((await channel.crNewBrowserCDPSession()).session);
});
}
async startTracing(page?: Page, options: { path?: string; screenshots?: boolean; categories?: string[]; } = {}) {
return this._wrapApiCall('chromiumBrowser.startTracing', async () => {
await this._channel.crStartTracing({ ...options, page: page ? page._channel : undefined });
return this._wrapApiCall('chromiumBrowser.startTracing', async (channel: channels.BrowserChannel) => {
await channel.crStartTracing({ ...options, page: page ? page._channel : undefined });
});
}
async stopTracing(): Promise<Buffer> {
return this._wrapApiCall('chromiumBrowser.stopTracing', async () => {
return Buffer.from((await this._channel.crStopTracing()).binary, 'base64');
return this._wrapApiCall('chromiumBrowser.stopTracing', async (channel: channels.BrowserChannel) => {
return Buffer.from((await channel.crStopTracing()).binary, 'base64');
});
}
}

View file

@ -53,8 +53,8 @@ export class ChromiumBrowserContext extends BrowserContext implements api.Chromi
}
async newCDPSession(page: Page): Promise<CDPSession> {
return this._wrapApiCall('chromiumBrowserContext.newCDPSession', async () => {
const result = await this._channel.crNewCDPSession({ page: page._channel });
return this._wrapApiCall('chromiumBrowserContext.newCDPSession', async (channel: channels.BrowserContextChannel) => {
const result = await channel.crNewCDPSession({ page: page._channel });
return CDPSession.from(result.session);
});
}

View file

@ -40,14 +40,14 @@ export class Dialog extends ChannelOwner<channels.DialogChannel, channels.Dialog
}
async accept(promptText: string | undefined) {
return this._wrapApiCall('dialog.accept', async () => {
await this._channel.accept({ promptText });
return this._wrapApiCall('dialog.accept', async (channel: channels.DialogChannel) => {
await channel.accept({ promptText });
});
}
async dismiss() {
return this._wrapApiCall('dialog.dismiss', async () => {
await this._channel.dismiss();
return this._wrapApiCall('dialog.dismiss', async (channel: channels.DialogChannel) => {
await channel.dismiss();
});
}
}

View file

@ -47,17 +47,19 @@ export class Download extends ChannelOwner<channels.DownloadChannel, channels.Do
async path(): Promise<string | null> {
if (this._browser && this._browser._isRemote)
throw new Error(`Path is not available when using browserType.connect(). Use download.saveAs() to save a local copy.`);
return (await this._channel.path()).value || null;
return this._wrapApiCall('download.path', async (channel: channels.DownloadChannel) => {
return (await channel.path()).value || null;
});
}
async saveAs(path: string): Promise<void> {
return this._wrapApiCall('download.saveAs', async () => {
return this._wrapApiCall('download.saveAs', async (channel: channels.DownloadChannel) => {
if (!this._browser || !this._browser._isRemote) {
await this._channel.saveAs({ path });
await channel.saveAs({ path });
return;
}
const result = await this._channel.saveAsStream();
const result = await channel.saveAsStream();
const stream = Stream.from(result.stream);
await mkdirIfNeeded(path);
await new Promise((resolve, reject) => {
@ -69,14 +71,14 @@ export class Download extends ChannelOwner<channels.DownloadChannel, channels.Do
}
async failure(): Promise<string | null> {
return this._wrapApiCall('download.failure', async () => {
return (await this._channel.failure()).error || null;
return this._wrapApiCall('download.failure', async (channel: channels.DownloadChannel) => {
return (await channel.failure()).error || null;
});
}
async createReadStream(): Promise<Readable | null> {
return this._wrapApiCall('download.createReadStream', async () => {
const result = await this._channel.stream();
return this._wrapApiCall('download.createReadStream', async (channel: channels.DownloadChannel) => {
const result = await channel.stream();
if (!result.stream)
return null;
const stream = Stream.from(result.stream);
@ -85,8 +87,8 @@ export class Download extends ChannelOwner<channels.DownloadChannel, channels.Do
}
async delete(): Promise<void> {
return this._wrapApiCall('download.delete', async () => {
return this._channel.delete();
return this._wrapApiCall('download.delete', async (channel: channels.DownloadChannel) => {
return channel.delete();
});
}
}

View file

@ -44,13 +44,13 @@ export class Electron extends ChannelOwner<channels.ElectronChannel, channels.El
}
async launch(options: ElectronOptions = {}): Promise<ElectronApplication> {
return this._wrapApiCall('electron.launch', async () => {
return this._wrapApiCall('electron.launch', async (channel: channels.ElectronChannel) => {
const params: channels.ElectronLaunchParams = {
sdkLanguage: 'javascript',
...options,
env: envObjectToArray(options.env ? options.env : process.env),
};
return ElectronApplication.from((await this._channel.launch(params)).electronApplication);
return ElectronApplication.from((await channel.launch(params)).electronApplication);
});
}
}
@ -83,7 +83,7 @@ export class ElectronApplication extends ChannelOwner<channels.ElectronApplicati
}
async firstWindow(): Promise<Page> {
return this._wrapApiCall('electronApplication.firstWindow', async () => {
return this._wrapApiCall('electronApplication.firstWindow', async (channel: channels.ElectronApplicationChannel) => {
if (this._windows.size)
return this._windows.values().next().value;
return this.waitForEvent('window');
@ -111,15 +111,15 @@ export class ElectronApplication extends ChannelOwner<channels.ElectronApplicati
}
async evaluate<R, Arg>(pageFunction: structs.PageFunctionOn<ElectronAppType, Arg, R>, arg: Arg): Promise<R> {
return this._wrapApiCall('electronApplication.evaluate', async () => {
const result = await this._channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return this._wrapApiCall('electronApplication.evaluate', async (channel: channels.ElectronApplicationChannel) => {
const result = await channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return parseResult(result.value);
});
}
async evaluateHandle<R, Arg>(pageFunction: structs.PageFunctionOn<ElectronAppType, Arg, R>, arg: Arg): Promise<structs.SmartHandle<R>> {
return this._wrapApiCall('electronApplication.evaluateHandle', async () => {
const result = await this._channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return this._wrapApiCall('electronApplication.evaluateHandle', async (channel: channels.ElectronApplicationChannel) => {
const result = await channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return JSHandle.from(result.handle) as any as structs.SmartHandle<R>;
});
}

View file

@ -50,183 +50,183 @@ export class ElementHandle<T extends Node = Node> extends JSHandle<T> implements
}
async ownerFrame(): Promise<Frame | null> {
return this._wrapApiCall('elementHandle.ownerFrame', async () => {
return Frame.fromNullable((await this._elementChannel.ownerFrame()).frame);
return this._wrapApiCall('elementHandle.ownerFrame', async (channel: channels.ElementHandleChannel) => {
return Frame.fromNullable((await channel.ownerFrame()).frame);
});
}
async contentFrame(): Promise<Frame | null> {
return this._wrapApiCall('elementHandle.contentFrame', async () => {
return Frame.fromNullable((await this._elementChannel.contentFrame()).frame);
return this._wrapApiCall('elementHandle.contentFrame', async (channel: channels.ElementHandleChannel) => {
return Frame.fromNullable((await channel.contentFrame()).frame);
});
}
async getAttribute(name: string): Promise<string | null> {
return this._wrapApiCall('elementHandle.getAttribute', async () => {
const value = (await this._elementChannel.getAttribute({ name })).value;
return this._wrapApiCall('elementHandle.getAttribute', async (channel: channels.ElementHandleChannel) => {
const value = (await channel.getAttribute({ name })).value;
return value === undefined ? null : value;
});
}
async textContent(): Promise<string | null> {
return this._wrapApiCall('elementHandle.textContent', async () => {
const value = (await this._elementChannel.textContent()).value;
return this._wrapApiCall('elementHandle.textContent', async (channel: channels.ElementHandleChannel) => {
const value = (await channel.textContent()).value;
return value === undefined ? null : value;
});
}
async innerText(): Promise<string> {
return this._wrapApiCall('elementHandle.innerText', async () => {
return (await this._elementChannel.innerText()).value;
return this._wrapApiCall('elementHandle.innerText', async (channel: channels.ElementHandleChannel) => {
return (await channel.innerText()).value;
});
}
async innerHTML(): Promise<string> {
return this._wrapApiCall('elementHandle.innerHTML', async () => {
return (await this._elementChannel.innerHTML()).value;
return this._wrapApiCall('elementHandle.innerHTML', async (channel: channels.ElementHandleChannel) => {
return (await channel.innerHTML()).value;
});
}
async isChecked(): Promise<boolean> {
return this._wrapApiCall('elementHandle.isChecked', async () => {
return (await this._elementChannel.isChecked()).value;
return this._wrapApiCall('elementHandle.isChecked', async (channel: channels.ElementHandleChannel) => {
return (await channel.isChecked()).value;
});
}
async isDisabled(): Promise<boolean> {
return this._wrapApiCall('elementHandle.isDisabled', async () => {
return (await this._elementChannel.isDisabled()).value;
return this._wrapApiCall('elementHandle.isDisabled', async (channel: channels.ElementHandleChannel) => {
return (await channel.isDisabled()).value;
});
}
async isEditable(): Promise<boolean> {
return this._wrapApiCall('elementHandle.isEditable', async () => {
return (await this._elementChannel.isEditable()).value;
return this._wrapApiCall('elementHandle.isEditable', async (channel: channels.ElementHandleChannel) => {
return (await channel.isEditable()).value;
});
}
async isEnabled(): Promise<boolean> {
return this._wrapApiCall('elementHandle.isEnabled', async () => {
return (await this._elementChannel.isEnabled()).value;
return this._wrapApiCall('elementHandle.isEnabled', async (channel: channels.ElementHandleChannel) => {
return (await channel.isEnabled()).value;
});
}
async isHidden(): Promise<boolean> {
return this._wrapApiCall('elementHandle.isHidden', async () => {
return (await this._elementChannel.isHidden()).value;
return this._wrapApiCall('elementHandle.isHidden', async (channel: channels.ElementHandleChannel) => {
return (await channel.isHidden()).value;
});
}
async isVisible(): Promise<boolean> {
return this._wrapApiCall('elementHandle.isVisible', async () => {
return (await this._elementChannel.isVisible()).value;
return this._wrapApiCall('elementHandle.isVisible', async (channel: channels.ElementHandleChannel) => {
return (await channel.isVisible()).value;
});
}
async dispatchEvent(type: string, eventInit: Object = {}) {
return this._wrapApiCall('elementHandle.dispatchEvent', async () => {
await this._elementChannel.dispatchEvent({ type, eventInit: serializeArgument(eventInit) });
return this._wrapApiCall('elementHandle.dispatchEvent', async (channel: channels.ElementHandleChannel) => {
await channel.dispatchEvent({ type, eventInit: serializeArgument(eventInit) });
});
}
async scrollIntoViewIfNeeded(options: channels.ElementHandleScrollIntoViewIfNeededOptions = {}) {
return this._wrapApiCall('elementHandle.scrollIntoViewIfNeeded', async () => {
await this._elementChannel.scrollIntoViewIfNeeded(options);
return this._wrapApiCall('elementHandle.scrollIntoViewIfNeeded', async (channel: channels.ElementHandleChannel) => {
await channel.scrollIntoViewIfNeeded(options);
});
}
async hover(options: channels.ElementHandleHoverOptions = {}): Promise<void> {
return this._wrapApiCall('elementHandle.hover', async () => {
await this._elementChannel.hover(options);
return this._wrapApiCall('elementHandle.hover', async (channel: channels.ElementHandleChannel) => {
await channel.hover(options);
});
}
async click(options: channels.ElementHandleClickOptions = {}): Promise<void> {
return this._wrapApiCall('elementHandle.click', async () => {
return await this._elementChannel.click(options);
return this._wrapApiCall('elementHandle.click', async (channel: channels.ElementHandleChannel) => {
return await channel.click(options);
});
}
async dblclick(options: channels.ElementHandleDblclickOptions = {}): Promise<void> {
return this._wrapApiCall('elementHandle.dblclick', async () => {
return await this._elementChannel.dblclick(options);
return this._wrapApiCall('elementHandle.dblclick', async (channel: channels.ElementHandleChannel) => {
return await channel.dblclick(options);
});
}
async tap(options: channels.ElementHandleTapOptions = {}): Promise<void> {
return this._wrapApiCall('elementHandle.tap', async () => {
return await this._elementChannel.tap(options);
return this._wrapApiCall('elementHandle.tap', async (channel: channels.ElementHandleChannel) => {
return await channel.tap(options);
});
}
async selectOption(values: string | api.ElementHandle | SelectOption | string[] | api.ElementHandle[] | SelectOption[] | null, options: SelectOptionOptions = {}): Promise<string[]> {
return this._wrapApiCall('elementHandle.selectOption', async () => {
const result = await this._elementChannel.selectOption({ ...convertSelectOptionValues(values), ...options });
return this._wrapApiCall('elementHandle.selectOption', async (channel: channels.ElementHandleChannel) => {
const result = await channel.selectOption({ ...convertSelectOptionValues(values), ...options });
return result.values;
});
}
async fill(value: string, options: channels.ElementHandleFillOptions = {}): Promise<void> {
return this._wrapApiCall('elementHandle.fill', async () => {
return await this._elementChannel.fill({ value, ...options });
return this._wrapApiCall('elementHandle.fill', async (channel: channels.ElementHandleChannel) => {
return await channel.fill({ value, ...options });
});
}
async selectText(options: channels.ElementHandleSelectTextOptions = {}): Promise<void> {
return this._wrapApiCall('elementHandle.selectText', async () => {
await this._elementChannel.selectText(options);
return this._wrapApiCall('elementHandle.selectText', async (channel: channels.ElementHandleChannel) => {
await channel.selectText(options);
});
}
async setInputFiles(files: string | FilePayload | string[] | FilePayload[], options: channels.ElementHandleSetInputFilesOptions = {}) {
return this._wrapApiCall('elementHandle.setInputFiles', async () => {
await this._elementChannel.setInputFiles({ files: await convertInputFiles(files), ...options });
return this._wrapApiCall('elementHandle.setInputFiles', async (channel: channels.ElementHandleChannel) => {
await channel.setInputFiles({ files: await convertInputFiles(files), ...options });
});
}
async focus(): Promise<void> {
return this._wrapApiCall('elementHandle.focus', async () => {
await this._elementChannel.focus();
return this._wrapApiCall('elementHandle.focus', async (channel: channels.ElementHandleChannel) => {
await channel.focus();
});
}
async type(text: string, options: channels.ElementHandleTypeOptions = {}): Promise<void> {
return this._wrapApiCall('elementHandle.type', async () => {
await this._elementChannel.type({ text, ...options });
return this._wrapApiCall('elementHandle.type', async (channel: channels.ElementHandleChannel) => {
await channel.type({ text, ...options });
});
}
async press(key: string, options: channels.ElementHandlePressOptions = {}): Promise<void> {
return this._wrapApiCall('elementHandle.press', async () => {
await this._elementChannel.press({ key, ...options });
return this._wrapApiCall('elementHandle.press', async (channel: channels.ElementHandleChannel) => {
await channel.press({ key, ...options });
});
}
async check(options: channels.ElementHandleCheckOptions = {}) {
return this._wrapApiCall('elementHandle.check', async () => {
return await this._elementChannel.check(options);
return this._wrapApiCall('elementHandle.check', async (channel: channels.ElementHandleChannel) => {
return await channel.check(options);
});
}
async uncheck(options: channels.ElementHandleUncheckOptions = {}) {
return this._wrapApiCall('elementHandle.uncheck', async () => {
return await this._elementChannel.uncheck(options);
return this._wrapApiCall('elementHandle.uncheck', async (channel: channels.ElementHandleChannel) => {
return await channel.uncheck(options);
});
}
async boundingBox(): Promise<Rect | null> {
return this._wrapApiCall('elementHandle.boundingBox', async () => {
const value = (await this._elementChannel.boundingBox()).value;
return this._wrapApiCall('elementHandle.boundingBox', async (channel: channels.ElementHandleChannel) => {
const value = (await channel.boundingBox()).value;
return value === undefined ? null : value;
});
}
async screenshot(options: channels.ElementHandleScreenshotOptions & { path?: string } = {}): Promise<Buffer> {
return this._wrapApiCall('elementHandle.screenshot', async () => {
return this._wrapApiCall('elementHandle.screenshot', async (channel: channels.ElementHandleChannel) => {
const copy = { ...options };
if (!copy.type)
copy.type = determineScreenshotType(options);
const result = await this._elementChannel.screenshot(copy);
const result = await channel.screenshot(copy);
const buffer = Buffer.from(result.binary, 'base64');
if (options.path) {
await mkdirIfNeeded(options.path);
@ -237,43 +237,43 @@ export class ElementHandle<T extends Node = Node> extends JSHandle<T> implements
}
async $(selector: string): Promise<ElementHandle<SVGElement | HTMLElement> | null> {
return this._wrapApiCall('elementHandle.$', async () => {
return ElementHandle.fromNullable((await this._elementChannel.querySelector({ selector })).element) as ElementHandle<SVGElement | HTMLElement> | null;
return this._wrapApiCall('elementHandle.$', async (channel: channels.ElementHandleChannel) => {
return ElementHandle.fromNullable((await channel.querySelector({ selector })).element) as ElementHandle<SVGElement | HTMLElement> | null;
});
}
async $$(selector: string): Promise<ElementHandle<SVGElement | HTMLElement>[]> {
return this._wrapApiCall('elementHandle.$$', async () => {
const result = await this._elementChannel.querySelectorAll({ selector });
return this._wrapApiCall('elementHandle.$$', async (channel: channels.ElementHandleChannel) => {
const result = await channel.querySelectorAll({ selector });
return result.elements.map(h => ElementHandle.from(h) as ElementHandle<SVGElement | HTMLElement>);
});
}
async $eval<R, Arg>(selector: string, pageFunction: structs.PageFunctionOn<Element, Arg, R>, arg?: Arg): Promise<R> {
return this._wrapApiCall('elementHandle.$eval', async () => {
const result = await this._elementChannel.evalOnSelector({ selector, expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return this._wrapApiCall('elementHandle.$eval', async (channel: channels.ElementHandleChannel) => {
const result = await channel.evalOnSelector({ selector, expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return parseResult(result.value);
});
}
async $$eval<R, Arg>(selector: string, pageFunction: structs.PageFunctionOn<Element[], Arg, R>, arg?: Arg): Promise<R> {
return this._wrapApiCall('elementHandle.$$eval', async () => {
const result = await this._elementChannel.evalOnSelectorAll({ selector, expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return this._wrapApiCall('elementHandle.$$eval', async (channel: channels.ElementHandleChannel) => {
const result = await channel.evalOnSelectorAll({ selector, expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return parseResult(result.value);
});
}
async waitForElementState(state: 'visible' | 'hidden' | 'stable' | 'enabled' | 'disabled', options: channels.ElementHandleWaitForElementStateOptions = {}): Promise<void> {
return this._wrapApiCall('elementHandle.waitForElementState', async () => {
return await this._elementChannel.waitForElementState({ state, ...options });
return this._wrapApiCall('elementHandle.waitForElementState', async (channel: channels.ElementHandleChannel) => {
return await channel.waitForElementState({ state, ...options });
});
}
waitForSelector(selector: string, options: channels.ElementHandleWaitForSelectorOptions & { state: 'attached' | 'visible' }): Promise<ElementHandle<SVGElement | HTMLElement>>;
waitForSelector(selector: string, options?: channels.ElementHandleWaitForSelectorOptions): Promise<ElementHandle<SVGElement | HTMLElement> | null>;
async waitForSelector(selector: string, options: channels.ElementHandleWaitForSelectorOptions = {}): Promise<ElementHandle<SVGElement | HTMLElement> | null> {
return this._wrapApiCall('elementHandle.waitForSelector', async () => {
const result = await this._elementChannel.waitForSelector({ selector, ...options });
return this._wrapApiCall('elementHandle.waitForSelector', async (channel: channels.ElementHandleChannel) => {
const result = await channel.waitForSelector({ selector, ...options });
return ElementHandle.fromNullable(result.element) as ElementHandle<SVGElement | HTMLElement> | null;
});
}

View file

@ -94,9 +94,9 @@ export class Frame extends ChannelOwner<channels.FrameChannel, channels.FrameIni
}
async goto(url: string, options: channels.FrameGotoOptions = {}): Promise<network.Response | null> {
return this._wrapApiCall(this._apiName('goto'), async () => {
return this._wrapApiCall(this._apiName('goto'), async (channel: channels.FrameChannel) => {
const waitUntil = verifyLoadState('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);
return network.Response.fromNullable((await this._channel.goto({ url, ...options, waitUntil })).response);
return network.Response.fromNullable((await channel.goto({ url, ...options, waitUntil })).response);
});
}
@ -111,7 +111,7 @@ export class Frame extends ChannelOwner<channels.FrameChannel, channels.FrameIni
}
async waitForNavigation(options: WaitForNavigationOptions = {}): Promise<network.Response | null> {
return this._wrapApiCall(this._apiName('waitForNavigation'), async () => {
return this._wrapApiCall(this._apiName('waitForNavigation'), async (channel: channels.FrameChannel) => {
const waitUntil = verifyLoadState('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);
const waiter = this._setupNavigationWaiter('waitForNavigation', options);
@ -149,7 +149,7 @@ export class Frame extends ChannelOwner<channels.FrameChannel, channels.FrameIni
state = verifyLoadState('state', state);
if (this._loadStates.has(state))
return;
return this._wrapApiCall(this._apiName('waitForLoadState'), async () => {
return this._wrapApiCall(this._apiName('waitForLoadState'), async (channel: channels.FrameChannel) => {
const waiter = this._setupNavigationWaiter('waitForLoadState', options);
await waiter.waitForEvent<LifecycleEvent>(this._eventEmitter, 'loadstate', s => {
waiter.log(` "${s}" event fired`);
@ -160,15 +160,15 @@ export class Frame extends ChannelOwner<channels.FrameChannel, channels.FrameIni
}
async frameElement(): Promise<ElementHandle> {
return this._wrapApiCall(this._apiName('frameElement'), async () => {
return ElementHandle.from((await this._channel.frameElement()).element);
return this._wrapApiCall(this._apiName('frameElement'), async (channel: channels.FrameChannel) => {
return ElementHandle.from((await channel.frameElement()).element);
});
}
async evaluateHandle<R, Arg>(pageFunction: structs.PageFunction<Arg, R>, arg?: Arg): Promise<structs.SmartHandle<R>> {
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 this._wrapApiCall(this._apiName('evaluateHandle'), async (channel: channels.FrameChannel) => {
const result = await channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return JSHandle.from(result.handle) as any as structs.SmartHandle<R>;
});
}
@ -177,16 +177,16 @@ export class Frame extends ChannelOwner<channels.FrameChannel, channels.FrameIni
async _evaluateHandleInUtility<R>(pageFunction: structs.PageFunction<void, R>, arg?: any): Promise<structs.SmartHandle<R>>;
async _evaluateHandleInUtility<R, Arg>(pageFunction: structs.PageFunction<Arg, R>, arg?: Arg): Promise<structs.SmartHandle<R>> {
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 this._wrapApiCall(this._apiName('_evaluateHandleInUtility'), async (channel: channels.FrameChannel) => {
const result = await channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg), world: 'utility' });
return JSHandle.from(result.handle) as any as structs.SmartHandle<R>;
});
}
async evaluate<R, Arg>(pageFunction: structs.PageFunction<Arg, R>, arg?: Arg): Promise<R> {
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) });
return this._wrapApiCall(this._apiName('evaluate'), async (channel: channels.FrameChannel) => {
const result = await channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return parseResult(result.value);
});
}
@ -195,15 +195,15 @@ export class Frame extends ChannelOwner<channels.FrameChannel, channels.FrameIni
async _evaluateInUtility<R>(pageFunction: structs.PageFunction<void, R>, arg?: any): Promise<R>;
async _evaluateInUtility<R, Arg>(pageFunction: structs.PageFunction<Arg, R>, arg?: Arg): Promise<R> {
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' });
return this._wrapApiCall(this._apiName('evaluate'), async (channel: channels.FrameChannel) => {
const result = await channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg), world: 'utility' });
return parseResult(result.value);
});
}
async $(selector: string): Promise<ElementHandle<SVGElement | HTMLElement> | null> {
return this._wrapApiCall(this._apiName('$'), async () => {
const result = await this._channel.querySelector({ selector });
return this._wrapApiCall(this._apiName('$'), async (channel: channels.FrameChannel) => {
const result = await channel.querySelector({ selector });
return ElementHandle.fromNullable(result.element) as ElementHandle<SVGElement | HTMLElement> | null;
});
}
@ -211,55 +211,55 @@ export class Frame extends ChannelOwner<channels.FrameChannel, channels.FrameIni
waitForSelector(selector: string, options: channels.FrameWaitForSelectorOptions & { state: 'attached' | 'visible' }): Promise<ElementHandle<SVGElement | HTMLElement>>;
waitForSelector(selector: string, options?: channels.FrameWaitForSelectorOptions): Promise<ElementHandle<SVGElement | HTMLElement> | null>;
async waitForSelector(selector: string, options: channels.FrameWaitForSelectorOptions = {}): Promise<ElementHandle<SVGElement | HTMLElement> | null> {
return this._wrapApiCall(this._apiName('waitForSelector'), async () => {
return this._wrapApiCall(this._apiName('waitForSelector'), async (channel: channels.FrameChannel) => {
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 });
const result = await channel.waitForSelector({ selector, ...options });
return ElementHandle.fromNullable(result.element) as ElementHandle<SVGElement | HTMLElement> | null;
});
}
async dispatchEvent(selector: string, type: string, eventInit?: any, options: channels.FrameDispatchEventOptions = {}): Promise<void> {
return this._wrapApiCall(this._apiName('dispatchEvent'), async () => {
await this._channel.dispatchEvent({ selector, type, eventInit: serializeArgument(eventInit), ...options });
return this._wrapApiCall(this._apiName('dispatchEvent'), async (channel: channels.FrameChannel) => {
await channel.dispatchEvent({ selector, type, eventInit: serializeArgument(eventInit), ...options });
});
}
async $eval<R, Arg>(selector: string, pageFunction: structs.PageFunctionOn<Element, Arg, R>, arg?: Arg): Promise<R> {
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) });
return this._wrapApiCall(this._apiName('$eval'), async (channel: channels.FrameChannel) => {
const result = await channel.evalOnSelector({ selector, expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return parseResult(result.value);
});
}
async $$eval<R, Arg>(selector: string, pageFunction: structs.PageFunctionOn<Element[], Arg, R>, arg?: Arg): Promise<R> {
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) });
return this._wrapApiCall(this._apiName('$$eval'), async (channel: channels.FrameChannel) => {
const result = await channel.evalOnSelectorAll({ selector, expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return parseResult(result.value);
});
}
async $$(selector: string): Promise<ElementHandle<SVGElement | HTMLElement>[]> {
return this._wrapApiCall(this._apiName('$$'), async () => {
const result = await this._channel.querySelectorAll({ selector });
return this._wrapApiCall(this._apiName('$$'), async (channel: channels.FrameChannel) => {
const result = await channel.querySelectorAll({ selector });
return result.elements.map(e => ElementHandle.from(e) as ElementHandle<SVGElement | HTMLElement>);
});
}
async content(): Promise<string> {
return this._wrapApiCall(this._apiName('content'), async () => {
return (await this._channel.content()).value;
return this._wrapApiCall(this._apiName('content'), async (channel: channels.FrameChannel) => {
return (await channel.content()).value;
});
}
async setContent(html: string, options: channels.FrameSetContentOptions = {}): Promise<void> {
return this._wrapApiCall(this._apiName('setContent'), async () => {
return this._wrapApiCall(this._apiName('setContent'), async (channel: channels.FrameChannel) => {
const waitUntil = verifyLoadState('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);
await this._channel.setContent({ html, ...options, waitUntil });
await channel.setContent({ html, ...options, waitUntil });
});
}
@ -284,172 +284,172 @@ export class Frame extends ChannelOwner<channels.FrameChannel, channels.FrameIni
}
async addScriptTag(options: { url?: string, path?: string, content?: string, type?: string } = {}): Promise<ElementHandle> {
return this._wrapApiCall(this._apiName('addScriptTag'), async () => {
return this._wrapApiCall(this._apiName('addScriptTag'), async (channel: channels.FrameChannel) => {
const copy = { ...options };
if (copy.path) {
copy.content = (await fsReadFileAsync(copy.path)).toString();
copy.content += '//# sourceURL=' + copy.path.replace(/\n/g, '');
}
return ElementHandle.from((await this._channel.addScriptTag({ ...copy })).element);
return ElementHandle.from((await channel.addScriptTag({ ...copy })).element);
});
}
async addStyleTag(options: { url?: string; path?: string; content?: string; } = {}): Promise<ElementHandle> {
return this._wrapApiCall(this._apiName('addStyleTag'), async () => {
return this._wrapApiCall(this._apiName('addStyleTag'), async (channel: channels.FrameChannel) => {
const copy = { ...options };
if (copy.path) {
copy.content = (await fsReadFileAsync(copy.path)).toString();
copy.content += '/*# sourceURL=' + copy.path.replace(/\n/g, '') + '*/';
}
return ElementHandle.from((await this._channel.addStyleTag({ ...copy })).element);
return ElementHandle.from((await channel.addStyleTag({ ...copy })).element);
});
}
async click(selector: string, options: channels.FrameClickOptions = {}) {
return this._wrapApiCall(this._apiName('click'), async () => {
return await this._channel.click({ selector, ...options });
return this._wrapApiCall(this._apiName('click'), async (channel: channels.FrameChannel) => {
return await channel.click({ selector, ...options });
});
}
async dblclick(selector: string, options: channels.FrameDblclickOptions = {}) {
return this._wrapApiCall(this._apiName('dblclick'), async () => {
return await this._channel.dblclick({ selector, ...options });
return this._wrapApiCall(this._apiName('dblclick'), async (channel: channels.FrameChannel) => {
return await channel.dblclick({ selector, ...options });
});
}
async tap(selector: string, options: channels.FrameTapOptions = {}) {
return this._wrapApiCall(this._apiName('tap'), async () => {
return await this._channel.tap({ selector, ...options });
return this._wrapApiCall(this._apiName('tap'), async (channel: channels.FrameChannel) => {
return await channel.tap({ selector, ...options });
});
}
async fill(selector: string, value: string, options: channels.FrameFillOptions = {}) {
return this._wrapApiCall(this._apiName('fill'), async () => {
return await this._channel.fill({ selector, value, ...options });
return this._wrapApiCall(this._apiName('fill'), async (channel: channels.FrameChannel) => {
return await channel.fill({ selector, value, ...options });
});
}
async focus(selector: string, options: channels.FrameFocusOptions = {}) {
return this._wrapApiCall(this._apiName('focus'), async () => {
await this._channel.focus({ selector, ...options });
return this._wrapApiCall(this._apiName('focus'), async (channel: channels.FrameChannel) => {
await channel.focus({ selector, ...options });
});
}
async textContent(selector: string, options: channels.FrameTextContentOptions = {}): Promise<null|string> {
return this._wrapApiCall(this._apiName('textContent'), async () => {
const value = (await this._channel.textContent({ selector, ...options })).value;
return this._wrapApiCall(this._apiName('textContent'), async (channel: channels.FrameChannel) => {
const value = (await channel.textContent({ selector, ...options })).value;
return value === undefined ? null : value;
});
}
async innerText(selector: string, options: channels.FrameInnerTextOptions = {}): Promise<string> {
return this._wrapApiCall(this._apiName('innerText'), async () => {
return (await this._channel.innerText({ selector, ...options })).value;
return this._wrapApiCall(this._apiName('innerText'), async (channel: channels.FrameChannel) => {
return (await channel.innerText({ selector, ...options })).value;
});
}
async innerHTML(selector: string, options: channels.FrameInnerHTMLOptions = {}): Promise<string> {
return this._wrapApiCall(this._apiName('innerHTML'), async () => {
return (await this._channel.innerHTML({ selector, ...options })).value;
return this._wrapApiCall(this._apiName('innerHTML'), async (channel: channels.FrameChannel) => {
return (await channel.innerHTML({ selector, ...options })).value;
});
}
async getAttribute(selector: string, name: string, options: channels.FrameGetAttributeOptions = {}): Promise<string | null> {
return this._wrapApiCall(this._apiName('getAttribute'), async () => {
const value = (await this._channel.getAttribute({ selector, name, ...options })).value;
return this._wrapApiCall(this._apiName('getAttribute'), async (channel: channels.FrameChannel) => {
const value = (await channel.getAttribute({ selector, name, ...options })).value;
return value === undefined ? null : value;
});
}
async isChecked(selector: string, options: channels.FrameIsCheckedOptions = {}): Promise<boolean> {
return this._wrapApiCall(this._apiName('isChecked'), async () => {
return (await this._channel.isChecked({ selector, ...options })).value;
return this._wrapApiCall(this._apiName('isChecked'), async (channel: channels.FrameChannel) => {
return (await channel.isChecked({ selector, ...options })).value;
});
}
async isDisabled(selector: string, options: channels.FrameIsDisabledOptions = {}): Promise<boolean> {
return this._wrapApiCall(this._apiName('isDisabled'), async () => {
return (await this._channel.isDisabled({ selector, ...options })).value;
return this._wrapApiCall(this._apiName('isDisabled'), async (channel: channels.FrameChannel) => {
return (await channel.isDisabled({ selector, ...options })).value;
});
}
async isEditable(selector: string, options: channels.FrameIsEditableOptions = {}): Promise<boolean> {
return this._wrapApiCall(this._apiName('isEditable'), async () => {
return (await this._channel.isEditable({ selector, ...options })).value;
return this._wrapApiCall(this._apiName('isEditable'), async (channel: channels.FrameChannel) => {
return (await channel.isEditable({ selector, ...options })).value;
});
}
async isEnabled(selector: string, options: channels.FrameIsEnabledOptions = {}): Promise<boolean> {
return this._wrapApiCall(this._apiName('isEnabled'), async () => {
return (await this._channel.isEnabled({ selector, ...options })).value;
return this._wrapApiCall(this._apiName('isEnabled'), async (channel: channels.FrameChannel) => {
return (await channel.isEnabled({ selector, ...options })).value;
});
}
async isHidden(selector: string, options: channels.FrameIsHiddenOptions = {}): Promise<boolean> {
return this._wrapApiCall(this._apiName('isHidden'), async () => {
return (await this._channel.isHidden({ selector, ...options })).value;
return this._wrapApiCall(this._apiName('isHidden'), async (channel: channels.FrameChannel) => {
return (await channel.isHidden({ selector, ...options })).value;
});
}
async isVisible(selector: string, options: channels.FrameIsVisibleOptions = {}): Promise<boolean> {
return this._wrapApiCall(this._apiName('isVisible'), async () => {
return (await this._channel.isVisible({ selector, ...options })).value;
return this._wrapApiCall(this._apiName('isVisible'), async (channel: channels.FrameChannel) => {
return (await channel.isVisible({ selector, ...options })).value;
});
}
async hover(selector: string, options: channels.FrameHoverOptions = {}) {
return this._wrapApiCall(this._apiName('hover'), async () => {
await this._channel.hover({ selector, ...options });
return this._wrapApiCall(this._apiName('hover'), async (channel: channels.FrameChannel) => {
await channel.hover({ selector, ...options });
});
}
async selectOption(selector: string, values: string | api.ElementHandle | SelectOption | string[] | api.ElementHandle[] | SelectOption[] | null, options: SelectOptionOptions = {}): Promise<string[]> {
return this._wrapApiCall(this._apiName('selectOption'), async () => {
return (await this._channel.selectOption({ selector, ...convertSelectOptionValues(values), ...options })).values;
return this._wrapApiCall(this._apiName('selectOption'), async (channel: channels.FrameChannel) => {
return (await channel.selectOption({ selector, ...convertSelectOptionValues(values), ...options })).values;
});
}
async setInputFiles(selector: string, files: string | FilePayload | string[] | FilePayload[], options: channels.FrameSetInputFilesOptions = {}): Promise<void> {
return this._wrapApiCall(this._apiName('setInputFiles'), async () => {
await this._channel.setInputFiles({ selector, files: await convertInputFiles(files), ...options });
return this._wrapApiCall(this._apiName('setInputFiles'), async (channel: channels.FrameChannel) => {
await channel.setInputFiles({ selector, files: await convertInputFiles(files), ...options });
});
}
async type(selector: string, text: string, options: channels.FrameTypeOptions = {}) {
return this._wrapApiCall(this._apiName('type'), async () => {
await this._channel.type({ selector, text, ...options });
return this._wrapApiCall(this._apiName('type'), async (channel: channels.FrameChannel) => {
await channel.type({ selector, text, ...options });
});
}
async press(selector: string, key: string, options: channels.FramePressOptions = {}) {
return this._wrapApiCall(this._apiName('press'), async () => {
await this._channel.press({ selector, key, ...options });
return this._wrapApiCall(this._apiName('press'), async (channel: channels.FrameChannel) => {
await channel.press({ selector, key, ...options });
});
}
async check(selector: string, options: channels.FrameCheckOptions = {}) {
return this._wrapApiCall(this._apiName('check'), async () => {
await this._channel.check({ selector, ...options });
return this._wrapApiCall(this._apiName('check'), async (channel: channels.FrameChannel) => {
await channel.check({ selector, ...options });
});
}
async uncheck(selector: string, options: channels.FrameUncheckOptions = {}) {
return this._wrapApiCall(this._apiName('uncheck'), async () => {
await this._channel.uncheck({ selector, ...options });
return this._wrapApiCall(this._apiName('uncheck'), async (channel: channels.FrameChannel) => {
await channel.uncheck({ selector, ...options });
});
}
async waitForTimeout(timeout: number) {
return this._wrapApiCall(this._apiName('waitForTimeout'), async () => {
return this._wrapApiCall(this._apiName('waitForTimeout'), async (channel: channels.FrameChannel) => {
await new Promise(fulfill => setTimeout(fulfill, timeout));
});
}
async waitForFunction<R, Arg>(pageFunction: structs.PageFunction<Arg, R>, arg?: Arg, options: WaitForFunctionOptions = {}): Promise<structs.SmartHandle<R>> {
return this._wrapApiCall(this._apiName('waitForFunction'), async () => {
return this._wrapApiCall(this._apiName('waitForFunction'), async (channel: channels.FrameChannel) => {
if (typeof options.polling === 'string')
assert(options.polling === 'raf', 'Unknown polling option: ' + options.polling);
const result = await this._channel.waitForFunction({
const result = await channel.waitForFunction({
...options,
pollingInterval: options.polling === 'raf' ? undefined : options.polling,
expression: String(pageFunction),
@ -461,8 +461,8 @@ export class Frame extends ChannelOwner<channels.FrameChannel, channels.FrameIni
}
async title(): Promise<string> {
return this._wrapApiCall(this._apiName('title'), async () => {
return (await this._channel.title()).value;
return this._wrapApiCall(this._apiName('title'), async (channel: channels.FrameChannel) => {
return (await channel.title()).value;
});
}
}

View file

@ -34,38 +34,38 @@ export class JSHandle<T = any> extends ChannelOwner<channels.JSHandleChannel, ch
}
async evaluate<R, Arg>(pageFunction: structs.PageFunctionOn<T, Arg, R>, arg?: Arg): Promise<R> {
return this._wrapApiCall('jsHandle.evaluate', async () => {
const result = await this._channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return this._wrapApiCall('jsHandle.evaluate', async (channel: channels.JSHandleChannel) => {
const result = await channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return parseResult(result.value);
});
}
async evaluateHandle<R, Arg>(pageFunction: structs.PageFunctionOn<T, Arg, R>, arg?: Arg): Promise<structs.SmartHandle<R>> {
return this._wrapApiCall('jsHandle.evaluateHandle', async () => {
const result = await this._channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return this._wrapApiCall('jsHandle.evaluateHandle', async (channel: channels.JSHandleChannel) => {
const result = await channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return JSHandle.from(result.handle) as any as structs.SmartHandle<R>;
});
}
async getProperty(propertyName: string): Promise<JSHandle> {
return this._wrapApiCall('jsHandle.getProperty', async () => {
const result = await this._channel.getProperty({ name: propertyName });
return this._wrapApiCall('jsHandle.getProperty', async (channel: channels.JSHandleChannel) => {
const result = await channel.getProperty({ name: propertyName });
return JSHandle.from(result.handle);
});
}
async getProperties(): Promise<Map<string, JSHandle>> {
return this._wrapApiCall('jsHandle.getProperties', async () => {
return this._wrapApiCall('jsHandle.getProperties', async (channel: channels.JSHandleChannel) => {
const map = new Map<string, JSHandle>();
for (const { name, value } of (await this._channel.getPropertyList()).properties)
for (const { name, value } of (await channel.getPropertyList()).properties)
map.set(name, JSHandle.from(value));
return map;
});
}
async jsonValue(): Promise<T> {
return this._wrapApiCall('jsHandle.jsonValue', async () => {
return parseResult((await this._channel.jsonValue()).value);
return this._wrapApiCall('jsHandle.jsonValue', async (channel: channels.JSHandleChannel) => {
return parseResult((await channel.jsonValue()).value);
});
}
@ -74,7 +74,9 @@ export class JSHandle<T = any> extends ChannelOwner<channels.JSHandleChannel, ch
}
async dispose() {
return await this._channel.dispose();
return this._wrapApiCall('jsHandle.dispose', async (channel: channels.JSHandleChannel) => {
return await channel.dispose();
});
}
toString(): string {

View file

@ -132,8 +132,8 @@ export class Request extends ChannelOwner<channels.RequestChannel, channels.Requ
}
async response(): Promise<Response | null> {
return this._wrapApiCall('request.response', async () => {
return Response.fromNullable((await this._channel.response()).response);
return this._wrapApiCall('request.response', async (channel: channels.RequestChannel) => {
return Response.fromNullable((await channel.response()).response);
});
}
@ -184,13 +184,13 @@ export class Route extends ChannelOwner<channels.RouteChannel, channels.RouteIni
}
async abort(errorCode?: string) {
return this._wrapApiCall('route.abort', async () => {
await this._channel.abort({ errorCode });
return this._wrapApiCall('route.abort', async (channel: channels.RouteChannel) => {
await channel.abort({ errorCode });
});
}
async fulfill(options: { status?: number, headers?: Headers, contentType?: string, body?: string | Buffer, path?: string } = {}) {
return this._wrapApiCall('route.fulfill', async () => {
return this._wrapApiCall('route.fulfill', async (channel: channels.RouteChannel) => {
let body = '';
let isBase64 = false;
let length = 0;
@ -219,7 +219,7 @@ export class Route extends ChannelOwner<channels.RouteChannel, channels.RouteIni
if (length && !('content-length' in headers))
headers['content-length'] = String(length);
await this._channel.fulfill({
await channel.fulfill({
status: options.status || 200,
headers: headersObjectToArray(headers),
body,
@ -229,9 +229,9 @@ export class Route extends ChannelOwner<channels.RouteChannel, channels.RouteIni
}
async continue(options: { url?: string, method?: string, headers?: Headers, postData?: string | Buffer } = {}) {
return this._wrapApiCall('route.continue', async () => {
return this._wrapApiCall('route.continue', async (channel: channels.RouteChannel) => {
const postDataBuffer = isString(options.postData) ? Buffer.from(options.postData, 'utf8') : options.postData;
await this._channel.continue({
await channel.continue({
url: options.url,
method: options.method,
headers: options.headers ? headersObjectToArray(options.headers) : undefined,
@ -303,8 +303,8 @@ export class Response extends ChannelOwner<channels.ResponseChannel, channels.Re
}
async body(): Promise<Buffer> {
return this._wrapApiCall('response.body', async () => {
return Buffer.from((await this._channel.body()).binary, 'base64');
return this._wrapApiCall('response.body', async (channel: channels.ResponseChannel) => {
return Buffer.from((await channel.body()).binary, 'base64');
});
}

View file

@ -213,7 +213,9 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
}
async opener(): Promise<Page | null> {
return Page.fromNullable((await this._channel.opener()).page);
return this._wrapApiCall('page.opener', async (channel: channels.PageChannel) => {
return Page.fromNullable((await channel.opener()).page);
});
}
mainFrame(): Frame {
@ -308,24 +310,24 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
}
async exposeFunction(name: string, callback: Function) {
return this._wrapApiCall('page.exposeFunction', async () => {
await this._channel.exposeBinding({ name });
return this._wrapApiCall('page.exposeFunction', async (channel: channels.PageChannel) => {
await channel.exposeBinding({ name });
const binding = (source: structs.BindingSource, ...args: any[]) => callback(...args);
this._bindings.set(name, binding);
});
}
async exposeBinding(name: string, callback: (source: structs.BindingSource, ...args: any[]) => any, options: { handle?: boolean } = {}) {
return this._wrapApiCall('page.exposeBinding', async () => {
await this._channel.exposeBinding({ name, needsHandle: options.handle });
return this._wrapApiCall('page.exposeBinding', async (channel: channels.PageChannel) => {
await channel.exposeBinding({ name, needsHandle: options.handle });
this._bindings.set(name, callback);
});
}
async setExtraHTTPHeaders(headers: Headers) {
return this._wrapApiCall('page.setExtraHTTPHeaders', async () => {
return this._wrapApiCall('page.setExtraHTTPHeaders', async (channel: channels.PageChannel) => {
validateHeaders(headers);
await this._channel.setExtraHTTPHeaders({ headers: headersObjectToArray(headers) });
await channel.setExtraHTTPHeaders({ headers: headersObjectToArray(headers) });
});
}
@ -346,9 +348,9 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
}
async reload(options: channels.PageReloadOptions = {}): Promise<Response | null> {
return this._wrapApiCall('page.reload', async () => {
return this._wrapApiCall('page.reload', async (channel: channels.PageChannel) => {
const waitUntil = verifyLoadState('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);
return Response.fromNullable((await this._channel.reload({ ...options, waitUntil })).response);
return Response.fromNullable((await channel.reload({ ...options, waitUntil })).response);
});
}
@ -361,7 +363,7 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
}
async waitForRequest(urlOrPredicate: string | RegExp | ((r: Request) => boolean), options: { timeout?: number } = {}): Promise<Request> {
return this._wrapApiCall('page.waitForRequest', async () => {
return this._wrapApiCall('page.waitForRequest', async (channel: channels.PageChannel) => {
const predicate = (request: Request) => {
if (isString(urlOrPredicate) || isRegExp(urlOrPredicate))
return urlMatches(request.url(), urlOrPredicate);
@ -374,7 +376,7 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
}
async waitForResponse(urlOrPredicate: string | RegExp | ((r: Response) => boolean), options: { timeout?: number } = {}): Promise<Response> {
return this._wrapApiCall('page.waitForResponse', async () => {
return this._wrapApiCall('page.waitForResponse', async (channel: channels.PageChannel) => {
const predicate = (response: Response) => {
if (isString(urlOrPredicate) || isRegExp(urlOrPredicate))
return urlMatches(response.url(), urlOrPredicate);
@ -387,7 +389,7 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
}
async waitForEvent(event: string, optionsOrPredicate: WaitForEventOptions = {}): Promise<any> {
return this._wrapApiCall('page.waitForEvent', async () => {
return this._wrapApiCall('page.waitForEvent', async (channel: channels.PageChannel) => {
return this._waitForEvent(event, optionsOrPredicate, `waiting for event "${event}"`);
});
}
@ -409,22 +411,22 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
}
async goBack(options: channels.PageGoBackOptions = {}): Promise<Response | null> {
return this._wrapApiCall('page.goBack', async () => {
return this._wrapApiCall('page.goBack', async (channel: channels.PageChannel) => {
const waitUntil = verifyLoadState('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);
return Response.fromNullable((await this._channel.goBack({ ...options, waitUntil })).response);
return Response.fromNullable((await channel.goBack({ ...options, waitUntil })).response);
});
}
async goForward(options: channels.PageGoForwardOptions = {}): Promise<Response | null> {
return this._wrapApiCall('page.goForward', async () => {
return this._wrapApiCall('page.goForward', async (channel: channels.PageChannel) => {
const waitUntil = verifyLoadState('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);
return Response.fromNullable((await this._channel.goForward({ ...options, waitUntil })).response);
return Response.fromNullable((await channel.goForward({ ...options, waitUntil })).response);
});
}
async emulateMedia(options: { media?: 'screen' | 'print' | null, colorScheme?: 'dark' | 'light' | 'no-preference' | null } = {}) {
return this._wrapApiCall('page.emulateMedia', async () => {
await this._channel.emulateMedia({
return this._wrapApiCall('page.emulateMedia', async (channel: channels.PageChannel) => {
await channel.emulateMedia({
media: options.media === null ? 'null' : options.media,
colorScheme: options.colorScheme === null ? 'null' : options.colorScheme,
});
@ -432,9 +434,9 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
}
async setViewportSize(viewportSize: Size) {
return this._wrapApiCall('page.setViewportSize', async () => {
return this._wrapApiCall('page.setViewportSize', async (channel: channels.PageChannel) => {
this._viewportSize = viewportSize;
await this._channel.setViewportSize({ viewportSize });
await channel.setViewportSize({ viewportSize });
});
}
@ -448,34 +450,34 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
}
async addInitScript(script: Function | string | { path?: string, content?: string }, arg?: any) {
return this._wrapApiCall('page.addInitScript', async () => {
return this._wrapApiCall('page.addInitScript', async (channel: channels.PageChannel) => {
const source = await evaluationScript(script, arg);
await this._channel.addInitScript({ source });
await channel.addInitScript({ source });
});
}
async route(url: URLMatch, handler: RouteHandler): Promise<void> {
return this._wrapApiCall('page.route', async () => {
return this._wrapApiCall('page.route', async (channel: channels.PageChannel) => {
this._routes.push({ url, handler });
if (this._routes.length === 1)
await this._channel.setNetworkInterceptionEnabled({ enabled: true });
await channel.setNetworkInterceptionEnabled({ enabled: true });
});
}
async unroute(url: URLMatch, handler?: RouteHandler): Promise<void> {
return this._wrapApiCall('page.unroute', async () => {
return this._wrapApiCall('page.unroute', async (channel: channels.PageChannel) => {
this._routes = this._routes.filter(route => route.url !== url || (handler && route.handler !== handler));
if (this._routes.length === 0)
await this._channel.setNetworkInterceptionEnabled({ enabled: false });
await channel.setNetworkInterceptionEnabled({ enabled: false });
});
}
async screenshot(options: channels.PageScreenshotOptions & { path?: string } = {}): Promise<Buffer> {
return this._wrapApiCall('page.screenshot', async () => {
return this._wrapApiCall('page.screenshot', async (channel: channels.PageChannel) => {
const copy = { ...options };
if (!copy.type)
copy.type = determineScreenshotType(options);
const result = await this._channel.screenshot(copy);
const result = await channel.screenshot(copy);
const buffer = Buffer.from(result.binary, 'base64');
if (options.path) {
await mkdirIfNeeded(options.path);
@ -490,15 +492,15 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
}
async bringToFront(): Promise<void> {
return this._wrapApiCall('page.bringToFront', async () => {
await this._channel.bringToFront();
return this._wrapApiCall('page.bringToFront', async (channel: channels.PageChannel) => {
await channel.bringToFront();
});
}
async close(options: { runBeforeUnload?: boolean } = {runBeforeUnload: undefined}) {
try {
await this._wrapApiCall('page.close', async () => {
await this._channel.close(options);
await this._wrapApiCall('page.close', async (channel: channels.PageChannel) => {
await channel.close(options);
if (this._ownedContext)
await this._ownedContext.close();
});
@ -646,7 +648,7 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
}
async _pdf(options: PDFOptions = {}): Promise<Buffer> {
return this._wrapApiCall('page.pdf', async () => {
return this._wrapApiCall('page.pdf', async (channel: channels.PageChannel) => {
const transportOptions: channels.PagePdfParams = { ...options } as channels.PagePdfParams;
if (transportOptions.margin)
transportOptions.margin = { ...transportOptions.margin };
@ -659,7 +661,7 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
if (options.margin && typeof options.margin[index] === 'number')
transportOptions.margin![index] = transportOptions.margin![index] + 'px';
}
const result = await this._channel.pdf(transportOptions);
const result = await channel.pdf(transportOptions);
const buffer = Buffer.from(result.pdf, 'base64');
if (options.path) {
await mkdirAsync(path.dirname(options.path), { recursive: true });

View file

@ -49,16 +49,16 @@ export class Worker extends ChannelOwner<channels.WorkerChannel, channels.Worker
async evaluate<R, Arg>(pageFunction: structs.PageFunction<Arg, R>, arg?: Arg): Promise<R> {
assertMaxArguments(arguments.length, 2);
return this._wrapApiCall('worker.evaluate', async () => {
const result = await this._channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return this._wrapApiCall('worker.evaluate', async (channel: channels.WorkerChannel) => {
const result = await channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return parseResult(result.value);
});
}
async evaluateHandle<R, Arg>(pageFunction: structs.PageFunction<Arg, R>, arg?: Arg): Promise<structs.SmartHandle<R>> {
assertMaxArguments(arguments.length, 2);
return this._wrapApiCall('worker.evaluateHandle', async () => {
const result = await this._channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return this._wrapApiCall('worker.evaluateHandle', async (channel: channels.WorkerChannel) => {
const result = await channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return JSHandle.from(result.handle) as any as structs.SmartHandle<R>;
});
}