chore: refactor locator options (#10325)

This commit is contained in:
Alex Rudenko 2023-06-06 13:03:32 +02:00 committed by GitHub
parent a5d4900294
commit 1d43e571d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -66,7 +66,7 @@ export interface LocatorOptions {
/** /**
* Timeout for individual operations inside the locator. On errors the * Timeout for individual operations inside the locator. On errors the
* operation is retried as long as {@link LocatorOptions.timeout} is not * operation is retried as long as {@link Locator.setTimeout} is not
* exceeded. This timeout should be generally much lower as locating an * exceeded. This timeout should be generally much lower as locating an
* element means multiple asynchronious operations. * element means multiple asynchronious operations.
*/ */
@ -120,45 +120,26 @@ export class Locator extends EventEmitter {
/** /**
* @internal * @internal
*/ */
static create( static create(pageOrFrame: Page | Frame, selector: string): Locator {
pageOrFrame: Page | Frame, return new Locator(pageOrFrame, selector).setTimeout(
selector: string, 'getDefaultTimeout' in pageOrFrame
options: LocatorOptions = { ? pageOrFrame.getDefaultTimeout()
visibility: 'visible', : pageOrFrame.page().getDefaultTimeout()
timeout: );
'getDefaultTimeout' in pageOrFrame
? pageOrFrame.getDefaultTimeout()
: pageOrFrame.page().getDefaultTimeout(),
ensureElementIsInTheViewport: true,
waitForEnabled: true,
waitForStableBoundingBox: true,
}
): Locator {
return new Locator(pageOrFrame, selector, options);
} }
#pageOrFrame: Page | Frame; #pageOrFrame: Page | Frame;
#selector: string; #selector: string;
#options: LocatorOptions; #visibility: VisibilityOption = 'visible';
#timeout = 30_000;
#ensureElementIsInTheViewport = true;
#waitForEnabled = true;
#waitForStableBoundingBox = true;
private constructor( private constructor(pageOrFrame: Page | Frame, selector: string) {
pageOrFrame: Page | Frame,
selector: string,
options: LocatorOptions = {
visibility: 'visible',
timeout:
'getDefaultTimeout' in pageOrFrame
? pageOrFrame.getDefaultTimeout()
: pageOrFrame.page().getDefaultTimeout(),
ensureElementIsInTheViewport: true,
waitForEnabled: true,
waitForStableBoundingBox: true,
}
) {
super(); super();
this.#pageOrFrame = pageOrFrame; this.#pageOrFrame = pageOrFrame;
this.#selector = selector; this.#selector = selector;
this.#options = options;
} }
override on<K extends keyof LocatorEventObject>( override on<K extends keyof LocatorEventObject>(
@ -183,27 +164,27 @@ export class Locator extends EventEmitter {
} }
setVisibility(visibility: VisibilityOption): this { setVisibility(visibility: VisibilityOption): this {
this.#options.visibility = visibility; this.#visibility = visibility;
return this; return this;
} }
setTimeout(timeout: number): this { setTimeout(timeout: number): this {
this.#options.timeout = timeout; this.#timeout = timeout;
return this; return this;
} }
setEnsureElementIsInTheViewport(value: boolean): this { setEnsureElementIsInTheViewport(value: boolean): this {
this.#options.ensureElementIsInTheViewport = value; this.#ensureElementIsInTheViewport = value;
return this; return this;
} }
setWaitForEnabled(value: boolean): this { setWaitForEnabled(value: boolean): this {
this.#options.waitForEnabled = value; this.#waitForEnabled = value;
return this; return this;
} }
setWaitForStableBoundingBox(value: boolean): this { setWaitForStableBoundingBox(value: boolean): this {
this.#options.waitForStableBoundingBox = value; this.#waitForStableBoundingBox = value;
return this; return this;
} }
@ -272,11 +253,11 @@ export class Locator extends EventEmitter {
/** /**
* Checks if the element is in the viewport and auto-scrolls it if it is not. * Checks if the element is in the viewport and auto-scrolls it if it is not.
*/ */
#ensureElementIsInTheViewport = async ( #ensureElementIsInTheViewportIfNeeded = async (
element: ElementHandle, element: ElementHandle,
signal?: AbortSignal signal?: AbortSignal
): Promise<void> => { ): Promise<void> => {
if (!this.#options.ensureElementIsInTheViewport) { if (!this.#ensureElementIsInTheViewport) {
return; return;
} }
// Side-effect: this also checks if it is connected. // Side-effect: this also checks if it is connected.
@ -302,14 +283,14 @@ export class Locator extends EventEmitter {
* than 'hidden' or 'collapse' and non-empty bounding box. visibility === * than 'hidden' or 'collapse' and non-empty bounding box. visibility ===
* 'hidden' means the opposite of that. * 'hidden' means the opposite of that.
*/ */
#waitForVisibility = async ( #waitForVisibilityIfNeeded = async (
element: ElementHandle, element: ElementHandle,
signal?: AbortSignal signal?: AbortSignal
): Promise<void> => { ): Promise<void> => {
if (this.#options.visibility === null) { if (this.#visibility === null) {
return; return;
} }
if (this.#options.visibility === 'hidden') { if (this.#visibility === 'hidden') {
await this.#waitForFunction(async () => { await this.#waitForFunction(async () => {
return element.isHidden(); return element.isHidden();
}, signal); }, signal);
@ -323,11 +304,11 @@ export class Locator extends EventEmitter {
* If the element is a button, textarea, input or select, wait till the * If the element is a button, textarea, input or select, wait till the
* element becomes enabled. * element becomes enabled.
*/ */
#waitForEnabled = async ( #waitForEnabledIfNeeded = async (
element: ElementHandle, element: ElementHandle,
signal?: AbortSignal signal?: AbortSignal
): Promise<void> => { ): Promise<void> => {
if (!this.#options.waitForEnabled) { if (!this.#waitForEnabled) {
return; return;
} }
await this.#pageOrFrame.waitForFunction( await this.#pageOrFrame.waitForFunction(
@ -349,11 +330,11 @@ export class Locator extends EventEmitter {
* Compares the bounding box of the element for two consecutive animation * Compares the bounding box of the element for two consecutive animation
* frames and waits till they are the same. * frames and waits till they are the same.
*/ */
#waitForStableBoundingBox = async ( #waitForStableBoundingBoxIfNeeded = async (
element: ElementHandle, element: ElementHandle,
signal?: AbortSignal signal?: AbortSignal
): Promise<void> => { ): Promise<void> => {
if (!this.#options.waitForStableBoundingBox) { if (!this.#waitForStableBoundingBox) {
return; return;
} }
function getClientRect() { function getClientRect() {
@ -404,7 +385,7 @@ export class Locator extends EventEmitter {
this.#selector, this.#selector,
{ {
visible: false, visible: false,
timeout: this.#options.timeout, timeout: this.#timeout,
signal, signal,
} }
); );
@ -430,7 +411,7 @@ export class Locator extends EventEmitter {
} }
}, },
options?.signal, options?.signal,
this.#options.timeout this.#timeout
); );
} }
@ -446,10 +427,10 @@ export class Locator extends EventEmitter {
{ {
signal: clickOptions?.signal, signal: clickOptions?.signal,
conditions: [ conditions: [
this.#ensureElementIsInTheViewport, this.#ensureElementIsInTheViewportIfNeeded,
this.#waitForVisibility, this.#waitForVisibilityIfNeeded,
this.#waitForEnabled, this.#waitForEnabledIfNeeded,
this.#waitForStableBoundingBox, this.#waitForStableBoundingBoxIfNeeded,
], ],
} }
); );
@ -556,10 +537,10 @@ export class Locator extends EventEmitter {
{ {
signal: fillOptions?.signal, signal: fillOptions?.signal,
conditions: [ conditions: [
this.#ensureElementIsInTheViewport, this.#ensureElementIsInTheViewportIfNeeded,
this.#waitForVisibility, this.#waitForVisibilityIfNeeded,
this.#waitForEnabled, this.#waitForEnabledIfNeeded,
this.#waitForStableBoundingBox, this.#waitForStableBoundingBoxIfNeeded,
], ],
} }
); );
@ -573,9 +554,9 @@ export class Locator extends EventEmitter {
{ {
signal: hoverOptions?.signal, signal: hoverOptions?.signal,
conditions: [ conditions: [
this.#ensureElementIsInTheViewport, this.#ensureElementIsInTheViewportIfNeeded,
this.#waitForVisibility, this.#waitForVisibilityIfNeeded,
this.#waitForStableBoundingBox, this.#waitForStableBoundingBoxIfNeeded,
], ],
} }
); );
@ -604,9 +585,9 @@ export class Locator extends EventEmitter {
{ {
signal: scrollOptions?.signal, signal: scrollOptions?.signal,
conditions: [ conditions: [
this.#ensureElementIsInTheViewport, this.#ensureElementIsInTheViewportIfNeeded,
this.#waitForVisibility, this.#waitForVisibilityIfNeeded,
this.#waitForStableBoundingBox, this.#waitForStableBoundingBoxIfNeeded,
], ],
} }
); );