chore: use progress.continuePolling instead of passing it around (#9929)

This commit is contained in:
Dmitry Gozman 2021-11-01 13:57:13 -07:00 committed by GitHub
parent b924b7e076
commit 50f7477906
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 28 deletions

View File

@ -952,7 +952,7 @@ export function waitForSelectorTask(selector: SelectorInfo, state: 'attached' |
return injectedScript => injectedScript.evaluateHandle((injected, { parsed, strict, state, omitReturnValue, root }) => {
let lastElement: Element | undefined;
return injected.pollRaf((progress, continuePolling) => {
return injected.pollRaf(progress => {
const elements = injected.querySelectorAll(parsed, root || document);
let element: Element | undefined = elements[0];
const visible = element ? injected.isVisible(element) : false;
@ -977,13 +977,13 @@ export function waitForSelectorTask(selector: SelectorInfo, state: 'attached' |
switch (state) {
case 'attached':
return hasElement ? element : continuePolling;
return hasElement ? element : progress.continuePolling;
case 'detached':
return !hasElement ? undefined : continuePolling;
return !hasElement ? undefined : progress.continuePolling;
case 'visible':
return visible ? element : continuePolling;
return visible ? element : progress.continuePolling;
case 'hidden':
return !visible ? undefined : continuePolling;
return !visible ? undefined : progress.continuePolling;
}
});
}, { parsed: selector.parsed, strict: selector.strict, state, omitReturnValue, root });

View File

@ -70,7 +70,7 @@ export type NavigationEvent = {
};
export type SchedulableTask<T> = (injectedScript: js.JSHandle<InjectedScript>) => Promise<js.JSHandle<InjectedScriptPoll<T>>>;
export type DomTaskBody<T, R, E> = (progress: InjectedScriptProgress, element: E, data: T, elements: Element[], continuePolling: symbol) => R | symbol;
export type DomTaskBody<T, R, E> = (progress: InjectedScriptProgress, element: E, data: T, elements: Element[]) => R | symbol;
export class FrameManager {
private _page: Page;
@ -1158,7 +1158,7 @@ export class Frame extends SdkObject {
const controller = new ProgressController(metadata, this);
const querySelectorAll = options.expression === 'to.have.count' || options.expression.endsWith('.array');
const mainWorld = options.expression === 'to.have.property';
return await this._scheduleRerunnableTaskWithController(controller, selector, (progress, element, options, elements, continuePolling) => {
return await this._scheduleRerunnableTaskWithController(controller, selector, (progress, element, options, elements) => {
if (!element) {
// expect(locator).toBeHidden() passes when there is no element.
if (!options.isNot && options.expression === 'to.be.hidden')
@ -1181,7 +1181,7 @@ export class Frame extends SdkObject {
return { matches: expectsEmptyCount, received: 0 };
// When none of the above applies, keep waiting for the element.
return continuePolling;
return progress.continuePolling;
}
const { matches, received } = progress.injectedScript.expect(progress, element, options, elements);
@ -1192,7 +1192,7 @@ export class Frame extends SdkObject {
progress.setIntermediateResult(received);
if (!Array.isArray(received))
progress.log(` unexpected value "${received}"`);
return continuePolling;
return progress.continuePolling;
}
// Reached the expected state!
@ -1226,8 +1226,8 @@ export class Frame extends SdkObject {
return result;
};
if (typeof polling !== 'number')
return injectedScript.pollRaf((progress, continuePolling) => predicate(arg) || continuePolling);
return injectedScript.pollInterval(polling, (progress, continuePolling) => predicate(arg) || continuePolling);
return injectedScript.pollRaf(progress => predicate(arg) || progress.continuePolling);
return injectedScript.pollInterval(polling, progress => predicate(arg) || progress.continuePolling);
}, { expression, isFunction, polling: options.pollingInterval, arg });
return controller.run(
progress => this._scheduleRerunnableHandleTask(progress, world, task),
@ -1286,7 +1286,7 @@ export class Frame extends SdkObject {
const callback = injected.eval(callbackText) as DomTaskBody<T, R, Element | undefined>;
const poller = logScale ? injected.pollLogScale.bind(injected) : injected.pollRaf.bind(injected);
let markedElements = new Set<Element>();
return poller((progress, continuePolling) => {
return poller(progress => {
let element: Element | undefined;
let elements: Element[] = [];
if (querySelectorAll) {
@ -1301,7 +1301,7 @@ export class Frame extends SdkObject {
}
if (!element && !omitAttached)
return continuePolling;
return progress.continuePolling;
if (snapshotName) {
const previouslyMarkedElements = markedElements;
@ -1316,7 +1316,7 @@ export class Frame extends SdkObject {
}
}
return callback(progress, element, taskData as T, elements, continuePolling);
return callback(progress, element, taskData as T, elements);
});
}, { info, taskData, callbackText, querySelectorAll: options.querySelectorAll, logScale: options.logScale, omitAttached: options.omitAttached, snapshotName: progress.metadata.afterSnapshot });
}, true);

View File

@ -24,10 +24,11 @@ import { CSSComplexSelectorList } from '../common/cssParser';
import { generateSelector } from './selectorGenerator';
import type * as channels from '../../protocol/channels';
type Predicate<T> = (progress: InjectedScriptProgress, continuePolling: symbol) => T | symbol;
type Predicate<T> = (progress: InjectedScriptProgress) => T | symbol;
export type InjectedScriptProgress = {
injectedScript: InjectedScript;
continuePolling: symbol;
aborted: boolean;
log: (message: string) => void;
logRepeating: (message: string) => void;
@ -293,9 +294,8 @@ export class InjectedScript {
if (progress.aborted)
return;
try {
const continuePolling = Symbol('continuePolling');
const success = predicate(progress, continuePolling);
if (success !== continuePolling)
const success = predicate(progress);
if (success !== progress.continuePolling)
fulfill(success as T);
else
scheduleNext(next);
@ -333,6 +333,7 @@ export class InjectedScript {
const progress: InjectedScriptProgress = {
injectedScript: this,
aborted: false,
continuePolling: Symbol('continuePolling'),
log: (message: string) => {
lastMessage = message;
unsentLog.push({ message });
@ -399,16 +400,16 @@ export class InjectedScript {
}
waitForElementStatesAndPerformAction<T>(node: Node, states: ElementState[], force: boolean | undefined,
callback: (node: Node, progress: InjectedScriptProgress, continuePolling: symbol) => T | symbol): InjectedScriptPoll<T | 'error:notconnected'> {
callback: (node: Node, progress: InjectedScriptProgress) => T | symbol): InjectedScriptPoll<T | 'error:notconnected'> {
let lastRect: { x: number, y: number, width: number, height: number } | undefined;
let counter = 0;
let samePositionCounter = 0;
let lastTime = 0;
return this.pollRaf((progress, continuePolling) => {
return this.pollRaf(progress => {
if (force) {
progress.log(` forcing action`);
return callback(node, progress, continuePolling);
return callback(node, progress);
}
for (const state of states) {
@ -418,7 +419,7 @@ export class InjectedScript {
return result;
if (!result) {
progress.logRepeating(` element is not ${state} - waiting...`);
return continuePolling;
return progress.continuePolling;
}
continue;
}
@ -431,12 +432,12 @@ export class InjectedScript {
// any client rect difference compared to synchronous call. We skip the synchronous call
// and only force layout during actual rafs as a small optimisation.
if (++counter === 1)
return continuePolling;
return progress.continuePolling;
// Drop frames that are shorter than 16ms - WebKit Win bug.
const time = performance.now();
if (this._stableRafCount > 1 && time - lastTime < 15)
return continuePolling;
return progress.continuePolling;
lastTime = time;
const clientRect = element.getBoundingClientRect();
@ -452,10 +453,10 @@ export class InjectedScript {
if (!isStableForLogs)
progress.logRepeating(` element is not stable - waiting...`);
if (!isStable)
return continuePolling;
return progress.continuePolling;
}
return callback(node, progress, continuePolling);
return callback(node, progress);
});
}
@ -495,7 +496,7 @@ export class InjectedScript {
}
selectOptions(optionsToSelect: (Node | { value?: string, label?: string, index?: number })[],
node: Node, progress: InjectedScriptProgress, continuePolling: symbol): string[] | 'error:notconnected' | symbol {
node: Node, progress: InjectedScriptProgress): string[] | 'error:notconnected' | symbol {
const element = this.retarget(node, 'follow-label');
if (!element)
return 'error:notconnected';
@ -531,7 +532,7 @@ export class InjectedScript {
}
if (remainingOptionsToSelect.length) {
progress.logRepeating(' did not find some options - waiting... ');
return continuePolling;
return progress.continuePolling;
}
select.value = undefined as any;
selectedOptions.forEach(option => option.selected = true);