chore(rpc): attribute calles to page, ignore USES_HOOKS (#2764)

This commit is contained in:
Pavel Feldman 2020-06-29 18:58:09 -07:00 committed by GitHub
parent 3a7d629c61
commit 5bb018e0e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 252 additions and 191 deletions

View File

@ -232,6 +232,10 @@ export class Page extends EventEmitter {
return this._attributeToPage(() => this.mainFrame().evaluateHandle(pageFunction, arg));
}
async _evaluateExpressionHandle(expression: string, isFunction: boolean, arg: any): Promise<any> {
return this._attributeToPage(() => this.mainFrame()._evaluateExpressionHandle(expression, isFunction, arg));
}
async $eval<R, Arg>(selector: string, pageFunction: js.FuncOn<Element, Arg, R>, arg: Arg): Promise<R>;
async $eval<R>(selector: string, pageFunction: js.FuncOn<Element, void, R>, arg?: any): Promise<R>;
async $eval<R, Arg>(selector: string, pageFunction: js.FuncOn<Element, Arg, R>, arg: Arg): Promise<R> {
@ -239,6 +243,10 @@ export class Page extends EventEmitter {
return this._attributeToPage(() => this.mainFrame().$eval(selector, pageFunction, arg));
}
async _$evalExpression(selector: string, expression: string, isFunction: boolean, arg: any): Promise<any> {
return this._attributeToPage(() => this.mainFrame()._$evalExpression(selector, expression, isFunction, arg));
}
async $$eval<R, Arg>(selector: string, pageFunction: js.FuncOn<Element[], Arg, R>, arg: Arg): Promise<R>;
async $$eval<R>(selector: string, pageFunction: js.FuncOn<Element[], void, R>, arg?: any): Promise<R>;
async $$eval<R, Arg>(selector: string, pageFunction: js.FuncOn<Element[], Arg, R>, arg: Arg): Promise<R> {
@ -246,6 +254,10 @@ export class Page extends EventEmitter {
return this._attributeToPage(() => this.mainFrame().$$eval(selector, pageFunction, arg));
}
async _$$evalExpression(selector: string, expression: string, isFunction: boolean, arg: any): Promise<any> {
return this._attributeToPage(() => this.mainFrame()._$$evalExpression(selector, expression, isFunction, arg));
}
async $$(selector: string): Promise<dom.ElementHandle<Element>[]> {
return this._attributeToPage(() => this.mainFrame().$$(selector));
}
@ -393,6 +405,10 @@ export class Page extends EventEmitter {
return this._attributeToPage(() => this.mainFrame().evaluate(pageFunction, arg));
}
async _evaluateExpression(expression: string, isFunction: boolean, arg: any): Promise<any> {
return this._attributeToPage(() => this.mainFrame()._evaluateExpression(expression, isFunction, arg));
}
async addInitScript(script: Function | string | { path?: string, content?: string }, arg?: any) {
const source = await helper.evaluationScript(script, arg);
await this._addInitScriptExpression(source);
@ -556,6 +572,10 @@ export class Page extends EventEmitter {
return this._attributeToPage(() => this.mainFrame().waitForFunction(pageFunction, arg, options));
}
async _waitForFunctionExpression<R>(expression: string, isFunction: boolean, arg: any, options: types.WaitForFunctionOptions = {}): Promise<js.SmartHandle<R>> {
return this._attributeToPage(() => this.mainFrame()._waitForFunctionExpression(expression, isFunction, arg, options));
}
workers(): Worker[] {
return [...this._workers.values()];
}

View File

@ -129,39 +129,39 @@ export type PageInitializer = {
export interface FrameChannel extends Channel {
$$eval(params: { selector: string; expression: string, isFunction: boolean, arg: any }): Promise<any>;
$eval(params: { selector: string; expression: string, isFunction: boolean, arg: any }): Promise<any>;
addScriptTag(params: { options: { url?: string | undefined, path?: string | undefined, content?: string | undefined, type?: string | undefined } }): Promise<ElementHandleChannel>;
addStyleTag(params: { options: { url?: string | undefined, path?: string | undefined, content?: string | undefined } }): Promise<ElementHandleChannel>;
check(params: { selector: string, options: types.TimeoutOptions & { force?: boolean } & { noWaitAfter?: boolean } }): Promise<void>;
click(params: { selector: string, options: types.PointerActionOptions & types.MouseClickOptions & types.TimeoutOptions & { force?: boolean } & { noWaitAfter?: boolean } }): Promise<void>;
$$eval(params: { selector: string; expression: string, isFunction: boolean, arg: any, isPage?: boolean }): Promise<any>;
$eval(params: { selector: string; expression: string, isFunction: boolean, arg: any, isPage?: boolean }): Promise<any>;
addScriptTag(params: { options: { url?: string | undefined, path?: string | undefined, content?: string | undefined, type?: string | undefined }, isPage?: boolean }): Promise<ElementHandleChannel>;
addStyleTag(params: { options: { url?: string | undefined, path?: string | undefined, content?: string | undefined }, isPage?: boolean }): Promise<ElementHandleChannel>;
check(params: { selector: string, options: types.TimeoutOptions & { force?: boolean } & { noWaitAfter?: boolean }, isPage?: boolean }): Promise<void>;
click(params: { selector: string, options: types.PointerActionOptions & types.MouseClickOptions & types.TimeoutOptions & { force?: boolean } & { noWaitAfter?: boolean }, isPage?: boolean }): Promise<void>;
content(): Promise<string>;
dblclick(params: { selector: string, options: types.PointerActionOptions & types.MouseMultiClickOptions & types.TimeoutOptions & { force?: boolean }}): Promise<void>;
dispatchEvent(params: { selector: string, type: string, eventInit: Object | undefined, options: types.TimeoutOptions }): Promise<void>;
evaluateExpression(params: { expression: string, isFunction: boolean, arg: any }): Promise<any>;
evaluateExpressionHandle(params: { expression: string, isFunction: boolean, arg: any}): Promise<JSHandleChannel>;
fill(params: { selector: string, value: string, options: types.NavigatingActionWaitOptions }): Promise<void>;
focus(params: { selector: string, options: types.TimeoutOptions }): Promise<void>;
dblclick(params: { selector: string, options: types.PointerActionOptions & types.MouseMultiClickOptions & types.TimeoutOptions & { force?: boolean }, isPage?: boolean}): Promise<void>;
dispatchEvent(params: { selector: string, type: string, eventInit: Object | undefined, options: types.TimeoutOptions, isPage?: boolean }): Promise<void>;
evaluateExpression(params: { expression: string, isFunction: boolean, arg: any, isPage?: boolean }): Promise<any>;
evaluateExpressionHandle(params: { expression: string, isFunction: boolean, arg: any, isPage?: boolean }): Promise<JSHandleChannel>;
fill(params: { selector: string, value: string, options: types.NavigatingActionWaitOptions, isPage?: boolean }): Promise<void>;
focus(params: { selector: string, options: types.TimeoutOptions, isPage?: boolean }): Promise<void>;
frameElement(): Promise<ElementHandleChannel>;
getAttribute(params: { selector: string, name: string, options: types.TimeoutOptions }): Promise<string | null>;
goto(params: { url: string, options: types.GotoOptions }): Promise<ResponseChannel | null>;
hover(params: { selector: string, options: types.PointerActionOptions & types.TimeoutOptions & { force?: boolean } }): Promise<void>;
innerHTML(params: { selector: string, options: types.TimeoutOptions }): Promise<string>;
innerText(params: { selector: string, options: types.TimeoutOptions }): Promise<string>;
press(params: { selector: string, key: string, options: { delay?: number | undefined } & types.TimeoutOptions & { noWaitAfter?: boolean } }): Promise<void>;
querySelector(params: { selector: string }): Promise<ElementHandleChannel | null>;
querySelectorAll(params: { selector: string }): Promise<ElementHandleChannel[]>;
selectOption(params: { selector: string, values: string | ElementHandleChannel | types.SelectOption | string[] | ElementHandleChannel[] | types.SelectOption[] | null, options: types.NavigatingActionWaitOptions }): Promise<string[]>;
setContent(params: { html: string, options: types.NavigateOptions }): Promise<void>;
setInputFiles(params: { selector: string, files: { name: string, mimeType: string, buffer: string }[], options: types.NavigatingActionWaitOptions }): Promise<void>;
textContent(params: { selector: string, options: types.TimeoutOptions }): Promise<string | null>;
getAttribute(params: { selector: string, name: string, options: types.TimeoutOptions, isPage?: boolean }): Promise<string | null>;
goto(params: { url: string, options: types.GotoOptions, isPage?: boolean }): Promise<ResponseChannel | null>;
hover(params: { selector: string, options: types.PointerActionOptions & types.TimeoutOptions & { force?: boolean }, isPage?: boolean }): Promise<void>;
innerHTML(params: { selector: string, options: types.TimeoutOptions, isPage?: boolean }): Promise<string>;
innerText(params: { selector: string, options: types.TimeoutOptions, isPage?: boolean }): Promise<string>;
press(params: { selector: string, key: string, options: { delay?: number | undefined } & types.TimeoutOptions & { noWaitAfter?: boolean }, isPage?: boolean }): Promise<void>;
querySelector(params: { selector: string, isPage?: boolean }): Promise<ElementHandleChannel | null>;
querySelectorAll(params: { selector: string, isPage?: boolean }): Promise<ElementHandleChannel[]>;
selectOption(params: { selector: string, values: string | ElementHandleChannel | types.SelectOption | string[] | ElementHandleChannel[] | types.SelectOption[] | null, options: types.NavigatingActionWaitOptions, isPage?: boolean }): Promise<string[]>;
setContent(params: { html: string, options: types.NavigateOptions, isPage?: boolean }): Promise<void>;
setInputFiles(params: { selector: string, files: { name: string, mimeType: string, buffer: string }[], options: types.NavigatingActionWaitOptions, isPage?: boolean }): Promise<void>;
textContent(params: { selector: string, options: types.TimeoutOptions, isPage?: boolean }): Promise<string | null>;
title(): Promise<string>;
type(params: { selector: string, text: string, options: { delay?: number | undefined } & types.TimeoutOptions & { noWaitAfter?: boolean } }): Promise<void>;
uncheck(params: { selector: string, options: types.TimeoutOptions & { force?: boolean } & { noWaitAfter?: boolean } }): Promise<void>;
waitForFunction(params: { expression: string, isFunction: boolean, arg: any; options: types.WaitForFunctionOptions }): Promise<JSHandleChannel>;
waitForLoadState(params: { state: types.LifecycleEvent, options: types.TimeoutOptions }): Promise<void>;
waitForNavigation(params: { options: types.WaitForNavigationOptions }): Promise<ResponseChannel | null>;
waitForSelector(params: { selector: string, options: types.WaitForElementOptions }): Promise<ElementHandleChannel | null>;
type(params: { selector: string, text: string, options: { delay?: number | undefined } & types.TimeoutOptions & { noWaitAfter?: boolean }, isPage?: boolean }): Promise<void>;
uncheck(params: { selector: string, options: types.TimeoutOptions & { force?: boolean } & { noWaitAfter?: boolean }, isPage?: boolean }): Promise<void>;
waitForFunction(params: { expression: string, isFunction: boolean, arg: any; options: types.WaitForFunctionOptions, isPage?: boolean }): Promise<JSHandleChannel>;
waitForLoadState(params: { state: types.LifecycleEvent, options: types.TimeoutOptions, isPage?: boolean }): Promise<void>;
waitForNavigation(params: { options: types.WaitForNavigationOptions, isPage?: boolean }): Promise<ResponseChannel | null>;
waitForSelector(params: { selector: string, options: types.WaitForElementOptions, isPage?: boolean }): Promise<ElementHandleChannel | null>;
}
export type FrameInitializer = {
url: string,
@ -245,7 +245,7 @@ export type RouteInitializer = {
export interface ResponseChannel extends Channel {
body(): Promise<Buffer>;
body(): Promise<Binary>;
finished(): Promise<Error | null>;
}
export type ResponseInitializer = {
@ -290,7 +290,7 @@ export type DialogInitializer = {
export interface DownloadChannel extends Channel {
path(): Promise<string>;
path(): Promise<string | null>;
failure(): Promise<string | null>;
delete(): Promise<void>;
}

View File

@ -60,15 +60,15 @@ export class Frame extends ChannelOwner<FrameChannel, FrameInitializer> {
}
async goto(url: string, options: GotoOptions = {}): Promise<network.Response | null> {
return Response.fromNullable(await this._channel.goto({ url, options }));
return Response.fromNullable(await this._channel.goto({ url, options, isPage: this._page!._isPageCall }));
}
async waitForNavigation(options: types.WaitForNavigationOptions = {}): Promise<network.Response | null> {
return Response.fromNullable(await this._channel.waitForNavigation({ options }));
return Response.fromNullable(await this._channel.waitForNavigation({ options, isPage: this._page!._isPageCall }));
}
async waitForLoadState(state: types.LifecycleEvent = 'load', options: types.TimeoutOptions = {}): Promise<void> {
await this._channel.waitForLoadState({ state, options });
await this._channel.waitForLoadState({ state, options, isPage: this._page!._isPageCall });
}
async frameElement(): Promise<ElementHandle> {
@ -79,44 +79,44 @@ export class Frame extends ChannelOwner<FrameChannel, FrameInitializer> {
async evaluateHandle<R>(pageFunction: Func1<void, R>, arg?: any): Promise<SmartHandle<R>>;
async evaluateHandle<R, Arg>(pageFunction: Func1<Arg, R>, arg: Arg): Promise<SmartHandle<R>> {
assertMaxArguments(arguments.length, 2);
return JSHandle.from(await this._channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) })) as SmartHandle<R>;
return JSHandle.from(await this._channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg), isPage: this._page!._isPageCall })) as SmartHandle<R>;
}
async evaluate<R, Arg>(pageFunction: Func1<Arg, R>, arg: Arg): Promise<R>;
async evaluate<R>(pageFunction: Func1<void, R>, arg?: any): Promise<R>;
async evaluate<R, Arg>(pageFunction: Func1<Arg, R>, arg: Arg): Promise<R> {
assertMaxArguments(arguments.length, 2);
return parseResult(await this._channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) }));
return parseResult(await this._channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg), isPage: this._page!._isPageCall }));
}
async $(selector: string): Promise<ElementHandle<Element> | null> {
return ElementHandle.fromNullable(await this._channel.querySelector({ selector })) as ElementHandle<Element> | null;
return ElementHandle.fromNullable(await this._channel.querySelector({ selector, isPage: this._page!._isPageCall })) as ElementHandle<Element> | null;
}
async waitForSelector(selector: string, options: types.WaitForElementOptions = {}): Promise<ElementHandle<Element> | null> {
return ElementHandle.fromNullable(await this._channel.waitForSelector({ selector, options })) as ElementHandle<Element> | null;
return ElementHandle.fromNullable(await this._channel.waitForSelector({ selector, options, isPage: this._page!._isPageCall })) as ElementHandle<Element> | null;
}
async dispatchEvent(selector: string, type: string, eventInit?: Object, options: types.TimeoutOptions = {}): Promise<void> {
await this._channel.dispatchEvent({ selector, type, eventInit, options });
await this._channel.dispatchEvent({ selector, type, eventInit, options, isPage: this._page!._isPageCall });
}
async $eval<R, Arg>(selector: string, pageFunction: FuncOn<Element, Arg, R>, arg: Arg): Promise<R>;
async $eval<R>(selector: string, pageFunction: FuncOn<Element, void, R>, arg?: any): Promise<R>;
async $eval<R, Arg>(selector: string, pageFunction: FuncOn<Element, Arg, R>, arg: Arg): Promise<R> {
assertMaxArguments(arguments.length, 3);
return await this._channel.$eval({ selector, expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return await this._channel.$eval({ selector, expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg), isPage: this._page!._isPageCall });
}
async $$eval<R, Arg>(selector: string, pageFunction: FuncOn<Element[], Arg, R>, arg: Arg): Promise<R>;
async $$eval<R>(selector: string, pageFunction: FuncOn<Element[], void, R>, arg?: any): Promise<R>;
async $$eval<R, Arg>(selector: string, pageFunction: FuncOn<Element[], Arg, R>, arg: Arg): Promise<R> {
assertMaxArguments(arguments.length, 3);
return await this._channel.$$eval({ selector, expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
return await this._channel.$$eval({ selector, expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg), isPage: this._page!._isPageCall });
}
async $$(selector: string): Promise<ElementHandle<Element>[]> {
const result = await this._channel.querySelectorAll({ selector });
const result = await this._channel.querySelectorAll({ selector, isPage: this._page!._isPageCall });
return result.map(c => ElementHandle.from(c) as ElementHandle<Element>);
}
@ -125,7 +125,7 @@ export class Frame extends ChannelOwner<FrameChannel, FrameInitializer> {
}
async setContent(html: string, options: types.NavigateOptions = {}): Promise<void> {
await this._channel.setContent({ html, options });
await this._channel.setContent({ html, options, isPage: this._page!._isPageCall });
}
name(): string {
@ -149,72 +149,72 @@ export class Frame extends ChannelOwner<FrameChannel, FrameInitializer> {
}
async addScriptTag(options: { url?: string, path?: string, content?: string, type?: string }): Promise<ElementHandle> {
return ElementHandle.from(await this._channel.addScriptTag({ options }));
return ElementHandle.from(await this._channel.addScriptTag({ options, isPage: this._page!._isPageCall }));
}
async addStyleTag(options: { url?: string; path?: string; content?: string; }): Promise<ElementHandle> {
return ElementHandle.from(await this._channel.addStyleTag({ options }));
return ElementHandle.from(await this._channel.addStyleTag({ options, isPage: this._page!._isPageCall }));
}
async click(selector: string, options: types.MouseClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
return await this._channel.click({ selector, options });
return await this._channel.click({ selector, options, isPage: this._page!._isPageCall });
}
async dblclick(selector: string, options: types.MouseMultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
return await this._channel.dblclick({ selector, options });
return await this._channel.dblclick({ selector, options, isPage: this._page!._isPageCall });
}
async fill(selector: string, value: string, options: types.NavigatingActionWaitOptions = {}) {
return await this._channel.fill({ selector, value, options });
return await this._channel.fill({ selector, value, options, isPage: this._page!._isPageCall });
}
async focus(selector: string, options: types.TimeoutOptions = {}) {
await this._channel.focus({ selector, options });
await this._channel.focus({ selector, options, isPage: this._page!._isPageCall });
}
async textContent(selector: string, options: types.TimeoutOptions = {}): Promise<null|string> {
return await this._channel.textContent({ selector, options });
return await this._channel.textContent({ selector, options, isPage: this._page!._isPageCall });
}
async innerText(selector: string, options: types.TimeoutOptions = {}): Promise<string> {
return await this._channel.innerText({ selector, options });
return await this._channel.innerText({ selector, options, isPage: this._page!._isPageCall });
}
async innerHTML(selector: string, options: types.TimeoutOptions = {}): Promise<string> {
return await this._channel.innerHTML({ selector, options });
return await this._channel.innerHTML({ selector, options, isPage: this._page!._isPageCall });
}
async getAttribute(selector: string, name: string, options: types.TimeoutOptions = {}): Promise<string | null> {
return await this._channel.getAttribute({ selector, name, options });
return await this._channel.getAttribute({ selector, name, options, isPage: this._page!._isPageCall });
}
async hover(selector: string, options: types.PointerActionOptions & types.PointerActionWaitOptions = {}) {
await this._channel.hover({ selector, options });
await this._channel.hover({ selector, options, isPage: this._page!._isPageCall });
}
async selectOption(selector: string, values: string | ElementHandle | types.SelectOption | string[] | ElementHandle[] | types.SelectOption[] | null, options: types.NavigatingActionWaitOptions = {}): Promise<string[]> {
return await this._channel.selectOption({ selector, values: convertSelectOptionValues(values), options });
return await this._channel.selectOption({ selector, values: convertSelectOptionValues(values), options, isPage: this._page!._isPageCall });
}
async setInputFiles(selector: string, files: string | types.FilePayload | string[] | types.FilePayload[], options: types.NavigatingActionWaitOptions = {}): Promise<void> {
const filePayloads = await normalizeFilePayloads(files);
await this._channel.setInputFiles({ selector, files: filePayloads.map(f => ({ name: f.name, mimeType: f.mimeType, buffer: f.buffer.toString('base64') })), options });
await this._channel.setInputFiles({ selector, files: filePayloads.map(f => ({ name: f.name, mimeType: f.mimeType, buffer: f.buffer.toString('base64') })), options, isPage: this._page!._isPageCall });
}
async type(selector: string, text: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) {
await this._channel.type({ selector, text, options });
await this._channel.type({ selector, text, options, isPage: this._page!._isPageCall });
}
async press(selector: string, key: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) {
await this._channel.press({ selector, key, options });
await this._channel.press({ selector, key, options, isPage: this._page!._isPageCall });
}
async check(selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
await this._channel.check({ selector, options });
await this._channel.check({ selector, options, isPage: this._page!._isPageCall });
}
async uncheck(selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
await this._channel.uncheck({ selector, options });
await this._channel.uncheck({ selector, options, isPage: this._page!._isPageCall });
}
async waitForTimeout(timeout: number) {
@ -224,7 +224,7 @@ export class Frame extends ChannelOwner<FrameChannel, FrameInitializer> {
async waitForFunction<R, Arg>(pageFunction: Func1<Arg, R>, arg: Arg, options?: types.WaitForFunctionOptions): Promise<SmartHandle<R>>;
async waitForFunction<R>(pageFunction: Func1<void, R>, arg?: any, options?: types.WaitForFunctionOptions): Promise<SmartHandle<R>>;
async waitForFunction<R, Arg>(pageFunction: Func1<Arg, R>, arg: Arg, options: types.WaitForFunctionOptions = {}): Promise<SmartHandle<R>> {
return JSHandle.from(await this._channel.waitForFunction({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg), options })) as SmartHandle<R>;
return JSHandle.from(await this._channel.waitForFunction({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg), options, isPage: this._page!._isPageCall })) as SmartHandle<R>;
}
async title(): Promise<string> {

View File

@ -205,7 +205,7 @@ export class Response extends ChannelOwner<ResponseChannel, ResponseInitializer>
}
async body(): Promise<Buffer> {
return await this._channel.body();
return Buffer.from(await this._channel.body(), 'base64');
}
async text(): Promise<string> {

View File

@ -55,6 +55,7 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
readonly _bindings = new Map<string, FunctionWithSource>();
private _pendingWaitForEvents = new Map<(error: Error) => void, string>();
private _timeoutSettings = new TimeoutSettings();
_isPageCall = false;
static from(page: PageChannel): Page {
return page._object;
@ -203,45 +204,54 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
this._channel.setDefaultTimeoutNoReply({ timeout });
}
private _attributeToPage<T>(func: () => T): T {
try {
this._isPageCall = true;
return func();
} finally {
this._isPageCall = false;
}
}
async $(selector: string): Promise<ElementHandle<Element> | null> {
return await this._mainFrame.$(selector);
return this._attributeToPage(() => this._mainFrame.$(selector));
}
async waitForSelector(selector: string, options?: types.WaitForElementOptions): Promise<ElementHandle<Element> | null> {
return await this._mainFrame.waitForSelector(selector, options);
return this._attributeToPage(() => this._mainFrame.waitForSelector(selector, options));
}
async dispatchEvent(selector: string, type: string, eventInit?: Object, options?: types.TimeoutOptions): Promise<void> {
return await this._mainFrame.dispatchEvent(selector, type, eventInit, options);
return this._attributeToPage(() => this._mainFrame.dispatchEvent(selector, type, eventInit, options));
}
async evaluateHandle<R, Arg>(pageFunction: Func1<Arg, R>, arg: Arg): Promise<SmartHandle<R>>;
async evaluateHandle<R>(pageFunction: Func1<void, R>, arg?: any): Promise<SmartHandle<R>>;
async evaluateHandle<R, Arg>(pageFunction: Func1<Arg, R>, arg: Arg): Promise<SmartHandle<R>> {
assertMaxArguments(arguments.length, 2);
return await this._mainFrame.evaluateHandle(pageFunction, arg);
return this._attributeToPage(() => this._mainFrame.evaluateHandle(pageFunction, arg));
}
async $eval<R, Arg>(selector: string, pageFunction: FuncOn<Element, Arg, R>, arg: Arg): Promise<R>;
async $eval<R>(selector: string, pageFunction: FuncOn<Element, void, R>, arg?: any): Promise<R>;
async $eval<R, Arg>(selector: string, pageFunction: FuncOn<Element, Arg, R>, arg: Arg): Promise<R> {
assertMaxArguments(arguments.length, 3);
return await this._mainFrame.$eval(selector, pageFunction, arg);
return this._attributeToPage(() => this._mainFrame.$eval(selector, pageFunction, arg));
}
async $$eval<R, Arg>(selector: string, pageFunction: FuncOn<Element[], Arg, R>, arg: Arg): Promise<R>;
async $$eval<R>(selector: string, pageFunction: FuncOn<Element[], void, R>, arg?: any): Promise<R>;
async $$eval<R, Arg>(selector: string, pageFunction: FuncOn<Element[], Arg, R>, arg: Arg): Promise<R> {
assertMaxArguments(arguments.length, 3);
return await this._mainFrame.$$eval(selector, pageFunction, arg);
return this._attributeToPage(() => this._mainFrame.$$eval(selector, pageFunction, arg));
}
async $$(selector: string): Promise<ElementHandle<Element>[]> {
return await this._mainFrame.$$(selector);
return this._attributeToPage(() => this._mainFrame.$$(selector));
}
async addScriptTag(options: { url?: string; path?: string; content?: string; type?: string; }): Promise<ElementHandle> {
return await this._mainFrame.addScriptTag(options);
return this._attributeToPage(() => this._mainFrame.addScriptTag(options));
}
async addStyleTag(options: { url?: string; path?: string; content?: string; }): Promise<ElementHandle> {
@ -266,19 +276,19 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
}
url(): string {
return this.mainFrame().url();
return this._attributeToPage(() => this._mainFrame.url());
}
async content(): Promise<string> {
return this.mainFrame().content();
return this._attributeToPage(() => this._mainFrame.content());
}
async setContent(html: string, options?: types.NavigateOptions): Promise<void> {
return this.mainFrame().setContent(html, options);
return this._attributeToPage(() => this._mainFrame.setContent(html, options));
}
async goto(url: string, options?: GotoOptions): Promise<Response | null> {
return this.mainFrame().goto(url, options);
return this._attributeToPage(() => this._mainFrame.goto(url, options));
}
async reload(options?: types.NavigateOptions): Promise<Response | null> {
@ -286,11 +296,11 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
}
async waitForLoadState(state?: types.LifecycleEvent, options?: types.TimeoutOptions): Promise<void> {
return this._mainFrame.waitForLoadState(state, options);
return this._attributeToPage(() => this._mainFrame.waitForLoadState(state, options));
}
async waitForNavigation(options?: types.WaitForNavigationOptions): Promise<Response | null> {
return this._mainFrame.waitForNavigation(options);
return this._attributeToPage(() => this._mainFrame.waitForNavigation(options));
}
async waitForRequest(urlOrPredicate: string | RegExp | ((r: Request) => boolean), options: types.TimeoutOptions = {}): Promise<Request> {
@ -346,7 +356,7 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
async evaluate<R>(pageFunction: Func1<void, R>, arg?: any): Promise<R>;
async evaluate<R, Arg>(pageFunction: Func1<Arg, R>, arg: Arg): Promise<R> {
assertMaxArguments(arguments.length, 2);
return this.mainFrame().evaluate(pageFunction, arg);
return this._attributeToPage(() => this._mainFrame.evaluate(pageFunction, arg));
}
async addInitScript(script: Function | string | { path?: string, content?: string }, arg?: any) {
@ -371,7 +381,7 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
}
async title(): Promise<string> {
return this.mainFrame().title();
return this._attributeToPage(() => this._mainFrame.title());
}
async close(options: { runBeforeUnload?: boolean } = {runBeforeUnload: undefined}) {
@ -385,73 +395,73 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
}
async click(selector: string, options?: types.MouseClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) {
return this.mainFrame().click(selector, options);
return this._attributeToPage(() => this._mainFrame.click(selector, options));
}
async dblclick(selector: string, options?: types.MouseMultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) {
return this.mainFrame().dblclick(selector, options);
return this._attributeToPage(() => this._mainFrame.dblclick(selector, options));
}
async fill(selector: string, value: string, options?: types.NavigatingActionWaitOptions) {
return this.mainFrame().fill(selector, value, options);
return this._attributeToPage(() => this._mainFrame.fill(selector, value, options));
}
async focus(selector: string, options?: types.TimeoutOptions) {
return this.mainFrame().focus(selector, options);
return this._attributeToPage(() => this._mainFrame.focus(selector, options));
}
async textContent(selector: string, options?: types.TimeoutOptions): Promise<null|string> {
return this.mainFrame().textContent(selector, options);
return this._attributeToPage(() => this._mainFrame.textContent(selector, options));
}
async innerText(selector: string, options?: types.TimeoutOptions): Promise<string> {
return this.mainFrame().innerText(selector, options);
return this._attributeToPage(() => this._mainFrame.innerText(selector, options));
}
async innerHTML(selector: string, options?: types.TimeoutOptions): Promise<string> {
return this.mainFrame().innerHTML(selector, options);
return this._attributeToPage(() => this._mainFrame.innerHTML(selector, options));
}
async getAttribute(selector: string, name: string, options?: types.TimeoutOptions): Promise<string | null> {
return this.mainFrame().getAttribute(selector, name, options);
return this._attributeToPage(() => this._mainFrame.getAttribute(selector, name, options));
}
async hover(selector: string, options?: types.PointerActionOptions & types.PointerActionWaitOptions) {
return this.mainFrame().hover(selector, options);
return this._attributeToPage(() => this._mainFrame.hover(selector, options));
}
async selectOption(selector: string, values: string | ElementHandle | types.SelectOption | string[] | ElementHandle[] | types.SelectOption[] | null, options?: types.NavigatingActionWaitOptions): Promise<string[]> {
return this.mainFrame().selectOption(selector, values, options);
return this._attributeToPage(() => this._mainFrame.selectOption(selector, values, options));
}
async setInputFiles(selector: string, files: string | types.FilePayload | string[] | types.FilePayload[], options?: types.NavigatingActionWaitOptions): Promise<void> {
return this.mainFrame().setInputFiles(selector, files, options);
return this._attributeToPage(() => this._mainFrame.setInputFiles(selector, files, options));
}
async type(selector: string, text: string, options?: { delay?: number } & types.NavigatingActionWaitOptions) {
return this.mainFrame().type(selector, text, options);
return this._attributeToPage(() => this._mainFrame.type(selector, text, options));
}
async press(selector: string, key: string, options?: { delay?: number } & types.NavigatingActionWaitOptions) {
return this.mainFrame().press(selector, key, options);
return this._attributeToPage(() => this._mainFrame.press(selector, key, options));
}
async check(selector: string, options?: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) {
return this.mainFrame().check(selector, options);
return this._attributeToPage(() => this._mainFrame.check(selector, options));
}
async uncheck(selector: string, options?: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) {
return this.mainFrame().uncheck(selector, options);
return this._attributeToPage(() => this._mainFrame.uncheck(selector, options));
}
async waitForTimeout(timeout: number) {
await this.mainFrame().waitForTimeout(timeout);
await this._mainFrame.waitForTimeout(timeout);
}
async waitForFunction<R, Arg>(pageFunction: Func1<Arg, R>, arg: Arg, options?: types.WaitForFunctionOptions): Promise<SmartHandle<R>>;
async waitForFunction<R>(pageFunction: Func1<void, R>, arg?: any, options?: types.WaitForFunctionOptions): Promise<SmartHandle<R>>;
async waitForFunction<R, Arg>(pageFunction: Func1<Arg, R>, arg: Arg, options?: types.WaitForFunctionOptions): Promise<SmartHandle<R>> {
return this.mainFrame().waitForFunction(pageFunction, arg, options);
return this._attributeToPage(() => this._mainFrame.waitForFunction(pageFunction, arg, options));
}
workers(): Worker[] {

View File

@ -23,7 +23,7 @@ export class Dispatcher<Type, Initializer> extends EventEmitter implements Chann
readonly _guid: string;
readonly _type: string;
protected _scope: DispatcherScope;
_object: any;
_object: Type;
constructor(scope: DispatcherScope, object: Type, type: string, initializer: Initializer, guid = type + '@' + helper.guid()) {
super();

View File

@ -32,7 +32,7 @@ export class DownloadDispatcher extends Dispatcher<Download, DownloadInitializer
});
}
async path(): Promise<string> {
async path(): Promise<string | null> {
return this._object.path();
}

View File

@ -46,52 +46,63 @@ export class FrameDispatcher extends Dispatcher<Frame, FrameInitializer> impleme
this._frame = frame;
}
async goto(params: { url: string, options: types.GotoOptions }): Promise<ResponseChannel | null> {
return ResponseDispatcher.fromNullable(this._scope, await this._frame.goto(params.url, params.options));
async goto(params: { url: string, options: types.GotoOptions, isPage?: boolean }): Promise<ResponseChannel | null> {
const target = params.isPage ? this._frame._page : this._frame;
return ResponseDispatcher.fromNullable(this._scope, await target.goto(params.url, params.options));
}
async waitForLoadState(params: { state?: 'load' | 'domcontentloaded' | 'networkidle', options?: types.TimeoutOptions }): Promise<void> {
await this._frame.waitForLoadState(params.state, params.options);
async waitForLoadState(params: { state?: 'load' | 'domcontentloaded' | 'networkidle', options?: types.TimeoutOptions, isPage?: boolean }): Promise<void> {
const target = params.isPage ? this._frame._page : this._frame;
await target.waitForLoadState(params.state, params.options);
}
async waitForNavigation(params: { options?: types.WaitForNavigationOptions }): Promise<ResponseChannel | null> {
return ResponseDispatcher.fromNullable(this._scope, await this._frame.waitForNavigation(params.options));
async waitForNavigation(params: { options?: types.WaitForNavigationOptions, isPage?: boolean }): Promise<ResponseChannel | null> {
const target = params.isPage ? this._frame._page : this._frame;
return ResponseDispatcher.fromNullable(this._scope, await target.waitForNavigation(params.options));
}
async frameElement(): Promise<ElementHandleChannel> {
return ElementHandleDispatcher.fromElement(this._scope, await this._frame.frameElement());
}
async evaluateExpression(params: { expression: string, isFunction: boolean, arg: any }): Promise<any> {
return serializeResult(await this._frame._evaluateExpression(params.expression, params.isFunction, parseArgument(params.arg)));
async evaluateExpression(params: { expression: string, isFunction: boolean, arg: any, isPage?: boolean }): Promise<any> {
const target = params.isPage ? this._frame._page : this._frame;
return serializeResult(await target._evaluateExpression(params.expression, params.isFunction, parseArgument(params.arg)));
}
async evaluateExpressionHandle(params: { expression: string, isFunction: boolean, arg: any}): Promise<JSHandleChannel> {
return ElementHandleDispatcher.fromElement(this._scope, await this._frame._evaluateExpressionHandle(params.expression, params.isFunction, parseArgument(params.arg)));
async evaluateExpressionHandle(params: { expression: string, isFunction: boolean, arg: any, isPage?: boolean }): Promise<JSHandleChannel> {
const target = params.isPage ? this._frame._page : this._frame;
return ElementHandleDispatcher.fromElement(this._scope, await target._evaluateExpressionHandle(params.expression, params.isFunction, parseArgument(params.arg)));
}
async waitForSelector(params: { selector: string, options: types.WaitForElementOptions }): Promise<ElementHandleChannel | null> {
return ElementHandleDispatcher.fromNullableElement(this._scope, await this._frame.waitForSelector(params.selector, params.options));
async waitForSelector(params: { selector: string, options: types.WaitForElementOptions, isPage?: boolean }): Promise<ElementHandleChannel | null> {
const target = params.isPage ? this._frame._page : this._frame;
return ElementHandleDispatcher.fromNullableElement(this._scope, await target.waitForSelector(params.selector, params.options));
}
async dispatchEvent(params: { selector: string, type: string, eventInit: Object | undefined, options: types.TimeoutOptions }): Promise<void> {
return this._frame.dispatchEvent(params.selector, params.type, params.eventInit, params.options);
async dispatchEvent(params: { selector: string, type: string, eventInit: Object | undefined, options: types.TimeoutOptions, isPage?: boolean }): Promise<void> {
const target = params.isPage ? this._frame._page : this._frame;
return target.dispatchEvent(params.selector, params.type, params.eventInit, params.options);
}
async $eval(params: { selector: string, expression: string, isFunction: boolean, arg: any }): Promise<any> {
return serializeResult(await this._frame._$evalExpression(params.selector, params.expression, params.isFunction, parseArgument(params.arg)));
async $eval(params: { selector: string, expression: string, isFunction: boolean, arg: any, isPage?: boolean }): Promise<any> {
const target = params.isPage ? this._frame._page : this._frame;
return serializeResult(await target._$evalExpression(params.selector, params.expression, params.isFunction, parseArgument(params.arg)));
}
async $$eval(params: { selector: string, expression: string, isFunction: boolean, arg: any }): Promise<any> {
return serializeResult(await this._frame._$$evalExpression(params.selector, params.expression, params.isFunction, parseArgument(params.arg)));
async $$eval(params: { selector: string, expression: string, isFunction: boolean, arg: any, isPage?: boolean }): Promise<any> {
const target = params.isPage ? this._frame._page : this._frame;
return serializeResult(await target._$$evalExpression(params.selector, params.expression, params.isFunction, parseArgument(params.arg)));
}
async querySelector(params: { selector: string }): Promise<ElementHandleChannel | null> {
return ElementHandleDispatcher.fromNullableElement(this._scope, await this._frame.$(params.selector));
async querySelector(params: { selector: string, isPage?: boolean }): Promise<ElementHandleChannel | null> {
const target = params.isPage ? this._frame._page : this._frame;
return ElementHandleDispatcher.fromNullableElement(this._scope, await target.$(params.selector));
}
async querySelectorAll(params: { selector: string }): Promise<ElementHandleChannel[]> {
const elements = await this._frame.$$(params.selector);
async querySelectorAll(params: { selector: string, isPage?: boolean }): Promise<ElementHandleChannel[]> {
const target = params.isPage ? this._frame._page : this._frame;
const elements = await target.$$(params.selector);
return elements.map(e => ElementHandleDispatcher.fromElement(this._scope, e));
}
@ -99,80 +110,99 @@ export class FrameDispatcher extends Dispatcher<Frame, FrameInitializer> impleme
return await this._frame.content();
}
async setContent(params: { html: string, options: types.NavigateOptions }): Promise<void> {
await this._frame.setContent(params.html, params.options);
async setContent(params: { html: string, options: types.NavigateOptions, isPage?: boolean }): Promise<void> {
const target = params.isPage ? this._frame._page : this._frame;
await target.setContent(params.html, params.options);
}
async addScriptTag(params: { options: { url?: string | undefined, path?: string | undefined, content?: string | undefined, type?: string | undefined } }): Promise<ElementHandleChannel> {
return ElementHandleDispatcher.fromElement(this._scope, await this._frame.addScriptTag(params.options));
async addScriptTag(params: { options: { url?: string | undefined, path?: string | undefined, content?: string | undefined, type?: string | undefined }, isPage?: boolean }): Promise<ElementHandleChannel> {
const target = params.isPage ? this._frame._page : this._frame;
return ElementHandleDispatcher.fromElement(this._scope, await target.addScriptTag(params.options));
}
async addStyleTag(params: { options: { url?: string | undefined, path?: string | undefined, content?: string | undefined } }): Promise<ElementHandleChannel> {
return ElementHandleDispatcher.fromElement(this._scope, await this._frame.addStyleTag(params.options));
async addStyleTag(params: { options: { url?: string | undefined, path?: string | undefined, content?: string | undefined }, isPage?: boolean }): Promise<ElementHandleChannel> {
const target = params.isPage ? this._frame._page : this._frame;
return ElementHandleDispatcher.fromElement(this._scope, await target.addStyleTag(params.options));
}
async click(params: { selector: string, options: types.PointerActionOptions & types.MouseClickOptions & types.TimeoutOptions & { force?: boolean } & { noWaitAfter?: boolean } }): Promise<void> {
await this._frame.click(params.selector, params.options);
async click(params: { selector: string, options: types.PointerActionOptions & types.MouseClickOptions & types.TimeoutOptions & { force?: boolean } & { noWaitAfter?: boolean }, isPage?: boolean }): Promise<void> {
const target = params.isPage ? this._frame._page : this._frame;
await target.click(params.selector, params.options);
}
async dblclick(params: { selector: string, options: types.PointerActionOptions & types.MouseMultiClickOptions & types.TimeoutOptions & { force?: boolean }}): Promise<void> {
await this._frame.dblclick(params.selector, params.options);
async dblclick(params: { selector: string, options: types.PointerActionOptions & types.MouseMultiClickOptions & types.TimeoutOptions & { force?: boolean }, isPage?: boolean }): Promise<void> {
const target = params.isPage ? this._frame._page : this._frame;
await target.dblclick(params.selector, params.options);
}
async fill(params: { selector: string, value: string, options: types.NavigatingActionWaitOptions }): Promise<void> {
await this._frame.fill(params.selector, params.value, params.options);
async fill(params: { selector: string, value: string, options: types.NavigatingActionWaitOptions, isPage?: boolean }): Promise<void> {
const target = params.isPage ? this._frame._page : this._frame;
await target.fill(params.selector, params.value, params.options);
}
async focus(params: { selector: string, options: types.TimeoutOptions }): Promise<void> {
await this._frame.focus(params.selector, params.options);
async focus(params: { selector: string, options: types.TimeoutOptions, isPage?: boolean }): Promise<void> {
const target = params.isPage ? this._frame._page : this._frame;
await target.focus(params.selector, params.options);
}
async textContent(params: { selector: string, options: types.TimeoutOptions }): Promise<string | null> {
return await this._frame.textContent(params.selector, params.options);
async textContent(params: { selector: string, options: types.TimeoutOptions, isPage?: boolean }): Promise<string | null> {
const target = params.isPage ? this._frame._page : this._frame;
return await target.textContent(params.selector, params.options);
}
async innerText(params: { selector: string, options: types.TimeoutOptions }): Promise<string> {
return await this._frame.innerText(params.selector, params.options);
async innerText(params: { selector: string, options: types.TimeoutOptions, isPage?: boolean }): Promise<string> {
const target = params.isPage ? this._frame._page : this._frame;
return await target.innerText(params.selector, params.options);
}
async innerHTML(params: { selector: string, options: types.TimeoutOptions }): Promise<string> {
return await this._frame.innerHTML(params.selector, params.options);
async innerHTML(params: { selector: string, options: types.TimeoutOptions, isPage?: boolean }): Promise<string> {
const target = params.isPage ? this._frame._page : this._frame;
return await target.innerHTML(params.selector, params.options);
}
async getAttribute(params: { selector: string, name: string, options: types.TimeoutOptions }): Promise<string | null> {
return await this._frame.getAttribute(params.selector, params.name, params.options);
async getAttribute(params: { selector: string, name: string, options: types.TimeoutOptions, isPage?: boolean }): Promise<string | null> {
const target = params.isPage ? this._frame._page : this._frame;
return await target.getAttribute(params.selector, params.name, params.options);
}
async hover(params: { selector: string, options: types.PointerActionOptions & types.TimeoutOptions & { force?: boolean } }): Promise<void> {
await this._frame.hover(params.selector, params.options);
async hover(params: { selector: string, options: types.PointerActionOptions & types.TimeoutOptions & { force?: boolean }, isPage?: boolean }): Promise<void> {
const target = params.isPage ? this._frame._page : this._frame;
await target.hover(params.selector, params.options);
}
async selectOption(params: { selector: string, values: string | ElementHandleChannel | types.SelectOption | string[] | ElementHandleChannel[] | types.SelectOption[] | null, options: types.NavigatingActionWaitOptions }): Promise<string[]> {
return this._frame.selectOption(params.selector, convertSelectOptionValues(params.values), params.options);
async selectOption(params: { selector: string, values: string | ElementHandleChannel | types.SelectOption | string[] | ElementHandleChannel[] | types.SelectOption[] | null, options: types.NavigatingActionWaitOptions, isPage?: boolean }): Promise<string[]> {
const target = params.isPage ? this._frame._page : this._frame;
return target.selectOption(params.selector, convertSelectOptionValues(params.values), params.options);
}
async setInputFiles(params: { selector: string, files: { name: string, mimeType: string, buffer: string }[], options: types.NavigatingActionWaitOptions }): Promise<void> {
await this._frame.setInputFiles(params.selector, params.files.map(f => ({ name: f.name, mimeType: f.mimeType, buffer: Buffer.from(f.buffer, 'base64') })), params.options);
async setInputFiles(params: { selector: string, files: { name: string, mimeType: string, buffer: string }[], options: types.NavigatingActionWaitOptions, isPage?: boolean }): Promise<void> {
const target = params.isPage ? this._frame._page : this._frame;
await target.setInputFiles(params.selector, params.files.map(f => ({ name: f.name, mimeType: f.mimeType, buffer: Buffer.from(f.buffer, 'base64') })), params.options);
}
async type(params: { selector: string, text: string, options: { delay?: number | undefined } & types.TimeoutOptions & { noWaitAfter?: boolean } }): Promise<void> {
await this._frame.type(params.selector, params.text, params.options);
async type(params: { selector: string, text: string, options: { delay?: number | undefined } & types.TimeoutOptions & { noWaitAfter?: boolean }, isPage?: boolean }): Promise<void> {
const target = params.isPage ? this._frame._page : this._frame;
await target.type(params.selector, params.text, params.options);
}
async press(params: { selector: string, key: string, options: { delay?: number | undefined } & types.TimeoutOptions & { noWaitAfter?: boolean } }): Promise<void> {
await this._frame.press(params.selector, params.key, params.options);
async press(params: { selector: string, key: string, options: { delay?: number | undefined } & types.TimeoutOptions & { noWaitAfter?: boolean }, isPage?: boolean }): Promise<void> {
const target = params.isPage ? this._frame._page : this._frame;
await target.press(params.selector, params.key, params.options);
}
async check(params: { selector: string, options: types.TimeoutOptions & { force?: boolean } & { noWaitAfter?: boolean } }): Promise<void> {
await this._frame.check(params.selector, params.options);
async check(params: { selector: string, options: types.TimeoutOptions & { force?: boolean } & { noWaitAfter?: boolean }, isPage?: boolean }): Promise<void> {
const target = params.isPage ? this._frame._page : this._frame;
await target.check(params.selector, params.options);
}
async uncheck(params: { selector: string, options: types.TimeoutOptions & { force?: boolean } & { noWaitAfter?: boolean } }): Promise<void> {
await this._frame.uncheck(params.selector, params.options);
async uncheck(params: { selector: string, options: types.TimeoutOptions & { force?: boolean } & { noWaitAfter?: boolean }, isPage?: boolean }): Promise<void> {
const target = params.isPage ? this._frame._page : this._frame;
await target.uncheck(params.selector, params.options);
}
async waitForFunction(params: { expression: string, isFunction: boolean, arg: any; options: types.WaitForFunctionOptions }): Promise<JSHandleChannel> {
return ElementHandleDispatcher.from(this._scope, await this._frame._waitForFunctionExpression(params.expression, params.isFunction, parseArgument(params.arg), params.options));
async waitForFunction(params: { expression: string, isFunction: boolean, arg: any; options: types.WaitForFunctionOptions, isPage?: boolean }): Promise<JSHandleChannel> {
const target = params.isPage ? this._frame._page : this._frame;
return ElementHandleDispatcher.from(this._scope, await target._waitForFunctionExpression(params.expression, params.isFunction, parseArgument(params.arg), params.options));
}
async title(): Promise<string> {

View File

@ -75,8 +75,8 @@ export class ResponseDispatcher extends Dispatcher<Response, ResponseInitializer
return await this._object.finished();
}
async body(): Promise<Buffer> {
return await this._object.body();
async body(): Promise<Binary> {
return (await this._object.body()).toString('base64');
}
}

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
const {FFOX, CHROMIUM, WEBKIT} = require('./utils').testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT, USES_HOOKS} = require('./utils').testOptions(browserType);
describe('Auto waiting', () => {
it('should await navigation when clicking anchor', async({page, server}) => {
@ -187,7 +187,7 @@ describe('Auto waiting', () => {
await page.click('input[type=submit]');
await page.goto(server.EMPTY_PAGE);
});
it('should report navigation in the log when clicking anchor', async({page, server}) => {
it.skip(USES_HOOKS)('should report navigation in the log when clicking anchor', async({page, server}) => {
await page.setContent(`<a href="${server.PREFIX + '/frames/one-frame.html'}">click me</a>`);
const __testHookAfterPointerAction = () => new Promise(f => setTimeout(f, 6000));
const error = await page.click('a', { timeout: 5000, __testHookAfterPointerAction }).catch(e => e);

View File

@ -17,7 +17,7 @@
const path = require('path');
const utils = require('../utils');
const {makeUserDataDir, removeUserDataDir} = utils;
const {FFOX, CHROMIUM, WEBKIT, WIN} = utils.testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT, WIN, USES_HOOKS} = utils.testOptions(browserType);
describe('launcher', function() {
it('should throw with remote-debugging-pipe argument', async({browserType, defaultBrowserOptions}) => {
@ -32,7 +32,7 @@ describe('launcher', function() {
const browser = await browserType.launchServer(options);
await browser.close();
});
it('should open devtools when "devtools: true" option is given', async({browserType, defaultBrowserOptions}) => {
it.skip(USES_HOOKS)('should open devtools when "devtools: true" option is given', async({browserType, defaultBrowserOptions}) => {
let devtoolsCallback;
const devtoolsPromise = new Promise(f => devtoolsCallback = f);
const __testHookForDevTools = devtools => devtools.__testHookOnBinding = parsed => {

View File

@ -16,7 +16,7 @@
*/
const utils = require('./utils');
const {FFOX, CHROMIUM, WEBKIT, WIN} = utils.testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT, WIN, USES_HOOKS} = utils.testOptions(browserType);
async function giveItAChanceToClick(page) {
for (let i = 0; i < 5; i++)
@ -66,7 +66,7 @@ describe('Page.click', function() {
]).catch(e => {});
await context.close();
});
it('should avoid side effects after timeout', async({page, server}) => {
it.skip(USES_HOOKS)('should avoid side effects after timeout', async({page, server}) => {
await page.goto(server.PREFIX + '/input/button.html');
const error = await page.click('button', { timeout: 2000, __testHookBeforePointerAction: () => new Promise(f => setTimeout(f, 2500))}).catch(e => e);
await page.waitForTimeout(5000); // Give it some time to click after the test hook is done waiting.
@ -707,7 +707,7 @@ describe('Page.click', function() {
expect(await page.evaluate(() => window.clicked)).toBe(undefined);
expect(error.message).toContain('Element is outside of the viewport');
});
it('should fail when element jumps during hit testing', async({page, server}) => {
it.skip(USES_HOOKS)('should fail when element jumps during hit testing', async({page, server}) => {
await page.setContent('<button>Click me</button>');
let clicked = false;
const handle = await page.$('button');
@ -745,7 +745,7 @@ describe('Page.click', function() {
await page.click('button');
expect(await page.evaluate(() => window.result)).toBe(1);
});
it.fail(true)('should retarget when element is recycled during hit testing', async ({page, server}) => {
it.skip(USES_HOOKS).fail(true)('should retarget when element is recycled during hit testing', async ({page, server}) => {
await page.goto(server.PREFIX + '/react.html');
await page.evaluate(() => {
renderComponent(e('div', {}, [e(MyButton, { name: 'button1' }), e(MyButton, { name: 'button2' })] ));
@ -759,7 +759,7 @@ describe('Page.click', function() {
expect(await page.evaluate(() => window.button1)).toBe(true);
expect(await page.evaluate(() => window.button2)).toBe(undefined);
});
it.fail(true)('should report that selector does not match anymore', async ({page, server}) => {
it.skip(USES_HOOKS).fail(true)('should report that selector does not match anymore', async ({page, server}) => {
await page.goto(server.PREFIX + '/react.html');
await page.evaluate(() => {
renderComponent(e('div', {}, [e(MyButton, { name: 'button1' }), e(MyButton, { name: 'button2' })] ));
@ -777,7 +777,7 @@ describe('Page.click', function() {
expect(error.message).toContain('Timeout 3000ms exceeded during page.dblclick.');
expect(error.message).toContain('element does not match the selector anymore');
});
it.fail(true)('should retarget when element is recycled before enabled check', async ({page, server}) => {
it.skip(USES_HOOKS).fail(true)('should retarget when element is recycled before enabled check', async ({page, server}) => {
await page.goto(server.PREFIX + '/react.html');
await page.evaluate(() => {
renderComponent(e('div', {}, [e(MyButton, { name: 'button1' }), e(MyButton, { name: 'button2', disabled: true })] ));
@ -791,7 +791,7 @@ describe('Page.click', function() {
expect(await page.evaluate(() => window.button1)).toBe(true);
expect(await page.evaluate(() => window.button2)).toBe(undefined);
});
it.fail(true)('should not retarget the handle when element is recycled', async ({page, server}) => {
it.skip(USES_HOOKS).fail(true)('should not retarget the handle when element is recycled', async ({page, server}) => {
await page.goto(server.PREFIX + '/react.html');
await page.evaluate(() => {
renderComponent(e('div', {}, [e(MyButton, { name: 'button1' }), e(MyButton, { name: 'button2', disabled: true })] ));

View File

@ -18,7 +18,7 @@
const fs = require('fs');
const utils = require('./utils');
const {makeUserDataDir, removeUserDataDir} = utils;
const {FFOX, MAC, CHROMIUM, WEBKIT, WIN} = utils.testOptions(browserType);
const {FFOX, MAC, CHROMIUM, WEBKIT, WIN, USES_HOOKS} = utils.testOptions(browserType);
describe('launchPersistentContext()', function() {
async function launch(state, options = {}) {
@ -353,14 +353,14 @@ describe('launchPersistentContext()', function() {
await browserContext.close();
await removeUserDataDir(userDataDir);
});
it('should handle timeout', async({browserType, defaultBrowserOptions}) => {
it.skip(USES_HOOKS)('should handle timeout', async({browserType, defaultBrowserOptions}) => {
const userDataDir = await makeUserDataDir();
const options = { ...defaultBrowserOptions, timeout: 5000, __testHookBeforeCreateBrowser: () => new Promise(f => setTimeout(f, 6000)) };
const error = await browserType.launchPersistentContext(userDataDir, options).catch(e => e);
expect(error.message).toContain(`Timeout 5000ms exceeded during browserType.launchPersistentContext.`);
await removeUserDataDir(userDataDir);
});
it('should handle exception', async({browserType, defaultBrowserOptions}) => {
it.skip(USES_HOOKS)('should handle exception', async({browserType, defaultBrowserOptions}) => {
const userDataDir = await makeUserDataDir();
const e = new Error('Dummy');
const options = { ...defaultBrowserOptions, __testHookBeforeCreateBrowser: () => { throw e; } };

View File

@ -17,7 +17,7 @@
const utils = require('./utils');
const path = require('path');
const {FFOX, CHROMIUM, WEBKIT} = utils.testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT, USES_HOOKS} = utils.testOptions(browserType);
describe('Page.evaluate', function() {
it('should work', async({page, server}) => {
@ -574,14 +574,14 @@ describe('Frame.evaluate', function() {
else
expect(page._delegate._contextIdToContext.size).toBe(count);
}
it('should dispose context on navigation', async({page, server}) => {
it.skip(USES_HOOKS)('should dispose context on navigation', async({page, server}) => {
await page.goto(server.PREFIX + '/frames/one-frame.html');
expect(page.frames().length).toBe(2);
expectContexts(page, 4);
await page.goto(server.EMPTY_PAGE);
expectContexts(page, 2);
});
it('should dispose context on cross-origin navigation', async({page, server}) => {
it.skip(USES_HOOKS)('should dispose context on cross-origin navigation', async({page, server}) => {
await page.goto(server.PREFIX + '/frames/one-frame.html');
expect(page.frames().length).toBe(2);
expectContexts(page, 4);

View File

@ -18,7 +18,7 @@
const path = require('path');
const fs = require('fs');
const utils = require('./utils');
const {FFOX, CHROMIUM, WEBKIT} = utils.testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT, USES_HOOKS} = utils.testOptions(browserType);
describe('Playwright', function() {
describe('browserType.launch', function() {
@ -50,20 +50,20 @@ describe('Playwright', function() {
await browserType.launch(options).catch(e => waitError = e);
expect(waitError.message).toContain('Failed to launch');
});
it('should handle timeout', async({browserType, defaultBrowserOptions}) => {
it.skip(USES_HOOKS)('should handle timeout', async({browserType, defaultBrowserOptions}) => {
const options = { ...defaultBrowserOptions, timeout: 5000, __testHookBeforeCreateBrowser: () => new Promise(f => setTimeout(f, 6000)) };
const error = await browserType.launch(options).catch(e => e);
expect(error.message).toContain(`Timeout 5000ms exceeded during browserType.launch.`);
expect(error.message).toContain(`[browser] <launching>`);
expect(error.message).toContain(`[browser] <launched> pid=`);
});
it('should handle exception', async({browserType, defaultBrowserOptions}) => {
it.skip(USES_HOOKS)('should handle exception', async({browserType, defaultBrowserOptions}) => {
const e = new Error('Dummy');
const options = { ...defaultBrowserOptions, __testHookBeforeCreateBrowser: () => { throw e; }, timeout: 9000 };
const error = await browserType.launch(options).catch(e => e);
expect(error).toBe(e);
});
it('should report launch log', async({browserType, defaultBrowserOptions}) => {
it.skip(USES_HOOKS)('should report launch log', async({browserType, defaultBrowserOptions}) => {
const e = new Error('Dummy');
const options = { ...defaultBrowserOptions, __testHookBeforeCreateBrowser: () => { throw e; }, timeout: 9000 };
const error = await browserType.launch(options).catch(e => e);
@ -293,7 +293,7 @@ describe('browserType.connect', function() {
await browserServer._checkLeaks();
await browserServer.close();
});
it.slow()('should handle exceptions during connect', async({browserType, defaultBrowserOptions, server}) => {
it.skip(USES_HOOKS).slow()('should handle exceptions during connect', async({browserType, defaultBrowserOptions, server}) => {
const browserServer = await browserType.launchServer(defaultBrowserOptions);
const __testHookBeforeCreateBrowser = () => { throw new Error('Dummy') };
const error = await browserType.connect({ wsEndpoint: browserServer.wsEndpoint(), __testHookBeforeCreateBrowser }).catch(e => e);

View File

@ -17,7 +17,7 @@
const path = require('path');
const utils = require('./utils');
const {FFOX, CHROMIUM, WEBKIT} = utils.testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT, USES_HOOKS} = utils.testOptions(browserType);
describe('Page.$eval', function() {
it('should work with css selector', async({page, server}) => {
@ -515,7 +515,7 @@ describe('text selector', () => {
expect(await page.$$eval(`text=lowo`, els => els.map(e => e.outerHTML).join(''))).toBe('<div>helloworld</div><span>helloworld</span>');
});
it('create', async ({page}) => {
it.skip(USES_HOOKS)('create', async ({page}) => {
await page.setContent(`<div>yo</div><div>"ya</div><div>ye ye</div>`);
expect(await playwright.selectors._createSelector('text', await page.$('div'))).toBe('yo');
expect(await playwright.selectors._createSelector('text', await page.$('div:nth-child(2)'))).toBe('"\\"ya"');
@ -744,7 +744,7 @@ describe('attribute selector', () => {
});
describe('selectors.register', () => {
it('should work', async ({page}) => {
it.skip(USES_HOOKS)('should work', async ({page}) => {
const createTagSelector = () => ({
create(root, target) {
return target.nodeName;

View File

@ -15,7 +15,7 @@
*/
const { Writable } = require('stream');
const {FFOX, CHROMIUM, WEBKIT} = require('./utils').testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT, USES_HOOKS} = require('./utils').testOptions(browserType);
const pattern = [
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
@ -56,7 +56,7 @@ class WritableBuffer {
}
}
describe('Recorder', function() {
describe.skip(USES_HOOKS)('Recorder', function() {
beforeEach(async state => {
state.context = await state.browser.newContext();
state.output = new WritableBuffer();

View File

@ -16,7 +16,7 @@
*/
const utils = require('./utils');
const {FFOX, CHROMIUM, WEBKIT} = utils.testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT, USES_HOOKS} = utils.testOptions(browserType);
const {PNG} = require('pngjs');
// Firefox headful produces a different image.
@ -474,7 +474,7 @@ describe.skip(ffheadful)('ElementHandle.screenshot', function() {
await utils.verifyViewport(page, 456, 789);
await context.close();
});
it('should restore viewport after page screenshot and exception', async({ browser, server }) => {
it.skip(USES_HOOKS)('should restore viewport after page screenshot and exception', async({ browser, server }) => {
const context = await browser.newContext({ viewport: { width: 350, height: 360 } });
const page = await context.newPage();
await page.goto(server.PREFIX + '/grid.html');
@ -484,7 +484,7 @@ describe.skip(ffheadful)('ElementHandle.screenshot', function() {
await utils.verifyViewport(page, 350, 360);
await context.close();
});
it('should restore viewport after page screenshot and timeout', async({ browser, server }) => {
it.skip(USES_HOOKS)('should restore viewport after page screenshot and timeout', async({ browser, server }) => {
const context = await browser.newContext({ viewport: { width: 350, height: 360 } });
const page = await context.newPage();
await page.goto(server.PREFIX + '/grid.html');
@ -526,7 +526,7 @@ describe.skip(ffheadful)('ElementHandle.screenshot', function() {
expect(sizeBefore.height).toBe(sizeAfter.height);
await context.close();
});
it('should restore viewport after element screenshot and exception', async({server, browser}) => {
it.skip(USES_HOOKS)('should restore viewport after element screenshot and exception', async({server, browser}) => {
const context = await browser.newContext({ viewport: { width: 350, height: 360 } });
const page = await context.newPage();
await page.setContent(`<div style="width:600px;height:600px;"></div>`);

View File

@ -200,6 +200,7 @@ const utils = module.exports = {
browserType,
GOLDEN_DIR,
OUTPUT_DIR,
USES_HOOKS: !!process.env.PWCHANNEL
};
},