fix: predicate arguments for waitForFunction (#7845)

The same predicate function is used by the waitForFunction
API that does not need the context element.

Issues: #7836
This commit is contained in:
Alex Rudenko 2021-12-15 09:40:56 +01:00 committed by GitHub
parent 36207c5efe
commit 1c44551f1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 5 deletions

View File

@ -645,6 +645,7 @@ export class DOMWorld {
const waitTaskOptions: WaitTaskOptions = { const waitTaskOptions: WaitTaskOptions = {
domWorld: this, domWorld: this,
predicateBody: helper.makePredicateString(predicate, queryOne), predicateBody: helper.makePredicateString(predicate, queryOne),
predicateAcceptsContextElement: true,
title, title,
polling, polling,
timeout, timeout,
@ -691,6 +692,7 @@ export class DOMWorld {
const waitTaskOptions: WaitTaskOptions = { const waitTaskOptions: WaitTaskOptions = {
domWorld: this, domWorld: this,
predicateBody: helper.makePredicateString(predicate), predicateBody: helper.makePredicateString(predicate),
predicateAcceptsContextElement: true,
title, title,
polling, polling,
timeout, timeout,
@ -717,6 +719,7 @@ export class DOMWorld {
const waitTaskOptions: WaitTaskOptions = { const waitTaskOptions: WaitTaskOptions = {
domWorld: this, domWorld: this,
predicateBody: pageFunction, predicateBody: pageFunction,
predicateAcceptsContextElement: false,
title: 'function', title: 'function',
polling, polling,
timeout, timeout,
@ -737,6 +740,7 @@ export class DOMWorld {
export interface WaitTaskOptions { export interface WaitTaskOptions {
domWorld: DOMWorld; domWorld: DOMWorld;
predicateBody: Function | string; predicateBody: Function | string;
predicateAcceptsContextElement: boolean;
title: string; title: string;
polling: string | number; polling: string | number;
timeout: number; timeout: number;
@ -753,6 +757,7 @@ export class WaitTask {
_polling: string | number; _polling: string | number;
_timeout: number; _timeout: number;
_predicateBody: string; _predicateBody: string;
_predicateAcceptsContextElement: boolean;
_args: SerializableOrJSHandle[]; _args: SerializableOrJSHandle[];
_binding: PageBinding; _binding: PageBinding;
_runCount = 0; _runCount = 0;
@ -786,6 +791,8 @@ export class WaitTask {
this._timeout = options.timeout; this._timeout = options.timeout;
this._root = options.root; this._root = options.root;
this._predicateBody = getPredicateBody(options.predicateBody); this._predicateBody = getPredicateBody(options.predicateBody);
this._predicateAcceptsContextElement =
options.predicateAcceptsContextElement;
this._args = options.args; this._args = options.args;
this._binding = options.binding; this._binding = options.binding;
this._runCount = 0; this._runCount = 0;
@ -835,6 +842,7 @@ export class WaitTask {
success = await this._root.evaluateHandle( success = await this._root.evaluateHandle(
waitForPredicatePageFunction, waitForPredicatePageFunction,
this._predicateBody, this._predicateBody,
this._predicateAcceptsContextElement,
this._polling, this._polling,
this._timeout, this._timeout,
...this._args ...this._args
@ -844,6 +852,7 @@ export class WaitTask {
waitForPredicatePageFunction, waitForPredicatePageFunction,
null, null,
this._predicateBody, this._predicateBody,
this._predicateAcceptsContextElement,
this._polling, this._polling,
this._timeout, this._timeout,
...this._args ...this._args
@ -911,6 +920,7 @@ export class WaitTask {
async function waitForPredicatePageFunction( async function waitForPredicatePageFunction(
root: Element | Document | null, root: Element | Document | null,
predicateBody: string, predicateBody: string,
predicateAcceptsContextElement: boolean,
polling: string, polling: string,
timeout: number, timeout: number,
...args: unknown[] ...args: unknown[]
@ -927,7 +937,9 @@ async function waitForPredicatePageFunction(
* @returns {!Promise<*>} * @returns {!Promise<*>}
*/ */
async function pollMutation(): Promise<unknown> { async function pollMutation(): Promise<unknown> {
const success = await predicate(root, ...args); const success = predicateAcceptsContextElement
? await predicate(root, ...args)
: await predicate(...args);
if (success) return Promise.resolve(success); if (success) return Promise.resolve(success);
let fulfill; let fulfill;
@ -937,7 +949,9 @@ async function waitForPredicatePageFunction(
observer.disconnect(); observer.disconnect();
fulfill(); fulfill();
} }
const success = await predicate(root, ...args); const success = predicateAcceptsContextElement
? await predicate(root, ...args)
: await predicate(...args);
if (success) { if (success) {
observer.disconnect(); observer.disconnect();
fulfill(success); fulfill(success);
@ -962,7 +976,9 @@ async function waitForPredicatePageFunction(
fulfill(); fulfill();
return; return;
} }
const success = await predicate(root, ...args); const success = predicateAcceptsContextElement
? await predicate(root, ...args)
: await predicate(...args);
if (success) fulfill(success); if (success) fulfill(success);
else requestAnimationFrame(onRaf); else requestAnimationFrame(onRaf);
} }
@ -979,7 +995,9 @@ async function waitForPredicatePageFunction(
fulfill(); fulfill();
return; return;
} }
const success = await predicate(root, ...args); const success = predicateAcceptsContextElement
? await predicate(root, ...args)
: await predicate(...args);
if (success) fulfill(success); if (success) fulfill(success);
else setTimeout(onTimeout, pollInterval); else setTimeout(onTimeout, pollInterval);
} }

View File

@ -293,7 +293,11 @@ describe('waittask specs', function () {
const div = await page.$('div'); const div = await page.$('div');
let resolved = false; let resolved = false;
const waitForFunction = page const waitForFunction = page
.waitForFunction((element) => !element.parentElement, {}, div) .waitForFunction(
(element) => element.localName === 'div' && !element.parentElement,
{},
div
)
.then(() => (resolved = true)); .then(() => (resolved = true));
expect(resolved).toBe(false); expect(resolved).toBe(false);
await page.evaluate((element: HTMLElement) => element.remove(), div); await page.evaluate((element: HTMLElement) => element.remove(), div);