mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
chore: turn on rulesdir/use-using
(#10806)
This commit is contained in:
parent
a540085176
commit
900a1f227d
@ -144,7 +144,7 @@ module.exports = {
|
||||
// Keeps comments formatted.
|
||||
'rulesdir/prettier-comments': 'error',
|
||||
// Enforces clean up of used resources.
|
||||
'rulesdir/use-using': 'off',
|
||||
'rulesdir/use-using': 'error',
|
||||
// Brackets keep code readable.
|
||||
curly: ['error', 'all'],
|
||||
// Brackets keep code readable and `return` intentions clear.
|
||||
|
@ -28,11 +28,7 @@ import {
|
||||
NodeFor,
|
||||
} from '../common/types.js';
|
||||
import {KeyInput} from '../common/USKeyboardLayout.js';
|
||||
import {
|
||||
debugError,
|
||||
isString,
|
||||
withSourcePuppeteerURLIfNone,
|
||||
} from '../common/util.js';
|
||||
import {isString, withSourcePuppeteerURLIfNone} from '../common/util.js';
|
||||
import {assert} from '../util/assert.js';
|
||||
import {AsyncIterableUtil} from '../util/AsyncIterableUtil.js';
|
||||
|
||||
@ -336,15 +332,13 @@ export abstract class ElementHandle<
|
||||
...args: Params
|
||||
): Promise<Awaited<ReturnType<Func>>> {
|
||||
pageFunction = withSourcePuppeteerURLIfNone(this.$eval.name, pageFunction);
|
||||
const elementHandle = await this.$(selector);
|
||||
using elementHandle = await this.$(selector);
|
||||
if (!elementHandle) {
|
||||
throw new Error(
|
||||
`Error: failed to find element matching selector "${selector}"`
|
||||
);
|
||||
}
|
||||
const result = await elementHandle.evaluate(pageFunction, ...args);
|
||||
await elementHandle.dispose();
|
||||
return result;
|
||||
return await elementHandle.evaluate(pageFunction, ...args);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -394,7 +388,7 @@ export abstract class ElementHandle<
|
||||
): Promise<Awaited<ReturnType<Func>>> {
|
||||
pageFunction = withSourcePuppeteerURLIfNone(this.$$eval.name, pageFunction);
|
||||
const results = await this.$$(selector);
|
||||
const elements = await this.evaluateHandle(
|
||||
using elements = await this.evaluateHandle(
|
||||
(_, ...elements) => {
|
||||
return elements;
|
||||
},
|
||||
@ -406,7 +400,6 @@ export abstract class ElementHandle<
|
||||
return results.dispose();
|
||||
}),
|
||||
]);
|
||||
await elements.dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -480,8 +473,7 @@ export abstract class ElementHandle<
|
||||
}
|
||||
|
||||
async #checkVisibility(visibility: boolean): Promise<boolean> {
|
||||
const element = await this.frame.isolatedRealm().adoptHandle(this);
|
||||
try {
|
||||
using element = await this.frame.isolatedRealm().adoptHandle(this);
|
||||
return await this.frame.isolatedRealm().evaluate(
|
||||
async (PuppeteerUtil, element, visibility) => {
|
||||
return Boolean(PuppeteerUtil.checkVisibility(element, visibility));
|
||||
@ -492,9 +484,6 @@ export abstract class ElementHandle<
|
||||
element,
|
||||
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.
|
||||
*/
|
||||
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) {
|
||||
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> {
|
||||
const adoptedThis = await this.frame.isolatedRealm().adoptHandle(this);
|
||||
const boxes = await adoptedThis.evaluate(element => {
|
||||
const boxes = await this.evaluate(element => {
|
||||
if (!(element instanceof Element)) {
|
||||
return null;
|
||||
}
|
||||
@ -912,17 +901,18 @@ export abstract class ElementHandle<
|
||||
return {x: rect.x, y: rect.y, width: rect.width, height: rect.height};
|
||||
});
|
||||
});
|
||||
void adoptedThis.dispose().catch(debugError);
|
||||
if (!boxes?.length) {
|
||||
return null;
|
||||
}
|
||||
await this.#intersectBoundingBoxesWithFrame(boxes);
|
||||
let frame: Frame | null | undefined = this.frame;
|
||||
let element: HandleFor<HTMLIFrameElement> | null | undefined;
|
||||
while ((element = await frame?.frameElement())) {
|
||||
try {
|
||||
element = await element.frame.isolatedRealm().transferHandle(element);
|
||||
const parentBox = await element.evaluate(element => {
|
||||
let frame = this.frame;
|
||||
let parentFrame: Frame | null | undefined;
|
||||
while ((parentFrame = frame?.parentFrame())) {
|
||||
using handle = await frame.frameElement();
|
||||
if (!handle) {
|
||||
throw new Error('Unsupported frame type');
|
||||
}
|
||||
const parentBox = await handle.evaluate(element => {
|
||||
// Element is not visible.
|
||||
if (element.getClientRects().length === 0) {
|
||||
return null;
|
||||
@ -947,11 +937,8 @@ export abstract class ElementHandle<
|
||||
box.x += parentBox.left;
|
||||
box.y += parentBox.top;
|
||||
}
|
||||
await element.#intersectBoundingBoxesWithFrame(boxes);
|
||||
frame = frame?.parentFrame();
|
||||
} finally {
|
||||
void element.dispose().catch(debugError);
|
||||
}
|
||||
await handle.#intersectBoundingBoxesWithFrame(boxes);
|
||||
frame = parentFrame;
|
||||
}
|
||||
const box = boxes.find(box => {
|
||||
return box.width >= 1 && box.height >= 1;
|
||||
@ -986,7 +973,7 @@ export abstract class ElementHandle<
|
||||
* or `null` if the element is not visible.
|
||||
*/
|
||||
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 => {
|
||||
if (!(element instanceof Element)) {
|
||||
return null;
|
||||
@ -998,11 +985,10 @@ export abstract class ElementHandle<
|
||||
const rect = element.getBoundingClientRect();
|
||||
return {x: rect.x, y: rect.y, width: rect.width, height: rect.height};
|
||||
});
|
||||
void adoptedThis.dispose().catch(debugError);
|
||||
if (!box) {
|
||||
return null;
|
||||
}
|
||||
const offset = await this.#getTopLeftCornerOfFrame();
|
||||
const offset = await adoptedThis.#getTopLeftCornerOfFrame();
|
||||
if (!offset) {
|
||||
return null;
|
||||
}
|
||||
@ -1023,8 +1009,9 @@ export abstract class ElementHandle<
|
||||
* Each Point is an object `{x, y}`. Box points are sorted clock-wise.
|
||||
*/
|
||||
async boxModel(): Promise<BoxModel | null> {
|
||||
const adoptedThis = await this.frame.isolatedRealm().adoptHandle(this);
|
||||
const model = await adoptedThis.evaluate(element => {
|
||||
const model = await (async () => {
|
||||
using adoptedThis = await this.frame.isolatedRealm().adoptHandle(this);
|
||||
return await adoptedThis.evaluate(element => {
|
||||
if (!(element instanceof Element)) {
|
||||
return null;
|
||||
}
|
||||
@ -1096,7 +1083,7 @@ export abstract class ElementHandle<
|
||||
];
|
||||
}
|
||||
});
|
||||
void adoptedThis.dispose().catch(debugError);
|
||||
})();
|
||||
if (!model) {
|
||||
return null;
|
||||
}
|
||||
@ -1120,12 +1107,14 @@ export abstract class ElementHandle<
|
||||
|
||||
async #getTopLeftCornerOfFrame() {
|
||||
const point = {x: 0, y: 0};
|
||||
let frame: Frame | null | undefined = this.frame;
|
||||
let element: HandleFor<HTMLIFrameElement> | null | undefined;
|
||||
while ((element = await frame?.frameElement())) {
|
||||
try {
|
||||
element = await element.frame.isolatedRealm().transferHandle(element);
|
||||
const parentBox = await element.evaluate(element => {
|
||||
let frame = this.frame;
|
||||
let parentFrame: Frame | null | undefined;
|
||||
while ((parentFrame = frame?.parentFrame())) {
|
||||
using handle = await frame.frameElement();
|
||||
if (!handle) {
|
||||
throw new Error('Unsupported frame type');
|
||||
}
|
||||
const parentBox = await handle.evaluate(element => {
|
||||
// Element is not visible.
|
||||
if (element.getClientRects().length === 0) {
|
||||
return null;
|
||||
@ -1148,10 +1137,7 @@ export abstract class ElementHandle<
|
||||
}
|
||||
point.x += parentBox.left;
|
||||
point.y += parentBox.top;
|
||||
frame = frame?.parentFrame();
|
||||
} finally {
|
||||
void element.dispose().catch(debugError);
|
||||
}
|
||||
frame = parentFrame;
|
||||
}
|
||||
return point;
|
||||
}
|
||||
@ -1173,8 +1159,7 @@ export abstract class ElementHandle<
|
||||
* @internal
|
||||
*/
|
||||
protected async assertConnectedElement(): Promise<void> {
|
||||
const error = await this.evaluate(
|
||||
async (element): Promise<string | undefined> => {
|
||||
const error = await this.evaluate(async element => {
|
||||
if (!element.isConnected) {
|
||||
return 'Node is detached from document';
|
||||
}
|
||||
@ -1182,8 +1167,7 @@ export abstract class ElementHandle<
|
||||
return 'Node is not of type HTMLElement';
|
||||
}
|
||||
return;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw new Error(error);
|
||||
@ -1216,20 +1200,16 @@ export abstract class ElementHandle<
|
||||
*/
|
||||
async isIntersectingViewport(
|
||||
this: ElementHandle<Element>,
|
||||
options?: {
|
||||
options: {
|
||||
threshold?: number;
|
||||
}
|
||||
} = {}
|
||||
): Promise<boolean> {
|
||||
await this.assertConnectedElement();
|
||||
|
||||
const {threshold = 0} = options ?? {};
|
||||
const svgHandle = await this.#asSVGElementHandle(this);
|
||||
const intersectionTarget: ElementHandle<Element> = svgHandle
|
||||
? await this.#getOwnerSVGElement(svgHandle)
|
||||
: this;
|
||||
|
||||
try {
|
||||
return await intersectionTarget.evaluate(async (element, threshold) => {
|
||||
// eslint-disable-next-line rulesdir/use-using -- Returns `this`.
|
||||
const handle = await this.#asSVGElementHandle();
|
||||
using target = handle && (await handle.#getOwnerSVGElement());
|
||||
return await ((target ?? this) as ElementHandle<Element>).evaluate(
|
||||
async (element, threshold) => {
|
||||
const visibleRatio = await new Promise<number>(resolve => {
|
||||
const observer = new IntersectionObserver(entries => {
|
||||
resolve(entries[0]!.intersectionRatio);
|
||||
@ -1238,12 +1218,9 @@ export abstract class ElementHandle<
|
||||
observer.observe(element);
|
||||
});
|
||||
return threshold === 1 ? visibleRatio === 1 : visibleRatio > threshold;
|
||||
}, threshold);
|
||||
} finally {
|
||||
if (intersectionTarget !== this) {
|
||||
await intersectionTarget.dispose();
|
||||
}
|
||||
}
|
||||
},
|
||||
options.threshold ?? 0
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1251,8 +1228,9 @@ export abstract class ElementHandle<
|
||||
* or by calling element.scrollIntoView.
|
||||
*/
|
||||
async scrollIntoView(this: ElementHandle<Element>): Promise<void> {
|
||||
await this.assertConnectedElement();
|
||||
await this.evaluate(async (element): Promise<void> => {
|
||||
using adoptedThis = await this.frame.isolatedRealm().adoptHandle(this);
|
||||
await adoptedThis.assertConnectedElement();
|
||||
await adoptedThis.evaluate(async (element): Promise<void> => {
|
||||
element.scrollIntoView({
|
||||
block: 'center',
|
||||
inline: 'center',
|
||||
@ -1266,24 +1244,24 @@ export abstract class ElementHandle<
|
||||
* etc.).
|
||||
*/
|
||||
async #asSVGElementHandle(
|
||||
handle: ElementHandle<Element>
|
||||
this: ElementHandle<Element>
|
||||
): Promise<ElementHandle<SVGElement> | null> {
|
||||
if (
|
||||
await handle.evaluate(element => {
|
||||
await this.evaluate(element => {
|
||||
return element instanceof SVGElement;
|
||||
})
|
||||
) {
|
||||
return handle as ElementHandle<SVGElement>;
|
||||
return this as ElementHandle<SVGElement>;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async #getOwnerSVGElement(
|
||||
handle: ElementHandle<SVGElement>
|
||||
this: ElementHandle<SVGElement>
|
||||
): Promise<ElementHandle<SVGSVGElement>> {
|
||||
// SVGSVGElement.ownerSVGElement === null.
|
||||
return await handle.evaluateHandle(element => {
|
||||
return await this.evaluateHandle(element => {
|
||||
if (element instanceof SVGSVGElement) {
|
||||
return element;
|
||||
}
|
||||
|
@ -37,12 +37,12 @@ import {
|
||||
InnerLazyParams,
|
||||
NodeFor,
|
||||
} from '../common/types.js';
|
||||
import {debugError, importFSPromises} from '../common/util.js';
|
||||
import {importFSPromises} from '../common/util.js';
|
||||
import {TaskManager} from '../common/WaitTask.js';
|
||||
|
||||
import {KeyboardTypeOptions} from './Input.js';
|
||||
import {JSHandle} from './JSHandle.js';
|
||||
import {Locator, FunctionLocator, NodeLocator} from './locators/locators.js';
|
||||
import {FunctionLocator, Locator, NodeLocator} from './locators/locators.js';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@ -389,15 +389,14 @@ export class Frame extends EventEmitter {
|
||||
if (!parentFrame) {
|
||||
return null;
|
||||
}
|
||||
const list = await parentFrame.isolatedRealm().evaluateHandle(() => {
|
||||
using list = await parentFrame.isolatedRealm().evaluateHandle(() => {
|
||||
return document.querySelectorAll('iframe');
|
||||
});
|
||||
for await (const iframe of transposeIterableHandle(list)) {
|
||||
for await (using iframe of transposeIterableHandle(list)) {
|
||||
const frame = await iframe.contentFrame();
|
||||
if (frame._id === this._id) {
|
||||
return iframe;
|
||||
return iframe.move();
|
||||
}
|
||||
void iframe.dispose().catch(debugError);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -692,12 +692,8 @@ export abstract class Locator<T> extends EventEmitter {
|
||||
* @public
|
||||
*/
|
||||
async wait(options?: Readonly<ActionOptions>): Promise<T> {
|
||||
const handle = await this.waitHandle(options);
|
||||
try {
|
||||
using handle = await this.waitHandle(options);
|
||||
return await handle.jsonValue();
|
||||
} finally {
|
||||
void handle.dispose().catch(debugError);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,11 +32,11 @@ export class Binding {
|
||||
args: unknown[],
|
||||
isTrivial: boolean
|
||||
): Promise<void> {
|
||||
const garbage = [];
|
||||
const stack = new DisposableStack();
|
||||
try {
|
||||
if (!isTrivial) {
|
||||
// Getting non-trivial arguments.
|
||||
const handles = await context.evaluateHandle(
|
||||
using handles = await context.evaluateHandle(
|
||||
(name, seq) => {
|
||||
// @ts-expect-error Code is evaluated in a different context.
|
||||
return globalThis[name].args.get(seq);
|
||||
@ -44,7 +44,6 @@ export class Binding {
|
||||
this.#name,
|
||||
id
|
||||
);
|
||||
try {
|
||||
const properties = await handles.getProperties();
|
||||
for (const [index, handle] of properties) {
|
||||
// This is not straight-forward since some arguments can stringify, but
|
||||
@ -55,15 +54,12 @@ export class Binding {
|
||||
args[+index] = handle;
|
||||
break;
|
||||
default:
|
||||
garbage.push(handle.dispose());
|
||||
stack.use(handle);
|
||||
}
|
||||
} else {
|
||||
garbage.push(handle.dispose());
|
||||
stack.use(handle);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
await handles.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
await context.evaluate(
|
||||
@ -80,7 +76,7 @@ export class Binding {
|
||||
|
||||
for (const arg of args) {
|
||||
if (arg instanceof JSHandle) {
|
||||
garbage.push(arg.dispose());
|
||||
stack.use(arg);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
@ -116,8 +112,6 @@ export class Binding {
|
||||
)
|
||||
.catch(debugError);
|
||||
}
|
||||
} finally {
|
||||
await Promise.all(garbage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ async function* fastTransposeIteratorHandle<T>(
|
||||
iterator: JSHandle<AwaitableIterator<T>>,
|
||||
size: number
|
||||
) {
|
||||
const array = await iterator.evaluateHandle(async (iterator, size) => {
|
||||
using array = await iterator.evaluateHandle(async (iterator, size) => {
|
||||
const results = [];
|
||||
while (results.length < size) {
|
||||
const result = await iterator.next();
|
||||
@ -43,8 +43,14 @@ async function* fastTransposeIteratorHandle<T>(
|
||||
return results;
|
||||
}, size);
|
||||
const properties = (await array.getProperties()) as Map<string, HandleFor<T>>;
|
||||
await array.dispose();
|
||||
yield* properties.values();
|
||||
const handles = properties.values();
|
||||
using stack = new DisposableStack();
|
||||
stack.defer(() => {
|
||||
for (using handle of handles) {
|
||||
handle[Symbol.dispose]();
|
||||
}
|
||||
});
|
||||
yield* handles;
|
||||
return properties.size === 0;
|
||||
}
|
||||
|
||||
@ -57,13 +63,9 @@ async function* transposeIteratorHandle<T>(
|
||||
iterator: JSHandle<AwaitableIterator<T>>
|
||||
) {
|
||||
let size = DEFAULT_BATCH_SIZE;
|
||||
try {
|
||||
while (!(yield* fastTransposeIteratorHandle(iterator, size))) {
|
||||
size <<= 1;
|
||||
}
|
||||
} finally {
|
||||
await iterator.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
type AwaitableIterator<T> = Iterator<T> | AsyncIterator<T>;
|
||||
@ -74,11 +76,10 @@ type AwaitableIterator<T> = Iterator<T> | AsyncIterator<T>;
|
||||
export async function* transposeIterableHandle<T>(
|
||||
handle: JSHandle<AwaitableIterable<T>>
|
||||
): AsyncIterableIterator<HandleFor<T>> {
|
||||
yield* transposeIteratorHandle(
|
||||
await handle.evaluateHandle(iterable => {
|
||||
using generatorHandle = await handle.evaluateHandle(iterable => {
|
||||
return (async function* () {
|
||||
yield* iterable;
|
||||
})();
|
||||
})
|
||||
);
|
||||
});
|
||||
yield* transposeIteratorHandle(generatorHandle);
|
||||
}
|
||||
|
@ -104,7 +104,6 @@ export interface IsolatedWorldChart {
|
||||
*/
|
||||
export class IsolatedWorld implements Realm {
|
||||
#frame: Frame;
|
||||
#document?: ElementHandle<Document>;
|
||||
#context = Deferred.create<ExecutionContext>();
|
||||
#detached = false;
|
||||
|
||||
@ -149,7 +148,6 @@ export class IsolatedWorld implements Realm {
|
||||
}
|
||||
|
||||
clearContext(): void {
|
||||
this.#document = undefined;
|
||||
this.#context = Deferred.create();
|
||||
}
|
||||
|
||||
@ -216,31 +214,27 @@ export class IsolatedWorld implements Realm {
|
||||
async $<Selector extends string>(
|
||||
selector: Selector
|
||||
): Promise<ElementHandle<NodeFor<Selector>> | null> {
|
||||
const document = await this.document();
|
||||
return document.$(selector);
|
||||
using document = await this.document();
|
||||
return await document.$(selector);
|
||||
}
|
||||
|
||||
async $$<Selector extends string>(
|
||||
selector: Selector
|
||||
): Promise<Array<ElementHandle<NodeFor<Selector>>>> {
|
||||
const document = await this.document();
|
||||
return document.$$(selector);
|
||||
using document = await this.document();
|
||||
return await document.$$(selector);
|
||||
}
|
||||
|
||||
async document(): Promise<ElementHandle<Document>> {
|
||||
if (this.#document) {
|
||||
return this.#document;
|
||||
}
|
||||
const context = await this.executionContext();
|
||||
this.#document = await context.evaluateHandle(() => {
|
||||
// TODO(#10813): Implement document caching.
|
||||
return await this.evaluateHandle(() => {
|
||||
return document;
|
||||
});
|
||||
return this.#document;
|
||||
}
|
||||
|
||||
async $x(expression: string): Promise<Array<ElementHandle<Node>>> {
|
||||
const document = await this.document();
|
||||
return document.$x(expression);
|
||||
using document = await this.document();
|
||||
return await document.$x(expression);
|
||||
}
|
||||
|
||||
async $eval<
|
||||
@ -256,8 +250,8 @@ export class IsolatedWorld implements Realm {
|
||||
...args: Params
|
||||
): Promise<Awaited<ReturnType<Func>>> {
|
||||
pageFunction = withSourcePuppeteerURLIfNone(this.$eval.name, pageFunction);
|
||||
const document = await this.document();
|
||||
return document.$eval(selector, pageFunction, ...args);
|
||||
using document = await this.document();
|
||||
return await document.$eval(selector, pageFunction, ...args);
|
||||
}
|
||||
|
||||
async $$eval<
|
||||
@ -273,8 +267,8 @@ export class IsolatedWorld implements Realm {
|
||||
...args: Params
|
||||
): Promise<Awaited<ReturnType<Func>>> {
|
||||
pageFunction = withSourcePuppeteerURLIfNone(this.$$eval.name, pageFunction);
|
||||
const document = await this.document();
|
||||
return document.$$eval(selector, pageFunction, ...args);
|
||||
using document = await this.document();
|
||||
return await document.$$eval(selector, pageFunction, ...args);
|
||||
}
|
||||
|
||||
async content(): Promise<string> {
|
||||
@ -315,39 +309,34 @@ export class IsolatedWorld implements Realm {
|
||||
selector: string,
|
||||
options?: Readonly<ClickOptions>
|
||||
): Promise<void> {
|
||||
const handle = await this.$(selector);
|
||||
using handle = await this.$(selector);
|
||||
assert(handle, `No element found for selector: ${selector}`);
|
||||
await handle.click(options);
|
||||
await handle.dispose();
|
||||
}
|
||||
|
||||
async focus(selector: string): Promise<void> {
|
||||
const handle = await this.$(selector);
|
||||
using handle = await this.$(selector);
|
||||
assert(handle, `No element found for selector: ${selector}`);
|
||||
await handle.focus();
|
||||
await handle.dispose();
|
||||
}
|
||||
|
||||
async hover(selector: string): Promise<void> {
|
||||
const handle = await this.$(selector);
|
||||
using handle = await this.$(selector);
|
||||
assert(handle, `No element found for selector: ${selector}`);
|
||||
await handle.hover();
|
||||
await handle.dispose();
|
||||
}
|
||||
|
||||
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}`);
|
||||
const result = await handle.select(...values);
|
||||
await handle.dispose();
|
||||
return result;
|
||||
return await handle.select(...values);
|
||||
}
|
||||
|
||||
async tap(selector: string): Promise<void> {
|
||||
const handle = await this.$(selector);
|
||||
using handle = await this.$(selector);
|
||||
assert(handle, `No element found for selector: ${selector}`);
|
||||
await handle.tap();
|
||||
await handle.dispose();
|
||||
}
|
||||
|
||||
async type(
|
||||
@ -355,10 +344,9 @@ export class IsolatedWorld implements Realm {
|
||||
text: string,
|
||||
options?: Readonly<KeyboardTypeOptions>
|
||||
): Promise<void> {
|
||||
const handle = await this.$(selector);
|
||||
using handle = await this.$(selector);
|
||||
assert(handle, `No element found for selector: ${selector}`);
|
||||
await handle.type(text, options);
|
||||
await handle.dispose();
|
||||
}
|
||||
|
||||
// If multiple waitFor are set up asynchronously, we need to wait for the
|
||||
|
@ -433,11 +433,11 @@ export class CDPPage extends Page {
|
||||
assert(frame, 'This should never happen.');
|
||||
|
||||
// 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
|
||||
)) as ElementHandle<HTMLInputElement>;
|
||||
|
||||
const fileChooser = new FileChooser(handle, event);
|
||||
const fileChooser = new FileChooser(handle.move(), event);
|
||||
for (const promise of this.#fileChooserDeferreds) {
|
||||
promise.resolve(fileChooser);
|
||||
}
|
||||
@ -885,6 +885,8 @@ export class CDPPage extends Page {
|
||||
return;
|
||||
}
|
||||
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) {
|
||||
const remoteObject = arg.remoteObject();
|
||||
if (remoteObject.objectId) {
|
||||
|
@ -107,7 +107,7 @@ export class QueryHandler {
|
||||
selector: string
|
||||
): AwaitableIterable<ElementHandle<Node>> {
|
||||
element.assertElementHasWorld();
|
||||
const handle = await element.evaluateHandle(
|
||||
using handle = await element.evaluateHandle(
|
||||
this._querySelectorAll,
|
||||
selector,
|
||||
LazyArg.create(context => {
|
||||
@ -127,7 +127,7 @@ export class QueryHandler {
|
||||
selector: string
|
||||
): Promise<ElementHandle<Node> | null> {
|
||||
element.assertElementHasWorld();
|
||||
const result = await element.evaluateHandle(
|
||||
using result = await element.evaluateHandle(
|
||||
this._querySelector,
|
||||
selector,
|
||||
LazyArg.create(context => {
|
||||
@ -135,10 +135,9 @@ export class QueryHandler {
|
||||
})
|
||||
);
|
||||
if (!(result instanceof ElementHandle)) {
|
||||
await result.dispose();
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
return result.move();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -153,21 +152,22 @@ export class QueryHandler {
|
||||
selector: string,
|
||||
options: WaitForSelectorOptions
|
||||
): Promise<ElementHandle<Node> | null> {
|
||||
let frame: Frame;
|
||||
let element: ElementHandle<Node> | undefined;
|
||||
let frame!: Frame;
|
||||
using element = await (async () => {
|
||||
if (!(elementOrFrame instanceof ElementHandle)) {
|
||||
frame = elementOrFrame;
|
||||
} else {
|
||||
frame = elementOrFrame.frame;
|
||||
element = await frame.isolatedRealm().adoptHandle(elementOrFrame);
|
||||
return;
|
||||
}
|
||||
frame = elementOrFrame.frame;
|
||||
return await frame.isolatedRealm().adoptHandle(elementOrFrame);
|
||||
})();
|
||||
|
||||
const {visible = false, hidden = false, timeout, signal} = options;
|
||||
|
||||
try {
|
||||
signal?.throwIfAborted();
|
||||
|
||||
const handle = await frame.isolatedRealm().waitForFunction(
|
||||
using handle = await frame.isolatedRealm().waitForFunction(
|
||||
async (PuppeteerUtil, query, selector, root, visible) => {
|
||||
const querySelector = PuppeteerUtil.createFunction(
|
||||
query
|
||||
@ -195,15 +195,13 @@ export class QueryHandler {
|
||||
);
|
||||
|
||||
if (signal?.aborted) {
|
||||
await handle.dispose();
|
||||
throw signal.reason;
|
||||
}
|
||||
|
||||
if (!(handle instanceof ElementHandle)) {
|
||||
await handle.dispose();
|
||||
return null;
|
||||
}
|
||||
return frame.mainRealm().transferHandle(handle);
|
||||
return await frame.mainRealm().transferHandle(handle);
|
||||
} catch (error) {
|
||||
if (!isErrorLike(error)) {
|
||||
throw error;
|
||||
@ -213,10 +211,6 @@ export class QueryHandler {
|
||||
}
|
||||
error.message = `Waiting for selector \`${selector}\` failed: ${error.message}`;
|
||||
throw error;
|
||||
} finally {
|
||||
if (element) {
|
||||
await element.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ import {
|
||||
AutofillData,
|
||||
ElementHandle as BaseElementHandle,
|
||||
} from '../../api/ElementHandle.js';
|
||||
import {debugError} from '../util.js';
|
||||
|
||||
import {Frame} from './Frame.js';
|
||||
import {JSHandle as BidiJSHandle, JSHandle} from './JSHandle.js';
|
||||
@ -86,15 +85,13 @@ export class ElementHandle<
|
||||
this: ElementHandle<HTMLIFrameElement>
|
||||
): Promise<Frame>;
|
||||
override async contentFrame(): Promise<Frame | null> {
|
||||
const adoptedThis = await this.frame.isolatedRealm().adoptHandle(this);
|
||||
const handle = (await adoptedThis.evaluateHandle(element => {
|
||||
using adoptedThis = await this.frame.isolatedRealm().adoptHandle(this);
|
||||
using handle = (await adoptedThis.evaluateHandle(element => {
|
||||
if (element instanceof HTMLIFrameElement) {
|
||||
return element.contentWindow;
|
||||
}
|
||||
return;
|
||||
})) as BidiJSHandle;
|
||||
void handle.dispose().catch(debugError);
|
||||
void adoptedThis.dispose().catch(debugError);
|
||||
const value = handle.remoteValue();
|
||||
if (value.type === 'window') {
|
||||
return this.frame.page().frame(value.value.context);
|
||||
|
@ -106,9 +106,9 @@ export class JSHandle<T = unknown> extends BaseJSHandle<T> {
|
||||
);
|
||||
|
||||
for (const [key, value] of Object.entries(keys)) {
|
||||
const handle = results[key as any];
|
||||
using handle = results[key as any];
|
||||
if (handle) {
|
||||
map.set(value, handle);
|
||||
map.set(value, handle.move());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,8 +56,7 @@ export class Realm extends EventEmitter {
|
||||
const promise = this.internalPuppeteerUtil;
|
||||
this.internalPuppeteerUtil = undefined;
|
||||
try {
|
||||
const util = await promise;
|
||||
await util?.dispose();
|
||||
await (await promise)?.dispose();
|
||||
} catch (error) {
|
||||
debugError(error);
|
||||
}
|
||||
|
@ -96,8 +96,7 @@ export class Sandbox implements RealmBase {
|
||||
}
|
||||
|
||||
async document(): Promise<ElementHandle<Document>> {
|
||||
// TODO(jrandolf): We should try to cache this because we need to dispose
|
||||
// this when it's unused.
|
||||
// TODO(#10813): Implement document caching.
|
||||
return await this.#realm.evaluateHandle(() => {
|
||||
return document;
|
||||
});
|
||||
@ -106,15 +105,15 @@ export class Sandbox implements RealmBase {
|
||||
async $<Selector extends string>(
|
||||
selector: Selector
|
||||
): Promise<ElementHandle<NodeFor<Selector>> | null> {
|
||||
const document = await this.document();
|
||||
return document.$(selector);
|
||||
using document = await this.document();
|
||||
return await document.$(selector);
|
||||
}
|
||||
|
||||
async $$<Selector extends string>(
|
||||
selector: Selector
|
||||
): Promise<Array<ElementHandle<NodeFor<Selector>>>> {
|
||||
const document = await this.document();
|
||||
return document.$$(selector);
|
||||
using document = await this.document();
|
||||
return await document.$$(selector);
|
||||
}
|
||||
|
||||
async $eval<
|
||||
@ -130,8 +129,8 @@ export class Sandbox implements RealmBase {
|
||||
...args: Params
|
||||
): Promise<Awaited<ReturnType<Func>>> {
|
||||
pageFunction = withSourcePuppeteerURLIfNone(this.$eval.name, pageFunction);
|
||||
const document = await this.document();
|
||||
return document.$eval(selector, pageFunction, ...args);
|
||||
using document = await this.document();
|
||||
return await document.$eval(selector, pageFunction, ...args);
|
||||
}
|
||||
|
||||
async $$eval<
|
||||
@ -147,13 +146,13 @@ export class Sandbox implements RealmBase {
|
||||
...args: Params
|
||||
): Promise<Awaited<ReturnType<Func>>> {
|
||||
pageFunction = withSourcePuppeteerURLIfNone(this.$$eval.name, pageFunction);
|
||||
const document = await this.document();
|
||||
return document.$$eval(selector, pageFunction, ...args);
|
||||
using document = await this.document();
|
||||
return await document.$$eval(selector, pageFunction, ...args);
|
||||
}
|
||||
|
||||
async $x(expression: string): Promise<Array<ElementHandle<Node>>> {
|
||||
const document = await this.document();
|
||||
return document.$x(expression);
|
||||
using document = await this.document();
|
||||
return await document.$x(expression);
|
||||
}
|
||||
|
||||
async evaluateHandle<
|
||||
@ -249,39 +248,34 @@ export class Sandbox implements RealmBase {
|
||||
selector: string,
|
||||
options?: Readonly<ClickOptions>
|
||||
): Promise<void> {
|
||||
const handle = await this.$(selector);
|
||||
using handle = await this.$(selector);
|
||||
assert(handle, `No element found for selector: ${selector}`);
|
||||
await handle.click(options);
|
||||
await handle.dispose();
|
||||
}
|
||||
|
||||
async focus(selector: string): Promise<void> {
|
||||
const handle = await this.$(selector);
|
||||
using handle = await this.$(selector);
|
||||
assert(handle, `No element found for selector: ${selector}`);
|
||||
await handle.focus();
|
||||
await handle.dispose();
|
||||
}
|
||||
|
||||
async hover(selector: string): Promise<void> {
|
||||
const handle = await this.$(selector);
|
||||
using handle = await this.$(selector);
|
||||
assert(handle, `No element found for selector: ${selector}`);
|
||||
await handle.hover();
|
||||
await handle.dispose();
|
||||
}
|
||||
|
||||
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}`);
|
||||
const result = await handle.select(...values);
|
||||
await handle.dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
async tap(selector: string): Promise<void> {
|
||||
const handle = await this.$(selector);
|
||||
using handle = await this.$(selector);
|
||||
assert(handle, `No element found for selector: ${selector}`);
|
||||
await handle.tap();
|
||||
await handle.dispose();
|
||||
}
|
||||
|
||||
async type(
|
||||
@ -289,9 +283,8 @@ export class Sandbox implements RealmBase {
|
||||
text: string,
|
||||
options?: Readonly<KeyboardTypeOptions>
|
||||
): Promise<void> {
|
||||
const handle = await this.$(selector);
|
||||
using handle = await this.$(selector);
|
||||
assert(handle, `No element found for selector: ${selector}`);
|
||||
await handle.type(text, options);
|
||||
await handle.dispose();
|
||||
}
|
||||
}
|
||||
|
@ -149,6 +149,7 @@ export class BidiSerializer {
|
||||
if (arg instanceof LazyArg) {
|
||||
arg = await arg.get(context);
|
||||
}
|
||||
// eslint-disable-next-line rulesdir/use-using -- We want this to continue living.
|
||||
const objectHandle =
|
||||
arg && (arg instanceof JSHandle || arg instanceof ElementHandle)
|
||||
? arg
|
||||
|
@ -200,7 +200,7 @@ describe('Accessibility', function () {
|
||||
async function getAccessibleName(page: any, element: any) {
|
||||
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');
|
||||
await button?.click();
|
||||
await page.waitForSelector('aria/Hide');
|
||||
@ -483,7 +483,7 @@ describe('Accessibility', function () {
|
||||
|
||||
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({
|
||||
role: 'button',
|
||||
name: 'My Button',
|
||||
@ -494,7 +494,7 @@ describe('Accessibility', function () {
|
||||
|
||||
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({
|
||||
role: 'textbox',
|
||||
name: 'My Input',
|
||||
@ -512,7 +512,7 @@ describe('Accessibility', function () {
|
||||
</div>
|
||||
`);
|
||||
|
||||
const menu = (await page.$('div[role="menu"]'))!;
|
||||
using menu = (await page.$('div[role="menu"]'))!;
|
||||
expect(await page.accessibility.snapshot({root: menu})).toEqual({
|
||||
role: 'menu',
|
||||
name: 'My Menu',
|
||||
@ -528,7 +528,7 @@ describe('Accessibility', function () {
|
||||
const {page} = await getTestState();
|
||||
|
||||
await page.setContent(`<button>My Button</button>`);
|
||||
const button = (await page.$('button'))!;
|
||||
using button = (await page.$('button'))!;
|
||||
await page.$eval('button', button => {
|
||||
return button.remove();
|
||||
});
|
||||
@ -538,7 +538,7 @@ describe('Accessibility', function () {
|
||||
const {page} = await getTestState();
|
||||
|
||||
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({
|
||||
|
@ -39,49 +39,67 @@ describe('AriaQueryHandler', () => {
|
||||
});
|
||||
expect(id).toBe('btn');
|
||||
};
|
||||
let button = await page.$(
|
||||
{
|
||||
using button = await page.$(
|
||||
'aria/Submit button and some spaces[role="button"]'
|
||||
);
|
||||
await expectFound(button);
|
||||
button = await page.$(
|
||||
}
|
||||
{
|
||||
using button = await page.$(
|
||||
"aria/Submit button and some spaces[role='button']"
|
||||
);
|
||||
await expectFound(button);
|
||||
button = await page.$(
|
||||
}
|
||||
using button = await page.$(
|
||||
'aria/ Submit button and some spaces[role="button"]'
|
||||
);
|
||||
await expectFound(button);
|
||||
button = await page.$(
|
||||
{
|
||||
using button = await page.$(
|
||||
'aria/Submit button and some spaces [role="button"]'
|
||||
);
|
||||
await expectFound(button);
|
||||
button = await page.$(
|
||||
}
|
||||
{
|
||||
using button = await page.$(
|
||||
'aria/Submit button and some spaces [ role = "button" ] '
|
||||
);
|
||||
await expectFound(button);
|
||||
button = await page.$(
|
||||
}
|
||||
{
|
||||
using button = await page.$(
|
||||
'aria/[role="button"]Submit button and some spaces'
|
||||
);
|
||||
await expectFound(button);
|
||||
button = await page.$(
|
||||
}
|
||||
{
|
||||
using button = await page.$(
|
||||
'aria/Submit button [role="button"]and some spaces'
|
||||
);
|
||||
await expectFound(button);
|
||||
button = await page.$(
|
||||
}
|
||||
{
|
||||
using button = await page.$(
|
||||
'aria/[name=" Submit button and some spaces"][role="button"]'
|
||||
);
|
||||
await expectFound(button);
|
||||
button = await page.$(
|
||||
}
|
||||
{
|
||||
using button = await page.$(
|
||||
"aria/[name=' Submit button and some spaces'][role='button']"
|
||||
);
|
||||
await expectFound(button);
|
||||
button = await page.$(
|
||||
}
|
||||
{
|
||||
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(
|
||||
'<div id="div"><button id="btn" role="button">Submit</button></div>'
|
||||
);
|
||||
const button = (await page.$(
|
||||
using button = (await page.$(
|
||||
'aria/[role="button"]'
|
||||
)) as ElementHandle<HTMLButtonElement>;
|
||||
const id = await button!.evaluate(button => {
|
||||
@ -105,7 +123,7 @@ describe('AriaQueryHandler', () => {
|
||||
await page.setContent(
|
||||
'<div id="div"><button id="btn" role="button">Submit</button></div>'
|
||||
);
|
||||
const button = (await page.$(
|
||||
using button = (await page.$(
|
||||
'aria/Submit[role="button"]'
|
||||
)) as ElementHandle<HTMLButtonElement>;
|
||||
const id = await button!.evaluate(button => {
|
||||
@ -122,7 +140,7 @@ describe('AriaQueryHandler', () => {
|
||||
<div role="menu" id="mnu2" aria-label="menu div"></div>
|
||||
`
|
||||
);
|
||||
const div = (await page.$(
|
||||
using div = (await page.$(
|
||||
'aria/menu div'
|
||||
)) as ElementHandle<HTMLDivElement>;
|
||||
const id = await div!.evaluate(div => {
|
||||
@ -139,7 +157,7 @@ describe('AriaQueryHandler', () => {
|
||||
<div role="menu" id="mnu2" aria-label="menu-label2">menu div</div>
|
||||
`
|
||||
);
|
||||
const menu = (await page.$(
|
||||
using menu = (await page.$(
|
||||
'aria/menu-label1'
|
||||
)) as ElementHandle<HTMLDivElement>;
|
||||
const id = await menu!.evaluate(div => {
|
||||
@ -156,7 +174,7 @@ describe('AriaQueryHandler', () => {
|
||||
<div role="menu" id="mnu2" aria-label="menu-label2">menu div</div>
|
||||
`
|
||||
);
|
||||
const menu = (await page.$(
|
||||
using menu = (await page.$(
|
||||
'aria/menu-label2'
|
||||
)) as ElementHandle<HTMLDivElement>;
|
||||
const id = await menu!.evaluate(div => {
|
||||
@ -230,7 +248,7 @@ describe('AriaQueryHandler', () => {
|
||||
await page.evaluate(() => {
|
||||
return (document.body.innerHTML = `<div><button>test</button></div>`);
|
||||
});
|
||||
const element = (await page.$('div'))!;
|
||||
using element = (await page.$('div'))!;
|
||||
await element!.waitForSelector('aria/test');
|
||||
});
|
||||
|
||||
@ -299,7 +317,7 @@ describe('AriaQueryHandler', () => {
|
||||
const watchdog = frame.waitForSelector('aria/[role="heading"]');
|
||||
await frame.evaluate(addElement, 'br');
|
||||
await frame.evaluate(addElement, 'h1');
|
||||
const elementHandle = (await watchdog)!;
|
||||
using elementHandle = (await watchdog)!;
|
||||
const tagName = await (
|
||||
await elementHandle.getProperty('tagName')
|
||||
).jsonValue();
|
||||
@ -328,7 +346,7 @@ describe('AriaQueryHandler', () => {
|
||||
const watchdog = page.waitForSelector('aria/[role="button"]');
|
||||
await otherFrame!.evaluate(addElement, 'button');
|
||||
await page.evaluate(addElement, 'button');
|
||||
const elementHandle = await watchdog;
|
||||
using elementHandle = await watchdog;
|
||||
expect(elementHandle!.frame).toBe(page.mainFrame());
|
||||
});
|
||||
|
||||
@ -344,7 +362,7 @@ describe('AriaQueryHandler', () => {
|
||||
);
|
||||
await frame1!.evaluate(addElement, 'button');
|
||||
await frame2!.evaluate(addElement, 'button');
|
||||
const elementHandle = await waitForSelectorPromise;
|
||||
using elementHandle = await waitForSelectorPromise;
|
||||
expect(elementHandle!.frame).toBe(frame2);
|
||||
});
|
||||
|
||||
@ -517,7 +535,7 @@ describe('AriaQueryHandler', () => {
|
||||
it('should return null if waiting to hide non-existing element', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const handle = await page.waitForSelector('aria/non-existing', {
|
||||
using handle = await page.waitForSelector('aria/non-existing', {
|
||||
hidden: true,
|
||||
});
|
||||
expect(handle).toBe(null);
|
||||
|
@ -24,7 +24,7 @@ describe('Autofill', function () {
|
||||
it('should fill out a credit card', async () => {
|
||||
const {page, server} = await getTestState();
|
||||
await page.goto(server.PREFIX + '/credit-card.html');
|
||||
const name = await page.waitForSelector('#name');
|
||||
using name = await page.waitForSelector('#name');
|
||||
await name!.autofill({
|
||||
creditCard: {
|
||||
number: '4444444444444444',
|
||||
|
@ -117,7 +117,7 @@ describe('Page.click', function () {
|
||||
|
||||
await page.setJavaScriptEnabled(false);
|
||||
await page.goto(server.PREFIX + '/wrappedlink.html');
|
||||
const body = await page.waitForSelector('body');
|
||||
using body = await page.waitForSelector('body');
|
||||
await body!.evaluate(el => {
|
||||
el.style.paddingTop = '3000px';
|
||||
});
|
||||
@ -332,7 +332,7 @@ describe('Page.click', function () {
|
||||
(globalThis as any).double = true;
|
||||
});
|
||||
});
|
||||
const button = (await page.$('button'))!;
|
||||
using button = (await page.$('button'))!;
|
||||
await button!.click({count: 2});
|
||||
expect(await page.evaluate('double')).toBe(true);
|
||||
expect(await page.evaluate('result')).toBe('Clicked');
|
||||
@ -428,7 +428,7 @@ describe('Page.click', function () {
|
||||
server.PREFIX + '/input/button.html'
|
||||
);
|
||||
const frame = page.frames()[1];
|
||||
const button = await frame!.$('button');
|
||||
using button = await frame!.$('button');
|
||||
await button!.click();
|
||||
expect(
|
||||
await frame!.evaluate(() => {
|
||||
@ -477,7 +477,7 @@ describe('Page.click', function () {
|
||||
server.PREFIX + '/input/button.html'
|
||||
);
|
||||
const frame = page.frames()[1];
|
||||
const button = await frame!.$('button');
|
||||
using button = await frame!.$('button');
|
||||
await button!.click();
|
||||
expect(
|
||||
await frame!.evaluate(() => {
|
||||
|
@ -25,7 +25,7 @@ describe('Input.drag', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/drag-and-drop.html');
|
||||
const draggable = (await page.$('#drag'))!;
|
||||
using draggable = (await page.$('#drag'))!;
|
||||
|
||||
try {
|
||||
await draggable!.drag({x: 1, y: 1});
|
||||
@ -42,7 +42,7 @@ describe('Input.drag', function () {
|
||||
expect(page.isDragInterceptionEnabled()).toBe(false);
|
||||
await page.setDragInterception(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});
|
||||
|
||||
expect(data.items).toHaveLength(1);
|
||||
@ -59,9 +59,9 @@ describe('Input.drag', function () {
|
||||
expect(page.isDragInterceptionEnabled()).toBe(false);
|
||||
await page.setDragInterception(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 dropzone = (await page.$('#drop'))!;
|
||||
using dropzone = (await page.$('#drop'))!;
|
||||
await dropzone.dragEnter(data);
|
||||
|
||||
expect(
|
||||
@ -82,9 +82,9 @@ describe('Input.drag', function () {
|
||||
expect(page.isDragInterceptionEnabled()).toBe(false);
|
||||
await page.setDragInterception(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 dropzone = (await page.$('#drop'))!;
|
||||
using dropzone = (await page.$('#drop'))!;
|
||||
await dropzone.dragEnter(data);
|
||||
await dropzone.dragOver(data);
|
||||
|
||||
@ -111,8 +111,8 @@ describe('Input.drag', function () {
|
||||
expect(page.isDragInterceptionEnabled()).toBe(false);
|
||||
await page.setDragInterception(true);
|
||||
expect(page.isDragInterceptionEnabled()).toBe(true);
|
||||
const draggable = (await page.$('#drag'))!;
|
||||
const dropzone = (await page.$('#drop'))!;
|
||||
using draggable = (await page.$('#drag'))!;
|
||||
using dropzone = (await page.$('#drop'))!;
|
||||
const data = await draggable.drag({x: 1, y: 1});
|
||||
await dropzone.dragEnter(data);
|
||||
await dropzone.dragOver(data);
|
||||
@ -146,8 +146,8 @@ describe('Input.drag', function () {
|
||||
expect(page.isDragInterceptionEnabled()).toBe(false);
|
||||
await page.setDragInterception(true);
|
||||
expect(page.isDragInterceptionEnabled()).toBe(true);
|
||||
const draggable = (await page.$('#drag'))!;
|
||||
const dropzone = (await page.$('#drop'))!;
|
||||
using draggable = (await page.$('#drag'))!;
|
||||
using dropzone = (await page.$('#drop'))!;
|
||||
await draggable.dragAndDrop(dropzone);
|
||||
|
||||
expect(
|
||||
@ -178,7 +178,7 @@ describe('Input.drag', function () {
|
||||
expect(page.isDragInterceptionEnabled()).toBe(false);
|
||||
await page.setDragInterception(true);
|
||||
expect(page.isDragInterceptionEnabled()).toBe(true);
|
||||
const draggable = (await page.$('#drag'))!;
|
||||
using draggable = (await page.$('#drag'))!;
|
||||
await draggable.drag({x: 1, y: 1});
|
||||
await page.setDragInterception(false);
|
||||
|
||||
|
@ -35,7 +35,7 @@ describe('ElementHandle specs', function () {
|
||||
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
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();
|
||||
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.goto(server.PREFIX + '/frames/nested-frames.html');
|
||||
const nestedFrame = page.frames()[1]!.childFrames()[1]!;
|
||||
const elementHandle = (await nestedFrame.$('div'))!;
|
||||
using elementHandle = (await nestedFrame.$('div'))!;
|
||||
const box = await elementHandle.boundingBox();
|
||||
if (isChrome) {
|
||||
expect(box).toEqual({x: 28, y: 182, width: 264, height: 18});
|
||||
@ -57,7 +57,7 @@ describe('ElementHandle specs', function () {
|
||||
const {page} = await getTestState();
|
||||
|
||||
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);
|
||||
});
|
||||
it('should force a layout', async () => {
|
||||
@ -67,7 +67,7 @@ describe('ElementHandle specs', function () {
|
||||
await page.setContent(
|
||||
'<div style="width: 100px; height: 100px">hello</div>'
|
||||
);
|
||||
const elementHandle = (await page.$('div'))!;
|
||||
using elementHandle = (await page.$('div'))!;
|
||||
await page.evaluate((element: HTMLElement) => {
|
||||
return (element.style.height = '200px');
|
||||
}, elementHandle);
|
||||
@ -82,7 +82,7 @@ describe('ElementHandle specs', function () {
|
||||
<rect id="theRect" x="30" y="50" width="200" height="300"></rect>
|
||||
</svg>
|
||||
`);
|
||||
const element = (await page.$(
|
||||
using element = (await page.$(
|
||||
'#therect'
|
||||
)) as ElementHandle<SVGRectElement>;
|
||||
const pptrBoundingBox = await element.boundingBox();
|
||||
@ -111,7 +111,7 @@ describe('ElementHandle specs', function () {
|
||||
|
||||
// Step 2: Add div and position it absolutely inside frame.
|
||||
const frame = page.frames()[1]!;
|
||||
const divHandle = (
|
||||
using divHandle = (
|
||||
await frame.evaluateHandle(() => {
|
||||
const div = document.createElement('div');
|
||||
document.body.appendChild(div);
|
||||
@ -154,7 +154,7 @@ describe('ElementHandle specs', function () {
|
||||
const {page} = await getTestState();
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
@ -165,7 +165,7 @@ describe('ElementHandle specs', function () {
|
||||
|
||||
await page.goto(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();
|
||||
expect(frame).toBe(page.frames()[1]);
|
||||
});
|
||||
@ -175,7 +175,7 @@ describe('ElementHandle specs', function () {
|
||||
it('should work', async () => {
|
||||
const {page} = await getTestState();
|
||||
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.isHidden()).resolves.toBeTruthy();
|
||||
await element.evaluate(e => {
|
||||
@ -191,7 +191,7 @@ describe('ElementHandle specs', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
const button = (await page.$('button'))!;
|
||||
using button = (await page.$('button'))!;
|
||||
await button.click();
|
||||
expect(
|
||||
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({
|
||||
offset: {
|
||||
@ -237,7 +237,7 @@ describe('ElementHandle specs', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
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.
|
||||
return button as HTMLButtonElement;
|
||||
});
|
||||
@ -253,7 +253,7 @@ describe('ElementHandle specs', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
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;
|
||||
});
|
||||
let error!: Error;
|
||||
@ -269,7 +269,7 @@ describe('ElementHandle specs', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
const button = (await page.$('button'))!;
|
||||
using button = (await page.$('button'))!;
|
||||
await page.evaluate((button: HTMLElement) => {
|
||||
return button.remove();
|
||||
}, button);
|
||||
@ -286,7 +286,7 @@ describe('ElementHandle specs', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
const button = (await page.$('button'))!;
|
||||
using button = (await page.$('button'))!;
|
||||
await page.evaluate((button: HTMLElement) => {
|
||||
return (button.style.display = 'none');
|
||||
}, button);
|
||||
@ -302,7 +302,7 @@ describe('ElementHandle specs', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
const button = (await page.$('button'))!;
|
||||
using button = (await page.$('button'))!;
|
||||
await page.evaluate((button: HTMLElement) => {
|
||||
return (button.parentElement!.style.display = 'none');
|
||||
}, button);
|
||||
@ -318,7 +318,7 @@ describe('ElementHandle specs', function () {
|
||||
const {page} = await getTestState();
|
||||
|
||||
await page.setContent('hello<br>goodbye');
|
||||
const br = (await page.$('br'))!;
|
||||
using br = (await page.$('br'))!;
|
||||
const error = await br.click().catch(error_ => {
|
||||
return error_;
|
||||
});
|
||||
@ -345,7 +345,7 @@ describe('ElementHandle specs', function () {
|
||||
return window.requestAnimationFrame(resolve);
|
||||
});
|
||||
});
|
||||
const divHandle = (await page.$('div'))!;
|
||||
using divHandle = (await page.$('div'))!;
|
||||
expect(await divHandle.clickablePoint()).toEqual({
|
||||
x: 45 + 60, // margin + middle point offset
|
||||
y: 45 + 30, // margin + middle point offset
|
||||
@ -367,25 +367,25 @@ describe('ElementHandle specs', function () {
|
||||
await page.setContent(
|
||||
'<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 page.setContent(
|
||||
'<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 page.setContent(
|
||||
'<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 page.setContent(
|
||||
'<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);
|
||||
});
|
||||
|
||||
@ -399,7 +399,7 @@ describe('ElementHandle specs', function () {
|
||||
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 page.setContent(
|
||||
@ -409,7 +409,7 @@ describe('ElementHandle specs', function () {
|
||||
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);
|
||||
});
|
||||
|
||||
@ -428,7 +428,7 @@ describe('ElementHandle specs', function () {
|
||||
});
|
||||
});
|
||||
const frame = page.frames()[1]!;
|
||||
const divHandle = (await frame.$('div'))!;
|
||||
using divHandle = (await frame.$('div'))!;
|
||||
expect(await divHandle.clickablePoint()).toEqual({
|
||||
x: 20 + 45 + 60, // 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(
|
||||
'<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) {
|
||||
throw element;
|
||||
}
|
||||
@ -467,13 +467,13 @@ describe('ElementHandle specs', function () {
|
||||
await element.evaluate(el => {
|
||||
el.innerHTML = '<div class="bar">bar1</div>';
|
||||
});
|
||||
element = (await innerWaitFor)!;
|
||||
if (element instanceof Error) {
|
||||
throw element;
|
||||
using element2 = (await innerWaitFor)!;
|
||||
if (element2 instanceof Error) {
|
||||
throw element2;
|
||||
}
|
||||
expect(element).toBeDefined();
|
||||
expect(element2).toBeDefined();
|
||||
expect(
|
||||
await element.evaluate(el => {
|
||||
await element2.evaluate(el => {
|
||||
return (el as HTMLElement).innerText;
|
||||
})
|
||||
).toStrictEqual('bar1');
|
||||
@ -496,12 +496,12 @@ describe('ElementHandle specs', function () {
|
||||
</div>`
|
||||
);
|
||||
|
||||
const el1 = (await page.waitForSelector(
|
||||
using el1 = (await page.waitForSelector(
|
||||
'#el1'
|
||||
)) as ElementHandle<HTMLDivElement>;
|
||||
|
||||
for (const path of ['//div', './/div']) {
|
||||
const e = (await el1.waitForXPath(
|
||||
using e = (await el1.waitForXPath(
|
||||
path
|
||||
)) as ElementHandle<HTMLDivElement>;
|
||||
expect(
|
||||
@ -518,7 +518,7 @@ describe('ElementHandle specs', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/scrollable.html');
|
||||
const button = (await page.$('#button-6'))!;
|
||||
using button = (await page.$('#button-6'))!;
|
||||
await button.hover();
|
||||
expect(
|
||||
await page.evaluate(() => {
|
||||
@ -533,7 +533,7 @@ describe('ElementHandle specs', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
async function getVisibilityForButton(selector: string) {
|
||||
const button = (await page.$(selector))!;
|
||||
using button = (await page.$(selector))!;
|
||||
return await button.isIntersectingViewport();
|
||||
}
|
||||
|
||||
@ -557,7 +557,7 @@ describe('ElementHandle specs', function () {
|
||||
await page.goto(server.PREFIX + '/offscreenbuttons.html');
|
||||
// a button almost cannot be seen
|
||||
// sometimes we expect to return false by isIntersectingViewport1
|
||||
const button = (await page.$('#btn11'))!;
|
||||
using button = (await page.$('#btn11'))!;
|
||||
expect(
|
||||
await button.isIntersectingViewport({
|
||||
threshold: 0.001,
|
||||
@ -570,7 +570,7 @@ describe('ElementHandle specs', function () {
|
||||
await page.goto(server.PREFIX + '/offscreenbuttons.html');
|
||||
// a button almost cannot be seen
|
||||
// sometimes we expect to return false by isIntersectingViewport1
|
||||
const button = (await page.$('#btn0'))!;
|
||||
using button = (await page.$('#btn0'))!;
|
||||
expect(
|
||||
await button.isIntersectingViewport({
|
||||
threshold: 1,
|
||||
@ -615,7 +615,7 @@ describe('ElementHandle specs', function () {
|
||||
|
||||
const [invisibleCircle, invisibleSvg] = await Promise.all([
|
||||
page.$('div circle'),
|
||||
await page.$('div svg'),
|
||||
page.$('div svg'),
|
||||
]);
|
||||
|
||||
// Firefox seems slow when using `isIntersectingViewport`
|
||||
@ -661,7 +661,7 @@ describe('ElementHandle specs', function () {
|
||||
return document.querySelector(`[id="${selector}"]`);
|
||||
},
|
||||
});
|
||||
const element = (await page.$(
|
||||
using element = (await page.$(
|
||||
'getById/foo'
|
||||
)) as ElementHandle<HTMLDivElement>;
|
||||
expect(
|
||||
@ -780,7 +780,7 @@ describe('ElementHandle specs', function () {
|
||||
await page.setContent(
|
||||
'<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) {
|
||||
throw element;
|
||||
}
|
||||
@ -796,13 +796,13 @@ describe('ElementHandle specs', function () {
|
||||
el.innerHTML = '<div class="bar">bar1</div>';
|
||||
});
|
||||
|
||||
element = (await innerWaitFor)!;
|
||||
if (element instanceof Error) {
|
||||
throw element;
|
||||
using element2 = (await innerWaitFor)!;
|
||||
if (element2 instanceof Error) {
|
||||
throw element2;
|
||||
}
|
||||
expect(element).toBeDefined();
|
||||
expect(element2).toBeDefined();
|
||||
expect(
|
||||
await element.evaluate(el => {
|
||||
await element2.evaluate(el => {
|
||||
return el.innerText;
|
||||
})
|
||||
).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();
|
||||
|
||||
const elements = await page.$$('getByClass/foo');
|
||||
@ -893,7 +893,7 @@ describe('ElementHandle specs', function () {
|
||||
},
|
||||
});
|
||||
|
||||
const element = (await page.$(
|
||||
using element = (await page.$(
|
||||
'getById/foo'
|
||||
)) as ElementHandle<HTMLDivElement>;
|
||||
expect(
|
||||
@ -908,8 +908,8 @@ describe('ElementHandle specs', function () {
|
||||
it('should work', async () => {
|
||||
const {page} = await getTestState();
|
||||
await page.setContent('<div class="foo">Foo1</div>');
|
||||
const element = await page.$('.foo');
|
||||
const div = await element?.toElement('div');
|
||||
using element = await page.$('.foo');
|
||||
using div = await element?.toElement('div');
|
||||
expect(div).toBeDefined();
|
||||
});
|
||||
});
|
||||
@ -917,7 +917,7 @@ describe('ElementHandle specs', function () {
|
||||
describe('ElementHandle[Symbol.dispose]', () => {
|
||||
it('should work', async () => {
|
||||
const {page} = await getTestState();
|
||||
const handle = await page.evaluateHandle('document');
|
||||
using handle = await page.evaluateHandle('document');
|
||||
const spy = sinon.spy(handle, Symbol.dispose);
|
||||
{
|
||||
using _ = handle;
|
||||
@ -931,7 +931,7 @@ describe('ElementHandle specs', function () {
|
||||
describe('ElementHandle[Symbol.asyncDispose]', () => {
|
||||
it('should work', async () => {
|
||||
const {page} = await getTestState();
|
||||
const handle = await page.evaluateHandle('document');
|
||||
using handle = await page.evaluateHandle('document');
|
||||
const spy = sinon.spy(handle, Symbol.asyncDispose);
|
||||
{
|
||||
await using _ = handle;
|
||||
@ -945,7 +945,7 @@ describe('ElementHandle specs', function () {
|
||||
describe('ElementHandle.move', () => {
|
||||
it('should work', async () => {
|
||||
const {page} = await getTestState();
|
||||
const handle = await page.evaluateHandle('document');
|
||||
using handle = await page.evaluateHandle('document');
|
||||
const spy = sinon.spy(handle, Symbol.dispose);
|
||||
{
|
||||
using _ = handle;
|
||||
|
@ -167,7 +167,7 @@ describe('Emulation', () => {
|
||||
|
||||
await page.emulate(iPhone);
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
const button = (await page.$('button'))!;
|
||||
using button = (await page.$('button'))!;
|
||||
await page.evaluate((button: HTMLElement) => {
|
||||
return (button.style.marginTop = '200px');
|
||||
}, button);
|
||||
|
@ -367,7 +367,7 @@ describe('Evaluation specs', function () {
|
||||
const {page} = await getTestState();
|
||||
|
||||
await page.setContent('<section>42</section>');
|
||||
const element = (await page.$('section'))!;
|
||||
using element = (await page.$('section'))!;
|
||||
const text = await page.evaluate(e => {
|
||||
return e.textContent;
|
||||
}, element);
|
||||
@ -377,8 +377,9 @@ describe('Evaluation specs', function () {
|
||||
const {page} = await getTestState();
|
||||
|
||||
await page.setContent('<section>39</section>');
|
||||
const element = (await page.$('section'))!;
|
||||
using element = (await page.$('section'))!;
|
||||
expect(element).toBeTruthy();
|
||||
// We want to dispose early.
|
||||
await element.dispose();
|
||||
let error!: Error;
|
||||
await page
|
||||
@ -394,7 +395,7 @@ describe('Evaluation specs', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||
const bodyHandle = await page.frames()[1]!.$('body');
|
||||
using bodyHandle = await page.frames()[1]!.$('body');
|
||||
let error!: Error;
|
||||
await page
|
||||
.evaluate(body => {
|
||||
|
@ -73,7 +73,7 @@ describe('Frame specs', function () {
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const mainFrame = page.mainFrame();
|
||||
const windowHandle = await mainFrame.evaluateHandle(() => {
|
||||
using windowHandle = await mainFrame.evaluateHandle(() => {
|
||||
return window;
|
||||
});
|
||||
expect(windowHandle).toBeTruthy();
|
||||
|
@ -24,7 +24,7 @@ describe('Emulate idle state', () => {
|
||||
setupTestBrowserHooks();
|
||||
|
||||
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 element.innerText;
|
||||
}, stateElement);
|
||||
|
@ -33,7 +33,7 @@ describe('input tests', function () {
|
||||
|
||||
await page.goto(server.PREFIX + '/input/fileupload.html');
|
||||
const filePath = path.relative(process.cwd(), FILE_TO_UPLOAD);
|
||||
const input = (await page.$('input'))!;
|
||||
using input = (await page.$('input'))!;
|
||||
await page.evaluate((e: HTMLElement) => {
|
||||
(globalThis as any)._inputEvents = [];
|
||||
e.addEventListener('change', ev => {
|
||||
|
@ -27,7 +27,7 @@ describe('JSHandle', function () {
|
||||
it('should work', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const windowHandle = await page.evaluateHandle(() => {
|
||||
using windowHandle = await page.evaluateHandle(() => {
|
||||
return window;
|
||||
});
|
||||
expect(windowHandle).toBeTruthy();
|
||||
@ -35,7 +35,7 @@ describe('JSHandle', function () {
|
||||
it('should return the RemoteObject', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const windowHandle = await page.evaluateHandle(() => {
|
||||
using windowHandle = await page.evaluateHandle(() => {
|
||||
return window;
|
||||
});
|
||||
expect(windowHandle.remoteObject()).toBeTruthy();
|
||||
@ -43,7 +43,7 @@ describe('JSHandle', function () {
|
||||
it('should accept object handle as an argument', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const navigatorHandle = await page.evaluateHandle(() => {
|
||||
using navigatorHandle = await page.evaluateHandle(() => {
|
||||
return navigator;
|
||||
});
|
||||
const text = await page.evaluate(e => {
|
||||
@ -54,7 +54,7 @@ describe('JSHandle', function () {
|
||||
it('should accept object handle to primitive types', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const aHandle = await page.evaluateHandle(() => {
|
||||
using aHandle = await page.evaluateHandle(() => {
|
||||
return 5;
|
||||
});
|
||||
const isFive = await page.evaluate(e => {
|
||||
@ -80,7 +80,7 @@ describe('JSHandle', function () {
|
||||
it('should accept object handle to unserializable value', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const aHandle = await page.evaluateHandle(() => {
|
||||
using aHandle = await page.evaluateHandle(() => {
|
||||
return Infinity;
|
||||
});
|
||||
expect(
|
||||
@ -92,7 +92,7 @@ describe('JSHandle', function () {
|
||||
it('should use the same JS wrappers', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const aHandle = await page.evaluateHandle(() => {
|
||||
using aHandle = await page.evaluateHandle(() => {
|
||||
(globalThis as any).FOO = 123;
|
||||
return window;
|
||||
});
|
||||
@ -108,14 +108,14 @@ describe('JSHandle', function () {
|
||||
it('should work', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const aHandle = await page.evaluateHandle(() => {
|
||||
using aHandle = await page.evaluateHandle(() => {
|
||||
return {
|
||||
one: 1,
|
||||
two: 2,
|
||||
three: 3,
|
||||
};
|
||||
});
|
||||
const twoHandle = await aHandle.getProperty('two');
|
||||
using twoHandle = await aHandle.getProperty('two');
|
||||
expect(await twoHandle.jsonValue()).toEqual(2);
|
||||
});
|
||||
});
|
||||
@ -124,7 +124,7 @@ describe('JSHandle', function () {
|
||||
it('should work', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const aHandle = await page.evaluateHandle(() => {
|
||||
using aHandle = await page.evaluateHandle(() => {
|
||||
return {foo: 'bar'};
|
||||
});
|
||||
const json = await aHandle.jsonValue();
|
||||
@ -134,7 +134,7 @@ describe('JSHandle', function () {
|
||||
it('works with jsonValues that are not objects', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const aHandle = await page.evaluateHandle(() => {
|
||||
using aHandle = await page.evaluateHandle(() => {
|
||||
return ['a', 'b'];
|
||||
});
|
||||
const json = await aHandle.jsonValue();
|
||||
@ -144,12 +144,12 @@ describe('JSHandle', function () {
|
||||
it('works with jsonValues that are primitives', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const aHandle = await page.evaluateHandle(() => {
|
||||
using aHandle = await page.evaluateHandle(() => {
|
||||
return 'foo';
|
||||
});
|
||||
expect(await aHandle.jsonValue()).toEqual('foo');
|
||||
|
||||
const bHandle = await page.evaluateHandle(() => {
|
||||
using bHandle = await page.evaluateHandle(() => {
|
||||
return undefined;
|
||||
});
|
||||
expect(await bHandle.jsonValue()).toEqual(undefined);
|
||||
@ -158,7 +158,7 @@ describe('JSHandle', function () {
|
||||
it('should work with dates', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const dateHandle = await page.evaluateHandle(() => {
|
||||
using dateHandle = await page.evaluateHandle(() => {
|
||||
return new Date('2017-09-26T00:00:00.000Z');
|
||||
});
|
||||
const date = await dateHandle.jsonValue();
|
||||
@ -168,7 +168,7 @@ describe('JSHandle', function () {
|
||||
it('should not throw for circular objects', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const handle = await page.evaluateHandle(() => {
|
||||
using handle = await page.evaluateHandle(() => {
|
||||
const t: {t?: unknown; g: number} = {g: 1};
|
||||
t.t = t;
|
||||
return t;
|
||||
@ -181,20 +181,20 @@ describe('JSHandle', function () {
|
||||
it('should work', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const aHandle = await page.evaluateHandle(() => {
|
||||
using aHandle = await page.evaluateHandle(() => {
|
||||
return {
|
||||
foo: 'bar',
|
||||
};
|
||||
});
|
||||
const properties = await aHandle.getProperties();
|
||||
const foo = properties.get('foo')!;
|
||||
using foo = properties.get('foo')!;
|
||||
expect(foo).toBeTruthy();
|
||||
expect(await foo.jsonValue()).toBe('bar');
|
||||
});
|
||||
it('should return even non-own properties', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const aHandle = await page.evaluateHandle(() => {
|
||||
using aHandle = await page.evaluateHandle(() => {
|
||||
class A {
|
||||
a: string;
|
||||
constructor() {
|
||||
@ -220,29 +220,29 @@ describe('JSHandle', function () {
|
||||
it('should work', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const aHandle = await page.evaluateHandle(() => {
|
||||
using aHandle = await page.evaluateHandle(() => {
|
||||
return document.body;
|
||||
});
|
||||
const element = aHandle.asElement();
|
||||
using element = aHandle.asElement();
|
||||
expect(element).toBeTruthy();
|
||||
});
|
||||
it('should return null for non-elements', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const aHandle = await page.evaluateHandle(() => {
|
||||
using aHandle = await page.evaluateHandle(() => {
|
||||
return 2;
|
||||
});
|
||||
const element = aHandle.asElement();
|
||||
using element = aHandle.asElement();
|
||||
expect(element).toBeFalsy();
|
||||
});
|
||||
it('should return ElementHandle for TextNodes', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
await page.setContent('<div>ee!</div>');
|
||||
const aHandle = await page.evaluateHandle(() => {
|
||||
using aHandle = await page.evaluateHandle(() => {
|
||||
return document.querySelector('div')!.firstChild;
|
||||
});
|
||||
const element = aHandle.asElement();
|
||||
using element = aHandle.asElement();
|
||||
expect(element).toBeTruthy();
|
||||
expect(
|
||||
await page.evaluate(e => {
|
||||
@ -256,11 +256,11 @@ describe('JSHandle', function () {
|
||||
it('should work for primitives', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const numberHandle = await page.evaluateHandle(() => {
|
||||
using numberHandle = await page.evaluateHandle(() => {
|
||||
return 2;
|
||||
});
|
||||
expect(numberHandle.toString()).toBe('JSHandle:2');
|
||||
const stringHandle = await page.evaluateHandle(() => {
|
||||
using stringHandle = await page.evaluateHandle(() => {
|
||||
return 'a';
|
||||
});
|
||||
expect(stringHandle.toString()).toBe('JSHandle:a');
|
||||
@ -268,7 +268,7 @@ describe('JSHandle', function () {
|
||||
it('should work for complicated objects', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const aHandle = await page.evaluateHandle(() => {
|
||||
using aHandle = await page.evaluateHandle(() => {
|
||||
return window;
|
||||
});
|
||||
expect(aHandle.toString()).atLeastOneToContain([
|
||||
@ -337,7 +337,7 @@ describe('JSHandle', function () {
|
||||
describe('JSHandle[Symbol.dispose]', () => {
|
||||
it('should work', async () => {
|
||||
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);
|
||||
{
|
||||
using _ = handle;
|
||||
@ -351,7 +351,7 @@ describe('JSHandle', function () {
|
||||
describe('JSHandle[Symbol.asyncDispose]', () => {
|
||||
it('should work', async () => {
|
||||
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);
|
||||
{
|
||||
await using _ = handle;
|
||||
@ -365,7 +365,7 @@ describe('JSHandle', function () {
|
||||
describe('JSHandle.move', () => {
|
||||
it('should work', async () => {
|
||||
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);
|
||||
{
|
||||
using _ = handle;
|
||||
|
@ -119,7 +119,7 @@ describe('Keyboard', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
const textarea = (await page.$('textarea'))!;
|
||||
using textarea = (await page.$('textarea'))!;
|
||||
await textarea.press('a');
|
||||
expect(
|
||||
await page.evaluate(() => {
|
||||
@ -148,7 +148,7 @@ describe('Keyboard', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
const textarea = (await page.$('textarea'))!;
|
||||
using textarea = (await page.$('textarea'))!;
|
||||
await textarea.press('a', {text: 'ё'});
|
||||
expect(
|
||||
await page.evaluate(() => {
|
||||
@ -444,7 +444,7 @@ describe('Keyboard', function () {
|
||||
true
|
||||
);
|
||||
});
|
||||
const textarea = (await page.$('textarea'))!;
|
||||
using textarea = (await page.$('textarea'))!;
|
||||
|
||||
await textarea.press('Digit5');
|
||||
expect(await page.evaluate('keyLocation')).toBe(0);
|
||||
@ -490,7 +490,7 @@ describe('Keyboard', function () {
|
||||
server.PREFIX + '/input/textarea.html'
|
||||
);
|
||||
const frame = page.frames()[1]!;
|
||||
const textarea = (await frame.$('textarea'))!;
|
||||
using textarea = (await frame.$('textarea'))!;
|
||||
await textarea.type('👹 Tokyo street Japan 🇯🇵');
|
||||
expect(
|
||||
await frame.$eval('textarea', textarea => {
|
||||
|
@ -863,10 +863,9 @@ describe('Launcher specs', function () {
|
||||
return page.url() === server.EMPTY_PAGE;
|
||||
})!;
|
||||
await pageTwo.reload();
|
||||
const bodyHandle = await pageTwo.waitForSelector('body', {
|
||||
using _ = await pageTwo.waitForSelector('body', {
|
||||
timeout: 10000,
|
||||
});
|
||||
await bodyHandle!.dispose();
|
||||
await browserTwo.close();
|
||||
} finally {
|
||||
await close();
|
||||
|
@ -42,7 +42,7 @@ describe('Locator', function () {
|
||||
willClick = true;
|
||||
})
|
||||
.click();
|
||||
const button = await page.$('button');
|
||||
using button = await page.$('button');
|
||||
const text = await button?.evaluate(el => {
|
||||
return el.innerText;
|
||||
});
|
||||
@ -69,7 +69,7 @@ describe('Locator', function () {
|
||||
willClick = true;
|
||||
})
|
||||
.click();
|
||||
const button = await page.$('button');
|
||||
using button = await page.$('button');
|
||||
const text = await button?.evaluate(el => {
|
||||
return el.innerText;
|
||||
});
|
||||
@ -92,7 +92,7 @@ describe('Locator', function () {
|
||||
willClick = true;
|
||||
})
|
||||
.click();
|
||||
const button = await page.$('button');
|
||||
using button = await page.$('button');
|
||||
const text = await button?.evaluate(el => {
|
||||
return el.innerText;
|
||||
});
|
||||
@ -114,7 +114,7 @@ describe('Locator', function () {
|
||||
clicked = true;
|
||||
})
|
||||
.click();
|
||||
const button = await page.$('button');
|
||||
using button = await page.$('button');
|
||||
const text = await button?.evaluate(el => {
|
||||
return el.innerText;
|
||||
});
|
||||
@ -130,7 +130,7 @@ describe('Locator', function () {
|
||||
<button style="margin-top: 600px;" onclick="this.innerText = 'clicked';">test</button>
|
||||
`);
|
||||
await page.locator('button').click();
|
||||
const button = await page.$('button');
|
||||
using button = await page.$('button');
|
||||
const text = await button?.evaluate(el => {
|
||||
return el.innerText;
|
||||
});
|
||||
@ -144,7 +144,7 @@ describe('Locator', function () {
|
||||
await page.setContent(`
|
||||
<button style="display: none;" onclick="this.innerText = 'clicked';">test</button>
|
||||
`);
|
||||
const button = await page.$('button');
|
||||
using button = await page.$('button');
|
||||
const result = page
|
||||
.locator('button')
|
||||
.click()
|
||||
@ -177,7 +177,7 @@ describe('Locator', function () {
|
||||
await page.setContent(`
|
||||
<button disabled onclick="this.innerText = 'clicked';">test</button>
|
||||
`);
|
||||
const button = await page.$('button');
|
||||
using button = await page.$('button');
|
||||
const result = page.locator('button').click();
|
||||
expect(
|
||||
await button?.evaluate(el => {
|
||||
@ -202,7 +202,7 @@ describe('Locator', function () {
|
||||
await page.setContent(`
|
||||
<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();
|
||||
expect(
|
||||
await button?.evaluate(el => {
|
||||
@ -308,7 +308,7 @@ describe('Locator', function () {
|
||||
willClick = true;
|
||||
})
|
||||
.click();
|
||||
const button = await frame.$('button');
|
||||
using button = await frame.$('button');
|
||||
const text = await button?.evaluate(el => {
|
||||
return el.innerText;
|
||||
});
|
||||
@ -332,7 +332,7 @@ describe('Locator', function () {
|
||||
hovered = true;
|
||||
})
|
||||
.hover();
|
||||
const button = await page.$('button');
|
||||
using button = await page.$('button');
|
||||
const text = await button?.evaluate(el => {
|
||||
return el.innerText;
|
||||
});
|
||||
@ -361,7 +361,7 @@ describe('Locator', function () {
|
||||
scrollTop: 500,
|
||||
scrollLeft: 500,
|
||||
});
|
||||
const scrollable = await page.$('div');
|
||||
using scrollable = await page.$('div');
|
||||
const scroll = await scrollable?.evaluate(el => {
|
||||
return el.scrollTop + ' ' + el.scrollLeft;
|
||||
});
|
||||
@ -435,7 +435,7 @@ describe('Locator', function () {
|
||||
await page.setContent(`
|
||||
<input disabled>
|
||||
`);
|
||||
const input = await page.$('input');
|
||||
using input = await page.$('input');
|
||||
const result = page.locator('input').fill('test');
|
||||
expect(
|
||||
await input?.evaluate(el => {
|
||||
|
@ -212,7 +212,7 @@ describe('Mouse', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/wheel.html');
|
||||
const elem = (await page.$('div'))!;
|
||||
using elem = (await page.$('div'))!;
|
||||
const boundingBoxBefore = (await elem.boundingBox())!;
|
||||
expect(boundingBoxBefore).toMatchObject({
|
||||
width: 115,
|
||||
|
@ -378,7 +378,7 @@ describeWithDebugLogs('OOPIF', function () {
|
||||
button.innerText = 'click';
|
||||
document.body.appendChild(button);
|
||||
});
|
||||
const button = (await frame.waitForSelector('#test-button', {
|
||||
using button = (await frame.waitForSelector('#test-button', {
|
||||
visible: true,
|
||||
}))!;
|
||||
const result = await button.clickablePoint();
|
||||
|
@ -530,7 +530,7 @@ describe('Page', function () {
|
||||
const {page} = await getTestState();
|
||||
|
||||
// Create a custom class
|
||||
const classHandle = await page.evaluateHandle(() => {
|
||||
using classHandle = await page.evaluateHandle(() => {
|
||||
return class CustomClass {};
|
||||
});
|
||||
|
||||
@ -541,10 +541,10 @@ describe('Page', function () {
|
||||
}, classHandle);
|
||||
|
||||
// Validate only one has been added.
|
||||
const prototypeHandle = await page.evaluateHandle(CustomClass => {
|
||||
using prototypeHandle = await page.evaluateHandle(CustomClass => {
|
||||
return CustomClass.prototype;
|
||||
}, classHandle);
|
||||
const objectsHandle = await page.queryObjects(prototypeHandle);
|
||||
using objectsHandle = await page.queryObjects(prototypeHandle);
|
||||
await expect(
|
||||
page.evaluate(objects => {
|
||||
return objects.length;
|
||||
@ -564,7 +564,7 @@ describe('Page', function () {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
|
||||
// Create a custom class
|
||||
const classHandle = await page.evaluateHandle(() => {
|
||||
using classHandle = await page.evaluateHandle(() => {
|
||||
return class CustomClass {};
|
||||
});
|
||||
|
||||
@ -575,10 +575,10 @@ describe('Page', function () {
|
||||
}, classHandle);
|
||||
|
||||
// Validate only one has been added.
|
||||
const prototypeHandle = await page.evaluateHandle(CustomClass => {
|
||||
using prototypeHandle = await page.evaluateHandle(CustomClass => {
|
||||
return CustomClass.prototype;
|
||||
}, classHandle);
|
||||
const objectsHandle = await page.queryObjects(prototypeHandle);
|
||||
using objectsHandle = await page.queryObjects(prototypeHandle);
|
||||
await expect(
|
||||
page.evaluate(objects => {
|
||||
return objects.length;
|
||||
@ -596,9 +596,10 @@ describe('Page', function () {
|
||||
it('should fail for disposed handles', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const prototypeHandle = await page.evaluateHandle(() => {
|
||||
using prototypeHandle = await page.evaluateHandle(() => {
|
||||
return HTMLBodyElement.prototype;
|
||||
});
|
||||
// We want to dispose early.
|
||||
await prototypeHandle.dispose();
|
||||
let error!: Error;
|
||||
await page.queryObjects(prototypeHandle).catch(error_ => {
|
||||
@ -609,7 +610,7 @@ describe('Page', function () {
|
||||
it('should fail primitive values as prototypes', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const prototypeHandle = await page.evaluateHandle(() => {
|
||||
using prototypeHandle = await page.evaluateHandle(() => {
|
||||
return 42;
|
||||
});
|
||||
let error!: Error;
|
||||
@ -1160,7 +1161,7 @@ describe('Page', function () {
|
||||
|
||||
await page.goto(server.PREFIX + '/abort-request.html');
|
||||
|
||||
const element = await page.$(`#abort`);
|
||||
using element = await page.$(`#abort`);
|
||||
await element!.click();
|
||||
|
||||
let error = false;
|
||||
@ -1733,7 +1734,7 @@ describe('Page', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
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(
|
||||
await page.evaluate(() => {
|
||||
@ -1811,7 +1812,7 @@ describe('Page', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const scriptHandle = await page.addScriptTag({
|
||||
using scriptHandle = await page.addScriptTag({
|
||||
path: path.join(__dirname, '../assets/injectedfile.js'),
|
||||
});
|
||||
expect(scriptHandle.asElement()).not.toBeNull();
|
||||
@ -1839,7 +1840,7 @@ describe('Page', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const scriptHandle = await page.addScriptTag({
|
||||
using scriptHandle = await page.addScriptTag({
|
||||
content: 'window.__injected = 35;',
|
||||
});
|
||||
expect(scriptHandle.asElement()).not.toBeNull();
|
||||
@ -1907,7 +1908,7 @@ describe('Page', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
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(
|
||||
await page.evaluate(
|
||||
@ -1937,7 +1938,7 @@ describe('Page', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const styleHandle = await page.addStyleTag({
|
||||
using styleHandle = await page.addStyleTag({
|
||||
path: path.join(__dirname, '../assets/injectedstyle.css'),
|
||||
});
|
||||
expect(styleHandle.asElement()).not.toBeNull();
|
||||
@ -1955,7 +1956,7 @@ describe('Page', function () {
|
||||
await page.addStyleTag({
|
||||
path: path.join(__dirname, '../assets/injectedstyle.css'),
|
||||
});
|
||||
const styleHandle = (await page.$('style'))!;
|
||||
using styleHandle = (await page.$('style'))!;
|
||||
const styleContent = await page.evaluate((style: HTMLStyleElement) => {
|
||||
return style.innerHTML;
|
||||
}, styleHandle);
|
||||
@ -1966,7 +1967,7 @@ describe('Page', function () {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const styleHandle = await page.addStyleTag({
|
||||
using styleHandle = await page.addStyleTag({
|
||||
content: 'body { background-color: green; }',
|
||||
});
|
||||
expect(styleHandle.asElement()).not.toBeNull();
|
||||
|
@ -25,10 +25,10 @@ describe('Prerender', function () {
|
||||
const {page, server} = await getTestState();
|
||||
await page.goto(server.PREFIX + '/prerender/index.html');
|
||||
|
||||
const button = await page.waitForSelector('button');
|
||||
using button = await page.waitForSelector('button');
|
||||
await button?.click();
|
||||
|
||||
const link = await page.waitForSelector('a');
|
||||
using link = await page.waitForSelector('a');
|
||||
await Promise.all([page.waitForNavigation(), link?.click()]);
|
||||
expect(
|
||||
await page.evaluate(() => {
|
||||
@ -41,7 +41,7 @@ describe('Prerender', function () {
|
||||
const {page, server} = await getTestState();
|
||||
await page.goto(server.PREFIX + '/prerender/index.html');
|
||||
|
||||
const button = await page.waitForSelector('button');
|
||||
using button = await page.waitForSelector('button');
|
||||
await button?.click();
|
||||
|
||||
await page.goto(server.PREFIX + '/prerender/target.html');
|
||||
@ -57,11 +57,11 @@ describe('Prerender', function () {
|
||||
const {page, server} = await getTestState();
|
||||
await page.goto(server.PREFIX + '/prerender/index.html');
|
||||
|
||||
const button = await page.waitForSelector('button');
|
||||
using button = await page.waitForSelector('button');
|
||||
await button?.click();
|
||||
|
||||
const mainFrame = page.mainFrame();
|
||||
const link = await mainFrame.waitForSelector('a');
|
||||
using link = await mainFrame.waitForSelector('a');
|
||||
await Promise.all([mainFrame.waitForNavigation(), link?.click()]);
|
||||
expect(mainFrame).toBe(page.mainFrame());
|
||||
expect(
|
||||
@ -76,7 +76,7 @@ describe('Prerender', function () {
|
||||
const {page, server} = await getTestState();
|
||||
await page.goto(server.PREFIX + '/prerender/index.html');
|
||||
|
||||
const button = await page.waitForSelector('button');
|
||||
using button = await page.waitForSelector('button');
|
||||
await button?.click();
|
||||
|
||||
const mainFrame = page.mainFrame();
|
||||
@ -100,10 +100,10 @@ describe('Prerender', function () {
|
||||
});
|
||||
|
||||
await page.goto(server.PREFIX + '/prerender/index.html');
|
||||
const button = await page.waitForSelector('button');
|
||||
using button = await page.waitForSelector('button');
|
||||
await button?.click();
|
||||
const mainFrame = page.mainFrame();
|
||||
const link = await mainFrame.waitForSelector('a');
|
||||
using link = await mainFrame.waitForSelector('a');
|
||||
await Promise.all([mainFrame.waitForNavigation(), link?.click()]);
|
||||
expect(mainFrame).toBe(page.mainFrame());
|
||||
expect(
|
||||
@ -138,9 +138,9 @@ describe('Prerender', function () {
|
||||
height: 400,
|
||||
});
|
||||
await page.goto(server.PREFIX + '/prerender/index.html');
|
||||
const button = await page.waitForSelector('button');
|
||||
using button = await page.waitForSelector('button');
|
||||
await button?.click();
|
||||
const link = await page.waitForSelector('a');
|
||||
using link = await page.waitForSelector('a');
|
||||
await Promise.all([page.waitForNavigation(), link?.click()]);
|
||||
const result = await page.evaluate(() => {
|
||||
return {
|
||||
|
@ -46,7 +46,7 @@ describe('Query handler tests', function () {
|
||||
}
|
||||
it('should find first element in shadow', async () => {
|
||||
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 => {
|
||||
return element.textContent;
|
||||
});
|
||||
@ -68,8 +68,8 @@ describe('Query handler tests', function () {
|
||||
});
|
||||
it('should find first child element', async () => {
|
||||
const {page} = await setUpPage();
|
||||
const parentElement = (await page.$('html > div'))!;
|
||||
const childElement = (await parentElement.$(
|
||||
using parentElement = (await page.$('html > div'))!;
|
||||
using childElement = (await parentElement.$(
|
||||
'pierce/div'
|
||||
)) as ElementHandle<HTMLElement>;
|
||||
const text = await childElement.evaluate(element => {
|
||||
@ -79,7 +79,7 @@ describe('Query handler tests', function () {
|
||||
});
|
||||
it('should find all child elements', async () => {
|
||||
const {page} = await setUpPage();
|
||||
const parentElement = (await page.$('html > div'))!;
|
||||
using parentElement = (await page.$('html > div'))!;
|
||||
const childElements = (await parentElement.$$('pierce/div')) as Array<
|
||||
ElementHandle<HTMLElement>
|
||||
>;
|
||||
@ -115,7 +115,7 @@ describe('Query handler tests', function () {
|
||||
|
||||
await page.setContent('<div id="1">a</div><div>a</div>');
|
||||
|
||||
const element = await page.$('text/a');
|
||||
using element = await page.$('text/a');
|
||||
expect(
|
||||
await element?.evaluate(e => {
|
||||
return e.id;
|
||||
@ -145,7 +145,7 @@ describe('Query handler tests', function () {
|
||||
document.body.append(div);
|
||||
});
|
||||
|
||||
const element = await page.$('text/a');
|
||||
using element = await page.$('text/a');
|
||||
expect(
|
||||
await element?.evaluate(e => {
|
||||
return e.textContent;
|
||||
@ -157,7 +157,7 @@ describe('Query handler tests', function () {
|
||||
|
||||
await page.setContent('<div><div>a</div><div>b</div></div>');
|
||||
|
||||
const element = await page.$('text/a');
|
||||
using element = await page.$('text/a');
|
||||
expect(
|
||||
await element?.evaluate(e => {
|
||||
return e.textContent;
|
||||
@ -169,7 +169,7 @@ describe('Query handler tests', function () {
|
||||
|
||||
await page.setContent('<input value="a">');
|
||||
|
||||
const element = (await page.$(
|
||||
using element = (await page.$(
|
||||
'text/a'
|
||||
)) as ElementHandle<HTMLInputElement>;
|
||||
expect(
|
||||
@ -190,7 +190,7 @@ describe('Query handler tests', function () {
|
||||
|
||||
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(
|
||||
await element?.evaluate(e => {
|
||||
return e.textContent;
|
||||
@ -203,8 +203,8 @@ describe('Query handler tests', function () {
|
||||
await page.setContent(
|
||||
'<div id=target1>text</div><input id=target2 value=text><div id=target3>text</div>'
|
||||
);
|
||||
const div = (await page.$('#target1')) as ElementHandle<HTMLDivElement>;
|
||||
const input = (await page.$(
|
||||
using div = (await page.$('#target1')) as ElementHandle<HTMLDivElement>;
|
||||
using input = (await page.$(
|
||||
'#target2'
|
||||
)) as ElementHandle<HTMLInputElement>;
|
||||
|
||||
@ -271,7 +271,7 @@ describe('Query handler tests', function () {
|
||||
|
||||
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`)).toHaveLength(1);
|
||||
});
|
||||
@ -281,7 +281,7 @@ describe('Query handler tests', function () {
|
||||
|
||||
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`)).toHaveLength(0);
|
||||
});
|
||||
@ -313,7 +313,7 @@ describe('Query handler tests', function () {
|
||||
|
||||
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(
|
||||
await element?.evaluate(e => {
|
||||
return e.textContent === 'a';
|
||||
@ -335,7 +335,7 @@ describe('Query handler tests', function () {
|
||||
|
||||
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`)).toHaveLength(1);
|
||||
});
|
||||
@ -345,7 +345,7 @@ describe('Query handler tests', function () {
|
||||
|
||||
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`)).toHaveLength(0);
|
||||
});
|
||||
@ -360,7 +360,7 @@ describe('Query handler tests', function () {
|
||||
it('should work with CSS selectors', async () => {
|
||||
const {server, page} = await getTestState();
|
||||
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');
|
||||
expect(
|
||||
await element.evaluate(element => {
|
||||
@ -383,7 +383,7 @@ describe('Query handler tests', function () {
|
||||
const {server, page} = await getTestState();
|
||||
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');
|
||||
expect(
|
||||
await element.evaluate(element => {
|
||||
@ -423,7 +423,7 @@ describe('Query handler tests', function () {
|
||||
it('should work with text selectors', async () => {
|
||||
const {server, page} = await getTestState();
|
||||
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');
|
||||
expect(
|
||||
await element.evaluate(element => {
|
||||
@ -435,7 +435,7 @@ describe('Query handler tests', function () {
|
||||
it('should work ARIA selectors', async () => {
|
||||
const {server, page} = await getTestState();
|
||||
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');
|
||||
expect(
|
||||
await element.evaluate(element => {
|
||||
@ -447,7 +447,7 @@ describe('Query handler tests', function () {
|
||||
it('should work for ARIA selectors in multiple isolated worlds', async () => {
|
||||
const {server, page} = await getTestState();
|
||||
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');
|
||||
expect(
|
||||
await element.evaluate(element => {
|
||||
@ -456,10 +456,10 @@ describe('Query handler tests', function () {
|
||||
).toBeTruthy();
|
||||
// $ would add ARIA query handler to the main world.
|
||||
await element.$('::-p-aria(world)');
|
||||
element = await page.waitForSelector('::-p-aria(world)');
|
||||
assert(element, 'Could not find element');
|
||||
using element2 = await page.waitForSelector('::-p-aria(world)');
|
||||
assert(element2, 'Could not find element');
|
||||
expect(
|
||||
await element.evaluate(element => {
|
||||
await element2.evaluate(element => {
|
||||
return element.id === 'b';
|
||||
})
|
||||
).toBeTruthy();
|
||||
@ -468,7 +468,7 @@ describe('Query handler tests', function () {
|
||||
it('should work ARIA selectors with role', async () => {
|
||||
const {server, page} = await getTestState();
|
||||
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');
|
||||
expect(
|
||||
await element.evaluate(element => {
|
||||
@ -480,7 +480,7 @@ describe('Query handler tests', function () {
|
||||
it('should work ARIA selectors with name and role', async () => {
|
||||
const {server, page} = await getTestState();
|
||||
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');
|
||||
expect(
|
||||
await element.evaluate(element => {
|
||||
@ -492,7 +492,7 @@ describe('Query handler tests', function () {
|
||||
it('should work XPath selectors', async () => {
|
||||
const {server, page} = await getTestState();
|
||||
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');
|
||||
expect(
|
||||
await element.evaluate(element => {
|
||||
@ -510,7 +510,7 @@ describe('Query handler tests', function () {
|
||||
|
||||
const {server, page} = await getTestState();
|
||||
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');
|
||||
expect(
|
||||
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');
|
||||
expect(
|
||||
await element.evaluate(element => {
|
||||
@ -542,7 +542,7 @@ describe('Query handler tests', function () {
|
||||
).toBeTruthy();
|
||||
}
|
||||
{
|
||||
const element = await page.$('::-p-div("true")');
|
||||
using element = await page.$('::-p-div("true")');
|
||||
assert(element, 'Could not find element');
|
||||
expect(
|
||||
await element.evaluate(element => {
|
||||
@ -551,7 +551,7 @@ describe('Query handler tests', function () {
|
||||
).toBeTruthy();
|
||||
}
|
||||
{
|
||||
const element = await page.$("::-p-div('true')");
|
||||
using element = await page.$("::-p-div('true')");
|
||||
assert(element, 'Could not find element');
|
||||
expect(
|
||||
await element.evaluate(element => {
|
||||
@ -560,7 +560,7 @@ describe('Query handler tests', function () {
|
||||
).toBeTruthy();
|
||||
}
|
||||
{
|
||||
const element = await page.$('::-p-div');
|
||||
using element = await page.$('::-p-div');
|
||||
assert(element, 'Could not find element');
|
||||
expect(
|
||||
await element.evaluate(element => {
|
||||
@ -573,14 +573,13 @@ describe('Query handler tests', function () {
|
||||
it('should work with :hover', async () => {
|
||||
const {server, page} = await getTestState();
|
||||
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');
|
||||
await button.hover();
|
||||
await button.dispose();
|
||||
|
||||
button = await page.$('div ::-p-text(world):hover');
|
||||
assert(button, 'Could not find element');
|
||||
const value = await button.evaluate(span => {
|
||||
using button2 = await page.$('div ::-p-text(world):hover');
|
||||
assert(button2, 'Could not find element');
|
||||
const value = await button2.evaluate(span => {
|
||||
return {textContent: span.textContent, tagName: span.tagName};
|
||||
});
|
||||
expect(value).toMatchObject({textContent: 'world', tagName: 'BUTTON'});
|
||||
@ -643,22 +642,22 @@ describe('Query handler tests', function () {
|
||||
it('should handle escapes', async () => {
|
||||
const {server, page} = await getTestState();
|
||||
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"\\))'
|
||||
);
|
||||
expect(element).toBeTruthy();
|
||||
element = await page.$(
|
||||
using element2 = await page.$(
|
||||
':scope >>> ::-p-text("My name is Jun (pronounced like \\"June\\")")'
|
||||
);
|
||||
expect(element).toBeTruthy();
|
||||
element = await page.$(
|
||||
expect(element2).toBeTruthy();
|
||||
using element3 = await page.$(
|
||||
':scope >>> ::-p-text(My name is Jun \\(pronounced like "June"\\)")'
|
||||
);
|
||||
expect(element).toBeFalsy();
|
||||
element = await page.$(
|
||||
expect(element3).toBeFalsy();
|
||||
using element4 = await page.$(
|
||||
':scope >>> ::-p-text("My name is Jun \\(pronounced like "June"\\))'
|
||||
);
|
||||
expect(element).toBeFalsy();
|
||||
expect(element4).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -49,7 +49,7 @@ describe('querySelector', function () {
|
||||
const {page} = await getTestState();
|
||||
|
||||
await page.setContent('<section>hello</section><div> world</div>');
|
||||
const divHandle = (await page.$('div'))!;
|
||||
using divHandle = (await page.$('div'))!;
|
||||
const text = await page.$eval(
|
||||
'section',
|
||||
(e, div) => {
|
||||
@ -111,7 +111,7 @@ describe('querySelector', function () {
|
||||
await page.setContent(
|
||||
'<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(
|
||||
'section',
|
||||
(sections, div) => {
|
||||
@ -152,13 +152,13 @@ describe('querySelector', function () {
|
||||
const {page} = await getTestState();
|
||||
|
||||
await page.setContent('<section>test</section>');
|
||||
const element = (await page.$('section'))!;
|
||||
using element = (await page.$('section'))!;
|
||||
expect(element).toBeTruthy();
|
||||
});
|
||||
it('should return null for non-existing element', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const element = (await page.$('non-existing-element'))!;
|
||||
using element = (await page.$('non-existing-element'))!;
|
||||
expect(element).toBe(null);
|
||||
});
|
||||
});
|
||||
@ -218,9 +218,9 @@ describe('querySelector', function () {
|
||||
await page.setContent(
|
||||
'<html><body><div class="second"><div class="inner">A</div></div></body></html>'
|
||||
);
|
||||
const html = (await page.$('html'))!;
|
||||
const second = (await html.$('.second'))!;
|
||||
const inner = await second.$('.inner');
|
||||
using html = (await page.$('html'))!;
|
||||
using second = (await html.$('.second'))!;
|
||||
using inner = await second.$('.inner');
|
||||
const content = await page.evaluate(e => {
|
||||
return e?.textContent;
|
||||
}, inner);
|
||||
@ -233,8 +233,8 @@ describe('querySelector', function () {
|
||||
await page.setContent(
|
||||
'<html><body><div class="second"><div class="inner">B</div></div></body></html>'
|
||||
);
|
||||
const html = (await page.$('html'))!;
|
||||
const second = await html.$('.third');
|
||||
using html = (await page.$('html'))!;
|
||||
using second = await html.$('.third');
|
||||
expect(second).toBe(null);
|
||||
});
|
||||
});
|
||||
@ -245,7 +245,7 @@ describe('querySelector', function () {
|
||||
await page.setContent(
|
||||
'<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 => {
|
||||
return (node as HTMLElement).innerText;
|
||||
});
|
||||
@ -258,7 +258,7 @@ describe('querySelector', function () {
|
||||
const htmlContent =
|
||||
'<div class="a">not-a-child-div</div><div id="myId"><div class="a">a-child-div</div></div>';
|
||||
await page.setContent(htmlContent);
|
||||
const elementHandle = (await page.$('#myId'))!;
|
||||
using elementHandle = (await page.$('#myId'))!;
|
||||
const content = await elementHandle.$eval('.a', node => {
|
||||
return (node as HTMLElement).innerText;
|
||||
});
|
||||
@ -271,7 +271,7 @@ describe('querySelector', function () {
|
||||
const htmlContent =
|
||||
'<div class="a">not-a-child-div</div><div id="myId"></div>';
|
||||
await page.setContent(htmlContent);
|
||||
const elementHandle = (await page.$('#myId'))!;
|
||||
using elementHandle = (await page.$('#myId'))!;
|
||||
const errorMessage = await elementHandle
|
||||
.$eval('.a', node => {
|
||||
return (node as HTMLElement).innerText;
|
||||
@ -291,7 +291,7 @@ describe('querySelector', function () {
|
||||
await page.setContent(
|
||||
'<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 => {
|
||||
return (nodes as HTMLElement[]).map(n => {
|
||||
return n.innerText;
|
||||
@ -306,7 +306,7 @@ describe('querySelector', function () {
|
||||
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>';
|
||||
await page.setContent(htmlContent);
|
||||
const elementHandle = (await page.$('#myId'))!;
|
||||
using elementHandle = (await page.$('#myId'))!;
|
||||
const content = await elementHandle.$$eval('.a', nodes => {
|
||||
return (nodes as HTMLElement[]).map(n => {
|
||||
return n.innerText;
|
||||
@ -321,7 +321,7 @@ describe('querySelector', function () {
|
||||
const htmlContent =
|
||||
'<div class="a">not-a-child-div</div><div id="myId"></div>';
|
||||
await page.setContent(htmlContent);
|
||||
const elementHandle = (await page.$('#myId'))!;
|
||||
using elementHandle = (await page.$('#myId'))!;
|
||||
const nodesLength = await elementHandle.$$eval('.a', nodes => {
|
||||
return nodes.length;
|
||||
});
|
||||
@ -336,7 +336,7 @@ describe('querySelector', function () {
|
||||
await page.setContent(
|
||||
'<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');
|
||||
expect(elements).toHaveLength(2);
|
||||
const promises = elements.map(element => {
|
||||
@ -353,7 +353,7 @@ describe('querySelector', function () {
|
||||
await page.setContent(
|
||||
'<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');
|
||||
expect(elements).toHaveLength(0);
|
||||
});
|
||||
@ -367,7 +367,7 @@ describe('querySelector', function () {
|
||||
await page.setContent(
|
||||
'<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 inner = await second[0]!.$x(`./div[contains(@class, 'inner')]`);
|
||||
const content = await page.evaluate(e => {
|
||||
@ -382,7 +382,7 @@ describe('querySelector', function () {
|
||||
await page.setContent(
|
||||
'<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')]`);
|
||||
expect(second).toEqual([]);
|
||||
});
|
||||
@ -411,7 +411,7 @@ describe('querySelector', function () {
|
||||
await page.setContent(
|
||||
'<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');
|
||||
expect(elements).toHaveLength(2);
|
||||
const promises = elements.map(element => {
|
||||
@ -428,7 +428,7 @@ describe('querySelector', function () {
|
||||
await page.setContent(
|
||||
'<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');
|
||||
expect(elements).toHaveLength(0);
|
||||
});
|
||||
@ -463,7 +463,7 @@ describe('querySelector', function () {
|
||||
await page.setContent(
|
||||
'<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(
|
||||
'allArray/section',
|
||||
(sections, div) => {
|
||||
|
@ -921,7 +921,7 @@ describe('request interception', function () {
|
||||
return (img.onload = fulfill);
|
||||
});
|
||||
}, server.PREFIX);
|
||||
const img = (await page.$('img'))!;
|
||||
using img = (await page.$('img'))!;
|
||||
expect(await img.screenshot()).toBeGolden('mock-binary-response.png');
|
||||
});
|
||||
it('should stringify intercepted request response headers', async () => {
|
||||
|
@ -868,7 +868,7 @@ describe('request interception', function () {
|
||||
return (img.onload = fulfill);
|
||||
});
|
||||
}, server.PREFIX);
|
||||
const img = (await page.$('img'))!;
|
||||
using img = (await page.$('img'))!;
|
||||
expect(await img.screenshot()).toBeGolden('mock-binary-response.png');
|
||||
});
|
||||
it('should stringify intercepted request response headers', async () => {
|
||||
|
@ -14,6 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import assert from 'assert';
|
||||
|
||||
import expect from 'expect';
|
||||
|
||||
import {getTestState, launch, setupTestBrowserHooks} from './mocha-utils.js';
|
||||
@ -213,7 +215,7 @@ describe('Screenshots', function () {
|
||||
await page.evaluate(() => {
|
||||
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();
|
||||
expect(screenshot).toBeGolden('screenshot-element-bounding-box.png');
|
||||
});
|
||||
@ -231,7 +233,8 @@ describe('Screenshots', function () {
|
||||
await page.evaluate(() => {
|
||||
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();
|
||||
expect(screenshot).toBeTruthy();
|
||||
} finally {
|
||||
@ -253,7 +256,7 @@ describe('Screenshots', function () {
|
||||
</style>
|
||||
<div></div>
|
||||
`);
|
||||
const elementHandle = (await page.$('div'))!;
|
||||
using elementHandle = (await page.$('div'))!;
|
||||
const screenshot = await elementHandle.screenshot();
|
||||
expect(screenshot).toBeGolden('screenshot-element-padding-border.png');
|
||||
});
|
||||
@ -277,7 +280,7 @@ describe('Screenshots', function () {
|
||||
</style>
|
||||
<div class="to-screenshot"></div>
|
||||
`);
|
||||
const elementHandle = (await page.$('div.to-screenshot'))!;
|
||||
using elementHandle = (await page.$('div.to-screenshot'))!;
|
||||
const screenshot = await elementHandle.screenshot();
|
||||
expect(screenshot).toBeGolden(
|
||||
'screenshot-element-larger-than-viewport.png'
|
||||
@ -313,7 +316,7 @@ describe('Screenshots', function () {
|
||||
<div class="above"></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();
|
||||
expect(screenshot).toBeGolden(
|
||||
'screenshot-element-scrolled-into-view.png'
|
||||
@ -330,7 +333,7 @@ describe('Screenshots', function () {
|
||||
height: 100px;
|
||||
background: green;
|
||||
transform: rotateZ(200deg);"> </div>`);
|
||||
const elementHandle = (await page.$('div'))!;
|
||||
using elementHandle = (await page.$('div'))!;
|
||||
const screenshot = await elementHandle.screenshot();
|
||||
expect(screenshot).toBeGolden('screenshot-element-rotate.png');
|
||||
});
|
||||
@ -338,7 +341,7 @@ describe('Screenshots', function () {
|
||||
const {page} = await getTestState();
|
||||
|
||||
await page.setContent('<h1>remove this</h1>');
|
||||
const elementHandle = (await page.$('h1'))!;
|
||||
using elementHandle = (await page.$('h1'))!;
|
||||
await page.evaluate((element: HTMLElement) => {
|
||||
return element.remove();
|
||||
}, elementHandle);
|
||||
@ -353,7 +356,7 @@ describe('Screenshots', function () {
|
||||
const {page} = await getTestState();
|
||||
|
||||
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_ => {
|
||||
return error_;
|
||||
});
|
||||
@ -365,7 +368,7 @@ describe('Screenshots', function () {
|
||||
await page.setContent(
|
||||
'<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();
|
||||
expect(screenshot).toBeGolden('screenshot-element-fractional.png');
|
||||
});
|
||||
@ -375,7 +378,7 @@ describe('Screenshots', function () {
|
||||
await page.setContent(
|
||||
'<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();
|
||||
expect(screenshot).toBeGolden('screenshot-element-fractional-offset.png');
|
||||
});
|
||||
|
@ -84,7 +84,7 @@ describe('Stack trace', function () {
|
||||
it('should work with contiguous evaluation', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const thrower = await page.evaluateHandle(() => {
|
||||
using thrower = await page.evaluateHandle(() => {
|
||||
return () => {
|
||||
throw new Error('Test');
|
||||
};
|
||||
|
@ -40,7 +40,7 @@ describe('Touchscreen', function () {
|
||||
const iPhone = KnownDevices['iPhone 6']!;
|
||||
await page.emulate(iPhone);
|
||||
await page.goto(server.PREFIX + '/input/touches.html');
|
||||
const button = (await page.$('button'))!;
|
||||
using button = (await page.$('button'))!;
|
||||
await button.tap();
|
||||
expect(
|
||||
await page.evaluate(() => {
|
||||
@ -54,7 +54,7 @@ describe('Touchscreen', function () {
|
||||
const iPhone = KnownDevices['iPhone 6']!;
|
||||
await page.emulate(iPhone);
|
||||
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;
|
||||
await page.touchscreen.touchStart(touchObj.x, touchObj.y);
|
||||
const movePosx = 100;
|
||||
|
@ -73,7 +73,7 @@ export const attachFrame = async (
|
||||
frameId: string,
|
||||
url: string
|
||||
): 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;
|
||||
|
||||
async function attachFrame(frameId: string, url: string) {
|
||||
|
@ -221,11 +221,11 @@ describe('waittask specs', function () {
|
||||
const {page} = await getTestState();
|
||||
|
||||
await page.setContent('<div></div>');
|
||||
const div = (await page.$('div'))!;
|
||||
using div = (await page.$('div'))!;
|
||||
let resolved = false;
|
||||
const waitForFunction = page
|
||||
.waitForFunction(
|
||||
(element: Element) => {
|
||||
element => {
|
||||
return element.localName === 'div' && !element.parentElement;
|
||||
},
|
||||
{},
|
||||
@ -432,7 +432,7 @@ describe('waittask specs', function () {
|
||||
const watchdog = frame.waitForSelector('div');
|
||||
await frame.evaluate(addElement, 'br');
|
||||
await frame.evaluate(addElement, 'div');
|
||||
const eHandle = (await watchdog)!;
|
||||
using eHandle = (await watchdog)!;
|
||||
const tagName = await (await eHandle.getProperty('tagName')).jsonValue();
|
||||
expect(tagName).toBe('DIV');
|
||||
});
|
||||
@ -459,7 +459,7 @@ describe('waittask specs', function () {
|
||||
const watchdog = page.waitForSelector('div');
|
||||
await otherFrame.evaluate(addElement, 'div');
|
||||
await page.evaluate(addElement, 'div');
|
||||
const eHandle = await watchdog;
|
||||
using eHandle = await watchdog;
|
||||
expect(eHandle?.frame).toBe(page.mainFrame());
|
||||
});
|
||||
|
||||
@ -473,7 +473,7 @@ describe('waittask specs', function () {
|
||||
const waitForSelectorPromise = frame2.waitForSelector('div');
|
||||
await frame1.evaluate(addElement, 'div');
|
||||
await frame2.evaluate(addElement, 'div');
|
||||
const eHandle = await waitForSelectorPromise;
|
||||
using eHandle = await waitForSelectorPromise;
|
||||
expect(eHandle?.frame).toBe(frame2);
|
||||
});
|
||||
|
||||
@ -513,7 +513,7 @@ describe('waittask specs', function () {
|
||||
|
||||
const promise = page.waitForSelector('div', {visible: true});
|
||||
await page.setContent('<div style="display: none">text</div>');
|
||||
const element = await page.evaluateHandle(() => {
|
||||
using element = await page.evaluateHandle(() => {
|
||||
return document.getElementsByTagName('div')[0]!;
|
||||
});
|
||||
await expect(
|
||||
@ -529,7 +529,7 @@ describe('waittask specs', function () {
|
||||
|
||||
const promise = page.waitForSelector('div', {visible: true});
|
||||
await page.setContent('<div style="visibility: hidden">text</div>');
|
||||
const element = await page.evaluateHandle(() => {
|
||||
using element = await page.evaluateHandle(() => {
|
||||
return document.getElementsByTagName('div')[0]!;
|
||||
});
|
||||
await expect(
|
||||
@ -551,7 +551,7 @@ describe('waittask specs', function () {
|
||||
|
||||
const promise = page.waitForSelector('div', {visible: true});
|
||||
await page.setContent('<div style="width: 0">text</div>');
|
||||
const element = await page.evaluateHandle(() => {
|
||||
using element = await page.evaluateHandle(() => {
|
||||
return document.getElementsByTagName('div')[0]!;
|
||||
});
|
||||
await expect(
|
||||
@ -578,7 +578,7 @@ describe('waittask specs', function () {
|
||||
await page.setContent(
|
||||
`<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]!;
|
||||
});
|
||||
await expect(
|
||||
@ -600,7 +600,7 @@ describe('waittask specs', function () {
|
||||
|
||||
const promise = page.waitForSelector('div', {hidden: true});
|
||||
await page.setContent(`<div style='display: block;'>text</div>`);
|
||||
const element = await page.evaluateHandle(() => {
|
||||
using element = await page.evaluateHandle(() => {
|
||||
return document.getElementsByTagName('div')[0]!;
|
||||
});
|
||||
await expect(
|
||||
@ -616,7 +616,7 @@ describe('waittask specs', function () {
|
||||
|
||||
const promise = page.waitForSelector('div', {hidden: true});
|
||||
await page.setContent(`<div style='display: block;'>text</div>`);
|
||||
const element = await page.evaluateHandle(() => {
|
||||
using element = await page.evaluateHandle(() => {
|
||||
return document.getElementsByTagName('div')[0]!;
|
||||
});
|
||||
await expect(
|
||||
@ -632,7 +632,7 @@ describe('waittask specs', function () {
|
||||
|
||||
const promise = page.waitForSelector('div', {hidden: true});
|
||||
await page.setContent('<div>text</div>');
|
||||
const element = await page.evaluateHandle(() => {
|
||||
using element = await page.evaluateHandle(() => {
|
||||
return document.getElementsByTagName('div')[0]!;
|
||||
});
|
||||
await expect(
|
||||
@ -648,7 +648,7 @@ describe('waittask specs', function () {
|
||||
|
||||
const promise = page.waitForSelector('div', {hidden: true});
|
||||
await page.setContent(`<div>text</div>`);
|
||||
const element = await page.evaluateHandle(() => {
|
||||
using element = await page.evaluateHandle(() => {
|
||||
return document.getElementsByTagName('div')[0]!;
|
||||
});
|
||||
await expect(
|
||||
@ -662,7 +662,7 @@ describe('waittask specs', function () {
|
||||
it('should return null if waiting to hide non-existing element', async () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const handle = await page.waitForSelector('non-existing', {
|
||||
using handle = await page.waitForSelector('non-existing', {
|
||||
hidden: true,
|
||||
});
|
||||
expect(handle).toBe(null);
|
||||
@ -779,7 +779,7 @@ describe('waittask specs', function () {
|
||||
const waitForXPathPromise = frame2.waitForXPath('//div');
|
||||
await frame1.evaluate(addElement, 'div');
|
||||
await frame2.evaluate(addElement, 'div');
|
||||
const eHandle = await waitForXPathPromise;
|
||||
using eHandle = await waitForXPathPromise;
|
||||
expect(eHandle?.frame).toBe(frame2);
|
||||
});
|
||||
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 () => {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const waitForXPath = await page.waitForXPath('//div', {hidden: true});
|
||||
using waitForXPath = await page.waitForXPath('//div', {hidden: true});
|
||||
|
||||
expect(waitForXPath).toBe(null);
|
||||
});
|
||||
@ -832,7 +832,7 @@ describe('waittask specs', function () {
|
||||
|
||||
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);
|
||||
});
|
||||
@ -854,7 +854,7 @@ describe('waittask specs', function () {
|
||||
const {page} = await getTestState();
|
||||
|
||||
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(
|
||||
3 /* Node.TEXT_NODE */
|
||||
);
|
||||
|
@ -47,11 +47,11 @@ describe('Workers', function () {
|
||||
const {page} = await getTestState();
|
||||
|
||||
const workerCreatedPromise = waitEvent<WebWorker>(page, 'workercreated');
|
||||
const workerObj = await page.evaluateHandle(() => {
|
||||
using workerObj = await page.evaluateHandle(() => {
|
||||
return new Worker('data:text/javascript,1');
|
||||
});
|
||||
const worker = await workerCreatedPromise;
|
||||
const workerThisObj = await worker.evaluateHandle(() => {
|
||||
using workerThisObj = await worker.evaluateHandle(() => {
|
||||
return this;
|
||||
});
|
||||
const workerDestroyedPromise = waitEvent(page, 'workerdestroyed');
|
||||
|
Loading…
Reference in New Issue
Block a user