chore: turn on rulesdir/use-using (#10806)

This commit is contained in:
jrandolf 2023-08-30 12:02:59 +02:00 committed by GitHub
parent a540085176
commit 900a1f227d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 605 additions and 642 deletions

View File

@ -144,7 +144,7 @@ module.exports = {
// Keeps comments formatted. // Keeps comments formatted.
'rulesdir/prettier-comments': 'error', 'rulesdir/prettier-comments': 'error',
// Enforces clean up of used resources. // Enforces clean up of used resources.
'rulesdir/use-using': 'off', 'rulesdir/use-using': 'error',
// Brackets keep code readable. // Brackets keep code readable.
curly: ['error', 'all'], curly: ['error', 'all'],
// Brackets keep code readable and `return` intentions clear. // Brackets keep code readable and `return` intentions clear.

View File

@ -28,11 +28,7 @@ import {
NodeFor, NodeFor,
} from '../common/types.js'; } from '../common/types.js';
import {KeyInput} from '../common/USKeyboardLayout.js'; import {KeyInput} from '../common/USKeyboardLayout.js';
import { import {isString, withSourcePuppeteerURLIfNone} from '../common/util.js';
debugError,
isString,
withSourcePuppeteerURLIfNone,
} from '../common/util.js';
import {assert} from '../util/assert.js'; import {assert} from '../util/assert.js';
import {AsyncIterableUtil} from '../util/AsyncIterableUtil.js'; import {AsyncIterableUtil} from '../util/AsyncIterableUtil.js';
@ -336,15 +332,13 @@ export abstract class ElementHandle<
...args: Params ...args: Params
): Promise<Awaited<ReturnType<Func>>> { ): Promise<Awaited<ReturnType<Func>>> {
pageFunction = withSourcePuppeteerURLIfNone(this.$eval.name, pageFunction); pageFunction = withSourcePuppeteerURLIfNone(this.$eval.name, pageFunction);
const elementHandle = await this.$(selector); using elementHandle = await this.$(selector);
if (!elementHandle) { if (!elementHandle) {
throw new Error( throw new Error(
`Error: failed to find element matching selector "${selector}"` `Error: failed to find element matching selector "${selector}"`
); );
} }
const result = await elementHandle.evaluate(pageFunction, ...args); return await elementHandle.evaluate(pageFunction, ...args);
await elementHandle.dispose();
return result;
} }
/** /**
@ -394,7 +388,7 @@ export abstract class ElementHandle<
): Promise<Awaited<ReturnType<Func>>> { ): Promise<Awaited<ReturnType<Func>>> {
pageFunction = withSourcePuppeteerURLIfNone(this.$$eval.name, pageFunction); pageFunction = withSourcePuppeteerURLIfNone(this.$$eval.name, pageFunction);
const results = await this.$$(selector); const results = await this.$$(selector);
const elements = await this.evaluateHandle( using elements = await this.evaluateHandle(
(_, ...elements) => { (_, ...elements) => {
return elements; return elements;
}, },
@ -406,7 +400,6 @@ export abstract class ElementHandle<
return results.dispose(); return results.dispose();
}), }),
]); ]);
await elements.dispose();
return result; return result;
} }
@ -480,21 +473,17 @@ export abstract class ElementHandle<
} }
async #checkVisibility(visibility: boolean): Promise<boolean> { async #checkVisibility(visibility: boolean): Promise<boolean> {
const element = await this.frame.isolatedRealm().adoptHandle(this); using element = await this.frame.isolatedRealm().adoptHandle(this);
try { return await this.frame.isolatedRealm().evaluate(
return await this.frame.isolatedRealm().evaluate( async (PuppeteerUtil, element, visibility) => {
async (PuppeteerUtil, element, visibility) => { return Boolean(PuppeteerUtil.checkVisibility(element, visibility));
return Boolean(PuppeteerUtil.checkVisibility(element, visibility)); },
}, LazyArg.create(context => {
LazyArg.create(context => { return context.puppeteerUtil;
return context.puppeteerUtil; }),
}), element,
element, visibility
visibility );
);
} finally {
await element.dispose();
}
} }
/** /**
@ -630,7 +619,8 @@ export abstract class ElementHandle<
* Returns the middle point within an element unless a specific offset is provided. * Returns the middle point within an element unless a specific offset is provided.
*/ */
async clickablePoint(offset?: Offset): Promise<Point> { async clickablePoint(offset?: Offset): Promise<Point> {
const box = await this.#clickableBox(); using adoptedThis = await this.frame.isolatedRealm().adoptHandle(this);
const box = await adoptedThis.#clickableBox();
if (!box) { if (!box) {
throw new Error('Node is either not clickable or not an Element'); throw new Error('Node is either not clickable or not an Element');
} }
@ -903,8 +893,7 @@ export abstract class ElementHandle<
} }
async #clickableBox(): Promise<BoundingBox | null> { async #clickableBox(): Promise<BoundingBox | null> {
const adoptedThis = await this.frame.isolatedRealm().adoptHandle(this); const boxes = await this.evaluate(element => {
const boxes = await adoptedThis.evaluate(element => {
if (!(element instanceof Element)) { if (!(element instanceof Element)) {
return null; return null;
} }
@ -912,46 +901,44 @@ export abstract class ElementHandle<
return {x: rect.x, y: rect.y, width: rect.width, height: rect.height}; return {x: rect.x, y: rect.y, width: rect.width, height: rect.height};
}); });
}); });
void adoptedThis.dispose().catch(debugError);
if (!boxes?.length) { if (!boxes?.length) {
return null; return null;
} }
await this.#intersectBoundingBoxesWithFrame(boxes); await this.#intersectBoundingBoxesWithFrame(boxes);
let frame: Frame | null | undefined = this.frame; let frame = this.frame;
let element: HandleFor<HTMLIFrameElement> | null | undefined; let parentFrame: Frame | null | undefined;
while ((element = await frame?.frameElement())) { while ((parentFrame = frame?.parentFrame())) {
try { using handle = await frame.frameElement();
element = await element.frame.isolatedRealm().transferHandle(element); if (!handle) {
const parentBox = await element.evaluate(element => { throw new Error('Unsupported frame type');
// Element is not visible. }
if (element.getClientRects().length === 0) { const parentBox = await handle.evaluate(element => {
return null; // Element is not visible.
} if (element.getClientRects().length === 0) {
const rect = element.getBoundingClientRect();
const style = window.getComputedStyle(element);
return {
left:
rect.left +
parseInt(style.paddingLeft, 10) +
parseInt(style.borderLeftWidth, 10),
top:
rect.top +
parseInt(style.paddingTop, 10) +
parseInt(style.borderTopWidth, 10),
};
});
if (!parentBox) {
return null; return null;
} }
for (const box of boxes) { const rect = element.getBoundingClientRect();
box.x += parentBox.left; const style = window.getComputedStyle(element);
box.y += parentBox.top; return {
} left:
await element.#intersectBoundingBoxesWithFrame(boxes); rect.left +
frame = frame?.parentFrame(); parseInt(style.paddingLeft, 10) +
} finally { parseInt(style.borderLeftWidth, 10),
void element.dispose().catch(debugError); top:
rect.top +
parseInt(style.paddingTop, 10) +
parseInt(style.borderTopWidth, 10),
};
});
if (!parentBox) {
return null;
} }
for (const box of boxes) {
box.x += parentBox.left;
box.y += parentBox.top;
}
await handle.#intersectBoundingBoxesWithFrame(boxes);
frame = parentFrame;
} }
const box = boxes.find(box => { const box = boxes.find(box => {
return box.width >= 1 && box.height >= 1; return box.width >= 1 && box.height >= 1;
@ -986,7 +973,7 @@ export abstract class ElementHandle<
* or `null` if the element is not visible. * or `null` if the element is not visible.
*/ */
async boundingBox(): Promise<BoundingBox | null> { async boundingBox(): Promise<BoundingBox | null> {
const adoptedThis = await this.frame.isolatedRealm().adoptHandle(this); using adoptedThis = await this.frame.isolatedRealm().adoptHandle(this);
const box = await adoptedThis.evaluate(element => { const box = await adoptedThis.evaluate(element => {
if (!(element instanceof Element)) { if (!(element instanceof Element)) {
return null; return null;
@ -998,11 +985,10 @@ export abstract class ElementHandle<
const rect = element.getBoundingClientRect(); const rect = element.getBoundingClientRect();
return {x: rect.x, y: rect.y, width: rect.width, height: rect.height}; return {x: rect.x, y: rect.y, width: rect.width, height: rect.height};
}); });
void adoptedThis.dispose().catch(debugError);
if (!box) { if (!box) {
return null; return null;
} }
const offset = await this.#getTopLeftCornerOfFrame(); const offset = await adoptedThis.#getTopLeftCornerOfFrame();
if (!offset) { if (!offset) {
return null; return null;
} }
@ -1023,80 +1009,81 @@ export abstract class ElementHandle<
* Each Point is an object `{x, y}`. Box points are sorted clock-wise. * Each Point is an object `{x, y}`. Box points are sorted clock-wise.
*/ */
async boxModel(): Promise<BoxModel | null> { async boxModel(): Promise<BoxModel | null> {
const adoptedThis = await this.frame.isolatedRealm().adoptHandle(this); const model = await (async () => {
const model = await adoptedThis.evaluate(element => { using adoptedThis = await this.frame.isolatedRealm().adoptHandle(this);
if (!(element instanceof Element)) { return await adoptedThis.evaluate(element => {
return null; if (!(element instanceof Element)) {
} return null;
// Element is not visible. }
if (element.getClientRects().length === 0) { // Element is not visible.
return null; if (element.getClientRects().length === 0) {
} return null;
const rect = element.getBoundingClientRect(); }
const style = window.getComputedStyle(element); const rect = element.getBoundingClientRect();
const offsets = { const style = window.getComputedStyle(element);
padding: { const offsets = {
left: parseInt(style.paddingLeft, 10), padding: {
top: parseInt(style.paddingTop, 10), left: parseInt(style.paddingLeft, 10),
right: parseInt(style.paddingRight, 10), top: parseInt(style.paddingTop, 10),
bottom: parseInt(style.paddingBottom, 10), right: parseInt(style.paddingRight, 10),
}, bottom: parseInt(style.paddingBottom, 10),
margin: {
left: -parseInt(style.marginLeft, 10),
top: -parseInt(style.marginTop, 10),
right: -parseInt(style.marginRight, 10),
bottom: -parseInt(style.marginBottom, 10),
},
border: {
left: parseInt(style.borderLeft, 10),
top: parseInt(style.borderTop, 10),
right: parseInt(style.borderRight, 10),
bottom: parseInt(style.borderBottom, 10),
},
};
const border: Quad = [
{x: rect.left, y: rect.top},
{x: rect.left + rect.width, y: rect.top},
{x: rect.left + rect.width, y: rect.top + rect.bottom},
{x: rect.left, y: rect.top + rect.bottom},
];
const padding = transformQuadWithOffsets(border, offsets.border);
const content = transformQuadWithOffsets(padding, offsets.padding);
const margin = transformQuadWithOffsets(border, offsets.margin);
return {
content,
padding,
border,
margin,
width: rect.width,
height: rect.height,
};
function transformQuadWithOffsets(
quad: Quad,
offsets: {top: number; left: number; right: number; bottom: number}
): Quad {
return [
{
x: quad[0].x + offsets.left,
y: quad[0].y + offsets.top,
}, },
{ margin: {
x: quad[1].x - offsets.right, left: -parseInt(style.marginLeft, 10),
y: quad[1].y + offsets.top, top: -parseInt(style.marginTop, 10),
right: -parseInt(style.marginRight, 10),
bottom: -parseInt(style.marginBottom, 10),
}, },
{ border: {
x: quad[2].x - offsets.right, left: parseInt(style.borderLeft, 10),
y: quad[2].y - offsets.bottom, top: parseInt(style.borderTop, 10),
}, right: parseInt(style.borderRight, 10),
{ bottom: parseInt(style.borderBottom, 10),
x: quad[3].x + offsets.left,
y: quad[3].y - offsets.bottom,
}, },
};
const border: Quad = [
{x: rect.left, y: rect.top},
{x: rect.left + rect.width, y: rect.top},
{x: rect.left + rect.width, y: rect.top + rect.bottom},
{x: rect.left, y: rect.top + rect.bottom},
]; ];
} const padding = transformQuadWithOffsets(border, offsets.border);
}); const content = transformQuadWithOffsets(padding, offsets.padding);
void adoptedThis.dispose().catch(debugError); const margin = transformQuadWithOffsets(border, offsets.margin);
return {
content,
padding,
border,
margin,
width: rect.width,
height: rect.height,
};
function transformQuadWithOffsets(
quad: Quad,
offsets: {top: number; left: number; right: number; bottom: number}
): Quad {
return [
{
x: quad[0].x + offsets.left,
y: quad[0].y + offsets.top,
},
{
x: quad[1].x - offsets.right,
y: quad[1].y + offsets.top,
},
{
x: quad[2].x - offsets.right,
y: quad[2].y - offsets.bottom,
},
{
x: quad[3].x + offsets.left,
y: quad[3].y - offsets.bottom,
},
];
}
});
})();
if (!model) { if (!model) {
return null; return null;
} }
@ -1120,38 +1107,37 @@ export abstract class ElementHandle<
async #getTopLeftCornerOfFrame() { async #getTopLeftCornerOfFrame() {
const point = {x: 0, y: 0}; const point = {x: 0, y: 0};
let frame: Frame | null | undefined = this.frame; let frame = this.frame;
let element: HandleFor<HTMLIFrameElement> | null | undefined; let parentFrame: Frame | null | undefined;
while ((element = await frame?.frameElement())) { while ((parentFrame = frame?.parentFrame())) {
try { using handle = await frame.frameElement();
element = await element.frame.isolatedRealm().transferHandle(element); if (!handle) {
const parentBox = await element.evaluate(element => { throw new Error('Unsupported frame type');
// Element is not visible. }
if (element.getClientRects().length === 0) { const parentBox = await handle.evaluate(element => {
return null; // Element is not visible.
} if (element.getClientRects().length === 0) {
const rect = element.getBoundingClientRect();
const style = window.getComputedStyle(element);
return {
left:
rect.left +
parseInt(style.paddingLeft, 10) +
parseInt(style.borderLeftWidth, 10),
top:
rect.top +
parseInt(style.paddingTop, 10) +
parseInt(style.borderTopWidth, 10),
};
});
if (!parentBox) {
return null; return null;
} }
point.x += parentBox.left; const rect = element.getBoundingClientRect();
point.y += parentBox.top; const style = window.getComputedStyle(element);
frame = frame?.parentFrame(); return {
} finally { left:
void element.dispose().catch(debugError); rect.left +
parseInt(style.paddingLeft, 10) +
parseInt(style.borderLeftWidth, 10),
top:
rect.top +
parseInt(style.paddingTop, 10) +
parseInt(style.borderTopWidth, 10),
};
});
if (!parentBox) {
return null;
} }
point.x += parentBox.left;
point.y += parentBox.top;
frame = parentFrame;
} }
return point; return point;
} }
@ -1173,17 +1159,15 @@ export abstract class ElementHandle<
* @internal * @internal
*/ */
protected async assertConnectedElement(): Promise<void> { protected async assertConnectedElement(): Promise<void> {
const error = await this.evaluate( const error = await this.evaluate(async element => {
async (element): Promise<string | undefined> => { if (!element.isConnected) {
if (!element.isConnected) { return 'Node is detached from document';
return 'Node is detached from document';
}
if (element.nodeType !== Node.ELEMENT_NODE) {
return 'Node is not of type HTMLElement';
}
return;
} }
); if (element.nodeType !== Node.ELEMENT_NODE) {
return 'Node is not of type HTMLElement';
}
return;
});
if (error) { if (error) {
throw new Error(error); throw new Error(error);
@ -1216,20 +1200,16 @@ export abstract class ElementHandle<
*/ */
async isIntersectingViewport( async isIntersectingViewport(
this: ElementHandle<Element>, this: ElementHandle<Element>,
options?: { options: {
threshold?: number; threshold?: number;
} } = {}
): Promise<boolean> { ): Promise<boolean> {
await this.assertConnectedElement(); await this.assertConnectedElement();
// eslint-disable-next-line rulesdir/use-using -- Returns `this`.
const {threshold = 0} = options ?? {}; const handle = await this.#asSVGElementHandle();
const svgHandle = await this.#asSVGElementHandle(this); using target = handle && (await handle.#getOwnerSVGElement());
const intersectionTarget: ElementHandle<Element> = svgHandle return await ((target ?? this) as ElementHandle<Element>).evaluate(
? await this.#getOwnerSVGElement(svgHandle) async (element, threshold) => {
: this;
try {
return await intersectionTarget.evaluate(async (element, threshold) => {
const visibleRatio = await new Promise<number>(resolve => { const visibleRatio = await new Promise<number>(resolve => {
const observer = new IntersectionObserver(entries => { const observer = new IntersectionObserver(entries => {
resolve(entries[0]!.intersectionRatio); resolve(entries[0]!.intersectionRatio);
@ -1238,12 +1218,9 @@ export abstract class ElementHandle<
observer.observe(element); observer.observe(element);
}); });
return threshold === 1 ? visibleRatio === 1 : visibleRatio > threshold; return threshold === 1 ? visibleRatio === 1 : visibleRatio > threshold;
}, threshold); },
} finally { options.threshold ?? 0
if (intersectionTarget !== this) { );
await intersectionTarget.dispose();
}
}
} }
/** /**
@ -1251,8 +1228,9 @@ export abstract class ElementHandle<
* or by calling element.scrollIntoView. * or by calling element.scrollIntoView.
*/ */
async scrollIntoView(this: ElementHandle<Element>): Promise<void> { async scrollIntoView(this: ElementHandle<Element>): Promise<void> {
await this.assertConnectedElement(); using adoptedThis = await this.frame.isolatedRealm().adoptHandle(this);
await this.evaluate(async (element): Promise<void> => { await adoptedThis.assertConnectedElement();
await adoptedThis.evaluate(async (element): Promise<void> => {
element.scrollIntoView({ element.scrollIntoView({
block: 'center', block: 'center',
inline: 'center', inline: 'center',
@ -1266,24 +1244,24 @@ export abstract class ElementHandle<
* etc.). * etc.).
*/ */
async #asSVGElementHandle( async #asSVGElementHandle(
handle: ElementHandle<Element> this: ElementHandle<Element>
): Promise<ElementHandle<SVGElement> | null> { ): Promise<ElementHandle<SVGElement> | null> {
if ( if (
await handle.evaluate(element => { await this.evaluate(element => {
return element instanceof SVGElement; return element instanceof SVGElement;
}) })
) { ) {
return handle as ElementHandle<SVGElement>; return this as ElementHandle<SVGElement>;
} else { } else {
return null; return null;
} }
} }
async #getOwnerSVGElement( async #getOwnerSVGElement(
handle: ElementHandle<SVGElement> this: ElementHandle<SVGElement>
): Promise<ElementHandle<SVGSVGElement>> { ): Promise<ElementHandle<SVGSVGElement>> {
// SVGSVGElement.ownerSVGElement === null. // SVGSVGElement.ownerSVGElement === null.
return await handle.evaluateHandle(element => { return await this.evaluateHandle(element => {
if (element instanceof SVGSVGElement) { if (element instanceof SVGSVGElement) {
return element; return element;
} }

View File

@ -37,12 +37,12 @@ import {
InnerLazyParams, InnerLazyParams,
NodeFor, NodeFor,
} from '../common/types.js'; } from '../common/types.js';
import {debugError, importFSPromises} from '../common/util.js'; import {importFSPromises} from '../common/util.js';
import {TaskManager} from '../common/WaitTask.js'; import {TaskManager} from '../common/WaitTask.js';
import {KeyboardTypeOptions} from './Input.js'; import {KeyboardTypeOptions} from './Input.js';
import {JSHandle} from './JSHandle.js'; import {JSHandle} from './JSHandle.js';
import {Locator, FunctionLocator, NodeLocator} from './locators/locators.js'; import {FunctionLocator, Locator, NodeLocator} from './locators/locators.js';
/** /**
* @internal * @internal
@ -389,15 +389,14 @@ export class Frame extends EventEmitter {
if (!parentFrame) { if (!parentFrame) {
return null; return null;
} }
const list = await parentFrame.isolatedRealm().evaluateHandle(() => { using list = await parentFrame.isolatedRealm().evaluateHandle(() => {
return document.querySelectorAll('iframe'); return document.querySelectorAll('iframe');
}); });
for await (const iframe of transposeIterableHandle(list)) { for await (using iframe of transposeIterableHandle(list)) {
const frame = await iframe.contentFrame(); const frame = await iframe.contentFrame();
if (frame._id === this._id) { if (frame._id === this._id) {
return iframe; return iframe.move();
} }
void iframe.dispose().catch(debugError);
} }
return null; return null;
} }

View File

@ -692,12 +692,8 @@ export abstract class Locator<T> extends EventEmitter {
* @public * @public
*/ */
async wait(options?: Readonly<ActionOptions>): Promise<T> { async wait(options?: Readonly<ActionOptions>): Promise<T> {
const handle = await this.waitHandle(options); using handle = await this.waitHandle(options);
try { return await handle.jsonValue();
return await handle.jsonValue();
} finally {
void handle.dispose().catch(debugError);
}
} }
/** /**

View File

@ -32,11 +32,11 @@ export class Binding {
args: unknown[], args: unknown[],
isTrivial: boolean isTrivial: boolean
): Promise<void> { ): Promise<void> {
const garbage = []; const stack = new DisposableStack();
try { try {
if (!isTrivial) { if (!isTrivial) {
// Getting non-trivial arguments. // Getting non-trivial arguments.
const handles = await context.evaluateHandle( using handles = await context.evaluateHandle(
(name, seq) => { (name, seq) => {
// @ts-expect-error Code is evaluated in a different context. // @ts-expect-error Code is evaluated in a different context.
return globalThis[name].args.get(seq); return globalThis[name].args.get(seq);
@ -44,25 +44,21 @@ export class Binding {
this.#name, this.#name,
id id
); );
try { const properties = await handles.getProperties();
const properties = await handles.getProperties(); for (const [index, handle] of properties) {
for (const [index, handle] of properties) { // This is not straight-forward since some arguments can stringify, but
// This is not straight-forward since some arguments can stringify, but // aren't plain objects so add subtypes when the use-case arises.
// aren't plain objects so add subtypes when the use-case arises. if (index in args) {
if (index in args) { switch (handle.remoteObject().subtype) {
switch (handle.remoteObject().subtype) { case 'node':
case 'node': args[+index] = handle;
args[+index] = handle; break;
break; default:
default: stack.use(handle);
garbage.push(handle.dispose());
}
} else {
garbage.push(handle.dispose());
} }
} else {
stack.use(handle);
} }
} finally {
await handles.dispose();
} }
} }
@ -80,7 +76,7 @@ export class Binding {
for (const arg of args) { for (const arg of args) {
if (arg instanceof JSHandle) { if (arg instanceof JSHandle) {
garbage.push(arg.dispose()); stack.use(arg);
} }
} }
} catch (error) { } catch (error) {
@ -116,8 +112,6 @@ export class Binding {
) )
.catch(debugError); .catch(debugError);
} }
} finally {
await Promise.all(garbage);
} }
} }
} }

View File

@ -31,7 +31,7 @@ async function* fastTransposeIteratorHandle<T>(
iterator: JSHandle<AwaitableIterator<T>>, iterator: JSHandle<AwaitableIterator<T>>,
size: number size: number
) { ) {
const array = await iterator.evaluateHandle(async (iterator, size) => { using array = await iterator.evaluateHandle(async (iterator, size) => {
const results = []; const results = [];
while (results.length < size) { while (results.length < size) {
const result = await iterator.next(); const result = await iterator.next();
@ -43,8 +43,14 @@ async function* fastTransposeIteratorHandle<T>(
return results; return results;
}, size); }, size);
const properties = (await array.getProperties()) as Map<string, HandleFor<T>>; const properties = (await array.getProperties()) as Map<string, HandleFor<T>>;
await array.dispose(); const handles = properties.values();
yield* properties.values(); using stack = new DisposableStack();
stack.defer(() => {
for (using handle of handles) {
handle[Symbol.dispose]();
}
});
yield* handles;
return properties.size === 0; return properties.size === 0;
} }
@ -57,12 +63,8 @@ async function* transposeIteratorHandle<T>(
iterator: JSHandle<AwaitableIterator<T>> iterator: JSHandle<AwaitableIterator<T>>
) { ) {
let size = DEFAULT_BATCH_SIZE; let size = DEFAULT_BATCH_SIZE;
try { while (!(yield* fastTransposeIteratorHandle(iterator, size))) {
while (!(yield* fastTransposeIteratorHandle(iterator, size))) { size <<= 1;
size <<= 1;
}
} finally {
await iterator.dispose();
} }
} }
@ -74,11 +76,10 @@ type AwaitableIterator<T> = Iterator<T> | AsyncIterator<T>;
export async function* transposeIterableHandle<T>( export async function* transposeIterableHandle<T>(
handle: JSHandle<AwaitableIterable<T>> handle: JSHandle<AwaitableIterable<T>>
): AsyncIterableIterator<HandleFor<T>> { ): AsyncIterableIterator<HandleFor<T>> {
yield* transposeIteratorHandle( using generatorHandle = await handle.evaluateHandle(iterable => {
await handle.evaluateHandle(iterable => { return (async function* () {
return (async function* () { yield* iterable;
yield* iterable; })();
})(); });
}) yield* transposeIteratorHandle(generatorHandle);
);
} }

View File

@ -104,7 +104,6 @@ export interface IsolatedWorldChart {
*/ */
export class IsolatedWorld implements Realm { export class IsolatedWorld implements Realm {
#frame: Frame; #frame: Frame;
#document?: ElementHandle<Document>;
#context = Deferred.create<ExecutionContext>(); #context = Deferred.create<ExecutionContext>();
#detached = false; #detached = false;
@ -149,7 +148,6 @@ export class IsolatedWorld implements Realm {
} }
clearContext(): void { clearContext(): void {
this.#document = undefined;
this.#context = Deferred.create(); this.#context = Deferred.create();
} }
@ -216,31 +214,27 @@ export class IsolatedWorld implements Realm {
async $<Selector extends string>( async $<Selector extends string>(
selector: Selector selector: Selector
): Promise<ElementHandle<NodeFor<Selector>> | null> { ): Promise<ElementHandle<NodeFor<Selector>> | null> {
const document = await this.document(); using document = await this.document();
return document.$(selector); return await document.$(selector);
} }
async $$<Selector extends string>( async $$<Selector extends string>(
selector: Selector selector: Selector
): Promise<Array<ElementHandle<NodeFor<Selector>>>> { ): Promise<Array<ElementHandle<NodeFor<Selector>>>> {
const document = await this.document(); using document = await this.document();
return document.$$(selector); return await document.$$(selector);
} }
async document(): Promise<ElementHandle<Document>> { async document(): Promise<ElementHandle<Document>> {
if (this.#document) { // TODO(#10813): Implement document caching.
return this.#document; return await this.evaluateHandle(() => {
}
const context = await this.executionContext();
this.#document = await context.evaluateHandle(() => {
return document; return document;
}); });
return this.#document;
} }
async $x(expression: string): Promise<Array<ElementHandle<Node>>> { async $x(expression: string): Promise<Array<ElementHandle<Node>>> {
const document = await this.document(); using document = await this.document();
return document.$x(expression); return await document.$x(expression);
} }
async $eval< async $eval<
@ -256,8 +250,8 @@ export class IsolatedWorld implements Realm {
...args: Params ...args: Params
): Promise<Awaited<ReturnType<Func>>> { ): Promise<Awaited<ReturnType<Func>>> {
pageFunction = withSourcePuppeteerURLIfNone(this.$eval.name, pageFunction); pageFunction = withSourcePuppeteerURLIfNone(this.$eval.name, pageFunction);
const document = await this.document(); using document = await this.document();
return document.$eval(selector, pageFunction, ...args); return await document.$eval(selector, pageFunction, ...args);
} }
async $$eval< async $$eval<
@ -273,8 +267,8 @@ export class IsolatedWorld implements Realm {
...args: Params ...args: Params
): Promise<Awaited<ReturnType<Func>>> { ): Promise<Awaited<ReturnType<Func>>> {
pageFunction = withSourcePuppeteerURLIfNone(this.$$eval.name, pageFunction); pageFunction = withSourcePuppeteerURLIfNone(this.$$eval.name, pageFunction);
const document = await this.document(); using document = await this.document();
return document.$$eval(selector, pageFunction, ...args); return await document.$$eval(selector, pageFunction, ...args);
} }
async content(): Promise<string> { async content(): Promise<string> {
@ -315,39 +309,34 @@ export class IsolatedWorld implements Realm {
selector: string, selector: string,
options?: Readonly<ClickOptions> options?: Readonly<ClickOptions>
): Promise<void> { ): Promise<void> {
const handle = await this.$(selector); using handle = await this.$(selector);
assert(handle, `No element found for selector: ${selector}`); assert(handle, `No element found for selector: ${selector}`);
await handle.click(options); await handle.click(options);
await handle.dispose(); await handle.dispose();
} }
async focus(selector: string): Promise<void> { async focus(selector: string): Promise<void> {
const handle = await this.$(selector); using handle = await this.$(selector);
assert(handle, `No element found for selector: ${selector}`); assert(handle, `No element found for selector: ${selector}`);
await handle.focus(); await handle.focus();
await handle.dispose();
} }
async hover(selector: string): Promise<void> { async hover(selector: string): Promise<void> {
const handle = await this.$(selector); using handle = await this.$(selector);
assert(handle, `No element found for selector: ${selector}`); assert(handle, `No element found for selector: ${selector}`);
await handle.hover(); await handle.hover();
await handle.dispose();
} }
async select(selector: string, ...values: string[]): Promise<string[]> { async select(selector: string, ...values: string[]): Promise<string[]> {
const handle = await this.$(selector); using handle = await this.$(selector);
assert(handle, `No element found for selector: ${selector}`); assert(handle, `No element found for selector: ${selector}`);
const result = await handle.select(...values); return await handle.select(...values);
await handle.dispose();
return result;
} }
async tap(selector: string): Promise<void> { async tap(selector: string): Promise<void> {
const handle = await this.$(selector); using handle = await this.$(selector);
assert(handle, `No element found for selector: ${selector}`); assert(handle, `No element found for selector: ${selector}`);
await handle.tap(); await handle.tap();
await handle.dispose();
} }
async type( async type(
@ -355,10 +344,9 @@ export class IsolatedWorld implements Realm {
text: string, text: string,
options?: Readonly<KeyboardTypeOptions> options?: Readonly<KeyboardTypeOptions>
): Promise<void> { ): Promise<void> {
const handle = await this.$(selector); using handle = await this.$(selector);
assert(handle, `No element found for selector: ${selector}`); assert(handle, `No element found for selector: ${selector}`);
await handle.type(text, options); await handle.type(text, options);
await handle.dispose();
} }
// If multiple waitFor are set up asynchronously, we need to wait for the // If multiple waitFor are set up asynchronously, we need to wait for the

View File

@ -433,11 +433,11 @@ export class CDPPage extends Page {
assert(frame, 'This should never happen.'); assert(frame, 'This should never happen.');
// This is guaranteed to be an HTMLInputElement handle by the event. // This is guaranteed to be an HTMLInputElement handle by the event.
const handle = (await frame.worlds[MAIN_WORLD].adoptBackendNode( using handle = (await frame.worlds[MAIN_WORLD].adoptBackendNode(
event.backendNodeId event.backendNodeId
)) as ElementHandle<HTMLInputElement>; )) as ElementHandle<HTMLInputElement>;
const fileChooser = new FileChooser(handle, event); const fileChooser = new FileChooser(handle.move(), event);
for (const promise of this.#fileChooserDeferreds) { for (const promise of this.#fileChooserDeferreds) {
promise.resolve(fileChooser); promise.resolve(fileChooser);
} }
@ -885,6 +885,8 @@ export class CDPPage extends Page {
return; return;
} }
const textTokens = []; const textTokens = [];
// eslint-disable-next-line max-len -- The comment is long.
// eslint-disable-next-line rulesdir/use-using -- These are not owned by this function.
for (const arg of args) { for (const arg of args) {
const remoteObject = arg.remoteObject(); const remoteObject = arg.remoteObject();
if (remoteObject.objectId) { if (remoteObject.objectId) {

View File

@ -107,7 +107,7 @@ export class QueryHandler {
selector: string selector: string
): AwaitableIterable<ElementHandle<Node>> { ): AwaitableIterable<ElementHandle<Node>> {
element.assertElementHasWorld(); element.assertElementHasWorld();
const handle = await element.evaluateHandle( using handle = await element.evaluateHandle(
this._querySelectorAll, this._querySelectorAll,
selector, selector,
LazyArg.create(context => { LazyArg.create(context => {
@ -127,7 +127,7 @@ export class QueryHandler {
selector: string selector: string
): Promise<ElementHandle<Node> | null> { ): Promise<ElementHandle<Node> | null> {
element.assertElementHasWorld(); element.assertElementHasWorld();
const result = await element.evaluateHandle( using result = await element.evaluateHandle(
this._querySelector, this._querySelector,
selector, selector,
LazyArg.create(context => { LazyArg.create(context => {
@ -135,10 +135,9 @@ export class QueryHandler {
}) })
); );
if (!(result instanceof ElementHandle)) { if (!(result instanceof ElementHandle)) {
await result.dispose();
return null; return null;
} }
return result; return result.move();
} }
/** /**
@ -153,21 +152,22 @@ export class QueryHandler {
selector: string, selector: string,
options: WaitForSelectorOptions options: WaitForSelectorOptions
): Promise<ElementHandle<Node> | null> { ): Promise<ElementHandle<Node> | null> {
let frame: Frame; let frame!: Frame;
let element: ElementHandle<Node> | undefined; using element = await (async () => {
if (!(elementOrFrame instanceof ElementHandle)) { if (!(elementOrFrame instanceof ElementHandle)) {
frame = elementOrFrame; frame = elementOrFrame;
} else { return;
}
frame = elementOrFrame.frame; frame = elementOrFrame.frame;
element = await frame.isolatedRealm().adoptHandle(elementOrFrame); return await frame.isolatedRealm().adoptHandle(elementOrFrame);
} })();
const {visible = false, hidden = false, timeout, signal} = options; const {visible = false, hidden = false, timeout, signal} = options;
try { try {
signal?.throwIfAborted(); signal?.throwIfAborted();
const handle = await frame.isolatedRealm().waitForFunction( using handle = await frame.isolatedRealm().waitForFunction(
async (PuppeteerUtil, query, selector, root, visible) => { async (PuppeteerUtil, query, selector, root, visible) => {
const querySelector = PuppeteerUtil.createFunction( const querySelector = PuppeteerUtil.createFunction(
query query
@ -195,15 +195,13 @@ export class QueryHandler {
); );
if (signal?.aborted) { if (signal?.aborted) {
await handle.dispose();
throw signal.reason; throw signal.reason;
} }
if (!(handle instanceof ElementHandle)) { if (!(handle instanceof ElementHandle)) {
await handle.dispose();
return null; return null;
} }
return frame.mainRealm().transferHandle(handle); return await frame.mainRealm().transferHandle(handle);
} catch (error) { } catch (error) {
if (!isErrorLike(error)) { if (!isErrorLike(error)) {
throw error; throw error;
@ -213,10 +211,6 @@ export class QueryHandler {
} }
error.message = `Waiting for selector \`${selector}\` failed: ${error.message}`; error.message = `Waiting for selector \`${selector}\` failed: ${error.message}`;
throw error; throw error;
} finally {
if (element) {
await element.dispose();
}
} }
} }
} }

View File

@ -20,7 +20,6 @@ import {
AutofillData, AutofillData,
ElementHandle as BaseElementHandle, ElementHandle as BaseElementHandle,
} from '../../api/ElementHandle.js'; } from '../../api/ElementHandle.js';
import {debugError} from '../util.js';
import {Frame} from './Frame.js'; import {Frame} from './Frame.js';
import {JSHandle as BidiJSHandle, JSHandle} from './JSHandle.js'; import {JSHandle as BidiJSHandle, JSHandle} from './JSHandle.js';
@ -86,15 +85,13 @@ export class ElementHandle<
this: ElementHandle<HTMLIFrameElement> this: ElementHandle<HTMLIFrameElement>
): Promise<Frame>; ): Promise<Frame>;
override async contentFrame(): Promise<Frame | null> { override async contentFrame(): Promise<Frame | null> {
const adoptedThis = await this.frame.isolatedRealm().adoptHandle(this); using adoptedThis = await this.frame.isolatedRealm().adoptHandle(this);
const handle = (await adoptedThis.evaluateHandle(element => { using handle = (await adoptedThis.evaluateHandle(element => {
if (element instanceof HTMLIFrameElement) { if (element instanceof HTMLIFrameElement) {
return element.contentWindow; return element.contentWindow;
} }
return; return;
})) as BidiJSHandle; })) as BidiJSHandle;
void handle.dispose().catch(debugError);
void adoptedThis.dispose().catch(debugError);
const value = handle.remoteValue(); const value = handle.remoteValue();
if (value.type === 'window') { if (value.type === 'window') {
return this.frame.page().frame(value.value.context); return this.frame.page().frame(value.value.context);

View File

@ -106,9 +106,9 @@ export class JSHandle<T = unknown> extends BaseJSHandle<T> {
); );
for (const [key, value] of Object.entries(keys)) { for (const [key, value] of Object.entries(keys)) {
const handle = results[key as any]; using handle = results[key as any];
if (handle) { if (handle) {
map.set(value, handle); map.set(value, handle.move());
} }
} }

View File

@ -56,8 +56,7 @@ export class Realm extends EventEmitter {
const promise = this.internalPuppeteerUtil; const promise = this.internalPuppeteerUtil;
this.internalPuppeteerUtil = undefined; this.internalPuppeteerUtil = undefined;
try { try {
const util = await promise; await (await promise)?.dispose();
await util?.dispose();
} catch (error) { } catch (error) {
debugError(error); debugError(error);
} }

View File

@ -96,8 +96,7 @@ export class Sandbox implements RealmBase {
} }
async document(): Promise<ElementHandle<Document>> { async document(): Promise<ElementHandle<Document>> {
// TODO(jrandolf): We should try to cache this because we need to dispose // TODO(#10813): Implement document caching.
// this when it's unused.
return await this.#realm.evaluateHandle(() => { return await this.#realm.evaluateHandle(() => {
return document; return document;
}); });
@ -106,15 +105,15 @@ export class Sandbox implements RealmBase {
async $<Selector extends string>( async $<Selector extends string>(
selector: Selector selector: Selector
): Promise<ElementHandle<NodeFor<Selector>> | null> { ): Promise<ElementHandle<NodeFor<Selector>> | null> {
const document = await this.document(); using document = await this.document();
return document.$(selector); return await document.$(selector);
} }
async $$<Selector extends string>( async $$<Selector extends string>(
selector: Selector selector: Selector
): Promise<Array<ElementHandle<NodeFor<Selector>>>> { ): Promise<Array<ElementHandle<NodeFor<Selector>>>> {
const document = await this.document(); using document = await this.document();
return document.$$(selector); return await document.$$(selector);
} }
async $eval< async $eval<
@ -130,8 +129,8 @@ export class Sandbox implements RealmBase {
...args: Params ...args: Params
): Promise<Awaited<ReturnType<Func>>> { ): Promise<Awaited<ReturnType<Func>>> {
pageFunction = withSourcePuppeteerURLIfNone(this.$eval.name, pageFunction); pageFunction = withSourcePuppeteerURLIfNone(this.$eval.name, pageFunction);
const document = await this.document(); using document = await this.document();
return document.$eval(selector, pageFunction, ...args); return await document.$eval(selector, pageFunction, ...args);
} }
async $$eval< async $$eval<
@ -147,13 +146,13 @@ export class Sandbox implements RealmBase {
...args: Params ...args: Params
): Promise<Awaited<ReturnType<Func>>> { ): Promise<Awaited<ReturnType<Func>>> {
pageFunction = withSourcePuppeteerURLIfNone(this.$$eval.name, pageFunction); pageFunction = withSourcePuppeteerURLIfNone(this.$$eval.name, pageFunction);
const document = await this.document(); using document = await this.document();
return document.$$eval(selector, pageFunction, ...args); return await document.$$eval(selector, pageFunction, ...args);
} }
async $x(expression: string): Promise<Array<ElementHandle<Node>>> { async $x(expression: string): Promise<Array<ElementHandle<Node>>> {
const document = await this.document(); using document = await this.document();
return document.$x(expression); return await document.$x(expression);
} }
async evaluateHandle< async evaluateHandle<
@ -249,39 +248,34 @@ export class Sandbox implements RealmBase {
selector: string, selector: string,
options?: Readonly<ClickOptions> options?: Readonly<ClickOptions>
): Promise<void> { ): Promise<void> {
const handle = await this.$(selector); using handle = await this.$(selector);
assert(handle, `No element found for selector: ${selector}`); assert(handle, `No element found for selector: ${selector}`);
await handle.click(options); await handle.click(options);
await handle.dispose();
} }
async focus(selector: string): Promise<void> { async focus(selector: string): Promise<void> {
const handle = await this.$(selector); using handle = await this.$(selector);
assert(handle, `No element found for selector: ${selector}`); assert(handle, `No element found for selector: ${selector}`);
await handle.focus(); await handle.focus();
await handle.dispose();
} }
async hover(selector: string): Promise<void> { async hover(selector: string): Promise<void> {
const handle = await this.$(selector); using handle = await this.$(selector);
assert(handle, `No element found for selector: ${selector}`); assert(handle, `No element found for selector: ${selector}`);
await handle.hover(); await handle.hover();
await handle.dispose();
} }
async select(selector: string, ...values: string[]): Promise<string[]> { async select(selector: string, ...values: string[]): Promise<string[]> {
const handle = await this.$(selector); using handle = await this.$(selector);
assert(handle, `No element found for selector: ${selector}`); assert(handle, `No element found for selector: ${selector}`);
const result = await handle.select(...values); const result = await handle.select(...values);
await handle.dispose();
return result; return result;
} }
async tap(selector: string): Promise<void> { async tap(selector: string): Promise<void> {
const handle = await this.$(selector); using handle = await this.$(selector);
assert(handle, `No element found for selector: ${selector}`); assert(handle, `No element found for selector: ${selector}`);
await handle.tap(); await handle.tap();
await handle.dispose();
} }
async type( async type(
@ -289,9 +283,8 @@ export class Sandbox implements RealmBase {
text: string, text: string,
options?: Readonly<KeyboardTypeOptions> options?: Readonly<KeyboardTypeOptions>
): Promise<void> { ): Promise<void> {
const handle = await this.$(selector); using handle = await this.$(selector);
assert(handle, `No element found for selector: ${selector}`); assert(handle, `No element found for selector: ${selector}`);
await handle.type(text, options); await handle.type(text, options);
await handle.dispose();
} }
} }

View File

@ -149,6 +149,7 @@ export class BidiSerializer {
if (arg instanceof LazyArg) { if (arg instanceof LazyArg) {
arg = await arg.get(context); arg = await arg.get(context);
} }
// eslint-disable-next-line rulesdir/use-using -- We want this to continue living.
const objectHandle = const objectHandle =
arg && (arg instanceof JSHandle || arg instanceof ElementHandle) arg && (arg instanceof JSHandle || arg instanceof ElementHandle)
? arg ? arg

View File

@ -200,7 +200,7 @@ describe('Accessibility', function () {
async function getAccessibleName(page: any, element: any) { async function getAccessibleName(page: any, element: any) {
return (await page.accessibility.snapshot({root: element})).name; return (await page.accessibility.snapshot({root: element})).name;
} }
const button = await page.$('button'); using button = await page.$('button');
expect(await getAccessibleName(page, button)).toEqual('Show'); expect(await getAccessibleName(page, button)).toEqual('Show');
await button?.click(); await button?.click();
await page.waitForSelector('aria/Hide'); await page.waitForSelector('aria/Hide');
@ -483,7 +483,7 @@ describe('Accessibility', function () {
await page.setContent(`<button>My Button</button>`); await page.setContent(`<button>My Button</button>`);
const button = (await page.$('button'))!; using button = (await page.$('button'))!;
expect(await page.accessibility.snapshot({root: button})).toEqual({ expect(await page.accessibility.snapshot({root: button})).toEqual({
role: 'button', role: 'button',
name: 'My Button', name: 'My Button',
@ -494,7 +494,7 @@ describe('Accessibility', function () {
await page.setContent(`<input title="My Input" value="My Value">`); await page.setContent(`<input title="My Input" value="My Value">`);
const input = (await page.$('input'))!; using input = (await page.$('input'))!;
expect(await page.accessibility.snapshot({root: input})).toEqual({ expect(await page.accessibility.snapshot({root: input})).toEqual({
role: 'textbox', role: 'textbox',
name: 'My Input', name: 'My Input',
@ -512,7 +512,7 @@ describe('Accessibility', function () {
</div> </div>
`); `);
const menu = (await page.$('div[role="menu"]'))!; using menu = (await page.$('div[role="menu"]'))!;
expect(await page.accessibility.snapshot({root: menu})).toEqual({ expect(await page.accessibility.snapshot({root: menu})).toEqual({
role: 'menu', role: 'menu',
name: 'My Menu', name: 'My Menu',
@ -528,7 +528,7 @@ describe('Accessibility', function () {
const {page} = await getTestState(); const {page} = await getTestState();
await page.setContent(`<button>My Button</button>`); await page.setContent(`<button>My Button</button>`);
const button = (await page.$('button'))!; using button = (await page.$('button'))!;
await page.$eval('button', button => { await page.$eval('button', button => {
return button.remove(); return button.remove();
}); });
@ -538,7 +538,7 @@ describe('Accessibility', function () {
const {page} = await getTestState(); const {page} = await getTestState();
await page.setContent(`<div><button>My Button</button></div>`); await page.setContent(`<div><button>My Button</button></div>`);
const div = (await page.$('div'))!; using div = (await page.$('div'))!;
expect(await page.accessibility.snapshot({root: div})).toEqual(null); expect(await page.accessibility.snapshot({root: div})).toEqual(null);
expect( expect(
await page.accessibility.snapshot({ await page.accessibility.snapshot({

View File

@ -39,49 +39,67 @@ describe('AriaQueryHandler', () => {
}); });
expect(id).toBe('btn'); expect(id).toBe('btn');
}; };
let button = await page.$( {
'aria/Submit button and some spaces[role="button"]' using button = await page.$(
); 'aria/Submit button and some spaces[role="button"]'
await expectFound(button); );
button = await page.$( await expectFound(button);
"aria/Submit button and some spaces[role='button']" }
); {
await expectFound(button); using button = await page.$(
button = await page.$( "aria/Submit button and some spaces[role='button']"
);
await expectFound(button);
}
using button = await page.$(
'aria/ Submit button and some spaces[role="button"]' 'aria/ Submit button and some spaces[role="button"]'
); );
await expectFound(button); await expectFound(button);
button = await page.$( {
'aria/Submit button and some spaces [role="button"]' using button = await page.$(
); 'aria/Submit button and some spaces [role="button"]'
await expectFound(button); );
button = await page.$( await expectFound(button);
'aria/Submit button and some spaces [ role = "button" ] ' }
); {
await expectFound(button); using button = await page.$(
button = await page.$( 'aria/Submit button and some spaces [ role = "button" ] '
'aria/[role="button"]Submit button and some spaces' );
); await expectFound(button);
await expectFound(button); }
button = await page.$( {
'aria/Submit button [role="button"]and some spaces' using button = await page.$(
); 'aria/[role="button"]Submit button and some spaces'
await expectFound(button); );
button = await page.$( await expectFound(button);
'aria/[name=" Submit button and some spaces"][role="button"]' }
); {
await expectFound(button); using button = await page.$(
button = await page.$( 'aria/Submit button [role="button"]and some spaces'
"aria/[name=' Submit button and some spaces'][role='button']" );
); await expectFound(button);
await expectFound(button); }
button = await page.$( {
'aria/ignored[name="Submit button and some spaces"][role="button"]' using button = await page.$(
); 'aria/[name=" Submit button and some spaces"][role="button"]'
await expectFound(button); );
await expect(page.$('aria/smth[smth="true"]')).rejects.toThrow( await expectFound(button);
'Unknown aria attribute "smth" in selector' }
); {
using button = await page.$(
"aria/[name=' Submit button and some spaces'][role='button']"
);
await expectFound(button);
}
{
using button = await page.$(
'aria/ignored[name="Submit button and some spaces"][role="button"]'
);
await expectFound(button);
await expect(page.$('aria/smth[smth="true"]')).rejects.toThrow(
'Unknown aria attribute "smth" in selector'
);
}
}); });
}); });
@ -91,7 +109,7 @@ describe('AriaQueryHandler', () => {
await page.setContent( await page.setContent(
'<div id="div"><button id="btn" role="button">Submit</button></div>' '<div id="div"><button id="btn" role="button">Submit</button></div>'
); );
const button = (await page.$( using button = (await page.$(
'aria/[role="button"]' 'aria/[role="button"]'
)) as ElementHandle<HTMLButtonElement>; )) as ElementHandle<HTMLButtonElement>;
const id = await button!.evaluate(button => { const id = await button!.evaluate(button => {
@ -105,7 +123,7 @@ describe('AriaQueryHandler', () => {
await page.setContent( await page.setContent(
'<div id="div"><button id="btn" role="button">Submit</button></div>' '<div id="div"><button id="btn" role="button">Submit</button></div>'
); );
const button = (await page.$( using button = (await page.$(
'aria/Submit[role="button"]' 'aria/Submit[role="button"]'
)) as ElementHandle<HTMLButtonElement>; )) as ElementHandle<HTMLButtonElement>;
const id = await button!.evaluate(button => { const id = await button!.evaluate(button => {
@ -122,7 +140,7 @@ describe('AriaQueryHandler', () => {
<div role="menu" id="mnu2" aria-label="menu div"></div> <div role="menu" id="mnu2" aria-label="menu div"></div>
` `
); );
const div = (await page.$( using div = (await page.$(
'aria/menu div' 'aria/menu div'
)) as ElementHandle<HTMLDivElement>; )) as ElementHandle<HTMLDivElement>;
const id = await div!.evaluate(div => { const id = await div!.evaluate(div => {
@ -139,7 +157,7 @@ describe('AriaQueryHandler', () => {
<div role="menu" id="mnu2" aria-label="menu-label2">menu div</div> <div role="menu" id="mnu2" aria-label="menu-label2">menu div</div>
` `
); );
const menu = (await page.$( using menu = (await page.$(
'aria/menu-label1' 'aria/menu-label1'
)) as ElementHandle<HTMLDivElement>; )) as ElementHandle<HTMLDivElement>;
const id = await menu!.evaluate(div => { const id = await menu!.evaluate(div => {
@ -156,7 +174,7 @@ describe('AriaQueryHandler', () => {
<div role="menu" id="mnu2" aria-label="menu-label2">menu div</div> <div role="menu" id="mnu2" aria-label="menu-label2">menu div</div>
` `
); );
const menu = (await page.$( using menu = (await page.$(
'aria/menu-label2' 'aria/menu-label2'
)) as ElementHandle<HTMLDivElement>; )) as ElementHandle<HTMLDivElement>;
const id = await menu!.evaluate(div => { const id = await menu!.evaluate(div => {
@ -230,7 +248,7 @@ describe('AriaQueryHandler', () => {
await page.evaluate(() => { await page.evaluate(() => {
return (document.body.innerHTML = `<div><button>test</button></div>`); return (document.body.innerHTML = `<div><button>test</button></div>`);
}); });
const element = (await page.$('div'))!; using element = (await page.$('div'))!;
await element!.waitForSelector('aria/test'); await element!.waitForSelector('aria/test');
}); });
@ -299,7 +317,7 @@ describe('AriaQueryHandler', () => {
const watchdog = frame.waitForSelector('aria/[role="heading"]'); const watchdog = frame.waitForSelector('aria/[role="heading"]');
await frame.evaluate(addElement, 'br'); await frame.evaluate(addElement, 'br');
await frame.evaluate(addElement, 'h1'); await frame.evaluate(addElement, 'h1');
const elementHandle = (await watchdog)!; using elementHandle = (await watchdog)!;
const tagName = await ( const tagName = await (
await elementHandle.getProperty('tagName') await elementHandle.getProperty('tagName')
).jsonValue(); ).jsonValue();
@ -328,7 +346,7 @@ describe('AriaQueryHandler', () => {
const watchdog = page.waitForSelector('aria/[role="button"]'); const watchdog = page.waitForSelector('aria/[role="button"]');
await otherFrame!.evaluate(addElement, 'button'); await otherFrame!.evaluate(addElement, 'button');
await page.evaluate(addElement, 'button'); await page.evaluate(addElement, 'button');
const elementHandle = await watchdog; using elementHandle = await watchdog;
expect(elementHandle!.frame).toBe(page.mainFrame()); expect(elementHandle!.frame).toBe(page.mainFrame());
}); });
@ -344,7 +362,7 @@ describe('AriaQueryHandler', () => {
); );
await frame1!.evaluate(addElement, 'button'); await frame1!.evaluate(addElement, 'button');
await frame2!.evaluate(addElement, 'button'); await frame2!.evaluate(addElement, 'button');
const elementHandle = await waitForSelectorPromise; using elementHandle = await waitForSelectorPromise;
expect(elementHandle!.frame).toBe(frame2); expect(elementHandle!.frame).toBe(frame2);
}); });
@ -517,7 +535,7 @@ describe('AriaQueryHandler', () => {
it('should return null if waiting to hide non-existing element', async () => { it('should return null if waiting to hide non-existing element', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const handle = await page.waitForSelector('aria/non-existing', { using handle = await page.waitForSelector('aria/non-existing', {
hidden: true, hidden: true,
}); });
expect(handle).toBe(null); expect(handle).toBe(null);

View File

@ -24,7 +24,7 @@ describe('Autofill', function () {
it('should fill out a credit card', async () => { it('should fill out a credit card', async () => {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.PREFIX + '/credit-card.html'); await page.goto(server.PREFIX + '/credit-card.html');
const name = await page.waitForSelector('#name'); using name = await page.waitForSelector('#name');
await name!.autofill({ await name!.autofill({
creditCard: { creditCard: {
number: '4444444444444444', number: '4444444444444444',

View File

@ -117,7 +117,7 @@ describe('Page.click', function () {
await page.setJavaScriptEnabled(false); await page.setJavaScriptEnabled(false);
await page.goto(server.PREFIX + '/wrappedlink.html'); await page.goto(server.PREFIX + '/wrappedlink.html');
const body = await page.waitForSelector('body'); using body = await page.waitForSelector('body');
await body!.evaluate(el => { await body!.evaluate(el => {
el.style.paddingTop = '3000px'; el.style.paddingTop = '3000px';
}); });
@ -332,7 +332,7 @@ describe('Page.click', function () {
(globalThis as any).double = true; (globalThis as any).double = true;
}); });
}); });
const button = (await page.$('button'))!; using button = (await page.$('button'))!;
await button!.click({count: 2}); await button!.click({count: 2});
expect(await page.evaluate('double')).toBe(true); expect(await page.evaluate('double')).toBe(true);
expect(await page.evaluate('result')).toBe('Clicked'); expect(await page.evaluate('result')).toBe('Clicked');
@ -428,7 +428,7 @@ describe('Page.click', function () {
server.PREFIX + '/input/button.html' server.PREFIX + '/input/button.html'
); );
const frame = page.frames()[1]; const frame = page.frames()[1];
const button = await frame!.$('button'); using button = await frame!.$('button');
await button!.click(); await button!.click();
expect( expect(
await frame!.evaluate(() => { await frame!.evaluate(() => {
@ -477,7 +477,7 @@ describe('Page.click', function () {
server.PREFIX + '/input/button.html' server.PREFIX + '/input/button.html'
); );
const frame = page.frames()[1]; const frame = page.frames()[1];
const button = await frame!.$('button'); using button = await frame!.$('button');
await button!.click(); await button!.click();
expect( expect(
await frame!.evaluate(() => { await frame!.evaluate(() => {

View File

@ -25,7 +25,7 @@ describe('Input.drag', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.PREFIX + '/input/drag-and-drop.html'); await page.goto(server.PREFIX + '/input/drag-and-drop.html');
const draggable = (await page.$('#drag'))!; using draggable = (await page.$('#drag'))!;
try { try {
await draggable!.drag({x: 1, y: 1}); await draggable!.drag({x: 1, y: 1});
@ -42,7 +42,7 @@ describe('Input.drag', function () {
expect(page.isDragInterceptionEnabled()).toBe(false); expect(page.isDragInterceptionEnabled()).toBe(false);
await page.setDragInterception(true); await page.setDragInterception(true);
expect(page.isDragInterceptionEnabled()).toBe(true); expect(page.isDragInterceptionEnabled()).toBe(true);
const draggable = (await page.$('#drag'))!; using draggable = (await page.$('#drag'))!;
const data = await draggable.drag({x: 1, y: 1}); const data = await draggable.drag({x: 1, y: 1});
expect(data.items).toHaveLength(1); expect(data.items).toHaveLength(1);
@ -59,9 +59,9 @@ describe('Input.drag', function () {
expect(page.isDragInterceptionEnabled()).toBe(false); expect(page.isDragInterceptionEnabled()).toBe(false);
await page.setDragInterception(true); await page.setDragInterception(true);
expect(page.isDragInterceptionEnabled()).toBe(true); expect(page.isDragInterceptionEnabled()).toBe(true);
const draggable = (await page.$('#drag'))!; using draggable = (await page.$('#drag'))!;
const data = await draggable.drag({x: 1, y: 1}); const data = await draggable.drag({x: 1, y: 1});
const dropzone = (await page.$('#drop'))!; using dropzone = (await page.$('#drop'))!;
await dropzone.dragEnter(data); await dropzone.dragEnter(data);
expect( expect(
@ -82,9 +82,9 @@ describe('Input.drag', function () {
expect(page.isDragInterceptionEnabled()).toBe(false); expect(page.isDragInterceptionEnabled()).toBe(false);
await page.setDragInterception(true); await page.setDragInterception(true);
expect(page.isDragInterceptionEnabled()).toBe(true); expect(page.isDragInterceptionEnabled()).toBe(true);
const draggable = (await page.$('#drag'))!; using draggable = (await page.$('#drag'))!;
const data = await draggable.drag({x: 1, y: 1}); const data = await draggable.drag({x: 1, y: 1});
const dropzone = (await page.$('#drop'))!; using dropzone = (await page.$('#drop'))!;
await dropzone.dragEnter(data); await dropzone.dragEnter(data);
await dropzone.dragOver(data); await dropzone.dragOver(data);
@ -111,8 +111,8 @@ describe('Input.drag', function () {
expect(page.isDragInterceptionEnabled()).toBe(false); expect(page.isDragInterceptionEnabled()).toBe(false);
await page.setDragInterception(true); await page.setDragInterception(true);
expect(page.isDragInterceptionEnabled()).toBe(true); expect(page.isDragInterceptionEnabled()).toBe(true);
const draggable = (await page.$('#drag'))!; using draggable = (await page.$('#drag'))!;
const dropzone = (await page.$('#drop'))!; using dropzone = (await page.$('#drop'))!;
const data = await draggable.drag({x: 1, y: 1}); const data = await draggable.drag({x: 1, y: 1});
await dropzone.dragEnter(data); await dropzone.dragEnter(data);
await dropzone.dragOver(data); await dropzone.dragOver(data);
@ -146,8 +146,8 @@ describe('Input.drag', function () {
expect(page.isDragInterceptionEnabled()).toBe(false); expect(page.isDragInterceptionEnabled()).toBe(false);
await page.setDragInterception(true); await page.setDragInterception(true);
expect(page.isDragInterceptionEnabled()).toBe(true); expect(page.isDragInterceptionEnabled()).toBe(true);
const draggable = (await page.$('#drag'))!; using draggable = (await page.$('#drag'))!;
const dropzone = (await page.$('#drop'))!; using dropzone = (await page.$('#drop'))!;
await draggable.dragAndDrop(dropzone); await draggable.dragAndDrop(dropzone);
expect( expect(
@ -178,7 +178,7 @@ describe('Input.drag', function () {
expect(page.isDragInterceptionEnabled()).toBe(false); expect(page.isDragInterceptionEnabled()).toBe(false);
await page.setDragInterception(true); await page.setDragInterception(true);
expect(page.isDragInterceptionEnabled()).toBe(true); expect(page.isDragInterceptionEnabled()).toBe(true);
const draggable = (await page.$('#drag'))!; using draggable = (await page.$('#drag'))!;
await draggable.drag({x: 1, y: 1}); await draggable.drag({x: 1, y: 1});
await page.setDragInterception(false); await page.setDragInterception(false);

View File

@ -35,7 +35,7 @@ describe('ElementHandle specs', function () {
await page.setViewport({width: 500, height: 500}); await page.setViewport({width: 500, height: 500});
await page.goto(server.PREFIX + '/grid.html'); await page.goto(server.PREFIX + '/grid.html');
const elementHandle = (await page.$('.box:nth-of-type(13)'))!; using elementHandle = (await page.$('.box:nth-of-type(13)'))!;
const box = await elementHandle.boundingBox(); const box = await elementHandle.boundingBox();
expect(box).toEqual({x: 100, y: 50, width: 50, height: 50}); expect(box).toEqual({x: 100, y: 50, width: 50, height: 50});
}); });
@ -45,7 +45,7 @@ describe('ElementHandle specs', function () {
await page.setViewport({width: 500, height: 500}); await page.setViewport({width: 500, height: 500});
await page.goto(server.PREFIX + '/frames/nested-frames.html'); await page.goto(server.PREFIX + '/frames/nested-frames.html');
const nestedFrame = page.frames()[1]!.childFrames()[1]!; const nestedFrame = page.frames()[1]!.childFrames()[1]!;
const elementHandle = (await nestedFrame.$('div'))!; using elementHandle = (await nestedFrame.$('div'))!;
const box = await elementHandle.boundingBox(); const box = await elementHandle.boundingBox();
if (isChrome) { if (isChrome) {
expect(box).toEqual({x: 28, y: 182, width: 264, height: 18}); expect(box).toEqual({x: 28, y: 182, width: 264, height: 18});
@ -57,7 +57,7 @@ describe('ElementHandle specs', function () {
const {page} = await getTestState(); const {page} = await getTestState();
await page.setContent('<div style="display:none">hi</div>'); await page.setContent('<div style="display:none">hi</div>');
const element = (await page.$('div'))!; using element = (await page.$('div'))!;
expect(await element.boundingBox()).toBe(null); expect(await element.boundingBox()).toBe(null);
}); });
it('should force a layout', async () => { it('should force a layout', async () => {
@ -67,7 +67,7 @@ describe('ElementHandle specs', function () {
await page.setContent( await page.setContent(
'<div style="width: 100px; height: 100px">hello</div>' '<div style="width: 100px; height: 100px">hello</div>'
); );
const elementHandle = (await page.$('div'))!; using elementHandle = (await page.$('div'))!;
await page.evaluate((element: HTMLElement) => { await page.evaluate((element: HTMLElement) => {
return (element.style.height = '200px'); return (element.style.height = '200px');
}, elementHandle); }, elementHandle);
@ -82,7 +82,7 @@ describe('ElementHandle specs', function () {
<rect id="theRect" x="30" y="50" width="200" height="300"></rect> <rect id="theRect" x="30" y="50" width="200" height="300"></rect>
</svg> </svg>
`); `);
const element = (await page.$( using element = (await page.$(
'#therect' '#therect'
)) as ElementHandle<SVGRectElement>; )) as ElementHandle<SVGRectElement>;
const pptrBoundingBox = await element.boundingBox(); const pptrBoundingBox = await element.boundingBox();
@ -111,7 +111,7 @@ describe('ElementHandle specs', function () {
// Step 2: Add div and position it absolutely inside frame. // Step 2: Add div and position it absolutely inside frame.
const frame = page.frames()[1]!; const frame = page.frames()[1]!;
const divHandle = ( using divHandle = (
await frame.evaluateHandle(() => { await frame.evaluateHandle(() => {
const div = document.createElement('div'); const div = document.createElement('div');
document.body.appendChild(div); document.body.appendChild(div);
@ -154,7 +154,7 @@ describe('ElementHandle specs', function () {
const {page} = await getTestState(); const {page} = await getTestState();
await page.setContent('<div style="display:none">hi</div>'); await page.setContent('<div style="display:none">hi</div>');
const element = (await page.$('div'))!; using element = (await page.$('div'))!;
expect(await element.boxModel()).toBe(null); expect(await element.boxModel()).toBe(null);
}); });
}); });
@ -165,7 +165,7 @@ describe('ElementHandle specs', function () {
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
await attachFrame(page, 'frame1', server.EMPTY_PAGE); await attachFrame(page, 'frame1', server.EMPTY_PAGE);
const elementHandle = (await page.$('#frame1'))!; using elementHandle = (await page.$('#frame1'))!;
const frame = await elementHandle.contentFrame(); const frame = await elementHandle.contentFrame();
expect(frame).toBe(page.frames()[1]); expect(frame).toBe(page.frames()[1]);
}); });
@ -175,7 +175,7 @@ describe('ElementHandle specs', function () {
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
await page.setContent('<div style="display: none">text</div>'); await page.setContent('<div style="display: none">text</div>');
const element = (await page.waitForSelector('div'))!; using element = (await page.waitForSelector('div'))!;
await expect(element.isVisible()).resolves.toBeFalsy(); await expect(element.isVisible()).resolves.toBeFalsy();
await expect(element.isHidden()).resolves.toBeTruthy(); await expect(element.isHidden()).resolves.toBeTruthy();
await element.evaluate(e => { await element.evaluate(e => {
@ -191,7 +191,7 @@ describe('ElementHandle specs', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.PREFIX + '/input/button.html'); await page.goto(server.PREFIX + '/input/button.html');
const button = (await page.$('button'))!; using button = (await page.$('button'))!;
await button.click(); await button.click();
expect( expect(
await page.evaluate(() => { await page.evaluate(() => {
@ -219,7 +219,7 @@ describe('ElementHandle specs', function () {
}); });
}); });
const divHandle = (await page.$('div'))!; using divHandle = (await page.$('div'))!;
await divHandle.click(); await divHandle.click();
await divHandle.click({ await divHandle.click({
offset: { offset: {
@ -237,7 +237,7 @@ describe('ElementHandle specs', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.PREFIX + '/shadow.html'); await page.goto(server.PREFIX + '/shadow.html');
const buttonHandle = await page.evaluateHandle(() => { using buttonHandle = await page.evaluateHandle(() => {
// @ts-expect-error button is expected to be in the page's scope. // @ts-expect-error button is expected to be in the page's scope.
return button as HTMLButtonElement; return button as HTMLButtonElement;
}); });
@ -253,7 +253,7 @@ describe('ElementHandle specs', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.PREFIX + '/input/button.html'); await page.goto(server.PREFIX + '/input/button.html');
const buttonTextNode = await page.evaluateHandle(() => { using buttonTextNode = await page.evaluateHandle(() => {
return document.querySelector('button')!.firstChild as HTMLElement; return document.querySelector('button')!.firstChild as HTMLElement;
}); });
let error!: Error; let error!: Error;
@ -269,7 +269,7 @@ describe('ElementHandle specs', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.PREFIX + '/input/button.html'); await page.goto(server.PREFIX + '/input/button.html');
const button = (await page.$('button'))!; using button = (await page.$('button'))!;
await page.evaluate((button: HTMLElement) => { await page.evaluate((button: HTMLElement) => {
return button.remove(); return button.remove();
}, button); }, button);
@ -286,7 +286,7 @@ describe('ElementHandle specs', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.PREFIX + '/input/button.html'); await page.goto(server.PREFIX + '/input/button.html');
const button = (await page.$('button'))!; using button = (await page.$('button'))!;
await page.evaluate((button: HTMLElement) => { await page.evaluate((button: HTMLElement) => {
return (button.style.display = 'none'); return (button.style.display = 'none');
}, button); }, button);
@ -302,7 +302,7 @@ describe('ElementHandle specs', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.PREFIX + '/input/button.html'); await page.goto(server.PREFIX + '/input/button.html');
const button = (await page.$('button'))!; using button = (await page.$('button'))!;
await page.evaluate((button: HTMLElement) => { await page.evaluate((button: HTMLElement) => {
return (button.parentElement!.style.display = 'none'); return (button.parentElement!.style.display = 'none');
}, button); }, button);
@ -318,7 +318,7 @@ describe('ElementHandle specs', function () {
const {page} = await getTestState(); const {page} = await getTestState();
await page.setContent('hello<br>goodbye'); await page.setContent('hello<br>goodbye');
const br = (await page.$('br'))!; using br = (await page.$('br'))!;
const error = await br.click().catch(error_ => { const error = await br.click().catch(error_ => {
return error_; return error_;
}); });
@ -345,7 +345,7 @@ describe('ElementHandle specs', function () {
return window.requestAnimationFrame(resolve); return window.requestAnimationFrame(resolve);
}); });
}); });
const divHandle = (await page.$('div'))!; using divHandle = (await page.$('div'))!;
expect(await divHandle.clickablePoint()).toEqual({ expect(await divHandle.clickablePoint()).toEqual({
x: 45 + 60, // margin + middle point offset x: 45 + 60, // margin + middle point offset
y: 45 + 30, // margin + middle point offset y: 45 + 30, // margin + middle point offset
@ -367,25 +367,25 @@ describe('ElementHandle specs', function () {
await page.setContent( await page.setContent(
'<button style="width: 10px; height: 10px; position: absolute; left: -20px"></button>' '<button style="width: 10px; height: 10px; position: absolute; left: -20px"></button>'
); );
const handle = await page.locator('button').waitHandle(); using handle = await page.locator('button').waitHandle();
await expect(handle.clickablePoint()).rejects.toBeInstanceOf(Error); await expect(handle.clickablePoint()).rejects.toBeInstanceOf(Error);
await page.setContent( await page.setContent(
'<button style="width: 10px; height: 10px; position: absolute; right: -20px"></button>' '<button style="width: 10px; height: 10px; position: absolute; right: -20px"></button>'
); );
const handle2 = await page.locator('button').waitHandle(); using handle2 = await page.locator('button').waitHandle();
await expect(handle2.clickablePoint()).rejects.toBeInstanceOf(Error); await expect(handle2.clickablePoint()).rejects.toBeInstanceOf(Error);
await page.setContent( await page.setContent(
'<button style="width: 10px; height: 10px; position: absolute; top: -20px"></button>' '<button style="width: 10px; height: 10px; position: absolute; top: -20px"></button>'
); );
const handle3 = await page.locator('button').waitHandle(); using handle3 = await page.locator('button').waitHandle();
await expect(handle3.clickablePoint()).rejects.toBeInstanceOf(Error); await expect(handle3.clickablePoint()).rejects.toBeInstanceOf(Error);
await page.setContent( await page.setContent(
'<button style="width: 10px; height: 10px; position: absolute; bottom: -20px"></button>' '<button style="width: 10px; height: 10px; position: absolute; bottom: -20px"></button>'
); );
const handle4 = await page.locator('button').waitHandle(); using handle4 = await page.locator('button').waitHandle();
await expect(handle4.clickablePoint()).rejects.toBeInstanceOf(Error); await expect(handle4.clickablePoint()).rejects.toBeInstanceOf(Error);
}); });
@ -399,7 +399,7 @@ describe('ElementHandle specs', function () {
return frame.name() === 'frame'; return frame.name() === 'frame';
}); });
const handle = await frame.locator('button').waitHandle(); using handle = await frame.locator('button').waitHandle();
await expect(handle.clickablePoint()).rejects.toBeInstanceOf(Error); await expect(handle.clickablePoint()).rejects.toBeInstanceOf(Error);
await page.setContent( await page.setContent(
@ -409,7 +409,7 @@ describe('ElementHandle specs', function () {
return frame.name() === 'frame2'; return frame.name() === 'frame2';
}); });
const handle2 = await frame2.locator('button').waitHandle(); using handle2 = await frame2.locator('button').waitHandle();
await expect(handle2.clickablePoint()).rejects.toBeInstanceOf(Error); await expect(handle2.clickablePoint()).rejects.toBeInstanceOf(Error);
}); });
@ -428,7 +428,7 @@ describe('ElementHandle specs', function () {
}); });
}); });
const frame = page.frames()[1]!; const frame = page.frames()[1]!;
const divHandle = (await frame.$('div'))!; using divHandle = (await frame.$('div'))!;
expect(await divHandle.clickablePoint()).toEqual({ expect(await divHandle.clickablePoint()).toEqual({
x: 20 + 45 + 60, // iframe pos + margin + middle point offset x: 20 + 45 + 60, // iframe pos + margin + middle point offset
y: 20 + 45 + 30, // iframe pos + margin + middle point offset y: 20 + 45 + 30, // iframe pos + margin + middle point offset
@ -455,7 +455,7 @@ describe('ElementHandle specs', function () {
await page.setContent( await page.setContent(
'<div id="not-foo"></div><div class="bar">bar2</div><div class="foo">Foo1</div>' '<div id="not-foo"></div><div class="bar">bar2</div><div class="foo">Foo1</div>'
); );
let element = (await waitFor)!; using element = (await waitFor)!;
if (element instanceof Error) { if (element instanceof Error) {
throw element; throw element;
} }
@ -467,13 +467,13 @@ describe('ElementHandle specs', function () {
await element.evaluate(el => { await element.evaluate(el => {
el.innerHTML = '<div class="bar">bar1</div>'; el.innerHTML = '<div class="bar">bar1</div>';
}); });
element = (await innerWaitFor)!; using element2 = (await innerWaitFor)!;
if (element instanceof Error) { if (element2 instanceof Error) {
throw element; throw element2;
} }
expect(element).toBeDefined(); expect(element2).toBeDefined();
expect( expect(
await element.evaluate(el => { await element2.evaluate(el => {
return (el as HTMLElement).innerText; return (el as HTMLElement).innerText;
}) })
).toStrictEqual('bar1'); ).toStrictEqual('bar1');
@ -496,12 +496,12 @@ describe('ElementHandle specs', function () {
</div>` </div>`
); );
const el1 = (await page.waitForSelector( using el1 = (await page.waitForSelector(
'#el1' '#el1'
)) as ElementHandle<HTMLDivElement>; )) as ElementHandle<HTMLDivElement>;
for (const path of ['//div', './/div']) { for (const path of ['//div', './/div']) {
const e = (await el1.waitForXPath( using e = (await el1.waitForXPath(
path path
)) as ElementHandle<HTMLDivElement>; )) as ElementHandle<HTMLDivElement>;
expect( expect(
@ -518,7 +518,7 @@ describe('ElementHandle specs', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.PREFIX + '/input/scrollable.html'); await page.goto(server.PREFIX + '/input/scrollable.html');
const button = (await page.$('#button-6'))!; using button = (await page.$('#button-6'))!;
await button.hover(); await button.hover();
expect( expect(
await page.evaluate(() => { await page.evaluate(() => {
@ -533,7 +533,7 @@ describe('ElementHandle specs', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
async function getVisibilityForButton(selector: string) { async function getVisibilityForButton(selector: string) {
const button = (await page.$(selector))!; using button = (await page.$(selector))!;
return await button.isIntersectingViewport(); return await button.isIntersectingViewport();
} }
@ -557,7 +557,7 @@ describe('ElementHandle specs', function () {
await page.goto(server.PREFIX + '/offscreenbuttons.html'); await page.goto(server.PREFIX + '/offscreenbuttons.html');
// a button almost cannot be seen // a button almost cannot be seen
// sometimes we expect to return false by isIntersectingViewport1 // sometimes we expect to return false by isIntersectingViewport1
const button = (await page.$('#btn11'))!; using button = (await page.$('#btn11'))!;
expect( expect(
await button.isIntersectingViewport({ await button.isIntersectingViewport({
threshold: 0.001, threshold: 0.001,
@ -570,7 +570,7 @@ describe('ElementHandle specs', function () {
await page.goto(server.PREFIX + '/offscreenbuttons.html'); await page.goto(server.PREFIX + '/offscreenbuttons.html');
// a button almost cannot be seen // a button almost cannot be seen
// sometimes we expect to return false by isIntersectingViewport1 // sometimes we expect to return false by isIntersectingViewport1
const button = (await page.$('#btn0'))!; using button = (await page.$('#btn0'))!;
expect( expect(
await button.isIntersectingViewport({ await button.isIntersectingViewport({
threshold: 1, threshold: 1,
@ -615,7 +615,7 @@ describe('ElementHandle specs', function () {
const [invisibleCircle, invisibleSvg] = await Promise.all([ const [invisibleCircle, invisibleSvg] = await Promise.all([
page.$('div circle'), page.$('div circle'),
await page.$('div svg'), page.$('div svg'),
]); ]);
// Firefox seems slow when using `isIntersectingViewport` // Firefox seems slow when using `isIntersectingViewport`
@ -661,7 +661,7 @@ describe('ElementHandle specs', function () {
return document.querySelector(`[id="${selector}"]`); return document.querySelector(`[id="${selector}"]`);
}, },
}); });
const element = (await page.$( using element = (await page.$(
'getById/foo' 'getById/foo'
)) as ElementHandle<HTMLDivElement>; )) as ElementHandle<HTMLDivElement>;
expect( expect(
@ -780,7 +780,7 @@ describe('ElementHandle specs', function () {
await page.setContent( await page.setContent(
'<div id="not-foo"></div><div class="bar">bar2</div><div class="foo">Foo1</div>' '<div id="not-foo"></div><div class="bar">bar2</div><div class="foo">Foo1</div>'
); );
let element = (await waitFor)!; using element = (await waitFor)!;
if (element instanceof Error) { if (element instanceof Error) {
throw element; throw element;
} }
@ -796,13 +796,13 @@ describe('ElementHandle specs', function () {
el.innerHTML = '<div class="bar">bar1</div>'; el.innerHTML = '<div class="bar">bar1</div>';
}); });
element = (await innerWaitFor)!; using element2 = (await innerWaitFor)!;
if (element instanceof Error) { if (element2 instanceof Error) {
throw element; throw element2;
} }
expect(element).toBeDefined(); expect(element2).toBeDefined();
expect( expect(
await element.evaluate(el => { await element2.evaluate(el => {
return el.innerText; return el.innerText;
}) })
).toStrictEqual('bar1'); ).toStrictEqual('bar1');
@ -847,7 +847,7 @@ describe('ElementHandle specs', function () {
}, },
}); });
const element = (await page.$('getByClass/foo'))!; using element = (await page.$('getByClass/foo'))!;
expect(element).toBeDefined(); expect(element).toBeDefined();
const elements = await page.$$('getByClass/foo'); const elements = await page.$$('getByClass/foo');
@ -893,7 +893,7 @@ describe('ElementHandle specs', function () {
}, },
}); });
const element = (await page.$( using element = (await page.$(
'getById/foo' 'getById/foo'
)) as ElementHandle<HTMLDivElement>; )) as ElementHandle<HTMLDivElement>;
expect( expect(
@ -908,8 +908,8 @@ describe('ElementHandle specs', function () {
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
await page.setContent('<div class="foo">Foo1</div>'); await page.setContent('<div class="foo">Foo1</div>');
const element = await page.$('.foo'); using element = await page.$('.foo');
const div = await element?.toElement('div'); using div = await element?.toElement('div');
expect(div).toBeDefined(); expect(div).toBeDefined();
}); });
}); });
@ -917,7 +917,7 @@ describe('ElementHandle specs', function () {
describe('ElementHandle[Symbol.dispose]', () => { describe('ElementHandle[Symbol.dispose]', () => {
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const handle = await page.evaluateHandle('document'); using handle = await page.evaluateHandle('document');
const spy = sinon.spy(handle, Symbol.dispose); const spy = sinon.spy(handle, Symbol.dispose);
{ {
using _ = handle; using _ = handle;
@ -931,7 +931,7 @@ describe('ElementHandle specs', function () {
describe('ElementHandle[Symbol.asyncDispose]', () => { describe('ElementHandle[Symbol.asyncDispose]', () => {
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const handle = await page.evaluateHandle('document'); using handle = await page.evaluateHandle('document');
const spy = sinon.spy(handle, Symbol.asyncDispose); const spy = sinon.spy(handle, Symbol.asyncDispose);
{ {
await using _ = handle; await using _ = handle;
@ -945,7 +945,7 @@ describe('ElementHandle specs', function () {
describe('ElementHandle.move', () => { describe('ElementHandle.move', () => {
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const handle = await page.evaluateHandle('document'); using handle = await page.evaluateHandle('document');
const spy = sinon.spy(handle, Symbol.dispose); const spy = sinon.spy(handle, Symbol.dispose);
{ {
using _ = handle; using _ = handle;

View File

@ -167,7 +167,7 @@ describe('Emulation', () => {
await page.emulate(iPhone); await page.emulate(iPhone);
await page.goto(server.PREFIX + '/input/button.html'); await page.goto(server.PREFIX + '/input/button.html');
const button = (await page.$('button'))!; using button = (await page.$('button'))!;
await page.evaluate((button: HTMLElement) => { await page.evaluate((button: HTMLElement) => {
return (button.style.marginTop = '200px'); return (button.style.marginTop = '200px');
}, button); }, button);

View File

@ -367,7 +367,7 @@ describe('Evaluation specs', function () {
const {page} = await getTestState(); const {page} = await getTestState();
await page.setContent('<section>42</section>'); await page.setContent('<section>42</section>');
const element = (await page.$('section'))!; using element = (await page.$('section'))!;
const text = await page.evaluate(e => { const text = await page.evaluate(e => {
return e.textContent; return e.textContent;
}, element); }, element);
@ -377,8 +377,9 @@ describe('Evaluation specs', function () {
const {page} = await getTestState(); const {page} = await getTestState();
await page.setContent('<section>39</section>'); await page.setContent('<section>39</section>');
const element = (await page.$('section'))!; using element = (await page.$('section'))!;
expect(element).toBeTruthy(); expect(element).toBeTruthy();
// We want to dispose early.
await element.dispose(); await element.dispose();
let error!: Error; let error!: Error;
await page await page
@ -394,7 +395,7 @@ describe('Evaluation specs', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await attachFrame(page, 'frame1', server.EMPTY_PAGE); await attachFrame(page, 'frame1', server.EMPTY_PAGE);
const bodyHandle = await page.frames()[1]!.$('body'); using bodyHandle = await page.frames()[1]!.$('body');
let error!: Error; let error!: Error;
await page await page
.evaluate(body => { .evaluate(body => {

View File

@ -73,7 +73,7 @@ describe('Frame specs', function () {
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const mainFrame = page.mainFrame(); const mainFrame = page.mainFrame();
const windowHandle = await mainFrame.evaluateHandle(() => { using windowHandle = await mainFrame.evaluateHandle(() => {
return window; return window;
}); });
expect(windowHandle).toBeTruthy(); expect(windowHandle).toBeTruthy();

View File

@ -24,7 +24,7 @@ describe('Emulate idle state', () => {
setupTestBrowserHooks(); setupTestBrowserHooks();
async function getIdleState(page: Page) { async function getIdleState(page: Page) {
const stateElement = (await page.$('#state')) as ElementHandle<HTMLElement>; using stateElement = (await page.$('#state')) as ElementHandle<HTMLElement>;
return await page.evaluate(element => { return await page.evaluate(element => {
return element.innerText; return element.innerText;
}, stateElement); }, stateElement);

View File

@ -33,7 +33,7 @@ describe('input tests', function () {
await page.goto(server.PREFIX + '/input/fileupload.html'); await page.goto(server.PREFIX + '/input/fileupload.html');
const filePath = path.relative(process.cwd(), FILE_TO_UPLOAD); const filePath = path.relative(process.cwd(), FILE_TO_UPLOAD);
const input = (await page.$('input'))!; using input = (await page.$('input'))!;
await page.evaluate((e: HTMLElement) => { await page.evaluate((e: HTMLElement) => {
(globalThis as any)._inputEvents = []; (globalThis as any)._inputEvents = [];
e.addEventListener('change', ev => { e.addEventListener('change', ev => {

View File

@ -27,7 +27,7 @@ describe('JSHandle', function () {
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const windowHandle = await page.evaluateHandle(() => { using windowHandle = await page.evaluateHandle(() => {
return window; return window;
}); });
expect(windowHandle).toBeTruthy(); expect(windowHandle).toBeTruthy();
@ -35,7 +35,7 @@ describe('JSHandle', function () {
it('should return the RemoteObject', async () => { it('should return the RemoteObject', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const windowHandle = await page.evaluateHandle(() => { using windowHandle = await page.evaluateHandle(() => {
return window; return window;
}); });
expect(windowHandle.remoteObject()).toBeTruthy(); expect(windowHandle.remoteObject()).toBeTruthy();
@ -43,7 +43,7 @@ describe('JSHandle', function () {
it('should accept object handle as an argument', async () => { it('should accept object handle as an argument', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const navigatorHandle = await page.evaluateHandle(() => { using navigatorHandle = await page.evaluateHandle(() => {
return navigator; return navigator;
}); });
const text = await page.evaluate(e => { const text = await page.evaluate(e => {
@ -54,7 +54,7 @@ describe('JSHandle', function () {
it('should accept object handle to primitive types', async () => { it('should accept object handle to primitive types', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const aHandle = await page.evaluateHandle(() => { using aHandle = await page.evaluateHandle(() => {
return 5; return 5;
}); });
const isFive = await page.evaluate(e => { const isFive = await page.evaluate(e => {
@ -80,7 +80,7 @@ describe('JSHandle', function () {
it('should accept object handle to unserializable value', async () => { it('should accept object handle to unserializable value', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const aHandle = await page.evaluateHandle(() => { using aHandle = await page.evaluateHandle(() => {
return Infinity; return Infinity;
}); });
expect( expect(
@ -92,7 +92,7 @@ describe('JSHandle', function () {
it('should use the same JS wrappers', async () => { it('should use the same JS wrappers', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const aHandle = await page.evaluateHandle(() => { using aHandle = await page.evaluateHandle(() => {
(globalThis as any).FOO = 123; (globalThis as any).FOO = 123;
return window; return window;
}); });
@ -108,14 +108,14 @@ describe('JSHandle', function () {
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const aHandle = await page.evaluateHandle(() => { using aHandle = await page.evaluateHandle(() => {
return { return {
one: 1, one: 1,
two: 2, two: 2,
three: 3, three: 3,
}; };
}); });
const twoHandle = await aHandle.getProperty('two'); using twoHandle = await aHandle.getProperty('two');
expect(await twoHandle.jsonValue()).toEqual(2); expect(await twoHandle.jsonValue()).toEqual(2);
}); });
}); });
@ -124,7 +124,7 @@ describe('JSHandle', function () {
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const aHandle = await page.evaluateHandle(() => { using aHandle = await page.evaluateHandle(() => {
return {foo: 'bar'}; return {foo: 'bar'};
}); });
const json = await aHandle.jsonValue(); const json = await aHandle.jsonValue();
@ -134,7 +134,7 @@ describe('JSHandle', function () {
it('works with jsonValues that are not objects', async () => { it('works with jsonValues that are not objects', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const aHandle = await page.evaluateHandle(() => { using aHandle = await page.evaluateHandle(() => {
return ['a', 'b']; return ['a', 'b'];
}); });
const json = await aHandle.jsonValue(); const json = await aHandle.jsonValue();
@ -144,12 +144,12 @@ describe('JSHandle', function () {
it('works with jsonValues that are primitives', async () => { it('works with jsonValues that are primitives', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const aHandle = await page.evaluateHandle(() => { using aHandle = await page.evaluateHandle(() => {
return 'foo'; return 'foo';
}); });
expect(await aHandle.jsonValue()).toEqual('foo'); expect(await aHandle.jsonValue()).toEqual('foo');
const bHandle = await page.evaluateHandle(() => { using bHandle = await page.evaluateHandle(() => {
return undefined; return undefined;
}); });
expect(await bHandle.jsonValue()).toEqual(undefined); expect(await bHandle.jsonValue()).toEqual(undefined);
@ -158,7 +158,7 @@ describe('JSHandle', function () {
it('should work with dates', async () => { it('should work with dates', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const dateHandle = await page.evaluateHandle(() => { using dateHandle = await page.evaluateHandle(() => {
return new Date('2017-09-26T00:00:00.000Z'); return new Date('2017-09-26T00:00:00.000Z');
}); });
const date = await dateHandle.jsonValue(); const date = await dateHandle.jsonValue();
@ -168,7 +168,7 @@ describe('JSHandle', function () {
it('should not throw for circular objects', async () => { it('should not throw for circular objects', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const handle = await page.evaluateHandle(() => { using handle = await page.evaluateHandle(() => {
const t: {t?: unknown; g: number} = {g: 1}; const t: {t?: unknown; g: number} = {g: 1};
t.t = t; t.t = t;
return t; return t;
@ -181,20 +181,20 @@ describe('JSHandle', function () {
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const aHandle = await page.evaluateHandle(() => { using aHandle = await page.evaluateHandle(() => {
return { return {
foo: 'bar', foo: 'bar',
}; };
}); });
const properties = await aHandle.getProperties(); const properties = await aHandle.getProperties();
const foo = properties.get('foo')!; using foo = properties.get('foo')!;
expect(foo).toBeTruthy(); expect(foo).toBeTruthy();
expect(await foo.jsonValue()).toBe('bar'); expect(await foo.jsonValue()).toBe('bar');
}); });
it('should return even non-own properties', async () => { it('should return even non-own properties', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const aHandle = await page.evaluateHandle(() => { using aHandle = await page.evaluateHandle(() => {
class A { class A {
a: string; a: string;
constructor() { constructor() {
@ -220,29 +220,29 @@ describe('JSHandle', function () {
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const aHandle = await page.evaluateHandle(() => { using aHandle = await page.evaluateHandle(() => {
return document.body; return document.body;
}); });
const element = aHandle.asElement(); using element = aHandle.asElement();
expect(element).toBeTruthy(); expect(element).toBeTruthy();
}); });
it('should return null for non-elements', async () => { it('should return null for non-elements', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const aHandle = await page.evaluateHandle(() => { using aHandle = await page.evaluateHandle(() => {
return 2; return 2;
}); });
const element = aHandle.asElement(); using element = aHandle.asElement();
expect(element).toBeFalsy(); expect(element).toBeFalsy();
}); });
it('should return ElementHandle for TextNodes', async () => { it('should return ElementHandle for TextNodes', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
await page.setContent('<div>ee!</div>'); await page.setContent('<div>ee!</div>');
const aHandle = await page.evaluateHandle(() => { using aHandle = await page.evaluateHandle(() => {
return document.querySelector('div')!.firstChild; return document.querySelector('div')!.firstChild;
}); });
const element = aHandle.asElement(); using element = aHandle.asElement();
expect(element).toBeTruthy(); expect(element).toBeTruthy();
expect( expect(
await page.evaluate(e => { await page.evaluate(e => {
@ -256,11 +256,11 @@ describe('JSHandle', function () {
it('should work for primitives', async () => { it('should work for primitives', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const numberHandle = await page.evaluateHandle(() => { using numberHandle = await page.evaluateHandle(() => {
return 2; return 2;
}); });
expect(numberHandle.toString()).toBe('JSHandle:2'); expect(numberHandle.toString()).toBe('JSHandle:2');
const stringHandle = await page.evaluateHandle(() => { using stringHandle = await page.evaluateHandle(() => {
return 'a'; return 'a';
}); });
expect(stringHandle.toString()).toBe('JSHandle:a'); expect(stringHandle.toString()).toBe('JSHandle:a');
@ -268,7 +268,7 @@ describe('JSHandle', function () {
it('should work for complicated objects', async () => { it('should work for complicated objects', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const aHandle = await page.evaluateHandle(() => { using aHandle = await page.evaluateHandle(() => {
return window; return window;
}); });
expect(aHandle.toString()).atLeastOneToContain([ expect(aHandle.toString()).atLeastOneToContain([
@ -337,7 +337,7 @@ describe('JSHandle', function () {
describe('JSHandle[Symbol.dispose]', () => { describe('JSHandle[Symbol.dispose]', () => {
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const handle = await page.evaluateHandle('new Set()'); using handle = await page.evaluateHandle('new Set()');
const spy = sinon.spy(handle, Symbol.dispose); const spy = sinon.spy(handle, Symbol.dispose);
{ {
using _ = handle; using _ = handle;
@ -351,7 +351,7 @@ describe('JSHandle', function () {
describe('JSHandle[Symbol.asyncDispose]', () => { describe('JSHandle[Symbol.asyncDispose]', () => {
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const handle = await page.evaluateHandle('new Set()'); using handle = await page.evaluateHandle('new Set()');
const spy = sinon.spy(handle, Symbol.asyncDispose); const spy = sinon.spy(handle, Symbol.asyncDispose);
{ {
await using _ = handle; await using _ = handle;
@ -365,7 +365,7 @@ describe('JSHandle', function () {
describe('JSHandle.move', () => { describe('JSHandle.move', () => {
it('should work', async () => { it('should work', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const handle = await page.evaluateHandle('new Set()'); using handle = await page.evaluateHandle('new Set()');
const spy = sinon.spy(handle, Symbol.dispose); const spy = sinon.spy(handle, Symbol.dispose);
{ {
using _ = handle; using _ = handle;

View File

@ -119,7 +119,7 @@ describe('Keyboard', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.PREFIX + '/input/textarea.html'); await page.goto(server.PREFIX + '/input/textarea.html');
const textarea = (await page.$('textarea'))!; using textarea = (await page.$('textarea'))!;
await textarea.press('a'); await textarea.press('a');
expect( expect(
await page.evaluate(() => { await page.evaluate(() => {
@ -148,7 +148,7 @@ describe('Keyboard', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.PREFIX + '/input/textarea.html'); await page.goto(server.PREFIX + '/input/textarea.html');
const textarea = (await page.$('textarea'))!; using textarea = (await page.$('textarea'))!;
await textarea.press('a', {text: 'ё'}); await textarea.press('a', {text: 'ё'});
expect( expect(
await page.evaluate(() => { await page.evaluate(() => {
@ -444,7 +444,7 @@ describe('Keyboard', function () {
true true
); );
}); });
const textarea = (await page.$('textarea'))!; using textarea = (await page.$('textarea'))!;
await textarea.press('Digit5'); await textarea.press('Digit5');
expect(await page.evaluate('keyLocation')).toBe(0); expect(await page.evaluate('keyLocation')).toBe(0);
@ -490,7 +490,7 @@ describe('Keyboard', function () {
server.PREFIX + '/input/textarea.html' server.PREFIX + '/input/textarea.html'
); );
const frame = page.frames()[1]!; const frame = page.frames()[1]!;
const textarea = (await frame.$('textarea'))!; using textarea = (await frame.$('textarea'))!;
await textarea.type('👹 Tokyo street Japan 🇯🇵'); await textarea.type('👹 Tokyo street Japan 🇯🇵');
expect( expect(
await frame.$eval('textarea', textarea => { await frame.$eval('textarea', textarea => {

View File

@ -863,10 +863,9 @@ describe('Launcher specs', function () {
return page.url() === server.EMPTY_PAGE; return page.url() === server.EMPTY_PAGE;
})!; })!;
await pageTwo.reload(); await pageTwo.reload();
const bodyHandle = await pageTwo.waitForSelector('body', { using _ = await pageTwo.waitForSelector('body', {
timeout: 10000, timeout: 10000,
}); });
await bodyHandle!.dispose();
await browserTwo.close(); await browserTwo.close();
} finally { } finally {
await close(); await close();

View File

@ -42,7 +42,7 @@ describe('Locator', function () {
willClick = true; willClick = true;
}) })
.click(); .click();
const button = await page.$('button'); using button = await page.$('button');
const text = await button?.evaluate(el => { const text = await button?.evaluate(el => {
return el.innerText; return el.innerText;
}); });
@ -69,7 +69,7 @@ describe('Locator', function () {
willClick = true; willClick = true;
}) })
.click(); .click();
const button = await page.$('button'); using button = await page.$('button');
const text = await button?.evaluate(el => { const text = await button?.evaluate(el => {
return el.innerText; return el.innerText;
}); });
@ -92,7 +92,7 @@ describe('Locator', function () {
willClick = true; willClick = true;
}) })
.click(); .click();
const button = await page.$('button'); using button = await page.$('button');
const text = await button?.evaluate(el => { const text = await button?.evaluate(el => {
return el.innerText; return el.innerText;
}); });
@ -114,7 +114,7 @@ describe('Locator', function () {
clicked = true; clicked = true;
}) })
.click(); .click();
const button = await page.$('button'); using button = await page.$('button');
const text = await button?.evaluate(el => { const text = await button?.evaluate(el => {
return el.innerText; return el.innerText;
}); });
@ -130,7 +130,7 @@ describe('Locator', function () {
<button style="margin-top: 600px;" onclick="this.innerText = 'clicked';">test</button> <button style="margin-top: 600px;" onclick="this.innerText = 'clicked';">test</button>
`); `);
await page.locator('button').click(); await page.locator('button').click();
const button = await page.$('button'); using button = await page.$('button');
const text = await button?.evaluate(el => { const text = await button?.evaluate(el => {
return el.innerText; return el.innerText;
}); });
@ -144,7 +144,7 @@ describe('Locator', function () {
await page.setContent(` await page.setContent(`
<button style="display: none;" onclick="this.innerText = 'clicked';">test</button> <button style="display: none;" onclick="this.innerText = 'clicked';">test</button>
`); `);
const button = await page.$('button'); using button = await page.$('button');
const result = page const result = page
.locator('button') .locator('button')
.click() .click()
@ -177,7 +177,7 @@ describe('Locator', function () {
await page.setContent(` await page.setContent(`
<button disabled onclick="this.innerText = 'clicked';">test</button> <button disabled onclick="this.innerText = 'clicked';">test</button>
`); `);
const button = await page.$('button'); using button = await page.$('button');
const result = page.locator('button').click(); const result = page.locator('button').click();
expect( expect(
await button?.evaluate(el => { await button?.evaluate(el => {
@ -202,7 +202,7 @@ describe('Locator', function () {
await page.setContent(` await page.setContent(`
<button style="margin-top: 600px;" style="display: none;" disabled onclick="this.innerText = 'clicked';">test</button> <button style="margin-top: 600px;" style="display: none;" disabled onclick="this.innerText = 'clicked';">test</button>
`); `);
const button = await page.$('button'); using button = await page.$('button');
const result = page.locator('button').click(); const result = page.locator('button').click();
expect( expect(
await button?.evaluate(el => { await button?.evaluate(el => {
@ -308,7 +308,7 @@ describe('Locator', function () {
willClick = true; willClick = true;
}) })
.click(); .click();
const button = await frame.$('button'); using button = await frame.$('button');
const text = await button?.evaluate(el => { const text = await button?.evaluate(el => {
return el.innerText; return el.innerText;
}); });
@ -332,7 +332,7 @@ describe('Locator', function () {
hovered = true; hovered = true;
}) })
.hover(); .hover();
const button = await page.$('button'); using button = await page.$('button');
const text = await button?.evaluate(el => { const text = await button?.evaluate(el => {
return el.innerText; return el.innerText;
}); });
@ -361,7 +361,7 @@ describe('Locator', function () {
scrollTop: 500, scrollTop: 500,
scrollLeft: 500, scrollLeft: 500,
}); });
const scrollable = await page.$('div'); using scrollable = await page.$('div');
const scroll = await scrollable?.evaluate(el => { const scroll = await scrollable?.evaluate(el => {
return el.scrollTop + ' ' + el.scrollLeft; return el.scrollTop + ' ' + el.scrollLeft;
}); });
@ -435,7 +435,7 @@ describe('Locator', function () {
await page.setContent(` await page.setContent(`
<input disabled> <input disabled>
`); `);
const input = await page.$('input'); using input = await page.$('input');
const result = page.locator('input').fill('test'); const result = page.locator('input').fill('test');
expect( expect(
await input?.evaluate(el => { await input?.evaluate(el => {

View File

@ -212,7 +212,7 @@ describe('Mouse', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.PREFIX + '/input/wheel.html'); await page.goto(server.PREFIX + '/input/wheel.html');
const elem = (await page.$('div'))!; using elem = (await page.$('div'))!;
const boundingBoxBefore = (await elem.boundingBox())!; const boundingBoxBefore = (await elem.boundingBox())!;
expect(boundingBoxBefore).toMatchObject({ expect(boundingBoxBefore).toMatchObject({
width: 115, width: 115,

View File

@ -378,7 +378,7 @@ describeWithDebugLogs('OOPIF', function () {
button.innerText = 'click'; button.innerText = 'click';
document.body.appendChild(button); document.body.appendChild(button);
}); });
const button = (await frame.waitForSelector('#test-button', { using button = (await frame.waitForSelector('#test-button', {
visible: true, visible: true,
}))!; }))!;
const result = await button.clickablePoint(); const result = await button.clickablePoint();

View File

@ -530,7 +530,7 @@ describe('Page', function () {
const {page} = await getTestState(); const {page} = await getTestState();
// Create a custom class // Create a custom class
const classHandle = await page.evaluateHandle(() => { using classHandle = await page.evaluateHandle(() => {
return class CustomClass {}; return class CustomClass {};
}); });
@ -541,10 +541,10 @@ describe('Page', function () {
}, classHandle); }, classHandle);
// Validate only one has been added. // Validate only one has been added.
const prototypeHandle = await page.evaluateHandle(CustomClass => { using prototypeHandle = await page.evaluateHandle(CustomClass => {
return CustomClass.prototype; return CustomClass.prototype;
}, classHandle); }, classHandle);
const objectsHandle = await page.queryObjects(prototypeHandle); using objectsHandle = await page.queryObjects(prototypeHandle);
await expect( await expect(
page.evaluate(objects => { page.evaluate(objects => {
return objects.length; return objects.length;
@ -564,7 +564,7 @@ describe('Page', function () {
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
// Create a custom class // Create a custom class
const classHandle = await page.evaluateHandle(() => { using classHandle = await page.evaluateHandle(() => {
return class CustomClass {}; return class CustomClass {};
}); });
@ -575,10 +575,10 @@ describe('Page', function () {
}, classHandle); }, classHandle);
// Validate only one has been added. // Validate only one has been added.
const prototypeHandle = await page.evaluateHandle(CustomClass => { using prototypeHandle = await page.evaluateHandle(CustomClass => {
return CustomClass.prototype; return CustomClass.prototype;
}, classHandle); }, classHandle);
const objectsHandle = await page.queryObjects(prototypeHandle); using objectsHandle = await page.queryObjects(prototypeHandle);
await expect( await expect(
page.evaluate(objects => { page.evaluate(objects => {
return objects.length; return objects.length;
@ -596,9 +596,10 @@ describe('Page', function () {
it('should fail for disposed handles', async () => { it('should fail for disposed handles', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const prototypeHandle = await page.evaluateHandle(() => { using prototypeHandle = await page.evaluateHandle(() => {
return HTMLBodyElement.prototype; return HTMLBodyElement.prototype;
}); });
// We want to dispose early.
await prototypeHandle.dispose(); await prototypeHandle.dispose();
let error!: Error; let error!: Error;
await page.queryObjects(prototypeHandle).catch(error_ => { await page.queryObjects(prototypeHandle).catch(error_ => {
@ -609,7 +610,7 @@ describe('Page', function () {
it('should fail primitive values as prototypes', async () => { it('should fail primitive values as prototypes', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const prototypeHandle = await page.evaluateHandle(() => { using prototypeHandle = await page.evaluateHandle(() => {
return 42; return 42;
}); });
let error!: Error; let error!: Error;
@ -1160,7 +1161,7 @@ describe('Page', function () {
await page.goto(server.PREFIX + '/abort-request.html'); await page.goto(server.PREFIX + '/abort-request.html');
const element = await page.$(`#abort`); using element = await page.$(`#abort`);
await element!.click(); await element!.click();
let error = false; let error = false;
@ -1733,7 +1734,7 @@ describe('Page', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const scriptHandle = await page.addScriptTag({url: '/injectedfile.js'}); using scriptHandle = await page.addScriptTag({url: '/injectedfile.js'});
expect(scriptHandle.asElement()).not.toBeNull(); expect(scriptHandle.asElement()).not.toBeNull();
expect( expect(
await page.evaluate(() => { await page.evaluate(() => {
@ -1811,7 +1812,7 @@ describe('Page', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const scriptHandle = await page.addScriptTag({ using scriptHandle = await page.addScriptTag({
path: path.join(__dirname, '../assets/injectedfile.js'), path: path.join(__dirname, '../assets/injectedfile.js'),
}); });
expect(scriptHandle.asElement()).not.toBeNull(); expect(scriptHandle.asElement()).not.toBeNull();
@ -1839,7 +1840,7 @@ describe('Page', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const scriptHandle = await page.addScriptTag({ using scriptHandle = await page.addScriptTag({
content: 'window.__injected = 35;', content: 'window.__injected = 35;',
}); });
expect(scriptHandle.asElement()).not.toBeNull(); expect(scriptHandle.asElement()).not.toBeNull();
@ -1907,7 +1908,7 @@ describe('Page', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const styleHandle = await page.addStyleTag({url: '/injectedstyle.css'}); using styleHandle = await page.addStyleTag({url: '/injectedstyle.css'});
expect(styleHandle.asElement()).not.toBeNull(); expect(styleHandle.asElement()).not.toBeNull();
expect( expect(
await page.evaluate( await page.evaluate(
@ -1937,7 +1938,7 @@ describe('Page', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const styleHandle = await page.addStyleTag({ using styleHandle = await page.addStyleTag({
path: path.join(__dirname, '../assets/injectedstyle.css'), path: path.join(__dirname, '../assets/injectedstyle.css'),
}); });
expect(styleHandle.asElement()).not.toBeNull(); expect(styleHandle.asElement()).not.toBeNull();
@ -1955,7 +1956,7 @@ describe('Page', function () {
await page.addStyleTag({ await page.addStyleTag({
path: path.join(__dirname, '../assets/injectedstyle.css'), path: path.join(__dirname, '../assets/injectedstyle.css'),
}); });
const styleHandle = (await page.$('style'))!; using styleHandle = (await page.$('style'))!;
const styleContent = await page.evaluate((style: HTMLStyleElement) => { const styleContent = await page.evaluate((style: HTMLStyleElement) => {
return style.innerHTML; return style.innerHTML;
}, styleHandle); }, styleHandle);
@ -1966,7 +1967,7 @@ describe('Page', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
const styleHandle = await page.addStyleTag({ using styleHandle = await page.addStyleTag({
content: 'body { background-color: green; }', content: 'body { background-color: green; }',
}); });
expect(styleHandle.asElement()).not.toBeNull(); expect(styleHandle.asElement()).not.toBeNull();

View File

@ -25,10 +25,10 @@ describe('Prerender', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.PREFIX + '/prerender/index.html'); await page.goto(server.PREFIX + '/prerender/index.html');
const button = await page.waitForSelector('button'); using button = await page.waitForSelector('button');
await button?.click(); await button?.click();
const link = await page.waitForSelector('a'); using link = await page.waitForSelector('a');
await Promise.all([page.waitForNavigation(), link?.click()]); await Promise.all([page.waitForNavigation(), link?.click()]);
expect( expect(
await page.evaluate(() => { await page.evaluate(() => {
@ -41,7 +41,7 @@ describe('Prerender', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.PREFIX + '/prerender/index.html'); await page.goto(server.PREFIX + '/prerender/index.html');
const button = await page.waitForSelector('button'); using button = await page.waitForSelector('button');
await button?.click(); await button?.click();
await page.goto(server.PREFIX + '/prerender/target.html'); await page.goto(server.PREFIX + '/prerender/target.html');
@ -57,11 +57,11 @@ describe('Prerender', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.PREFIX + '/prerender/index.html'); await page.goto(server.PREFIX + '/prerender/index.html');
const button = await page.waitForSelector('button'); using button = await page.waitForSelector('button');
await button?.click(); await button?.click();
const mainFrame = page.mainFrame(); const mainFrame = page.mainFrame();
const link = await mainFrame.waitForSelector('a'); using link = await mainFrame.waitForSelector('a');
await Promise.all([mainFrame.waitForNavigation(), link?.click()]); await Promise.all([mainFrame.waitForNavigation(), link?.click()]);
expect(mainFrame).toBe(page.mainFrame()); expect(mainFrame).toBe(page.mainFrame());
expect( expect(
@ -76,7 +76,7 @@ describe('Prerender', function () {
const {page, server} = await getTestState(); const {page, server} = await getTestState();
await page.goto(server.PREFIX + '/prerender/index.html'); await page.goto(server.PREFIX + '/prerender/index.html');
const button = await page.waitForSelector('button'); using button = await page.waitForSelector('button');
await button?.click(); await button?.click();
const mainFrame = page.mainFrame(); const mainFrame = page.mainFrame();
@ -100,10 +100,10 @@ describe('Prerender', function () {
}); });
await page.goto(server.PREFIX + '/prerender/index.html'); await page.goto(server.PREFIX + '/prerender/index.html');
const button = await page.waitForSelector('button'); using button = await page.waitForSelector('button');
await button?.click(); await button?.click();
const mainFrame = page.mainFrame(); const mainFrame = page.mainFrame();
const link = await mainFrame.waitForSelector('a'); using link = await mainFrame.waitForSelector('a');
await Promise.all([mainFrame.waitForNavigation(), link?.click()]); await Promise.all([mainFrame.waitForNavigation(), link?.click()]);
expect(mainFrame).toBe(page.mainFrame()); expect(mainFrame).toBe(page.mainFrame());
expect( expect(
@ -138,9 +138,9 @@ describe('Prerender', function () {
height: 400, height: 400,
}); });
await page.goto(server.PREFIX + '/prerender/index.html'); await page.goto(server.PREFIX + '/prerender/index.html');
const button = await page.waitForSelector('button'); using button = await page.waitForSelector('button');
await button?.click(); await button?.click();
const link = await page.waitForSelector('a'); using link = await page.waitForSelector('a');
await Promise.all([page.waitForNavigation(), link?.click()]); await Promise.all([page.waitForNavigation(), link?.click()]);
const result = await page.evaluate(() => { const result = await page.evaluate(() => {
return { return {

View File

@ -46,7 +46,7 @@ describe('Query handler tests', function () {
} }
it('should find first element in shadow', async () => { it('should find first element in shadow', async () => {
const {page} = await setUpPage(); const {page} = await setUpPage();
const div = (await page.$('pierce/.foo')) as ElementHandle<HTMLElement>; using div = (await page.$('pierce/.foo')) as ElementHandle<HTMLElement>;
const text = await div.evaluate(element => { const text = await div.evaluate(element => {
return element.textContent; return element.textContent;
}); });
@ -68,8 +68,8 @@ describe('Query handler tests', function () {
}); });
it('should find first child element', async () => { it('should find first child element', async () => {
const {page} = await setUpPage(); const {page} = await setUpPage();
const parentElement = (await page.$('html > div'))!; using parentElement = (await page.$('html > div'))!;
const childElement = (await parentElement.$( using childElement = (await parentElement.$(
'pierce/div' 'pierce/div'
)) as ElementHandle<HTMLElement>; )) as ElementHandle<HTMLElement>;
const text = await childElement.evaluate(element => { const text = await childElement.evaluate(element => {
@ -79,7 +79,7 @@ describe('Query handler tests', function () {
}); });
it('should find all child elements', async () => { it('should find all child elements', async () => {
const {page} = await setUpPage(); const {page} = await setUpPage();
const parentElement = (await page.$('html > div'))!; using parentElement = (await page.$('html > div'))!;
const childElements = (await parentElement.$$('pierce/div')) as Array< const childElements = (await parentElement.$$('pierce/div')) as Array<
ElementHandle<HTMLElement> ElementHandle<HTMLElement>
>; >;
@ -115,7 +115,7 @@ describe('Query handler tests', function () {
await page.setContent('<div id="1">a</div><div>a</div>'); await page.setContent('<div id="1">a</div><div>a</div>');
const element = await page.$('text/a'); using element = await page.$('text/a');
expect( expect(
await element?.evaluate(e => { await element?.evaluate(e => {
return e.id; return e.id;
@ -145,7 +145,7 @@ describe('Query handler tests', function () {
document.body.append(div); document.body.append(div);
}); });
const element = await page.$('text/a'); using element = await page.$('text/a');
expect( expect(
await element?.evaluate(e => { await element?.evaluate(e => {
return e.textContent; return e.textContent;
@ -157,7 +157,7 @@ describe('Query handler tests', function () {
await page.setContent('<div><div>a</div><div>b</div></div>'); await page.setContent('<div><div>a</div><div>b</div></div>');
const element = await page.$('text/a'); using element = await page.$('text/a');
expect( expect(
await element?.evaluate(e => { await element?.evaluate(e => {
return e.textContent; return e.textContent;
@ -169,7 +169,7 @@ describe('Query handler tests', function () {
await page.setContent('<input value="a">'); await page.setContent('<input value="a">');
const element = (await page.$( using element = (await page.$(
'text/a' 'text/a'
)) as ElementHandle<HTMLInputElement>; )) as ElementHandle<HTMLInputElement>;
expect( expect(
@ -190,7 +190,7 @@ describe('Query handler tests', function () {
await page.setContent('<div><span>a</span> <span>b</span><div>'); await page.setContent('<div><span>a</span> <span>b</span><div>');
const element = await page.$('text/a b'); using element = await page.$('text/a b');
expect( expect(
await element?.evaluate(e => { await element?.evaluate(e => {
return e.textContent; return e.textContent;
@ -203,8 +203,8 @@ describe('Query handler tests', function () {
await page.setContent( await page.setContent(
'<div id=target1>text</div><input id=target2 value=text><div id=target3>text</div>' '<div id=target1>text</div><input id=target2 value=text><div id=target3>text</div>'
); );
const div = (await page.$('#target1')) as ElementHandle<HTMLDivElement>; using div = (await page.$('#target1')) as ElementHandle<HTMLDivElement>;
const input = (await page.$( using input = (await page.$(
'#target2' '#target2'
)) as ElementHandle<HTMLInputElement>; )) as ElementHandle<HTMLInputElement>;
@ -271,7 +271,7 @@ describe('Query handler tests', function () {
await page.setContent('<div class="a"><span>a</span></div>'); await page.setContent('<div class="a"><span>a</span></div>');
const elementHandle = (await page.$('div'))!; using elementHandle = (await page.$('div'))!;
expect(await elementHandle.$(`text/a`)).toBeTruthy(); expect(await elementHandle.$(`text/a`)).toBeTruthy();
expect(await elementHandle.$$(`text/a`)).toHaveLength(1); expect(await elementHandle.$$(`text/a`)).toHaveLength(1);
}); });
@ -281,7 +281,7 @@ describe('Query handler tests', function () {
await page.setContent('<div class="a"></div>'); await page.setContent('<div class="a"></div>');
const elementHandle = (await page.$('div'))!; using elementHandle = (await page.$('div'))!;
expect(await elementHandle.$(`text/a`)).toBeFalsy(); expect(await elementHandle.$(`text/a`)).toBeFalsy();
expect(await elementHandle.$$(`text/a`)).toHaveLength(0); expect(await elementHandle.$$(`text/a`)).toHaveLength(0);
}); });
@ -313,7 +313,7 @@ describe('Query handler tests', function () {
await page.setContent('<div>a</div><div></div>'); await page.setContent('<div>a</div><div></div>');
const element = await page.$('xpath/html/body/div'); using element = await page.$('xpath/html/body/div');
expect( expect(
await element?.evaluate(e => { await element?.evaluate(e => {
return e.textContent === 'a'; return e.textContent === 'a';
@ -335,7 +335,7 @@ describe('Query handler tests', function () {
await page.setContent('<div class="a">a<span></span></div>'); await page.setContent('<div class="a">a<span></span></div>');
const elementHandle = (await page.$('div'))!; using elementHandle = (await page.$('div'))!;
expect(await elementHandle.$(`xpath/span`)).toBeTruthy(); expect(await elementHandle.$(`xpath/span`)).toBeTruthy();
expect(await elementHandle.$$(`xpath/span`)).toHaveLength(1); expect(await elementHandle.$$(`xpath/span`)).toHaveLength(1);
}); });
@ -345,7 +345,7 @@ describe('Query handler tests', function () {
await page.setContent('<div class="a">a</div>'); await page.setContent('<div class="a">a</div>');
const elementHandle = (await page.$('div'))!; using elementHandle = (await page.$('div'))!;
expect(await elementHandle.$(`xpath/span`)).toBeFalsy(); expect(await elementHandle.$(`xpath/span`)).toBeFalsy();
expect(await elementHandle.$$(`xpath/span`)).toHaveLength(0); expect(await elementHandle.$$(`xpath/span`)).toHaveLength(0);
}); });
@ -360,7 +360,7 @@ describe('Query handler tests', function () {
it('should work with CSS selectors', async () => { it('should work with CSS selectors', async () => {
const {server, page} = await getTestState(); const {server, page} = await getTestState();
await page.goto(`${server.PREFIX}/p-selectors.html`); await page.goto(`${server.PREFIX}/p-selectors.html`);
const element = await page.$('div > button'); using element = await page.$('div > button');
assert(element, 'Could not find element'); assert(element, 'Could not find element');
expect( expect(
await element.evaluate(element => { await element.evaluate(element => {
@ -383,7 +383,7 @@ describe('Query handler tests', function () {
const {server, page} = await getTestState(); const {server, page} = await getTestState();
await page.goto(`${server.PREFIX}/p-selectors.html`); await page.goto(`${server.PREFIX}/p-selectors.html`);
{ {
const element = await page.$('div >>>> div'); using element = await page.$('div >>>> div');
assert(element, 'Could not find element'); assert(element, 'Could not find element');
expect( expect(
await element.evaluate(element => { await element.evaluate(element => {
@ -423,7 +423,7 @@ describe('Query handler tests', function () {
it('should work with text selectors', async () => { it('should work with text selectors', async () => {
const {server, page} = await getTestState(); const {server, page} = await getTestState();
await page.goto(`${server.PREFIX}/p-selectors.html`); await page.goto(`${server.PREFIX}/p-selectors.html`);
const element = await page.$('div ::-p-text(world)'); using element = await page.$('div ::-p-text(world)');
assert(element, 'Could not find element'); assert(element, 'Could not find element');
expect( expect(
await element.evaluate(element => { await element.evaluate(element => {
@ -435,7 +435,7 @@ describe('Query handler tests', function () {
it('should work ARIA selectors', async () => { it('should work ARIA selectors', async () => {
const {server, page} = await getTestState(); const {server, page} = await getTestState();
await page.goto(`${server.PREFIX}/p-selectors.html`); await page.goto(`${server.PREFIX}/p-selectors.html`);
const element = await page.$('div ::-p-aria(world)'); using element = await page.$('div ::-p-aria(world)');
assert(element, 'Could not find element'); assert(element, 'Could not find element');
expect( expect(
await element.evaluate(element => { await element.evaluate(element => {
@ -447,7 +447,7 @@ describe('Query handler tests', function () {
it('should work for ARIA selectors in multiple isolated worlds', async () => { it('should work for ARIA selectors in multiple isolated worlds', async () => {
const {server, page} = await getTestState(); const {server, page} = await getTestState();
await page.goto(`${server.PREFIX}/p-selectors.html`); await page.goto(`${server.PREFIX}/p-selectors.html`);
let element = await page.waitForSelector('::-p-aria(world)'); using element = await page.waitForSelector('::-p-aria(world)');
assert(element, 'Could not find element'); assert(element, 'Could not find element');
expect( expect(
await element.evaluate(element => { await element.evaluate(element => {
@ -456,10 +456,10 @@ describe('Query handler tests', function () {
).toBeTruthy(); ).toBeTruthy();
// $ would add ARIA query handler to the main world. // $ would add ARIA query handler to the main world.
await element.$('::-p-aria(world)'); await element.$('::-p-aria(world)');
element = await page.waitForSelector('::-p-aria(world)'); using element2 = await page.waitForSelector('::-p-aria(world)');
assert(element, 'Could not find element'); assert(element2, 'Could not find element');
expect( expect(
await element.evaluate(element => { await element2.evaluate(element => {
return element.id === 'b'; return element.id === 'b';
}) })
).toBeTruthy(); ).toBeTruthy();
@ -468,7 +468,7 @@ describe('Query handler tests', function () {
it('should work ARIA selectors with role', async () => { it('should work ARIA selectors with role', async () => {
const {server, page} = await getTestState(); const {server, page} = await getTestState();
await page.goto(`${server.PREFIX}/p-selectors.html`); await page.goto(`${server.PREFIX}/p-selectors.html`);
const element = await page.$('::-p-aria(world[role="button"])'); using element = await page.$('::-p-aria(world[role="button"])');
assert(element, 'Could not find element'); assert(element, 'Could not find element');
expect( expect(
await element.evaluate(element => { await element.evaluate(element => {
@ -480,7 +480,7 @@ describe('Query handler tests', function () {
it('should work ARIA selectors with name and role', async () => { it('should work ARIA selectors with name and role', async () => {
const {server, page} = await getTestState(); const {server, page} = await getTestState();
await page.goto(`${server.PREFIX}/p-selectors.html`); await page.goto(`${server.PREFIX}/p-selectors.html`);
const element = await page.$('::-p-aria([name="world"][role="button"])'); using element = await page.$('::-p-aria([name="world"][role="button"])');
assert(element, 'Could not find element'); assert(element, 'Could not find element');
expect( expect(
await element.evaluate(element => { await element.evaluate(element => {
@ -492,7 +492,7 @@ describe('Query handler tests', function () {
it('should work XPath selectors', async () => { it('should work XPath selectors', async () => {
const {server, page} = await getTestState(); const {server, page} = await getTestState();
await page.goto(`${server.PREFIX}/p-selectors.html`); await page.goto(`${server.PREFIX}/p-selectors.html`);
const element = await page.$('div ::-p-xpath(//button)'); using element = await page.$('div ::-p-xpath(//button)');
assert(element, 'Could not find element'); assert(element, 'Could not find element');
expect( expect(
await element.evaluate(element => { await element.evaluate(element => {
@ -510,7 +510,7 @@ describe('Query handler tests', function () {
const {server, page} = await getTestState(); const {server, page} = await getTestState();
await page.goto(`${server.PREFIX}/p-selectors.html`); await page.goto(`${server.PREFIX}/p-selectors.html`);
const element = await page.$('::-p-div'); using element = await page.$('::-p-div');
assert(element, 'Could not find element'); assert(element, 'Could not find element');
expect( expect(
await element.evaluate(element => { await element.evaluate(element => {
@ -533,7 +533,7 @@ describe('Query handler tests', function () {
}); });
{ {
const element = await page.$('::-p-div(true)'); using element = await page.$('::-p-div(true)');
assert(element, 'Could not find element'); assert(element, 'Could not find element');
expect( expect(
await element.evaluate(element => { await element.evaluate(element => {
@ -542,7 +542,7 @@ describe('Query handler tests', function () {
).toBeTruthy(); ).toBeTruthy();
} }
{ {
const element = await page.$('::-p-div("true")'); using element = await page.$('::-p-div("true")');
assert(element, 'Could not find element'); assert(element, 'Could not find element');
expect( expect(
await element.evaluate(element => { await element.evaluate(element => {
@ -551,7 +551,7 @@ describe('Query handler tests', function () {
).toBeTruthy(); ).toBeTruthy();
} }
{ {
const element = await page.$("::-p-div('true')"); using element = await page.$("::-p-div('true')");
assert(element, 'Could not find element'); assert(element, 'Could not find element');
expect( expect(
await element.evaluate(element => { await element.evaluate(element => {
@ -560,7 +560,7 @@ describe('Query handler tests', function () {
).toBeTruthy(); ).toBeTruthy();
} }
{ {
const element = await page.$('::-p-div'); using element = await page.$('::-p-div');
assert(element, 'Could not find element'); assert(element, 'Could not find element');
expect( expect(
await element.evaluate(element => { await element.evaluate(element => {
@ -573,14 +573,13 @@ describe('Query handler tests', function () {
it('should work with :hover', async () => { it('should work with :hover', async () => {
const {server, page} = await getTestState(); const {server, page} = await getTestState();
await page.goto(`${server.PREFIX}/p-selectors.html`); await page.goto(`${server.PREFIX}/p-selectors.html`);
let button = await page.$('div ::-p-text(world)'); using button = await page.$('div ::-p-text(world)');
assert(button, 'Could not find element'); assert(button, 'Could not find element');
await button.hover(); await button.hover();
await button.dispose();
button = await page.$('div ::-p-text(world):hover'); using button2 = await page.$('div ::-p-text(world):hover');
assert(button, 'Could not find element'); assert(button2, 'Could not find element');
const value = await button.evaluate(span => { const value = await button2.evaluate(span => {
return {textContent: span.textContent, tagName: span.tagName}; return {textContent: span.textContent, tagName: span.tagName};
}); });
expect(value).toMatchObject({textContent: 'world', tagName: 'BUTTON'}); expect(value).toMatchObject({textContent: 'world', tagName: 'BUTTON'});
@ -643,22 +642,22 @@ describe('Query handler tests', function () {
it('should handle escapes', async () => { it('should handle escapes', async () => {
const {server, page} = await getTestState(); const {server, page} = await getTestState();
await page.goto(`${server.PREFIX}/p-selectors.html`); await page.goto(`${server.PREFIX}/p-selectors.html`);
let element = await page.$( using element = await page.$(
':scope >>> ::-p-text(My name is Jun \\(pronounced like "June"\\))' ':scope >>> ::-p-text(My name is Jun \\(pronounced like "June"\\))'
); );
expect(element).toBeTruthy(); expect(element).toBeTruthy();
element = await page.$( using element2 = await page.$(
':scope >>> ::-p-text("My name is Jun (pronounced like \\"June\\")")' ':scope >>> ::-p-text("My name is Jun (pronounced like \\"June\\")")'
); );
expect(element).toBeTruthy(); expect(element2).toBeTruthy();
element = await page.$( using element3 = await page.$(
':scope >>> ::-p-text(My name is Jun \\(pronounced like "June"\\)")' ':scope >>> ::-p-text(My name is Jun \\(pronounced like "June"\\)")'
); );
expect(element).toBeFalsy(); expect(element3).toBeFalsy();
element = await page.$( using element4 = await page.$(
':scope >>> ::-p-text("My name is Jun \\(pronounced like "June"\\))' ':scope >>> ::-p-text("My name is Jun \\(pronounced like "June"\\))'
); );
expect(element).toBeFalsy(); expect(element4).toBeFalsy();
}); });
}); });
}); });

View File

@ -49,7 +49,7 @@ describe('querySelector', function () {
const {page} = await getTestState(); const {page} = await getTestState();
await page.setContent('<section>hello</section><div> world</div>'); await page.setContent('<section>hello</section><div> world</div>');
const divHandle = (await page.$('div'))!; using divHandle = (await page.$('div'))!;
const text = await page.$eval( const text = await page.$eval(
'section', 'section',
(e, div) => { (e, div) => {
@ -111,7 +111,7 @@ describe('querySelector', function () {
await page.setContent( await page.setContent(
'<section>2</section><section>2</section><section>1</section><div>3</div>' '<section>2</section><section>2</section><section>1</section><div>3</div>'
); );
const divHandle = (await page.$('div'))!; using divHandle = (await page.$('div'))!;
const sum = await page.$$eval( const sum = await page.$$eval(
'section', 'section',
(sections, div) => { (sections, div) => {
@ -152,13 +152,13 @@ describe('querySelector', function () {
const {page} = await getTestState(); const {page} = await getTestState();
await page.setContent('<section>test</section>'); await page.setContent('<section>test</section>');
const element = (await page.$('section'))!; using element = (await page.$('section'))!;
expect(element).toBeTruthy(); expect(element).toBeTruthy();
}); });
it('should return null for non-existing element', async () => { it('should return null for non-existing element', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const element = (await page.$('non-existing-element'))!; using element = (await page.$('non-existing-element'))!;
expect(element).toBe(null); expect(element).toBe(null);
}); });
}); });
@ -218,9 +218,9 @@ describe('querySelector', function () {
await page.setContent( await page.setContent(
'<html><body><div class="second"><div class="inner">A</div></div></body></html>' '<html><body><div class="second"><div class="inner">A</div></div></body></html>'
); );
const html = (await page.$('html'))!; using html = (await page.$('html'))!;
const second = (await html.$('.second'))!; using second = (await html.$('.second'))!;
const inner = await second.$('.inner'); using inner = await second.$('.inner');
const content = await page.evaluate(e => { const content = await page.evaluate(e => {
return e?.textContent; return e?.textContent;
}, inner); }, inner);
@ -233,8 +233,8 @@ describe('querySelector', function () {
await page.setContent( await page.setContent(
'<html><body><div class="second"><div class="inner">B</div></div></body></html>' '<html><body><div class="second"><div class="inner">B</div></div></body></html>'
); );
const html = (await page.$('html'))!; using html = (await page.$('html'))!;
const second = await html.$('.third'); using second = await html.$('.third');
expect(second).toBe(null); expect(second).toBe(null);
}); });
}); });
@ -245,7 +245,7 @@ describe('querySelector', function () {
await page.setContent( await page.setContent(
'<html><body><div class="tweet"><div class="like">100</div><div class="retweets">10</div></div></body></html>' '<html><body><div class="tweet"><div class="like">100</div><div class="retweets">10</div></div></body></html>'
); );
const tweet = (await page.$('.tweet'))!; using tweet = (await page.$('.tweet'))!;
const content = await tweet.$eval('.like', node => { const content = await tweet.$eval('.like', node => {
return (node as HTMLElement).innerText; return (node as HTMLElement).innerText;
}); });
@ -258,7 +258,7 @@ describe('querySelector', function () {
const htmlContent = const htmlContent =
'<div class="a">not-a-child-div</div><div id="myId"><div class="a">a-child-div</div></div>'; '<div class="a">not-a-child-div</div><div id="myId"><div class="a">a-child-div</div></div>';
await page.setContent(htmlContent); await page.setContent(htmlContent);
const elementHandle = (await page.$('#myId'))!; using elementHandle = (await page.$('#myId'))!;
const content = await elementHandle.$eval('.a', node => { const content = await elementHandle.$eval('.a', node => {
return (node as HTMLElement).innerText; return (node as HTMLElement).innerText;
}); });
@ -271,7 +271,7 @@ describe('querySelector', function () {
const htmlContent = const htmlContent =
'<div class="a">not-a-child-div</div><div id="myId"></div>'; '<div class="a">not-a-child-div</div><div id="myId"></div>';
await page.setContent(htmlContent); await page.setContent(htmlContent);
const elementHandle = (await page.$('#myId'))!; using elementHandle = (await page.$('#myId'))!;
const errorMessage = await elementHandle const errorMessage = await elementHandle
.$eval('.a', node => { .$eval('.a', node => {
return (node as HTMLElement).innerText; return (node as HTMLElement).innerText;
@ -291,7 +291,7 @@ describe('querySelector', function () {
await page.setContent( await page.setContent(
'<html><body><div class="tweet"><div class="like">100</div><div class="like">10</div></div></body></html>' '<html><body><div class="tweet"><div class="like">100</div><div class="like">10</div></div></body></html>'
); );
const tweet = (await page.$('.tweet'))!; using tweet = (await page.$('.tweet'))!;
const content = await tweet.$$eval('.like', nodes => { const content = await tweet.$$eval('.like', nodes => {
return (nodes as HTMLElement[]).map(n => { return (nodes as HTMLElement[]).map(n => {
return n.innerText; return n.innerText;
@ -306,7 +306,7 @@ describe('querySelector', function () {
const htmlContent = const htmlContent =
'<div class="a">not-a-child-div</div><div id="myId"><div class="a">a1-child-div</div><div class="a">a2-child-div</div></div>'; '<div class="a">not-a-child-div</div><div id="myId"><div class="a">a1-child-div</div><div class="a">a2-child-div</div></div>';
await page.setContent(htmlContent); await page.setContent(htmlContent);
const elementHandle = (await page.$('#myId'))!; using elementHandle = (await page.$('#myId'))!;
const content = await elementHandle.$$eval('.a', nodes => { const content = await elementHandle.$$eval('.a', nodes => {
return (nodes as HTMLElement[]).map(n => { return (nodes as HTMLElement[]).map(n => {
return n.innerText; return n.innerText;
@ -321,7 +321,7 @@ describe('querySelector', function () {
const htmlContent = const htmlContent =
'<div class="a">not-a-child-div</div><div id="myId"></div>'; '<div class="a">not-a-child-div</div><div id="myId"></div>';
await page.setContent(htmlContent); await page.setContent(htmlContent);
const elementHandle = (await page.$('#myId'))!; using elementHandle = (await page.$('#myId'))!;
const nodesLength = await elementHandle.$$eval('.a', nodes => { const nodesLength = await elementHandle.$$eval('.a', nodes => {
return nodes.length; return nodes.length;
}); });
@ -336,7 +336,7 @@ describe('querySelector', function () {
await page.setContent( await page.setContent(
'<html><body><div>A</div><br/><div>B</div></body></html>' '<html><body><div>A</div><br/><div>B</div></body></html>'
); );
const html = (await page.$('html'))!; using html = (await page.$('html'))!;
const elements = await html.$$('div'); const elements = await html.$$('div');
expect(elements).toHaveLength(2); expect(elements).toHaveLength(2);
const promises = elements.map(element => { const promises = elements.map(element => {
@ -353,7 +353,7 @@ describe('querySelector', function () {
await page.setContent( await page.setContent(
'<html><body><span>A</span><br/><span>B</span></body></html>' '<html><body><span>A</span><br/><span>B</span></body></html>'
); );
const html = (await page.$('html'))!; using html = (await page.$('html'))!;
const elements = await html.$$('div'); const elements = await html.$$('div');
expect(elements).toHaveLength(0); expect(elements).toHaveLength(0);
}); });
@ -367,7 +367,7 @@ describe('querySelector', function () {
await page.setContent( await page.setContent(
'<html><body><div class="second"><div class="inner">A</div></div></body></html>' '<html><body><div class="second"><div class="inner">A</div></div></body></html>'
); );
const html = (await page.$('html'))!; using html = (await page.$('html'))!;
const second = await html.$x(`./body/div[contains(@class, 'second')]`); const second = await html.$x(`./body/div[contains(@class, 'second')]`);
const inner = await second[0]!.$x(`./div[contains(@class, 'inner')]`); const inner = await second[0]!.$x(`./div[contains(@class, 'inner')]`);
const content = await page.evaluate(e => { const content = await page.evaluate(e => {
@ -382,7 +382,7 @@ describe('querySelector', function () {
await page.setContent( await page.setContent(
'<html><body><div class="second"><div class="inner">B</div></div></body></html>' '<html><body><div class="second"><div class="inner">B</div></div></body></html>'
); );
const html = (await page.$('html'))!; using html = (await page.$('html'))!;
const second = await html.$x(`/div[contains(@class, 'third')]`); const second = await html.$x(`/div[contains(@class, 'third')]`);
expect(second).toEqual([]); expect(second).toEqual([]);
}); });
@ -411,7 +411,7 @@ describe('querySelector', function () {
await page.setContent( await page.setContent(
'<html><body><div>A</div><br/><div>B</div></body></html>' '<html><body><div>A</div><br/><div>B</div></body></html>'
); );
const html = (await page.$('html'))!; using html = (await page.$('html'))!;
const elements = await html.$$('allArray/div'); const elements = await html.$$('allArray/div');
expect(elements).toHaveLength(2); expect(elements).toHaveLength(2);
const promises = elements.map(element => { const promises = elements.map(element => {
@ -428,7 +428,7 @@ describe('querySelector', function () {
await page.setContent( await page.setContent(
'<html><body><span>A</span><br/><span>B</span></body></html>' '<html><body><span>A</span><br/><span>B</span></body></html>'
); );
const html = (await page.$('html'))!; using html = (await page.$('html'))!;
const elements = await html.$$('allArray/div'); const elements = await html.$$('allArray/div');
expect(elements).toHaveLength(0); expect(elements).toHaveLength(0);
}); });
@ -463,7 +463,7 @@ describe('querySelector', function () {
await page.setContent( await page.setContent(
'<section>2</section><section>2</section><section>1</section><div>3</div>' '<section>2</section><section>2</section><section>1</section><div>3</div>'
); );
const divHandle = (await page.$('div'))!; using divHandle = (await page.$('div'))!;
const sum = await page.$$eval( const sum = await page.$$eval(
'allArray/section', 'allArray/section',
(sections, div) => { (sections, div) => {

View File

@ -921,7 +921,7 @@ describe('request interception', function () {
return (img.onload = fulfill); return (img.onload = fulfill);
}); });
}, server.PREFIX); }, server.PREFIX);
const img = (await page.$('img'))!; using img = (await page.$('img'))!;
expect(await img.screenshot()).toBeGolden('mock-binary-response.png'); expect(await img.screenshot()).toBeGolden('mock-binary-response.png');
}); });
it('should stringify intercepted request response headers', async () => { it('should stringify intercepted request response headers', async () => {

View File

@ -868,7 +868,7 @@ describe('request interception', function () {
return (img.onload = fulfill); return (img.onload = fulfill);
}); });
}, server.PREFIX); }, server.PREFIX);
const img = (await page.$('img'))!; using img = (await page.$('img'))!;
expect(await img.screenshot()).toBeGolden('mock-binary-response.png'); expect(await img.screenshot()).toBeGolden('mock-binary-response.png');
}); });
it('should stringify intercepted request response headers', async () => { it('should stringify intercepted request response headers', async () => {

View File

@ -14,6 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
import assert from 'assert';
import expect from 'expect'; import expect from 'expect';
import {getTestState, launch, setupTestBrowserHooks} from './mocha-utils.js'; import {getTestState, launch, setupTestBrowserHooks} from './mocha-utils.js';
@ -213,7 +215,7 @@ describe('Screenshots', function () {
await page.evaluate(() => { await page.evaluate(() => {
return window.scrollBy(50, 100); return window.scrollBy(50, 100);
}); });
const elementHandle = (await page.$('.box:nth-of-type(3)'))!; using elementHandle = (await page.$('.box:nth-of-type(3)'))!;
const screenshot = await elementHandle.screenshot(); const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden('screenshot-element-bounding-box.png'); expect(screenshot).toBeGolden('screenshot-element-bounding-box.png');
}); });
@ -231,7 +233,8 @@ describe('Screenshots', function () {
await page.evaluate(() => { await page.evaluate(() => {
return window.scrollBy(50, 100); return window.scrollBy(50, 100);
}); });
const elementHandle = (await page.$('.box:nth-of-type(3)'))!; using elementHandle = await page.$('.box:nth-of-type(3)');
assert(elementHandle);
const screenshot = await elementHandle.screenshot(); const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeTruthy(); expect(screenshot).toBeTruthy();
} finally { } finally {
@ -253,7 +256,7 @@ describe('Screenshots', function () {
</style> </style>
<div></div> <div></div>
`); `);
const elementHandle = (await page.$('div'))!; using elementHandle = (await page.$('div'))!;
const screenshot = await elementHandle.screenshot(); const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden('screenshot-element-padding-border.png'); expect(screenshot).toBeGolden('screenshot-element-padding-border.png');
}); });
@ -277,7 +280,7 @@ describe('Screenshots', function () {
</style> </style>
<div class="to-screenshot"></div> <div class="to-screenshot"></div>
`); `);
const elementHandle = (await page.$('div.to-screenshot'))!; using elementHandle = (await page.$('div.to-screenshot'))!;
const screenshot = await elementHandle.screenshot(); const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden( expect(screenshot).toBeGolden(
'screenshot-element-larger-than-viewport.png' 'screenshot-element-larger-than-viewport.png'
@ -313,7 +316,7 @@ describe('Screenshots', function () {
<div class="above"></div> <div class="above"></div>
<div class="to-screenshot"></div> <div class="to-screenshot"></div>
`); `);
const elementHandle = (await page.$('div.to-screenshot'))!; using elementHandle = (await page.$('div.to-screenshot'))!;
const screenshot = await elementHandle.screenshot(); const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden( expect(screenshot).toBeGolden(
'screenshot-element-scrolled-into-view.png' 'screenshot-element-scrolled-into-view.png'
@ -330,7 +333,7 @@ describe('Screenshots', function () {
height: 100px; height: 100px;
background: green; background: green;
transform: rotateZ(200deg);">&nbsp;</div>`); transform: rotateZ(200deg);">&nbsp;</div>`);
const elementHandle = (await page.$('div'))!; using elementHandle = (await page.$('div'))!;
const screenshot = await elementHandle.screenshot(); const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden('screenshot-element-rotate.png'); expect(screenshot).toBeGolden('screenshot-element-rotate.png');
}); });
@ -338,7 +341,7 @@ describe('Screenshots', function () {
const {page} = await getTestState(); const {page} = await getTestState();
await page.setContent('<h1>remove this</h1>'); await page.setContent('<h1>remove this</h1>');
const elementHandle = (await page.$('h1'))!; using elementHandle = (await page.$('h1'))!;
await page.evaluate((element: HTMLElement) => { await page.evaluate((element: HTMLElement) => {
return element.remove(); return element.remove();
}, elementHandle); }, elementHandle);
@ -353,7 +356,7 @@ describe('Screenshots', function () {
const {page} = await getTestState(); const {page} = await getTestState();
await page.setContent('<div style="width: 50px; height: 0"></div>'); await page.setContent('<div style="width: 50px; height: 0"></div>');
const div = (await page.$('div'))!; using div = (await page.$('div'))!;
const error = await div.screenshot().catch(error_ => { const error = await div.screenshot().catch(error_ => {
return error_; return error_;
}); });
@ -365,7 +368,7 @@ describe('Screenshots', function () {
await page.setContent( await page.setContent(
'<div style="width:48.51px;height:19.8px;border:1px solid black;"></div>' '<div style="width:48.51px;height:19.8px;border:1px solid black;"></div>'
); );
const elementHandle = (await page.$('div'))!; using elementHandle = (await page.$('div'))!;
const screenshot = await elementHandle.screenshot(); const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden('screenshot-element-fractional.png'); expect(screenshot).toBeGolden('screenshot-element-fractional.png');
}); });
@ -375,7 +378,7 @@ describe('Screenshots', function () {
await page.setContent( await page.setContent(
'<div style="position:absolute; top: 10.3px; left: 20.4px;width:50.3px;height:20.2px;border:1px solid black;"></div>' '<div style="position:absolute; top: 10.3px; left: 20.4px;width:50.3px;height:20.2px;border:1px solid black;"></div>'
); );
const elementHandle = (await page.$('div'))!; using elementHandle = (await page.$('div'))!;
const screenshot = await elementHandle.screenshot(); const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden('screenshot-element-fractional-offset.png'); expect(screenshot).toBeGolden('screenshot-element-fractional-offset.png');
}); });

View File

@ -84,7 +84,7 @@ describe('Stack trace', function () {
it('should work with contiguous evaluation', async () => { it('should work with contiguous evaluation', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const thrower = await page.evaluateHandle(() => { using thrower = await page.evaluateHandle(() => {
return () => { return () => {
throw new Error('Test'); throw new Error('Test');
}; };

View File

@ -40,7 +40,7 @@ describe('Touchscreen', function () {
const iPhone = KnownDevices['iPhone 6']!; const iPhone = KnownDevices['iPhone 6']!;
await page.emulate(iPhone); await page.emulate(iPhone);
await page.goto(server.PREFIX + '/input/touches.html'); await page.goto(server.PREFIX + '/input/touches.html');
const button = (await page.$('button'))!; using button = (await page.$('button'))!;
await button.tap(); await button.tap();
expect( expect(
await page.evaluate(() => { await page.evaluate(() => {
@ -54,7 +54,7 @@ describe('Touchscreen', function () {
const iPhone = KnownDevices['iPhone 6']!; const iPhone = KnownDevices['iPhone 6']!;
await page.emulate(iPhone); await page.emulate(iPhone);
await page.goto(server.PREFIX + '/input/touches-move.html'); await page.goto(server.PREFIX + '/input/touches-move.html');
const touch = (await page.$('#touch'))!; using touch = (await page.$('#touch'))!;
const touchObj = (await touch.boundingBox()) as BoundingBox; const touchObj = (await touch.boundingBox()) as BoundingBox;
await page.touchscreen.touchStart(touchObj.x, touchObj.y); await page.touchscreen.touchStart(touchObj.x, touchObj.y);
const movePosx = 100; const movePosx = 100;

View File

@ -73,7 +73,7 @@ export const attachFrame = async (
frameId: string, frameId: string,
url: string url: string
): Promise<Frame | undefined> => { ): Promise<Frame | undefined> => {
const handle = await pageOrFrame.evaluateHandle(attachFrame, frameId, url); using handle = await pageOrFrame.evaluateHandle(attachFrame, frameId, url);
return (await handle.asElement()?.contentFrame()) ?? undefined; return (await handle.asElement()?.contentFrame()) ?? undefined;
async function attachFrame(frameId: string, url: string) { async function attachFrame(frameId: string, url: string) {

View File

@ -221,11 +221,11 @@ describe('waittask specs', function () {
const {page} = await getTestState(); const {page} = await getTestState();
await page.setContent('<div></div>'); await page.setContent('<div></div>');
const div = (await page.$('div'))!; using div = (await page.$('div'))!;
let resolved = false; let resolved = false;
const waitForFunction = page const waitForFunction = page
.waitForFunction( .waitForFunction(
(element: Element) => { element => {
return element.localName === 'div' && !element.parentElement; return element.localName === 'div' && !element.parentElement;
}, },
{}, {},
@ -432,7 +432,7 @@ describe('waittask specs', function () {
const watchdog = frame.waitForSelector('div'); const watchdog = frame.waitForSelector('div');
await frame.evaluate(addElement, 'br'); await frame.evaluate(addElement, 'br');
await frame.evaluate(addElement, 'div'); await frame.evaluate(addElement, 'div');
const eHandle = (await watchdog)!; using eHandle = (await watchdog)!;
const tagName = await (await eHandle.getProperty('tagName')).jsonValue(); const tagName = await (await eHandle.getProperty('tagName')).jsonValue();
expect(tagName).toBe('DIV'); expect(tagName).toBe('DIV');
}); });
@ -459,7 +459,7 @@ describe('waittask specs', function () {
const watchdog = page.waitForSelector('div'); const watchdog = page.waitForSelector('div');
await otherFrame.evaluate(addElement, 'div'); await otherFrame.evaluate(addElement, 'div');
await page.evaluate(addElement, 'div'); await page.evaluate(addElement, 'div');
const eHandle = await watchdog; using eHandle = await watchdog;
expect(eHandle?.frame).toBe(page.mainFrame()); expect(eHandle?.frame).toBe(page.mainFrame());
}); });
@ -473,7 +473,7 @@ describe('waittask specs', function () {
const waitForSelectorPromise = frame2.waitForSelector('div'); const waitForSelectorPromise = frame2.waitForSelector('div');
await frame1.evaluate(addElement, 'div'); await frame1.evaluate(addElement, 'div');
await frame2.evaluate(addElement, 'div'); await frame2.evaluate(addElement, 'div');
const eHandle = await waitForSelectorPromise; using eHandle = await waitForSelectorPromise;
expect(eHandle?.frame).toBe(frame2); expect(eHandle?.frame).toBe(frame2);
}); });
@ -513,7 +513,7 @@ describe('waittask specs', function () {
const promise = page.waitForSelector('div', {visible: true}); const promise = page.waitForSelector('div', {visible: true});
await page.setContent('<div style="display: none">text</div>'); await page.setContent('<div style="display: none">text</div>');
const element = await page.evaluateHandle(() => { using element = await page.evaluateHandle(() => {
return document.getElementsByTagName('div')[0]!; return document.getElementsByTagName('div')[0]!;
}); });
await expect( await expect(
@ -529,7 +529,7 @@ describe('waittask specs', function () {
const promise = page.waitForSelector('div', {visible: true}); const promise = page.waitForSelector('div', {visible: true});
await page.setContent('<div style="visibility: hidden">text</div>'); await page.setContent('<div style="visibility: hidden">text</div>');
const element = await page.evaluateHandle(() => { using element = await page.evaluateHandle(() => {
return document.getElementsByTagName('div')[0]!; return document.getElementsByTagName('div')[0]!;
}); });
await expect( await expect(
@ -551,7 +551,7 @@ describe('waittask specs', function () {
const promise = page.waitForSelector('div', {visible: true}); const promise = page.waitForSelector('div', {visible: true});
await page.setContent('<div style="width: 0">text</div>'); await page.setContent('<div style="width: 0">text</div>');
const element = await page.evaluateHandle(() => { using element = await page.evaluateHandle(() => {
return document.getElementsByTagName('div')[0]!; return document.getElementsByTagName('div')[0]!;
}); });
await expect( await expect(
@ -578,7 +578,7 @@ describe('waittask specs', function () {
await page.setContent( await page.setContent(
`<div style='display: none; visibility: hidden;'><div id="inner">hi</div></div>` `<div style='display: none; visibility: hidden;'><div id="inner">hi</div></div>`
); );
const element = await page.evaluateHandle(() => { using element = await page.evaluateHandle(() => {
return document.getElementsByTagName('div')[0]!; return document.getElementsByTagName('div')[0]!;
}); });
await expect( await expect(
@ -600,7 +600,7 @@ describe('waittask specs', function () {
const promise = page.waitForSelector('div', {hidden: true}); const promise = page.waitForSelector('div', {hidden: true});
await page.setContent(`<div style='display: block;'>text</div>`); await page.setContent(`<div style='display: block;'>text</div>`);
const element = await page.evaluateHandle(() => { using element = await page.evaluateHandle(() => {
return document.getElementsByTagName('div')[0]!; return document.getElementsByTagName('div')[0]!;
}); });
await expect( await expect(
@ -616,7 +616,7 @@ describe('waittask specs', function () {
const promise = page.waitForSelector('div', {hidden: true}); const promise = page.waitForSelector('div', {hidden: true});
await page.setContent(`<div style='display: block;'>text</div>`); await page.setContent(`<div style='display: block;'>text</div>`);
const element = await page.evaluateHandle(() => { using element = await page.evaluateHandle(() => {
return document.getElementsByTagName('div')[0]!; return document.getElementsByTagName('div')[0]!;
}); });
await expect( await expect(
@ -632,7 +632,7 @@ describe('waittask specs', function () {
const promise = page.waitForSelector('div', {hidden: true}); const promise = page.waitForSelector('div', {hidden: true});
await page.setContent('<div>text</div>'); await page.setContent('<div>text</div>');
const element = await page.evaluateHandle(() => { using element = await page.evaluateHandle(() => {
return document.getElementsByTagName('div')[0]!; return document.getElementsByTagName('div')[0]!;
}); });
await expect( await expect(
@ -648,7 +648,7 @@ describe('waittask specs', function () {
const promise = page.waitForSelector('div', {hidden: true}); const promise = page.waitForSelector('div', {hidden: true});
await page.setContent(`<div>text</div>`); await page.setContent(`<div>text</div>`);
const element = await page.evaluateHandle(() => { using element = await page.evaluateHandle(() => {
return document.getElementsByTagName('div')[0]!; return document.getElementsByTagName('div')[0]!;
}); });
await expect( await expect(
@ -662,7 +662,7 @@ describe('waittask specs', function () {
it('should return null if waiting to hide non-existing element', async () => { it('should return null if waiting to hide non-existing element', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const handle = await page.waitForSelector('non-existing', { using handle = await page.waitForSelector('non-existing', {
hidden: true, hidden: true,
}); });
expect(handle).toBe(null); expect(handle).toBe(null);
@ -779,7 +779,7 @@ describe('waittask specs', function () {
const waitForXPathPromise = frame2.waitForXPath('//div'); const waitForXPathPromise = frame2.waitForXPath('//div');
await frame1.evaluate(addElement, 'div'); await frame1.evaluate(addElement, 'div');
await frame2.evaluate(addElement, 'div'); await frame2.evaluate(addElement, 'div');
const eHandle = await waitForXPathPromise; using eHandle = await waitForXPathPromise;
expect(eHandle?.frame).toBe(frame2); expect(eHandle?.frame).toBe(frame2);
}); });
it('should throw when frame is detached', async () => { it('should throw when frame is detached', async () => {
@ -823,7 +823,7 @@ describe('waittask specs', function () {
it('hidden should return null if the element is not found', async () => { it('hidden should return null if the element is not found', async () => {
const {page} = await getTestState(); const {page} = await getTestState();
const waitForXPath = await page.waitForXPath('//div', {hidden: true}); using waitForXPath = await page.waitForXPath('//div', {hidden: true});
expect(waitForXPath).toBe(null); expect(waitForXPath).toBe(null);
}); });
@ -832,7 +832,7 @@ describe('waittask specs', function () {
await page.setContent(`<div style='display: none;'>text</div>`); await page.setContent(`<div style='display: none;'>text</div>`);
const waitForXPath = await page.waitForXPath('//div', {hidden: true}); using waitForXPath = await page.waitForXPath('//div', {hidden: true});
expect(waitForXPath).toBeInstanceOf(ElementHandle); expect(waitForXPath).toBeInstanceOf(ElementHandle);
}); });
@ -854,7 +854,7 @@ describe('waittask specs', function () {
const {page} = await getTestState(); const {page} = await getTestState();
await page.setContent(`<div>some text</div>`); await page.setContent(`<div>some text</div>`);
const text = await page.waitForXPath('//div/text()'); using text = await page.waitForXPath('//div/text()');
expect(await (await text!.getProperty('nodeType')!).jsonValue()).toBe( expect(await (await text!.getProperty('nodeType')!).jsonValue()).toBe(
3 /* Node.TEXT_NODE */ 3 /* Node.TEXT_NODE */
); );

View File

@ -47,11 +47,11 @@ describe('Workers', function () {
const {page} = await getTestState(); const {page} = await getTestState();
const workerCreatedPromise = waitEvent<WebWorker>(page, 'workercreated'); const workerCreatedPromise = waitEvent<WebWorker>(page, 'workercreated');
const workerObj = await page.evaluateHandle(() => { using workerObj = await page.evaluateHandle(() => {
return new Worker('data:text/javascript,1'); return new Worker('data:text/javascript,1');
}); });
const worker = await workerCreatedPromise; const worker = await workerCreatedPromise;
const workerThisObj = await worker.evaluateHandle(() => { using workerThisObj = await worker.evaluateHandle(() => {
return this; return this;
}); });
const workerDestroyedPromise = waitEvent(page, 'workerdestroyed'); const workerDestroyedPromise = waitEvent(page, 'workerdestroyed');