mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
chore: add waitForSelector for BiDi (#10383)
This commit is contained in:
parent
866addd132
commit
d560299aa8
16
package-lock.json
generated
16
package-lock.json
generated
@ -3085,9 +3085,9 @@
|
|||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/chromium-bidi": {
|
"node_modules/chromium-bidi": {
|
||||||
"version": "0.4.11",
|
"version": "0.4.12",
|
||||||
"resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.11.tgz",
|
"resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.12.tgz",
|
||||||
"integrity": "sha512-p03ajLhlQ5gebw3cmbDBFmBc2wnJM5dnXS8Phu6mblGn/KQd76yOVL5VwE0VAisa7oazNfKGTaXlIZ8Q5Bb9OA==",
|
"integrity": "sha512-yl0ngMHtYUGJa2G0lkcbPvbnUZ9WMQyMNSfYmlrGD1nHRNyI9KOGw3dOaofFugXHHToneUaSmF9iUdgCBamCjA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"mitt": "3.0.0"
|
"mitt": "3.0.0"
|
||||||
},
|
},
|
||||||
@ -10164,7 +10164,7 @@
|
|||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@puppeteer/browsers": "1.4.1",
|
"@puppeteer/browsers": "1.4.1",
|
||||||
"chromium-bidi": "0.4.11",
|
"chromium-bidi": "0.4.12",
|
||||||
"cross-fetch": "3.1.6",
|
"cross-fetch": "3.1.6",
|
||||||
"debug": "4.3.4",
|
"debug": "4.3.4",
|
||||||
"devtools-protocol": "0.0.1135028",
|
"devtools-protocol": "0.0.1135028",
|
||||||
@ -12317,9 +12317,9 @@
|
|||||||
"version": "1.1.4"
|
"version": "1.1.4"
|
||||||
},
|
},
|
||||||
"chromium-bidi": {
|
"chromium-bidi": {
|
||||||
"version": "0.4.11",
|
"version": "0.4.12",
|
||||||
"resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.11.tgz",
|
"resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.12.tgz",
|
||||||
"integrity": "sha512-p03ajLhlQ5gebw3cmbDBFmBc2wnJM5dnXS8Phu6mblGn/KQd76yOVL5VwE0VAisa7oazNfKGTaXlIZ8Q5Bb9OA==",
|
"integrity": "sha512-yl0ngMHtYUGJa2G0lkcbPvbnUZ9WMQyMNSfYmlrGD1nHRNyI9KOGw3dOaofFugXHHToneUaSmF9iUdgCBamCjA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"mitt": "3.0.0"
|
"mitt": "3.0.0"
|
||||||
}
|
}
|
||||||
@ -15738,7 +15738,7 @@
|
|||||||
"version": "file:packages/puppeteer-core",
|
"version": "file:packages/puppeteer-core",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@puppeteer/browsers": "1.4.1",
|
"@puppeteer/browsers": "1.4.1",
|
||||||
"chromium-bidi": "0.4.11",
|
"chromium-bidi": "0.4.12",
|
||||||
"cross-fetch": "3.1.6",
|
"cross-fetch": "3.1.6",
|
||||||
"debug": "4.3.4",
|
"debug": "4.3.4",
|
||||||
"devtools-protocol": "0.0.1135028",
|
"devtools-protocol": "0.0.1135028",
|
||||||
|
@ -132,7 +132,7 @@
|
|||||||
"author": "The Chromium Authors",
|
"author": "The Chromium Authors",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chromium-bidi": "0.4.11",
|
"chromium-bidi": "0.4.12",
|
||||||
"cross-fetch": "3.1.6",
|
"cross-fetch": "3.1.6",
|
||||||
"debug": "4.3.4",
|
"debug": "4.3.4",
|
||||||
"devtools-protocol": "0.0.1135028",
|
"devtools-protocol": "0.0.1135028",
|
||||||
|
@ -16,11 +16,13 @@
|
|||||||
|
|
||||||
import {Protocol} from 'devtools-protocol';
|
import {Protocol} from 'devtools-protocol';
|
||||||
|
|
||||||
|
import {Frame} from '../api/Frame.js';
|
||||||
import {CDPSession} from '../common/Connection.js';
|
import {CDPSession} from '../common/Connection.js';
|
||||||
import {ExecutionContext} from '../common/ExecutionContext.js';
|
import {ExecutionContext} from '../common/ExecutionContext.js';
|
||||||
import {getQueryHandlerAndSelector} from '../common/GetQueryHandler.js';
|
import {getQueryHandlerAndSelector} from '../common/GetQueryHandler.js';
|
||||||
import {MouseClickOptions} from '../common/Input.js';
|
import {MouseClickOptions} from '../common/Input.js';
|
||||||
import {WaitForSelectorOptions} from '../common/IsolatedWorld.js';
|
import {WaitForSelectorOptions} from '../common/IsolatedWorld.js';
|
||||||
|
import {LazyArg} from '../common/LazyArg.js';
|
||||||
import {
|
import {
|
||||||
ElementFor,
|
ElementFor,
|
||||||
EvaluateFuncWith,
|
EvaluateFuncWith,
|
||||||
@ -33,7 +35,6 @@ import {isString, withSourcePuppeteerURLIfNone} from '../common/util.js';
|
|||||||
import {assert} from '../util/assert.js';
|
import {assert} from '../util/assert.js';
|
||||||
import {AsyncIterableUtil} from '../util/AsyncIterableUtil.js';
|
import {AsyncIterableUtil} from '../util/AsyncIterableUtil.js';
|
||||||
|
|
||||||
import {Frame} from './Frame.js';
|
|
||||||
import {JSHandle} from './JSHandle.js';
|
import {JSHandle} from './JSHandle.js';
|
||||||
import {ScreenshotOptions} from './Page.js';
|
import {ScreenshotOptions} from './Page.js';
|
||||||
|
|
||||||
@ -485,12 +486,30 @@ export class ElementHandle<
|
|||||||
)) as ElementHandle<NodeFor<Selector>> | null;
|
)) as ElementHandle<NodeFor<Selector>> | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async #checkVisibility(visibility: boolean): Promise<boolean> {
|
||||||
|
const element = await this.frame.isolatedRealm().adoptHandle(this);
|
||||||
|
try {
|
||||||
|
return await this.frame.isolatedRealm().evaluate(
|
||||||
|
async (PuppeteerUtil, element, visibility) => {
|
||||||
|
return Boolean(PuppeteerUtil.checkVisibility(element, visibility));
|
||||||
|
},
|
||||||
|
LazyArg.create(context => {
|
||||||
|
return context.puppeteerUtil;
|
||||||
|
}),
|
||||||
|
element,
|
||||||
|
visibility
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
await element.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if an element is visible using the same mechanism as
|
* Checks if an element is visible using the same mechanism as
|
||||||
* {@link ElementHandle.waitForSelector}.
|
* {@link ElementHandle.waitForSelector}.
|
||||||
*/
|
*/
|
||||||
async isVisible(): Promise<boolean> {
|
async isVisible(): Promise<boolean> {
|
||||||
throw new Error('Not implemented.');
|
return this.#checkVisibility(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -498,7 +517,7 @@ export class ElementHandle<
|
|||||||
* {@link ElementHandle.waitForSelector}.
|
* {@link ElementHandle.waitForSelector}.
|
||||||
*/
|
*/
|
||||||
async isHidden(): Promise<boolean> {
|
async isHidden(): Promise<boolean> {
|
||||||
throw new Error('Not implemented.');
|
return this.#checkVisibility(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -565,14 +584,16 @@ export class ElementHandle<
|
|||||||
*/
|
*/
|
||||||
async waitForXPath(
|
async waitForXPath(
|
||||||
xpath: string,
|
xpath: string,
|
||||||
options?: {
|
options: {
|
||||||
visible?: boolean;
|
visible?: boolean;
|
||||||
hidden?: boolean;
|
hidden?: boolean;
|
||||||
timeout?: number;
|
timeout?: number;
|
||||||
|
} = {}
|
||||||
|
): Promise<ElementHandle<Node> | null> {
|
||||||
|
if (xpath.startsWith('//')) {
|
||||||
|
xpath = `.${xpath}`;
|
||||||
}
|
}
|
||||||
): Promise<ElementHandle<Node> | null>;
|
return this.waitForSelector(`xpath/${xpath}`, options);
|
||||||
async waitForXPath(): Promise<ElementHandle<Node> | null> {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,6 +20,7 @@ import {Page, WaitTimeoutOptions} from '../api/Page.js';
|
|||||||
import {CDPSession} from '../common/Connection.js';
|
import {CDPSession} from '../common/Connection.js';
|
||||||
import {DeviceRequestPrompt} from '../common/DeviceRequestPrompt.js';
|
import {DeviceRequestPrompt} from '../common/DeviceRequestPrompt.js';
|
||||||
import {ExecutionContext} from '../common/ExecutionContext.js';
|
import {ExecutionContext} from '../common/ExecutionContext.js';
|
||||||
|
import {getQueryHandlerAndSelector} from '../common/GetQueryHandler.js';
|
||||||
import {
|
import {
|
||||||
IsolatedWorldChart,
|
IsolatedWorldChart,
|
||||||
WaitForSelectorOptions,
|
WaitForSelectorOptions,
|
||||||
@ -29,11 +30,52 @@ import {
|
|||||||
EvaluateFunc,
|
EvaluateFunc,
|
||||||
EvaluateFuncWith,
|
EvaluateFuncWith,
|
||||||
HandleFor,
|
HandleFor,
|
||||||
|
InnerLazyParams,
|
||||||
NodeFor,
|
NodeFor,
|
||||||
} from '../common/types.js';
|
} from '../common/types.js';
|
||||||
|
import {TaskManager} from '../common/WaitTask.js';
|
||||||
|
|
||||||
|
import {JSHandle} from './JSHandle.js';
|
||||||
import {Locator} from './Locator.js';
|
import {Locator} from './Locator.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export interface Realm {
|
||||||
|
taskManager: TaskManager;
|
||||||
|
waitForFunction<
|
||||||
|
Params extends unknown[],
|
||||||
|
Func extends EvaluateFunc<InnerLazyParams<Params>> = EvaluateFunc<
|
||||||
|
InnerLazyParams<Params>
|
||||||
|
>
|
||||||
|
>(
|
||||||
|
pageFunction: Func | string,
|
||||||
|
options: {
|
||||||
|
polling?: 'raf' | 'mutation' | number;
|
||||||
|
timeout?: number;
|
||||||
|
root?: ElementHandle<Node>;
|
||||||
|
signal?: AbortSignal;
|
||||||
|
},
|
||||||
|
...args: Params
|
||||||
|
): Promise<HandleFor<Awaited<ReturnType<Func>>>>;
|
||||||
|
adoptHandle<T extends JSHandle<Node>>(handle: T): Promise<T>;
|
||||||
|
transferHandle<T extends JSHandle<Node>>(handle: T): Promise<T>;
|
||||||
|
evaluateHandle<
|
||||||
|
Params extends unknown[],
|
||||||
|
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
||||||
|
>(
|
||||||
|
pageFunction: Func | string,
|
||||||
|
...args: Params
|
||||||
|
): Promise<HandleFor<Awaited<ReturnType<Func>>>>;
|
||||||
|
evaluate<
|
||||||
|
Params extends unknown[],
|
||||||
|
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
||||||
|
>(
|
||||||
|
pageFunction: Func | string,
|
||||||
|
...args: Params
|
||||||
|
): Promise<Awaited<ReturnType<Func>>>;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
@ -307,6 +349,20 @@ export class Frame {
|
|||||||
throw new Error('Not implemented');
|
throw new Error('Not implemented');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
mainRealm(): Realm {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
isolatedRealm(): Realm {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Behaves identically to {@link Page.evaluateHandle} except it's run within
|
* Behaves identically to {@link Page.evaluateHandle} except it's run within
|
||||||
* the context of this frame.
|
* the context of this frame.
|
||||||
@ -529,12 +585,15 @@ export class Frame {
|
|||||||
*/
|
*/
|
||||||
async waitForSelector<Selector extends string>(
|
async waitForSelector<Selector extends string>(
|
||||||
selector: Selector,
|
selector: Selector,
|
||||||
options?: WaitForSelectorOptions
|
options: WaitForSelectorOptions = {}
|
||||||
): Promise<ElementHandle<NodeFor<Selector>> | null>;
|
): Promise<ElementHandle<NodeFor<Selector>> | null> {
|
||||||
async waitForSelector<Selector extends string>(): Promise<ElementHandle<
|
const {updatedSelector, QueryHandler} =
|
||||||
NodeFor<Selector>
|
getQueryHandlerAndSelector(selector);
|
||||||
> | null> {
|
return (await QueryHandler.waitFor(
|
||||||
throw new Error('Not implemented');
|
this,
|
||||||
|
updatedSelector,
|
||||||
|
options
|
||||||
|
)) as ElementHandle<NodeFor<Selector>> | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -561,10 +620,12 @@ export class Frame {
|
|||||||
*/
|
*/
|
||||||
async waitForXPath(
|
async waitForXPath(
|
||||||
xpath: string,
|
xpath: string,
|
||||||
options?: WaitForSelectorOptions
|
options: WaitForSelectorOptions = {}
|
||||||
): Promise<ElementHandle<Node> | null>;
|
): Promise<ElementHandle<Node> | null> {
|
||||||
async waitForXPath(): Promise<ElementHandle<Node> | null> {
|
if (xpath.startsWith('//')) {
|
||||||
throw new Error('Not implemented');
|
xpath = `.${xpath}`;
|
||||||
|
}
|
||||||
|
return this.waitForSelector(`xpath/${xpath}`, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -605,16 +666,15 @@ export class Frame {
|
|||||||
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
||||||
>(
|
>(
|
||||||
pageFunction: Func | string,
|
pageFunction: Func | string,
|
||||||
options?: FrameWaitForFunctionOptions,
|
options: FrameWaitForFunctionOptions = {},
|
||||||
...args: Params
|
...args: Params
|
||||||
): Promise<HandleFor<Awaited<ReturnType<Func>>>>;
|
): Promise<HandleFor<Awaited<ReturnType<Func>>>> {
|
||||||
waitForFunction<
|
return this.mainRealm().waitForFunction(
|
||||||
Params extends unknown[],
|
pageFunction,
|
||||||
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
options,
|
||||||
>(): Promise<HandleFor<Awaited<ReturnType<Func>>>> {
|
...args
|
||||||
throw new Error('Not implemented');
|
) as Promise<HandleFor<Awaited<ReturnType<Func>>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The full HTML contents of the frame, including the DOCTYPE.
|
* The full HTML contents of the frame, including the DOCTYPE.
|
||||||
*/
|
*/
|
||||||
|
@ -33,9 +33,7 @@ import {ExecutionContext} from './ExecutionContext.js';
|
|||||||
import {Frame} from './Frame.js';
|
import {Frame} from './Frame.js';
|
||||||
import {FrameManager} from './FrameManager.js';
|
import {FrameManager} from './FrameManager.js';
|
||||||
import {WaitForSelectorOptions} from './IsolatedWorld.js';
|
import {WaitForSelectorOptions} from './IsolatedWorld.js';
|
||||||
import {PUPPETEER_WORLD} from './IsolatedWorlds.js';
|
|
||||||
import {CDPJSHandle} from './JSHandle.js';
|
import {CDPJSHandle} from './JSHandle.js';
|
||||||
import {LazyArg} from './LazyArg.js';
|
|
||||||
import {CDPPage} from './Page.js';
|
import {CDPPage} from './Page.js';
|
||||||
import {NodeFor} from './types.js';
|
import {NodeFor} from './types.js';
|
||||||
import {KeyInput} from './USKeyboardLayout.js';
|
import {KeyInput} from './USKeyboardLayout.js';
|
||||||
@ -128,46 +126,6 @@ export class CDPElementHandle<
|
|||||||
> | null;
|
> | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
override async waitForXPath(
|
|
||||||
xpath: string,
|
|
||||||
options: {
|
|
||||||
visible?: boolean;
|
|
||||||
hidden?: boolean;
|
|
||||||
timeout?: number;
|
|
||||||
} = {}
|
|
||||||
): Promise<CDPElementHandle<Node> | null> {
|
|
||||||
if (xpath.startsWith('//')) {
|
|
||||||
xpath = `.${xpath}`;
|
|
||||||
}
|
|
||||||
return this.waitForSelector(`xpath/${xpath}`, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
async #checkVisibility(visibility: boolean): Promise<boolean> {
|
|
||||||
const element = await this.frame.worlds[PUPPETEER_WORLD].adoptHandle(this);
|
|
||||||
try {
|
|
||||||
return await this.frame.worlds[PUPPETEER_WORLD].evaluate(
|
|
||||||
async (PuppeteerUtil, element, visibility) => {
|
|
||||||
return Boolean(PuppeteerUtil.checkVisibility(element, visibility));
|
|
||||||
},
|
|
||||||
LazyArg.create(context => {
|
|
||||||
return context.puppeteerUtil;
|
|
||||||
}),
|
|
||||||
element,
|
|
||||||
visibility
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
await element.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override async isVisible(): Promise<boolean> {
|
|
||||||
return this.#checkVisibility(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
override async isHidden(): Promise<boolean> {
|
|
||||||
return this.#checkVisibility(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
override async contentFrame(): Promise<Frame | null> {
|
override async contentFrame(): Promise<Frame | null> {
|
||||||
const nodeInfo = await this.client.send('DOM.describeNode', {
|
const nodeInfo = await this.client.send('DOM.describeNode', {
|
||||||
objectId: this.id,
|
objectId: this.id,
|
||||||
|
@ -21,7 +21,6 @@ import {
|
|||||||
Frame as BaseFrame,
|
Frame as BaseFrame,
|
||||||
FrameAddScriptTagOptions,
|
FrameAddScriptTagOptions,
|
||||||
FrameAddStyleTagOptions,
|
FrameAddStyleTagOptions,
|
||||||
FrameWaitForFunctionOptions,
|
|
||||||
} from '../api/Frame.js';
|
} from '../api/Frame.js';
|
||||||
import {HTTPResponse} from '../api/HTTPResponse.js';
|
import {HTTPResponse} from '../api/HTTPResponse.js';
|
||||||
import {Page, WaitTimeoutOptions} from '../api/Page.js';
|
import {Page, WaitTimeoutOptions} from '../api/Page.js';
|
||||||
@ -36,12 +35,7 @@ import {
|
|||||||
} from './DeviceRequestPrompt.js';
|
} from './DeviceRequestPrompt.js';
|
||||||
import {ExecutionContext} from './ExecutionContext.js';
|
import {ExecutionContext} from './ExecutionContext.js';
|
||||||
import {FrameManager} from './FrameManager.js';
|
import {FrameManager} from './FrameManager.js';
|
||||||
import {getQueryHandlerAndSelector} from './GetQueryHandler.js';
|
import {IsolatedWorld, IsolatedWorldChart} from './IsolatedWorld.js';
|
||||||
import {
|
|
||||||
IsolatedWorld,
|
|
||||||
IsolatedWorldChart,
|
|
||||||
WaitForSelectorOptions,
|
|
||||||
} from './IsolatedWorld.js';
|
|
||||||
import {MAIN_WORLD, PUPPETEER_WORLD} from './IsolatedWorlds.js';
|
import {MAIN_WORLD, PUPPETEER_WORLD} from './IsolatedWorlds.js';
|
||||||
import {LazyArg} from './LazyArg.js';
|
import {LazyArg} from './LazyArg.js';
|
||||||
import {LifecycleWatcher, PuppeteerLifeCycleEvent} from './LifecycleWatcher.js';
|
import {LifecycleWatcher, PuppeteerLifeCycleEvent} from './LifecycleWatcher.js';
|
||||||
@ -221,6 +215,20 @@ export class Frame extends BaseFrame {
|
|||||||
return this.worlds[MAIN_WORLD].executionContext();
|
return this.worlds[MAIN_WORLD].executionContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
override mainRealm(): IsolatedWorld {
|
||||||
|
return this.worlds[MAIN_WORLD];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
override isolatedRealm(): IsolatedWorld {
|
||||||
|
return this.worlds[PUPPETEER_WORLD];
|
||||||
|
}
|
||||||
|
|
||||||
override async evaluateHandle<
|
override async evaluateHandle<
|
||||||
Params extends unknown[],
|
Params extends unknown[],
|
||||||
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
||||||
@ -232,7 +240,7 @@ export class Frame extends BaseFrame {
|
|||||||
this.evaluateHandle.name,
|
this.evaluateHandle.name,
|
||||||
pageFunction
|
pageFunction
|
||||||
);
|
);
|
||||||
return this.worlds[MAIN_WORLD].evaluateHandle(pageFunction, ...args);
|
return this.mainRealm().evaluateHandle(pageFunction, ...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
override async evaluate<
|
override async evaluate<
|
||||||
@ -246,19 +254,19 @@ export class Frame extends BaseFrame {
|
|||||||
this.evaluate.name,
|
this.evaluate.name,
|
||||||
pageFunction
|
pageFunction
|
||||||
);
|
);
|
||||||
return this.worlds[MAIN_WORLD].evaluate(pageFunction, ...args);
|
return this.mainRealm().evaluate(pageFunction, ...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
override async $<Selector extends string>(
|
override async $<Selector extends string>(
|
||||||
selector: Selector
|
selector: Selector
|
||||||
): Promise<ElementHandle<NodeFor<Selector>> | null> {
|
): Promise<ElementHandle<NodeFor<Selector>> | null> {
|
||||||
return this.worlds[MAIN_WORLD].$(selector);
|
return this.mainRealm().$(selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
override async $$<Selector extends string>(
|
override async $$<Selector extends string>(
|
||||||
selector: Selector
|
selector: Selector
|
||||||
): Promise<Array<ElementHandle<NodeFor<Selector>>>> {
|
): Promise<Array<ElementHandle<NodeFor<Selector>>>> {
|
||||||
return this.worlds[MAIN_WORLD].$$(selector);
|
return this.mainRealm().$$(selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
override async $eval<
|
override async $eval<
|
||||||
@ -274,7 +282,7 @@ export class Frame extends BaseFrame {
|
|||||||
...args: Params
|
...args: Params
|
||||||
): Promise<Awaited<ReturnType<Func>>> {
|
): Promise<Awaited<ReturnType<Func>>> {
|
||||||
pageFunction = withSourcePuppeteerURLIfNone(this.$eval.name, pageFunction);
|
pageFunction = withSourcePuppeteerURLIfNone(this.$eval.name, pageFunction);
|
||||||
return this.worlds[MAIN_WORLD].$eval(selector, pageFunction, ...args);
|
return this.mainRealm().$eval(selector, pageFunction, ...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
override async $$eval<
|
override async $$eval<
|
||||||
@ -290,53 +298,15 @@ export class Frame extends BaseFrame {
|
|||||||
...args: Params
|
...args: Params
|
||||||
): Promise<Awaited<ReturnType<Func>>> {
|
): Promise<Awaited<ReturnType<Func>>> {
|
||||||
pageFunction = withSourcePuppeteerURLIfNone(this.$$eval.name, pageFunction);
|
pageFunction = withSourcePuppeteerURLIfNone(this.$$eval.name, pageFunction);
|
||||||
return this.worlds[MAIN_WORLD].$$eval(selector, pageFunction, ...args);
|
return this.mainRealm().$$eval(selector, pageFunction, ...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
override async $x(expression: string): Promise<Array<ElementHandle<Node>>> {
|
override async $x(expression: string): Promise<Array<ElementHandle<Node>>> {
|
||||||
return this.worlds[MAIN_WORLD].$x(expression);
|
return this.mainRealm().$x(expression);
|
||||||
}
|
|
||||||
|
|
||||||
override async waitForSelector<Selector extends string>(
|
|
||||||
selector: Selector,
|
|
||||||
options: WaitForSelectorOptions = {}
|
|
||||||
): Promise<ElementHandle<NodeFor<Selector>> | null> {
|
|
||||||
const {updatedSelector, QueryHandler} =
|
|
||||||
getQueryHandlerAndSelector(selector);
|
|
||||||
return (await QueryHandler.waitFor(
|
|
||||||
this,
|
|
||||||
updatedSelector,
|
|
||||||
options
|
|
||||||
)) as ElementHandle<NodeFor<Selector>> | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
override async waitForXPath(
|
|
||||||
xpath: string,
|
|
||||||
options: WaitForSelectorOptions = {}
|
|
||||||
): Promise<ElementHandle<Node> | null> {
|
|
||||||
if (xpath.startsWith('//')) {
|
|
||||||
xpath = `.${xpath}`;
|
|
||||||
}
|
|
||||||
return this.waitForSelector(`xpath/${xpath}`, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
override waitForFunction<
|
|
||||||
Params extends unknown[],
|
|
||||||
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
|
||||||
>(
|
|
||||||
pageFunction: Func | string,
|
|
||||||
options: FrameWaitForFunctionOptions = {},
|
|
||||||
...args: Params
|
|
||||||
): Promise<HandleFor<Awaited<ReturnType<Func>>>> {
|
|
||||||
return this.worlds[MAIN_WORLD].waitForFunction(
|
|
||||||
pageFunction,
|
|
||||||
options,
|
|
||||||
...args
|
|
||||||
) as Promise<HandleFor<Awaited<ReturnType<Func>>>>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override async content(): Promise<string> {
|
override async content(): Promise<string> {
|
||||||
return this.worlds[PUPPETEER_WORLD].content();
|
return this.isolatedRealm().content();
|
||||||
}
|
}
|
||||||
|
|
||||||
override async setContent(
|
override async setContent(
|
||||||
@ -346,7 +316,7 @@ export class Frame extends BaseFrame {
|
|||||||
waitUntil?: PuppeteerLifeCycleEvent | PuppeteerLifeCycleEvent[];
|
waitUntil?: PuppeteerLifeCycleEvent | PuppeteerLifeCycleEvent[];
|
||||||
} = {}
|
} = {}
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
return this.worlds[PUPPETEER_WORLD].setContent(html, options);
|
return this.isolatedRealm().setContent(html, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
override name(): string {
|
override name(): string {
|
||||||
@ -388,8 +358,8 @@ export class Frame extends BaseFrame {
|
|||||||
|
|
||||||
type = type ?? 'text/javascript';
|
type = type ?? 'text/javascript';
|
||||||
|
|
||||||
return this.worlds[MAIN_WORLD].transferHandle(
|
return this.mainRealm().transferHandle(
|
||||||
await this.worlds[PUPPETEER_WORLD].evaluateHandle(
|
await this.isolatedRealm().evaluateHandle(
|
||||||
async ({Deferred}, {url, id, type, content}) => {
|
async ({Deferred}, {url, id, type, content}) => {
|
||||||
const deferred = Deferred.create<void>();
|
const deferred = Deferred.create<void>();
|
||||||
const script = document.createElement('script');
|
const script = document.createElement('script');
|
||||||
@ -456,8 +426,8 @@ export class Frame extends BaseFrame {
|
|||||||
options.content = content;
|
options.content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.worlds[MAIN_WORLD].transferHandle(
|
return this.mainRealm().transferHandle(
|
||||||
await this.worlds[PUPPETEER_WORLD].evaluateHandle(
|
await this.isolatedRealm().evaluateHandle(
|
||||||
async ({Deferred}, {url, content}) => {
|
async ({Deferred}, {url, content}) => {
|
||||||
const deferred = Deferred.create<void>();
|
const deferred = Deferred.create<void>();
|
||||||
let element: HTMLStyleElement | HTMLLinkElement;
|
let element: HTMLStyleElement | HTMLLinkElement;
|
||||||
@ -504,23 +474,23 @@ export class Frame extends BaseFrame {
|
|||||||
selector: string,
|
selector: string,
|
||||||
options: Readonly<ClickOptions> = {}
|
options: Readonly<ClickOptions> = {}
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
return this.worlds[PUPPETEER_WORLD].click(selector, options);
|
return this.isolatedRealm().click(selector, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
override async focus(selector: string): Promise<void> {
|
override async focus(selector: string): Promise<void> {
|
||||||
return this.worlds[PUPPETEER_WORLD].focus(selector);
|
return this.isolatedRealm().focus(selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
override async hover(selector: string): Promise<void> {
|
override async hover(selector: string): Promise<void> {
|
||||||
return this.worlds[PUPPETEER_WORLD].hover(selector);
|
return this.isolatedRealm().hover(selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
override select(selector: string, ...values: string[]): Promise<string[]> {
|
override select(selector: string, ...values: string[]): Promise<string[]> {
|
||||||
return this.worlds[PUPPETEER_WORLD].select(selector, ...values);
|
return this.isolatedRealm().select(selector, ...values);
|
||||||
}
|
}
|
||||||
|
|
||||||
override async tap(selector: string): Promise<void> {
|
override async tap(selector: string): Promise<void> {
|
||||||
return this.worlds[PUPPETEER_WORLD].tap(selector);
|
return this.isolatedRealm().tap(selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
override async type(
|
override async type(
|
||||||
@ -528,11 +498,11 @@ export class Frame extends BaseFrame {
|
|||||||
text: string,
|
text: string,
|
||||||
options?: {delay: number}
|
options?: {delay: number}
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
return this.worlds[PUPPETEER_WORLD].type(selector, text, options);
|
return this.isolatedRealm().type(selector, text, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
override async title(): Promise<string> {
|
override async title(): Promise<string> {
|
||||||
return this.worlds[PUPPETEER_WORLD].title();
|
return this.isolatedRealm().title();
|
||||||
}
|
}
|
||||||
|
|
||||||
_deviceRequestPromptManager(): DeviceRequestPromptManager {
|
_deviceRequestPromptManager(): DeviceRequestPromptManager {
|
||||||
|
@ -34,7 +34,10 @@ import {Target} from './Target.js';
|
|||||||
import {TimeoutSettings} from './TimeoutSettings.js';
|
import {TimeoutSettings} from './TimeoutSettings.js';
|
||||||
import {debugError, PuppeteerURL} from './util.js';
|
import {debugError, PuppeteerURL} from './util.js';
|
||||||
|
|
||||||
const UTILITY_WORLD_NAME = '__puppeteer_utility_world__';
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export const UTILITY_WORLD_NAME = '__puppeteer_utility_world__';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We use symbols to prevent external parties listening to these events.
|
* We use symbols to prevent external parties listening to these events.
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
import {Protocol} from 'devtools-protocol';
|
import {Protocol} from 'devtools-protocol';
|
||||||
|
|
||||||
import type {ClickOptions, ElementHandle} from '../api/ElementHandle.js';
|
import type {ClickOptions, ElementHandle} from '../api/ElementHandle.js';
|
||||||
|
import {Realm} from '../api/Frame.js';
|
||||||
import {JSHandle} from '../api/JSHandle.js';
|
import {JSHandle} from '../api/JSHandle.js';
|
||||||
import {assert} from '../util/assert.js';
|
import {assert} from '../util/assert.js';
|
||||||
import {Deferred} from '../util/Deferred.js';
|
import {Deferred} from '../util/Deferred.js';
|
||||||
@ -99,7 +100,7 @@ export interface IsolatedWorldChart {
|
|||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export class IsolatedWorld {
|
export class IsolatedWorld implements Realm {
|
||||||
#frame: Frame;
|
#frame: Frame;
|
||||||
#document?: ElementHandle<Document>;
|
#document?: ElementHandle<Document>;
|
||||||
#context = Deferred.create<ExecutionContext>();
|
#context = Deferred.create<ExecutionContext>();
|
||||||
|
@ -22,7 +22,6 @@ import {interpolateFunction, stringifyFunction} from '../util/Function.js';
|
|||||||
|
|
||||||
import {transposeIterableHandle} from './HandleIterator.js';
|
import {transposeIterableHandle} from './HandleIterator.js';
|
||||||
import type {WaitForSelectorOptions} from './IsolatedWorld.js';
|
import type {WaitForSelectorOptions} from './IsolatedWorld.js';
|
||||||
import {MAIN_WORLD, PUPPETEER_WORLD} from './IsolatedWorlds.js';
|
|
||||||
import {LazyArg} from './LazyArg.js';
|
import {LazyArg} from './LazyArg.js';
|
||||||
import type {Awaitable, AwaitableIterable} from './types.js';
|
import type {Awaitable, AwaitableIterable} from './types.js';
|
||||||
|
|
||||||
@ -160,7 +159,7 @@ export class QueryHandler {
|
|||||||
frame = elementOrFrame;
|
frame = elementOrFrame;
|
||||||
} else {
|
} else {
|
||||||
frame = elementOrFrame.frame;
|
frame = elementOrFrame.frame;
|
||||||
element = await frame.worlds[PUPPETEER_WORLD].adoptHandle(elementOrFrame);
|
element = await frame.isolatedRealm().adoptHandle(elementOrFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
const {visible = false, hidden = false, timeout, signal} = options;
|
const {visible = false, hidden = false, timeout, signal} = options;
|
||||||
@ -168,7 +167,7 @@ export class QueryHandler {
|
|||||||
try {
|
try {
|
||||||
signal?.throwIfAborted();
|
signal?.throwIfAborted();
|
||||||
|
|
||||||
const handle = await frame.worlds[PUPPETEER_WORLD].waitForFunction(
|
const handle = await frame.isolatedRealm().waitForFunction(
|
||||||
async (PuppeteerUtil, query, selector, root, visible) => {
|
async (PuppeteerUtil, query, selector, root, visible) => {
|
||||||
const querySelector = PuppeteerUtil.createFunction(
|
const querySelector = PuppeteerUtil.createFunction(
|
||||||
query
|
query
|
||||||
@ -204,7 +203,7 @@ export class QueryHandler {
|
|||||||
await handle.dispose();
|
await handle.dispose();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return frame.worlds[MAIN_WORLD].transferHandle(handle);
|
return frame.mainRealm().transferHandle(handle);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (!isErrorLike(error)) {
|
if (!isErrorLike(error)) {
|
||||||
throw error;
|
throw error;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {ElementHandle} from '../api/ElementHandle.js';
|
import {ElementHandle} from '../api/ElementHandle.js';
|
||||||
|
import {Realm} from '../api/Frame.js';
|
||||||
import {JSHandle} from '../api/JSHandle.js';
|
import {JSHandle} from '../api/JSHandle.js';
|
||||||
import type {Poller} from '../injected/Poller.js';
|
import type {Poller} from '../injected/Poller.js';
|
||||||
import {Deferred} from '../util/Deferred.js';
|
import {Deferred} from '../util/Deferred.js';
|
||||||
@ -22,7 +23,6 @@ import {isErrorLike} from '../util/ErrorLike.js';
|
|||||||
import {stringifyFunction} from '../util/Function.js';
|
import {stringifyFunction} from '../util/Function.js';
|
||||||
|
|
||||||
import {TimeoutError} from './Errors.js';
|
import {TimeoutError} from './Errors.js';
|
||||||
import {IsolatedWorld} from './IsolatedWorld.js';
|
|
||||||
import {LazyArg} from './LazyArg.js';
|
import {LazyArg} from './LazyArg.js';
|
||||||
import {HandleFor} from './types.js';
|
import {HandleFor} from './types.js';
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ export interface WaitTaskOptions {
|
|||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export class WaitTask<T = unknown> {
|
export class WaitTask<T = unknown> {
|
||||||
#world: IsolatedWorld;
|
#world: Realm;
|
||||||
#polling: 'raf' | 'mutation' | number;
|
#polling: 'raf' | 'mutation' | number;
|
||||||
#root?: ElementHandle<Node>;
|
#root?: ElementHandle<Node>;
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ export class WaitTask<T = unknown> {
|
|||||||
#signal?: AbortSignal;
|
#signal?: AbortSignal;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
world: IsolatedWorld,
|
world: Realm,
|
||||||
options: WaitTaskOptions,
|
options: WaitTaskOptions,
|
||||||
fn: ((...args: unknown[]) => Promise<T>) | string,
|
fn: ((...args: unknown[]) => Promise<T>) | string,
|
||||||
...args: unknown[]
|
...args: unknown[]
|
||||||
|
@ -2,37 +2,17 @@ import * as Bidi from 'chromium-bidi/lib/cjs/protocol/protocol.js';
|
|||||||
import ProtocolMapping from 'devtools-protocol/types/protocol-mapping.js';
|
import ProtocolMapping from 'devtools-protocol/types/protocol-mapping.js';
|
||||||
|
|
||||||
import {WaitForOptions} from '../../api/Page.js';
|
import {WaitForOptions} from '../../api/Page.js';
|
||||||
import PuppeteerUtil from '../../injected/injected.js';
|
|
||||||
import {assert} from '../../util/assert.js';
|
import {assert} from '../../util/assert.js';
|
||||||
import {Deferred} from '../../util/Deferred.js';
|
import {Deferred} from '../../util/Deferred.js';
|
||||||
import {stringifyFunction} from '../../util/Function.js';
|
|
||||||
import type {CDPSession, Connection as CDPConnection} from '../Connection.js';
|
import type {CDPSession, Connection as CDPConnection} from '../Connection.js';
|
||||||
import {ProtocolError, TimeoutError} from '../Errors.js';
|
import {ProtocolError, TimeoutError} from '../Errors.js';
|
||||||
import {EventEmitter} from '../EventEmitter.js';
|
import {EventEmitter} from '../EventEmitter.js';
|
||||||
import {PuppeteerLifeCycleEvent} from '../LifecycleWatcher.js';
|
import {PuppeteerLifeCycleEvent} from '../LifecycleWatcher.js';
|
||||||
import {scriptInjector} from '../ScriptInjector.js';
|
|
||||||
import {TimeoutSettings} from '../TimeoutSettings.js';
|
import {TimeoutSettings} from '../TimeoutSettings.js';
|
||||||
import {EvaluateFunc, HandleFor} from '../types.js';
|
import {getPageContent, setPageContent, waitWithTimeout} from '../util.js';
|
||||||
import {
|
|
||||||
PuppeteerURL,
|
|
||||||
getPageContent,
|
|
||||||
getSourcePuppeteerURLIfAvailable,
|
|
||||||
isString,
|
|
||||||
setPageContent,
|
|
||||||
waitWithTimeout,
|
|
||||||
} from '../util.js';
|
|
||||||
|
|
||||||
import {Connection} from './Connection.js';
|
import {Connection} from './Connection.js';
|
||||||
import {ElementHandle} from './ElementHandle.js';
|
import {Realm} from './Realm.js';
|
||||||
import {JSHandle} from './JSHandle.js';
|
|
||||||
import {BidiSerializer} from './Serializer.js';
|
|
||||||
import {createEvaluationError} from './utils.js';
|
|
||||||
|
|
||||||
const SOURCE_URL_REGEX = /^[\040\t]*\/\/[@#] sourceURL=\s*(\S*?)\s*$/m;
|
|
||||||
|
|
||||||
const getSourceUrlComment = (url: string) => {
|
|
||||||
return `//# sourceURL=${url}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
@ -104,8 +84,7 @@ export class CDPSessionWrapper extends EventEmitter implements CDPSession {
|
|||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export class BrowsingContext extends EventEmitter {
|
export class BrowsingContext extends Realm {
|
||||||
connection: Connection;
|
|
||||||
#timeoutSettings: TimeoutSettings;
|
#timeoutSettings: TimeoutSettings;
|
||||||
#id: string;
|
#id: string;
|
||||||
#url = 'about:blank';
|
#url = 'about:blank';
|
||||||
@ -116,27 +95,15 @@ export class BrowsingContext extends EventEmitter {
|
|||||||
timeoutSettings: TimeoutSettings,
|
timeoutSettings: TimeoutSettings,
|
||||||
info: Bidi.BrowsingContext.Info
|
info: Bidi.BrowsingContext.Info
|
||||||
) {
|
) {
|
||||||
super();
|
super(connection, info.context);
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
this.#timeoutSettings = timeoutSettings;
|
this.#timeoutSettings = timeoutSettings;
|
||||||
this.#id = info.context;
|
this.#id = info.context;
|
||||||
this.#cdpSession = new CDPSessionWrapper(this);
|
this.#cdpSession = new CDPSessionWrapper(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
#puppeteerUtil?: Promise<JSHandle<PuppeteerUtil>>;
|
createSandboxRealm(sandbox: string): Realm {
|
||||||
get puppeteerUtil(): Promise<JSHandle<PuppeteerUtil>> {
|
return new Realm(this.connection, this.#id, sandbox);
|
||||||
const promise = Promise.resolve() as Promise<unknown>;
|
|
||||||
scriptInjector.inject(script => {
|
|
||||||
if (this.#puppeteerUtil) {
|
|
||||||
void this.#puppeteerUtil.then(handle => {
|
|
||||||
void handle.dispose();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.#puppeteerUtil = promise.then(() => {
|
|
||||||
return this.evaluateHandle(script) as Promise<JSHandle<PuppeteerUtil>>;
|
|
||||||
});
|
|
||||||
}, !this.#puppeteerUtil);
|
|
||||||
return this.#puppeteerUtil as Promise<JSHandle<PuppeteerUtil>>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get url(): string {
|
get url(): string {
|
||||||
@ -212,97 +179,6 @@ export class BrowsingContext extends EventEmitter {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async evaluateHandle<
|
|
||||||
Params extends unknown[],
|
|
||||||
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
|
||||||
>(
|
|
||||||
pageFunction: Func | string,
|
|
||||||
...args: Params
|
|
||||||
): Promise<HandleFor<Awaited<ReturnType<Func>>>> {
|
|
||||||
return this.#evaluate(false, pageFunction, ...args);
|
|
||||||
}
|
|
||||||
|
|
||||||
async evaluate<
|
|
||||||
Params extends unknown[],
|
|
||||||
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
|
||||||
>(
|
|
||||||
pageFunction: Func | string,
|
|
||||||
...args: Params
|
|
||||||
): Promise<Awaited<ReturnType<Func>>> {
|
|
||||||
return this.#evaluate(true, pageFunction, ...args);
|
|
||||||
}
|
|
||||||
|
|
||||||
async #evaluate<
|
|
||||||
Params extends unknown[],
|
|
||||||
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
|
||||||
>(
|
|
||||||
returnByValue: true,
|
|
||||||
pageFunction: Func | string,
|
|
||||||
...args: Params
|
|
||||||
): Promise<Awaited<ReturnType<Func>>>;
|
|
||||||
async #evaluate<
|
|
||||||
Params extends unknown[],
|
|
||||||
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
|
||||||
>(
|
|
||||||
returnByValue: false,
|
|
||||||
pageFunction: Func | string,
|
|
||||||
...args: Params
|
|
||||||
): Promise<HandleFor<Awaited<ReturnType<Func>>>>;
|
|
||||||
async #evaluate<
|
|
||||||
Params extends unknown[],
|
|
||||||
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
|
||||||
>(
|
|
||||||
returnByValue: boolean,
|
|
||||||
pageFunction: Func | string,
|
|
||||||
...args: Params
|
|
||||||
): Promise<HandleFor<Awaited<ReturnType<Func>>> | Awaited<ReturnType<Func>>> {
|
|
||||||
const sourceUrlComment = getSourceUrlComment(
|
|
||||||
getSourcePuppeteerURLIfAvailable(pageFunction)?.toString() ??
|
|
||||||
PuppeteerURL.INTERNAL_URL
|
|
||||||
);
|
|
||||||
|
|
||||||
let responsePromise;
|
|
||||||
const resultOwnership = returnByValue ? 'none' : 'root';
|
|
||||||
if (isString(pageFunction)) {
|
|
||||||
const expression = SOURCE_URL_REGEX.test(pageFunction)
|
|
||||||
? pageFunction
|
|
||||||
: `${pageFunction}\n${sourceUrlComment}\n`;
|
|
||||||
|
|
||||||
responsePromise = this.connection.send('script.evaluate', {
|
|
||||||
expression,
|
|
||||||
target: {context: this.#id},
|
|
||||||
resultOwnership,
|
|
||||||
awaitPromise: true,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
let functionDeclaration = stringifyFunction(pageFunction);
|
|
||||||
functionDeclaration = SOURCE_URL_REGEX.test(functionDeclaration)
|
|
||||||
? functionDeclaration
|
|
||||||
: `${functionDeclaration}\n${sourceUrlComment}\n`;
|
|
||||||
responsePromise = this.connection.send('script.callFunction', {
|
|
||||||
functionDeclaration,
|
|
||||||
arguments: await Promise.all(
|
|
||||||
args.map(arg => {
|
|
||||||
return BidiSerializer.serialize(arg, this);
|
|
||||||
})
|
|
||||||
),
|
|
||||||
target: {context: this.#id},
|
|
||||||
resultOwnership,
|
|
||||||
awaitPromise: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const {result} = await responsePromise;
|
|
||||||
|
|
||||||
if ('type' in result && result.type === 'exception') {
|
|
||||||
throw createEvaluationError(result.exceptionDetails);
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnByValue
|
|
||||||
? BidiSerializer.deserialize(result.result)
|
|
||||||
: getBidiHandle(this, result.result);
|
|
||||||
}
|
|
||||||
|
|
||||||
async setContent(
|
async setContent(
|
||||||
html: string,
|
html: string,
|
||||||
options: {
|
options: {
|
||||||
@ -344,29 +220,16 @@ export class BrowsingContext extends EventEmitter {
|
|||||||
return this.#cdpSession.send(method, ...paramArgs);
|
return this.#cdpSession.send(method, ...paramArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
dispose(): void {
|
|
||||||
this.removeAllListeners();
|
|
||||||
this.connection.unregisterBrowsingContexts(this.#id);
|
|
||||||
}
|
|
||||||
|
|
||||||
title(): Promise<string> {
|
title(): Promise<string> {
|
||||||
return this.evaluate(() => {
|
return this.evaluate(() => {
|
||||||
return document.title;
|
return document.title;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
dispose(): void {
|
||||||
* @internal
|
this.removeAllListeners();
|
||||||
*/
|
this.connection.unregisterBrowsingContexts(this.#id);
|
||||||
export function getBidiHandle(
|
|
||||||
context: BrowsingContext,
|
|
||||||
result: Bidi.CommonDataTypes.RemoteValue
|
|
||||||
): JSHandle | ElementHandle<Node> {
|
|
||||||
if (result.type === 'node' || result.type === 'window') {
|
|
||||||
return new ElementHandle(context, result);
|
|
||||||
}
|
}
|
||||||
return new JSHandle(context, result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,6 +65,10 @@ interface Commands {
|
|||||||
params: Bidi.Script.DisownParameters;
|
params: Bidi.Script.DisownParameters;
|
||||||
returnType: Bidi.Script.DisownResult;
|
returnType: Bidi.Script.DisownResult;
|
||||||
};
|
};
|
||||||
|
'script.addPreloadScript': {
|
||||||
|
params: Bidi.Script.AddPreloadScriptParameters;
|
||||||
|
returnType: Bidi.Script.AddPreloadScriptResult;
|
||||||
|
};
|
||||||
|
|
||||||
'browsingContext.create': {
|
'browsingContext.create': {
|
||||||
params: Bidi.BrowsingContext.CreateParameters;
|
params: Bidi.BrowsingContext.CreateParameters;
|
||||||
@ -116,11 +120,11 @@ interface Commands {
|
|||||||
};
|
};
|
||||||
'session.subscribe': {
|
'session.subscribe': {
|
||||||
params: Bidi.Session.SubscriptionRequest;
|
params: Bidi.Session.SubscriptionRequest;
|
||||||
returnType: Bidi.Session.SubscribeResult;
|
returnType: Bidi.Message.EmptyResult;
|
||||||
};
|
};
|
||||||
'session.unsubscribe': {
|
'session.unsubscribe': {
|
||||||
params: Bidi.Session.SubscriptionRequest;
|
params: Bidi.Session.SubscriptionRequest;
|
||||||
returnType: Bidi.Session.UnsubscribeResult;
|
returnType: Bidi.Message.EmptyResult;
|
||||||
};
|
};
|
||||||
'cdp.sendCommand': {
|
'cdp.sendCommand': {
|
||||||
params: Bidi.CDP.SendCommandParams;
|
params: Bidi.CDP.SendCommandParams;
|
||||||
|
@ -18,8 +18,9 @@ import * as Bidi from 'chromium-bidi/lib/cjs/protocol/protocol.js';
|
|||||||
|
|
||||||
import {ElementHandle as BaseElementHandle} from '../../api/ElementHandle.js';
|
import {ElementHandle as BaseElementHandle} from '../../api/ElementHandle.js';
|
||||||
|
|
||||||
import {BrowsingContext} from './BrowsingContext.js';
|
import {Frame} from './Frame.js';
|
||||||
import {JSHandle} from './JSHandle.js';
|
import {JSHandle} from './JSHandle.js';
|
||||||
|
import {Realm} from './Realm.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
@ -28,15 +29,22 @@ export class ElementHandle<
|
|||||||
ElementType extends Node = Element
|
ElementType extends Node = Element
|
||||||
> extends BaseElementHandle<ElementType> {
|
> extends BaseElementHandle<ElementType> {
|
||||||
declare handle: JSHandle<ElementType>;
|
declare handle: JSHandle<ElementType>;
|
||||||
|
#frame: Frame;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
context: BrowsingContext,
|
realm: Realm,
|
||||||
remoteValue: Bidi.CommonDataTypes.RemoteValue
|
remoteValue: Bidi.CommonDataTypes.RemoteValue,
|
||||||
|
frame: Frame
|
||||||
) {
|
) {
|
||||||
super(new JSHandle(context, remoteValue));
|
super(new JSHandle(realm, remoteValue));
|
||||||
|
this.#frame = frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
context(): BrowsingContext {
|
override get frame(): Frame {
|
||||||
|
return this.#frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
context(): Realm {
|
||||||
return this.handle.context();
|
return this.handle.context();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
import {ElementHandle} from '../../api/ElementHandle.js';
|
import {ElementHandle} from '../../api/ElementHandle.js';
|
||||||
import {Frame as BaseFrame} from '../../api/Frame.js';
|
import {Frame as BaseFrame} from '../../api/Frame.js';
|
||||||
|
import {UTILITY_WORLD_NAME} from '../FrameManager.js';
|
||||||
import {PuppeteerLifeCycleEvent} from '../LifecycleWatcher.js';
|
import {PuppeteerLifeCycleEvent} from '../LifecycleWatcher.js';
|
||||||
|
import {TimeoutSettings} from '../TimeoutSettings.js';
|
||||||
import {EvaluateFunc, EvaluateFuncWith, HandleFor, NodeFor} from '../types.js';
|
import {EvaluateFunc, EvaluateFuncWith, HandleFor, NodeFor} from '../types.js';
|
||||||
import {withSourcePuppeteerURLIfNone} from '../util.js';
|
import {withSourcePuppeteerURLIfNone} from '../util.js';
|
||||||
|
|
||||||
@ -40,7 +42,12 @@ export class Frame extends BaseFrame {
|
|||||||
sandboxes: SandboxChart;
|
sandboxes: SandboxChart;
|
||||||
override _id: string;
|
override _id: string;
|
||||||
|
|
||||||
constructor(page: Page, context: BrowsingContext, parentId?: string | null) {
|
constructor(
|
||||||
|
page: Page,
|
||||||
|
context: BrowsingContext,
|
||||||
|
timeoutSettings: TimeoutSettings,
|
||||||
|
parentId?: string | null
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
this.#page = page;
|
this.#page = page;
|
||||||
this.#context = context;
|
this.#context = context;
|
||||||
@ -48,11 +55,22 @@ export class Frame extends BaseFrame {
|
|||||||
this._parentId = parentId ?? undefined;
|
this._parentId = parentId ?? undefined;
|
||||||
|
|
||||||
this.sandboxes = {
|
this.sandboxes = {
|
||||||
[MAIN_SANDBOX]: new Sandbox(context),
|
[MAIN_SANDBOX]: new Sandbox(context, timeoutSettings),
|
||||||
[PUPPETEER_SANDBOX]: new Sandbox(context),
|
[PUPPETEER_SANDBOX]: new Sandbox(
|
||||||
|
context.createSandboxRealm(UTILITY_WORLD_NAME),
|
||||||
|
timeoutSettings
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override mainRealm(): Sandbox {
|
||||||
|
return this.sandboxes[MAIN_SANDBOX];
|
||||||
|
}
|
||||||
|
|
||||||
|
override isolatedRealm(): Sandbox {
|
||||||
|
return this.sandboxes[PUPPETEER_SANDBOX];
|
||||||
|
}
|
||||||
|
|
||||||
override page(): Page {
|
override page(): Page {
|
||||||
return this.#page;
|
return this.#page;
|
||||||
}
|
}
|
||||||
|
@ -21,26 +21,23 @@ import {JSHandle as BaseJSHandle} from '../../api/JSHandle.js';
|
|||||||
import {EvaluateFuncWith, HandleFor, HandleOr} from '../../common/types.js';
|
import {EvaluateFuncWith, HandleFor, HandleOr} from '../../common/types.js';
|
||||||
import {withSourcePuppeteerURLIfNone} from '../util.js';
|
import {withSourcePuppeteerURLIfNone} from '../util.js';
|
||||||
|
|
||||||
import {BrowsingContext} from './BrowsingContext.js';
|
import {Realm} from './Realm.js';
|
||||||
import {BidiSerializer} from './Serializer.js';
|
import {BidiSerializer} from './Serializer.js';
|
||||||
import {releaseReference} from './utils.js';
|
import {releaseReference} from './utils.js';
|
||||||
|
|
||||||
export class JSHandle<T = unknown> extends BaseJSHandle<T> {
|
export class JSHandle<T = unknown> extends BaseJSHandle<T> {
|
||||||
#disposed = false;
|
#disposed = false;
|
||||||
#context;
|
#realm: Realm;
|
||||||
#remoteValue;
|
#remoteValue;
|
||||||
|
|
||||||
constructor(
|
constructor(realm: Realm, remoteValue: Bidi.CommonDataTypes.RemoteValue) {
|
||||||
context: BrowsingContext,
|
|
||||||
remoteValue: Bidi.CommonDataTypes.RemoteValue
|
|
||||||
) {
|
|
||||||
super();
|
super();
|
||||||
this.#context = context;
|
this.#realm = realm;
|
||||||
this.#remoteValue = remoteValue;
|
this.#remoteValue = remoteValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
context(): BrowsingContext {
|
context(): Realm {
|
||||||
return this.#context;
|
return this.#realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
override get disposed(): boolean {
|
override get disposed(): boolean {
|
||||||
@ -136,7 +133,7 @@ export class JSHandle<T = unknown> extends BaseJSHandle<T> {
|
|||||||
}
|
}
|
||||||
this.#disposed = true;
|
this.#disposed = true;
|
||||||
if ('handle' in this.#remoteValue) {
|
if ('handle' in this.#remoteValue) {
|
||||||
await releaseReference(this.#context, this.#remoteValue);
|
await releaseReference(this.#realm, this.#remoteValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,12 +53,13 @@ import {
|
|||||||
|
|
||||||
import {Browser} from './Browser.js';
|
import {Browser} from './Browser.js';
|
||||||
import {BrowserContext} from './BrowserContext.js';
|
import {BrowserContext} from './BrowserContext.js';
|
||||||
import {BrowsingContext, getBidiHandle} from './BrowsingContext.js';
|
import {BrowsingContext} from './BrowsingContext.js';
|
||||||
import {Connection} from './Connection.js';
|
import {Connection} from './Connection.js';
|
||||||
import {Frame} from './Frame.js';
|
import {Frame} from './Frame.js';
|
||||||
import {HTTPRequest} from './HTTPRequest.js';
|
import {HTTPRequest} from './HTTPRequest.js';
|
||||||
import {HTTPResponse} from './HTTPResponse.js';
|
import {HTTPResponse} from './HTTPResponse.js';
|
||||||
import {NetworkManager} from './NetworkManager.js';
|
import {NetworkManager} from './NetworkManager.js';
|
||||||
|
import {getBidiHandle} from './Realm.js';
|
||||||
import {BidiSerializer} from './Serializer.js';
|
import {BidiSerializer} from './Serializer.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -208,7 +209,13 @@ export class Page extends PageBase {
|
|||||||
);
|
);
|
||||||
this.#connection.registerBrowsingContexts(context);
|
this.#connection.registerBrowsingContexts(context);
|
||||||
|
|
||||||
const frame = new Frame(this, context, info.parent);
|
const frame = new Frame(
|
||||||
|
this,
|
||||||
|
context,
|
||||||
|
this.#timeoutSettings,
|
||||||
|
info.parent
|
||||||
|
);
|
||||||
|
context.setFrame(frame);
|
||||||
|
|
||||||
this.#frameTree.addFrame(frame);
|
this.#frameTree.addFrame(frame);
|
||||||
this.emit(FrameManagerEmittedEvents.FrameAttached, frame);
|
this.emit(FrameManagerEmittedEvents.FrameAttached, frame);
|
||||||
@ -250,12 +257,13 @@ export class Page extends PageBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#onLogEntryAdded(event: Bidi.Log.LogEntry): void {
|
#onLogEntryAdded(event: Bidi.Log.LogEntry): void {
|
||||||
if (!this.frame(event.source.context)) {
|
const frame = this.frame(event.source.context);
|
||||||
|
if (!frame) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isConsoleLogEntry(event)) {
|
if (isConsoleLogEntry(event)) {
|
||||||
const args = event.args.map(arg => {
|
const args = event.args.map(arg => {
|
||||||
return getBidiHandle(this.mainFrame().context(), arg);
|
return getBidiHandle(frame.context(), arg, frame);
|
||||||
});
|
});
|
||||||
|
|
||||||
const text = args
|
const text = args
|
||||||
|
171
packages/puppeteer-core/src/common/bidi/Realm.ts
Normal file
171
packages/puppeteer-core/src/common/bidi/Realm.ts
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
import * as Bidi from 'chromium-bidi/lib/cjs/protocol/protocol.js';
|
||||||
|
|
||||||
|
import PuppeteerUtil from '../../injected/injected.js';
|
||||||
|
import {stringifyFunction} from '../../util/Function.js';
|
||||||
|
import {EventEmitter} from '../EventEmitter.js';
|
||||||
|
import {scriptInjector} from '../ScriptInjector.js';
|
||||||
|
import {EvaluateFunc, HandleFor} from '../types.js';
|
||||||
|
import {
|
||||||
|
PuppeteerURL,
|
||||||
|
getSourcePuppeteerURLIfAvailable,
|
||||||
|
isString,
|
||||||
|
} from '../util.js';
|
||||||
|
|
||||||
|
import {Connection} from './Connection.js';
|
||||||
|
import {ElementHandle} from './ElementHandle.js';
|
||||||
|
import {Frame} from './Frame.js';
|
||||||
|
import {JSHandle} from './JSHandle.js';
|
||||||
|
import {BidiSerializer} from './Serializer.js';
|
||||||
|
import {createEvaluationError} from './utils.js';
|
||||||
|
|
||||||
|
export const SOURCE_URL_REGEX = /^[\040\t]*\/\/[@#] sourceURL=\s*(\S*?)\s*$/m;
|
||||||
|
|
||||||
|
export const getSourceUrlComment = (url: string): string => {
|
||||||
|
return `//# sourceURL=${url}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export class Realm extends EventEmitter {
|
||||||
|
connection: Connection;
|
||||||
|
#frame!: Frame;
|
||||||
|
#id: string;
|
||||||
|
#sandbox?: string;
|
||||||
|
|
||||||
|
constructor(connection: Connection, id: string, sandbox?: string) {
|
||||||
|
super();
|
||||||
|
this.connection = connection;
|
||||||
|
this.#id = id;
|
||||||
|
this.#sandbox = sandbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
get target(): Bidi.Script.Target {
|
||||||
|
return {
|
||||||
|
context: this.#id,
|
||||||
|
sandbox: this.#sandbox,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
setFrame(frame: Frame): void {
|
||||||
|
this.#frame = frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected internalPuppeteerUtil?: Promise<JSHandle<PuppeteerUtil>>;
|
||||||
|
get puppeteerUtil(): Promise<JSHandle<PuppeteerUtil>> {
|
||||||
|
const promise = Promise.resolve() as Promise<unknown>;
|
||||||
|
scriptInjector.inject(script => {
|
||||||
|
if (this.internalPuppeteerUtil) {
|
||||||
|
void this.internalPuppeteerUtil.then(handle => {
|
||||||
|
void handle.dispose();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.internalPuppeteerUtil = promise.then(() => {
|
||||||
|
return this.evaluateHandle(script) as Promise<JSHandle<PuppeteerUtil>>;
|
||||||
|
});
|
||||||
|
}, !this.internalPuppeteerUtil);
|
||||||
|
return this.internalPuppeteerUtil as Promise<JSHandle<PuppeteerUtil>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
async evaluateHandle<
|
||||||
|
Params extends unknown[],
|
||||||
|
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
||||||
|
>(
|
||||||
|
pageFunction: Func | string,
|
||||||
|
...args: Params
|
||||||
|
): Promise<HandleFor<Awaited<ReturnType<Func>>>> {
|
||||||
|
return this.#evaluate(false, pageFunction, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
async evaluate<
|
||||||
|
Params extends unknown[],
|
||||||
|
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
||||||
|
>(
|
||||||
|
pageFunction: Func | string,
|
||||||
|
...args: Params
|
||||||
|
): Promise<Awaited<ReturnType<Func>>> {
|
||||||
|
return this.#evaluate(true, pageFunction, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
async #evaluate<
|
||||||
|
Params extends unknown[],
|
||||||
|
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
||||||
|
>(
|
||||||
|
returnByValue: true,
|
||||||
|
pageFunction: Func | string,
|
||||||
|
...args: Params
|
||||||
|
): Promise<Awaited<ReturnType<Func>>>;
|
||||||
|
async #evaluate<
|
||||||
|
Params extends unknown[],
|
||||||
|
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
||||||
|
>(
|
||||||
|
returnByValue: false,
|
||||||
|
pageFunction: Func | string,
|
||||||
|
...args: Params
|
||||||
|
): Promise<HandleFor<Awaited<ReturnType<Func>>>>;
|
||||||
|
async #evaluate<
|
||||||
|
Params extends unknown[],
|
||||||
|
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
||||||
|
>(
|
||||||
|
returnByValue: boolean,
|
||||||
|
pageFunction: Func | string,
|
||||||
|
...args: Params
|
||||||
|
): Promise<HandleFor<Awaited<ReturnType<Func>>> | Awaited<ReturnType<Func>>> {
|
||||||
|
const sourceUrlComment = getSourceUrlComment(
|
||||||
|
getSourcePuppeteerURLIfAvailable(pageFunction)?.toString() ??
|
||||||
|
PuppeteerURL.INTERNAL_URL
|
||||||
|
);
|
||||||
|
|
||||||
|
let responsePromise;
|
||||||
|
const resultOwnership = returnByValue ? 'none' : 'root';
|
||||||
|
if (isString(pageFunction)) {
|
||||||
|
const expression = SOURCE_URL_REGEX.test(pageFunction)
|
||||||
|
? pageFunction
|
||||||
|
: `${pageFunction}\n${sourceUrlComment}\n`;
|
||||||
|
|
||||||
|
responsePromise = this.connection.send('script.evaluate', {
|
||||||
|
expression,
|
||||||
|
target: this.target,
|
||||||
|
resultOwnership,
|
||||||
|
awaitPromise: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
let functionDeclaration = stringifyFunction(pageFunction);
|
||||||
|
functionDeclaration = SOURCE_URL_REGEX.test(functionDeclaration)
|
||||||
|
? functionDeclaration
|
||||||
|
: `${functionDeclaration}\n${sourceUrlComment}\n`;
|
||||||
|
responsePromise = this.connection.send('script.callFunction', {
|
||||||
|
functionDeclaration,
|
||||||
|
arguments: await Promise.all(
|
||||||
|
args.map(arg => {
|
||||||
|
return BidiSerializer.serialize(arg, this as any);
|
||||||
|
})
|
||||||
|
),
|
||||||
|
target: this.target,
|
||||||
|
resultOwnership,
|
||||||
|
awaitPromise: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const {result} = await responsePromise;
|
||||||
|
|
||||||
|
if ('type' in result && result.type === 'exception') {
|
||||||
|
throw createEvaluationError(result.exceptionDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnByValue
|
||||||
|
? BidiSerializer.deserialize(result.result)
|
||||||
|
: getBidiHandle(this as any, result.result, this.#frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export function getBidiHandle(
|
||||||
|
realmOrContext: Realm,
|
||||||
|
result: Bidi.CommonDataTypes.RemoteValue,
|
||||||
|
frame: Frame
|
||||||
|
): JSHandle | ElementHandle<Node> {
|
||||||
|
if (result.type === 'node' || result.type === 'window') {
|
||||||
|
return new ElementHandle(realmOrContext, result, frame);
|
||||||
|
}
|
||||||
|
return new JSHandle(realmOrContext, result);
|
||||||
|
}
|
@ -15,11 +15,21 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {ElementHandle} from '../../api/ElementHandle.js';
|
import {ElementHandle} from '../../api/ElementHandle.js';
|
||||||
import {withSourcePuppeteerURLIfNone} from '../common.js';
|
import {Realm as RealmBase} from '../../api/Frame.js';
|
||||||
import {EvaluateFuncWith, NodeFor} from '../types.js';
|
import {JSHandle as BaseJSHandle} from '../../api/JSHandle.js';
|
||||||
|
import {TimeoutSettings} from '../TimeoutSettings.js';
|
||||||
import {BrowsingContext} from './BrowsingContext.js';
|
import {
|
||||||
|
EvaluateFunc,
|
||||||
|
EvaluateFuncWith,
|
||||||
|
HandleFor,
|
||||||
|
InnerLazyParams,
|
||||||
|
NodeFor,
|
||||||
|
} from '../types.js';
|
||||||
|
import {withSourcePuppeteerURLIfNone} from '../util.js';
|
||||||
|
import {TaskManager, WaitTask} from '../WaitTask.js';
|
||||||
|
|
||||||
|
import {JSHandle} from './JSHandle.js';
|
||||||
|
import {Realm} from './Realm.js';
|
||||||
/**
|
/**
|
||||||
* A unique key for {@link SandboxChart} to denote the default world.
|
* A unique key for {@link SandboxChart} to denote the default world.
|
||||||
* Realms are automatically created in the default sandbox.
|
* Realms are automatically created in the default sandbox.
|
||||||
@ -47,19 +57,27 @@ export interface SandboxChart {
|
|||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export class Sandbox {
|
export class Sandbox implements RealmBase {
|
||||||
#document?: ElementHandle<Document>;
|
#document?: ElementHandle<Document>;
|
||||||
#context: BrowsingContext;
|
#realm: Realm;
|
||||||
|
|
||||||
constructor(context: BrowsingContext) {
|
#timeoutSettings: TimeoutSettings;
|
||||||
this.#context = context;
|
#taskManager = new TaskManager();
|
||||||
|
|
||||||
|
constructor(context: Realm, timeoutSettings: TimeoutSettings) {
|
||||||
|
this.#realm = context;
|
||||||
|
this.#timeoutSettings = timeoutSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
get taskManager(): TaskManager {
|
||||||
|
return this.#taskManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
async document(): Promise<ElementHandle<Document>> {
|
async document(): Promise<ElementHandle<Document>> {
|
||||||
if (this.#document) {
|
if (this.#document) {
|
||||||
return this.#document;
|
return this.#document;
|
||||||
}
|
}
|
||||||
this.#document = await this.#context.evaluateHandle(() => {
|
this.#document = await this.#realm.evaluateHandle(() => {
|
||||||
return document;
|
return document;
|
||||||
});
|
});
|
||||||
return this.#document;
|
return this.#document;
|
||||||
@ -117,4 +135,90 @@ export class Sandbox {
|
|||||||
const document = await this.document();
|
const document = await this.document();
|
||||||
return document.$x(expression);
|
return document.$x(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async evaluateHandle<
|
||||||
|
Params extends unknown[],
|
||||||
|
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
||||||
|
>(
|
||||||
|
pageFunction: Func | string,
|
||||||
|
...args: Params
|
||||||
|
): Promise<HandleFor<Awaited<ReturnType<Func>>>> {
|
||||||
|
pageFunction = withSourcePuppeteerURLIfNone(
|
||||||
|
this.evaluateHandle.name,
|
||||||
|
pageFunction
|
||||||
|
);
|
||||||
|
return this.#realm.evaluateHandle(pageFunction, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
async evaluate<
|
||||||
|
Params extends unknown[],
|
||||||
|
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>
|
||||||
|
>(
|
||||||
|
pageFunction: Func | string,
|
||||||
|
...args: Params
|
||||||
|
): Promise<Awaited<ReturnType<Func>>> {
|
||||||
|
pageFunction = withSourcePuppeteerURLIfNone(
|
||||||
|
this.evaluate.name,
|
||||||
|
pageFunction
|
||||||
|
);
|
||||||
|
return this.#realm.evaluate(pageFunction, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
async adoptHandle<T extends BaseJSHandle<Node>>(handle: T): Promise<T> {
|
||||||
|
return (await this.evaluateHandle(node => {
|
||||||
|
return node;
|
||||||
|
}, handle)) as unknown as T;
|
||||||
|
}
|
||||||
|
|
||||||
|
async transferHandle<T extends BaseJSHandle<Node>>(handle: T): Promise<T> {
|
||||||
|
if ((handle as unknown as JSHandle).context() === this.#realm) {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
const transferredHandle = await this.evaluateHandle(node => {
|
||||||
|
return node;
|
||||||
|
}, handle);
|
||||||
|
|
||||||
|
await handle.dispose();
|
||||||
|
return transferredHandle as unknown as T;
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForFunction<
|
||||||
|
Params extends unknown[],
|
||||||
|
Func extends EvaluateFunc<InnerLazyParams<Params>> = EvaluateFunc<
|
||||||
|
InnerLazyParams<Params>
|
||||||
|
>
|
||||||
|
>(
|
||||||
|
pageFunction: Func | string,
|
||||||
|
options: {
|
||||||
|
polling?: 'raf' | 'mutation' | number;
|
||||||
|
timeout?: number;
|
||||||
|
root?: ElementHandle<Node>;
|
||||||
|
signal?: AbortSignal;
|
||||||
|
} = {},
|
||||||
|
...args: Params
|
||||||
|
): Promise<HandleFor<Awaited<ReturnType<Func>>>> {
|
||||||
|
const {
|
||||||
|
polling = 'raf',
|
||||||
|
timeout = this.#timeoutSettings.timeout(),
|
||||||
|
root,
|
||||||
|
signal,
|
||||||
|
} = options;
|
||||||
|
if (typeof polling === 'number' && polling < 0) {
|
||||||
|
throw new Error('Cannot poll with non-positive interval');
|
||||||
|
}
|
||||||
|
const waitTask = new WaitTask(
|
||||||
|
this,
|
||||||
|
{
|
||||||
|
polling,
|
||||||
|
root,
|
||||||
|
timeout,
|
||||||
|
signal,
|
||||||
|
},
|
||||||
|
pageFunction as unknown as
|
||||||
|
| ((...args: unknown[]) => Promise<Awaited<ReturnType<Func>>>)
|
||||||
|
| string,
|
||||||
|
...args
|
||||||
|
);
|
||||||
|
return waitTask.result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,10 @@ export class BidiSerializer {
|
|||||||
? arg
|
? arg
|
||||||
: null;
|
: null;
|
||||||
if (objectHandle) {
|
if (objectHandle) {
|
||||||
if (objectHandle.context() !== context) {
|
if (
|
||||||
|
objectHandle.context() !== context &&
|
||||||
|
!('sharedId' in objectHandle.remoteValue())
|
||||||
|
) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'JSHandles can be evaluated only in the context they were created!'
|
'JSHandles can be evaluated only in the context they were created!'
|
||||||
);
|
);
|
||||||
|
@ -19,7 +19,7 @@ import * as Bidi from 'chromium-bidi/lib/cjs/protocol/protocol.js';
|
|||||||
import {debug} from '../Debug.js';
|
import {debug} from '../Debug.js';
|
||||||
import {PuppeteerURL} from '../util.js';
|
import {PuppeteerURL} from '../util.js';
|
||||||
|
|
||||||
import {BrowsingContext} from './BrowsingContext.js';
|
import {Realm} from './Realm.js';
|
||||||
import {BidiSerializer} from './Serializer.js';
|
import {BidiSerializer} from './Serializer.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,7 +30,7 @@ export const debugError = debug('puppeteer:error');
|
|||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export async function releaseReference(
|
export async function releaseReference(
|
||||||
client: BrowsingContext,
|
client: Realm,
|
||||||
remoteReference: Bidi.CommonDataTypes.RemoteReference
|
remoteReference: Bidi.CommonDataTypes.RemoteReference
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (!remoteReference.handle) {
|
if (!remoteReference.handle) {
|
||||||
@ -38,7 +38,7 @@ export async function releaseReference(
|
|||||||
}
|
}
|
||||||
await client.connection
|
await client.connection
|
||||||
.send('script.disown', {
|
.send('script.disown', {
|
||||||
target: {context: client.id},
|
target: client.target,
|
||||||
handles: [remoteReference.handle],
|
handles: [remoteReference.handle],
|
||||||
})
|
})
|
||||||
.catch((error: any) => {
|
.catch((error: any) => {
|
||||||
|
@ -263,6 +263,24 @@
|
|||||||
"parameters": ["cdp", "firefox"],
|
"parameters": ["cdp", "firefox"],
|
||||||
"expectations": ["SKIP"]
|
"expectations": ["SKIP"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[ariaqueryhandler.spec] AriaQueryHandler waitForSelector (aria) should have an error message specifically for awaiting an element to be hidden",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[ariaqueryhandler.spec] AriaQueryHandler waitForSelector (aria) should have correct stack trace for timeout",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[ariaqueryhandler.spec] AriaQueryHandler waitForSelector (aria) should respect timeout",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[browser.spec] Browser specs Browser.process should return child_process instance",
|
"testIdPattern": "[browser.spec] Browser specs Browser.process should return child_process instance",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
@ -275,6 +293,12 @@
|
|||||||
"parameters": ["cdp", "firefox"],
|
"parameters": ["cdp", "firefox"],
|
||||||
"expectations": ["SKIP"]
|
"expectations": ["SKIP"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[chromiumonly.spec] Chromium-Specific Launcher tests Puppeteer.launch |pipe| option should fire \"disconnected\" when closing with pipe",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[Connection.spec] WebDriver BiDi Connection should work",
|
"testIdPattern": "[Connection.spec] WebDriver BiDi Connection should work",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
@ -311,35 +335,35 @@
|
|||||||
"parameters": ["webDriverBiDi"],
|
"parameters": ["webDriverBiDi"],
|
||||||
"expectations": ["PASS"]
|
"expectations": ["PASS"]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"testIdPattern": "[elementhandle.spec] ElementHandle specs Custom queries should wait correctly with waitFor",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["webDriverBiDi"],
|
|
||||||
"expectations": ["FAIL"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"testIdPattern": "[elementhandle.spec] ElementHandle specs Custom queries should wait correctly with waitForSelector",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["webDriverBiDi"],
|
|
||||||
"expectations": ["FAIL"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"testIdPattern": "[elementhandle.spec] ElementHandle specs Custom queries should wait correctly with waitForSelector on an element",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["webDriverBiDi"],
|
|
||||||
"expectations": ["FAIL"]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"testIdPattern": "[elementhandle.spec] ElementHandle specs Element.toElement should work",
|
"testIdPattern": "[elementhandle.spec] ElementHandle specs Element.toElement should work",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
"parameters": ["webDriverBiDi"],
|
"parameters": ["webDriverBiDi"],
|
||||||
"expectations": ["PASS"]
|
"expectations": ["PASS"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[elementhandle.spec] ElementHandle specs Element.waitForSelector should wait correctly with waitForSelector on an element",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[elementhandle.spec] ElementHandle specs Element.waitForXPath should wait correctly with waitForXPath on an element",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[elementhandle.spec] ElementHandle specs ElementHandle.isVisible and ElementHandle.isHidden should work",
|
"testIdPattern": "[elementhandle.spec] ElementHandle specs ElementHandle.isVisible and ElementHandle.isHidden should work",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
"parameters": ["webDriverBiDi"],
|
"parameters": ["webDriverBiDi"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[emulation.spec] *",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["chrome", "webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[evaluation.spec] Evaluation specs Frame.evaluate should have different execution contexts",
|
"testIdPattern": "[evaluation.spec] Evaluation specs Frame.evaluate should have different execution contexts",
|
||||||
@ -773,6 +797,12 @@
|
|||||||
"parameters": ["webDriverBiDi"],
|
"parameters": ["webDriverBiDi"],
|
||||||
"expectations": ["PASS"]
|
"expectations": ["PASS"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[page.spec] Page Page.url should work",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[page.spec] Page Page.waitForNetworkIdle should work with aborted requests",
|
"testIdPattern": "[page.spec] Page Page.waitForNetworkIdle should work with aborted requests",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
@ -807,7 +837,7 @@
|
|||||||
"testIdPattern": "[queryhandler.spec] Query handler tests P selectors should work for ARIA selectors in multiple isolated worlds",
|
"testIdPattern": "[queryhandler.spec] Query handler tests P selectors should work for ARIA selectors in multiple isolated worlds",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
"parameters": ["webDriverBiDi"],
|
"parameters": ["webDriverBiDi"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["FAIL", "TIMEOUT"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[queryhandler.spec] Query handler tests P selectors should work with :hover",
|
"testIdPattern": "[queryhandler.spec] Query handler tests P selectors should work with :hover",
|
||||||
@ -875,6 +905,120 @@
|
|||||||
"parameters": ["webDriverBiDi"],
|
"parameters": ["webDriverBiDi"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["FAIL"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should be cancellable",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should have an error message specifically for awaiting an element to be hidden",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should have correct stack trace for timeout",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should immediately resolve promise if node exists",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should resolve promise when node is added",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should respect timeout",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should respond to node attribute mutation",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should return null if waiting to hide non-existing element",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should return the element handle",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should wait for element to be hidden (bounding box)",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should wait for element to be hidden (display)",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should wait for element to be hidden (removal)",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should wait for element to be hidden (visibility)",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should wait for element to be visible (bounding box)",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should wait for element to be visible (display)",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should wait for element to be visible (visibility)",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should wait for element to be visible recursively",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should work when node is added through innerHTML",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector should work with removed MutationObserver",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForTimeout waits for the given timeout before resolving",
|
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForTimeout waits for the given timeout before resolving",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
@ -971,12 +1115,30 @@
|
|||||||
"parameters": ["chrome", "webDriverBiDi"],
|
"parameters": ["chrome", "webDriverBiDi"],
|
||||||
"expectations": ["PASS"]
|
"expectations": ["PASS"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[chromiumonly.spec] Chromium-Specific Launcher tests Puppeteer.launch |browserURL| option should be able to connect using browserUrl, with and without trailing slash",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["firefox", "webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[chromiumonly.spec] Chromium-Specific Launcher tests Puppeteer.launch |browserURL| option should throw when trying to connect to non-existing browser",
|
"testIdPattern": "[chromiumonly.spec] Chromium-Specific Launcher tests Puppeteer.launch |browserURL| option should throw when trying to connect to non-existing browser",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
"parameters": ["chrome", "webDriverBiDi"],
|
"parameters": ["chrome", "webDriverBiDi"],
|
||||||
"expectations": ["PASS"]
|
"expectations": ["PASS"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[chromiumonly.spec] Chromium-Specific Launcher tests Puppeteer.launch |browserURL| option should throw when trying to connect to non-existing browser",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["firefox", "webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[chromiumonly.spec] Chromium-Specific Launcher tests Puppeteer.launch |pipe| option should fire \"disconnected\" when closing with pipe",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["firefox", "webDriverBiDi"],
|
||||||
|
"expectations": ["SKIP"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[click.spec] Page.click should click on checkbox label and toggle",
|
"testIdPattern": "[click.spec] Page.click should click on checkbox label and toggle",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
@ -1175,18 +1337,42 @@
|
|||||||
"parameters": ["cdp", "firefox"],
|
"parameters": ["cdp", "firefox"],
|
||||||
"expectations": ["SKIP"]
|
"expectations": ["SKIP"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[emulation.spec] Emulation Page.emulate should support clicking",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["chrome", "webDriverBiDi"],
|
||||||
|
"expectations": ["FAIL"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[emulation.spec] Emulation Page.emulate should work",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["chrome", "webDriverBiDi"],
|
||||||
|
"expectations": ["FAIL"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[emulation.spec] Emulation Page.emulateCPUThrottling should change the CPU throttling rate successfully",
|
"testIdPattern": "[emulation.spec] Emulation Page.emulateCPUThrottling should change the CPU throttling rate successfully",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
"parameters": ["cdp", "firefox"],
|
"parameters": ["cdp", "firefox"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["FAIL"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[emulation.spec] Emulation Page.emulateMediaFeatures should throw in case of bad argument",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["firefox", "webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[emulation.spec] Emulation Page.emulateMediaFeatures should work",
|
"testIdPattern": "[emulation.spec] Emulation Page.emulateMediaFeatures should work",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
"parameters": ["cdp", "firefox"],
|
"parameters": ["cdp", "firefox"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["FAIL"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[emulation.spec] Emulation Page.emulateMediaType should throw in case of bad argument",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["firefox", "webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[emulation.spec] Emulation Page.emulateMediaType should work",
|
"testIdPattern": "[emulation.spec] Emulation Page.emulateMediaType should work",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
@ -1199,6 +1385,12 @@
|
|||||||
"parameters": ["cdp", "firefox"],
|
"parameters": ["cdp", "firefox"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["FAIL"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[emulation.spec] Emulation Page.emulateNetworkConditions should change navigator.connection.effectiveType",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["chrome", "webDriverBiDi"],
|
||||||
|
"expectations": ["FAIL"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[emulation.spec] Emulation Page.emulateTimezone should throw for invalid timezone IDs",
|
"testIdPattern": "[emulation.spec] Emulation Page.emulateTimezone should throw for invalid timezone IDs",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
@ -1211,12 +1403,24 @@
|
|||||||
"parameters": ["cdp", "firefox"],
|
"parameters": ["cdp", "firefox"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["FAIL"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[emulation.spec] Emulation Page.emulateVisionDeficiency should throw for invalid vision deficiencies",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["firefox", "webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[emulation.spec] Emulation Page.emulateVisionDeficiency should work",
|
"testIdPattern": "[emulation.spec] Emulation Page.emulateVisionDeficiency should work",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
"parameters": ["cdp", "firefox"],
|
"parameters": ["cdp", "firefox"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["FAIL"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[emulation.spec] Emulation Page.viewport should detect touch when applying viewport with touches",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["chrome", "webDriverBiDi"],
|
||||||
|
"expectations": ["FAIL"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[emulation.spec] Emulation Page.viewport should get the proper viewport size",
|
"testIdPattern": "[emulation.spec] Emulation Page.viewport should get the proper viewport size",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
@ -1229,42 +1433,12 @@
|
|||||||
"parameters": ["cdp", "firefox"],
|
"parameters": ["cdp", "firefox"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["FAIL"]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"testIdPattern": "[emulation.spec] *",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["chrome", "webDriverBiDi"],
|
|
||||||
"expectations": ["PASS"]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"testIdPattern": "[emulation.spec] Emulation Page.viewport should support touch emulation",
|
"testIdPattern": "[emulation.spec] Emulation Page.viewport should support touch emulation",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
"parameters": ["chrome", "webDriverBiDi"],
|
"parameters": ["chrome", "webDriverBiDi"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["FAIL"]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"testIdPattern": "[emulation.spec] Emulation Page.viewport should detect touch when applying viewport with touches",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["chrome", "webDriverBiDi"],
|
|
||||||
"expectations": ["FAIL"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"testIdPattern": "[emulation.spec] Emulation Page.emulate should work",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["chrome", "webDriverBiDi"],
|
|
||||||
"expectations": ["FAIL"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"testIdPattern": "[emulation.spec] Emulation Page.emulate should support clicking",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["chrome", "webDriverBiDi"],
|
|
||||||
"expectations": ["FAIL"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"testIdPattern": "[emulation.spec] Emulation Page.emulateNetworkConditions should change navigator.connection.effectiveType",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["chrome", "webDriverBiDi"],
|
|
||||||
"expectations": ["FAIL"]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"testIdPattern": "[evaluation.spec] Evaluation specs \"after each\" hook for \"should transfer 100Mb of data from page to node.js\"",
|
"testIdPattern": "[evaluation.spec] Evaluation specs \"after each\" hook for \"should transfer 100Mb of data from page to node.js\"",
|
||||||
"platforms": ["darwin"],
|
"platforms": ["darwin"],
|
||||||
@ -1367,6 +1541,12 @@
|
|||||||
"parameters": ["cdp", "firefox"],
|
"parameters": ["cdp", "firefox"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["FAIL"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[ignorehttpserrors.spec] ignoreHTTPSErrors should work with mixed content",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["firefox", "webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[ignorehttpserrors.spec] ignoreHTTPSErrors should work with request interception",
|
"testIdPattern": "[ignorehttpserrors.spec] ignoreHTTPSErrors should work with request interception",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
@ -1553,12 +1733,36 @@
|
|||||||
"parameters": ["firefox", "webDriverBiDi"],
|
"parameters": ["firefox", "webDriverBiDi"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["FAIL"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[locator.spec] Locator Locator.click can be aborted",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["chrome", "webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[locator.spec] Locator Locator.click should retry clicks on errors",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["chrome", "webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[locator.spec] Locator Locator.click should time out",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["chrome", "webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[locator.spec] Locator Locator.race can be aborted",
|
"testIdPattern": "[locator.spec] Locator Locator.race can be aborted",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
"parameters": ["chrome", "webDriverBiDi"],
|
"parameters": ["chrome", "webDriverBiDi"],
|
||||||
"expectations": ["PASS"]
|
"expectations": ["PASS"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[locator.spec] Locator Locator.scroll should work",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["chrome", "webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[mouse.spec] Mouse should reset properly",
|
"testIdPattern": "[mouse.spec] Mouse should reset properly",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
@ -2177,6 +2381,12 @@
|
|||||||
"parameters": ["cdp", "firefox"],
|
"parameters": ["cdp", "firefox"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["FAIL"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[page.spec] Page Page.addScriptTag should throw an error if loading from url fail",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["firefox", "webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[page.spec] Page Page.addScriptTag should throw when added with content to the CSP page",
|
"testIdPattern": "[page.spec] Page Page.addScriptTag should throw when added with content to the CSP page",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
@ -2189,6 +2399,12 @@
|
|||||||
"parameters": ["cdp", "firefox"],
|
"parameters": ["cdp", "firefox"],
|
||||||
"expectations": ["SKIP"]
|
"expectations": ["SKIP"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[page.spec] Page Page.addStyleTag should throw an error if loading from url fail",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["firefox", "webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[page.spec] Page Page.addStyleTag should throw when added with content to the CSP page",
|
"testIdPattern": "[page.spec] Page Page.addStyleTag should throw when added with content to the CSP page",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
@ -2459,12 +2675,6 @@
|
|||||||
"parameters": ["cdp", "firefox"],
|
"parameters": ["cdp", "firefox"],
|
||||||
"expectations": ["FAIL"]
|
"expectations": ["FAIL"]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"testIdPattern": "[page.spec] Page Page.url should work",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["chrome", "webDriverBiDi"],
|
|
||||||
"expectations": ["PASS"]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"testIdPattern": "[page.spec] Page Page.waitForNetworkIdle should work",
|
"testIdPattern": "[page.spec] Page Page.waitForNetworkIdle should work",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
@ -2783,6 +2993,12 @@
|
|||||||
"parameters": ["cdp", "firefox"],
|
"parameters": ["cdp", "firefox"],
|
||||||
"expectations": ["SKIP"]
|
"expectations": ["SKIP"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"testIdPattern": "[worker.spec] Workers should report errors",
|
||||||
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
"parameters": ["firefox", "webDriverBiDi"],
|
||||||
|
"expectations": ["PASS"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"testIdPattern": "[CDPSession.spec] Target.createCDPSession should send events",
|
"testIdPattern": "[CDPSession.spec] Target.createCDPSession should send events",
|
||||||
"platforms": ["win32"],
|
"platforms": ["win32"],
|
||||||
|
@ -39,7 +39,7 @@ describe('headful tests', function () {
|
|||||||
/* These tests fire up an actual browser so let's
|
/* These tests fire up an actual browser so let's
|
||||||
* allow a higher timeout
|
* allow a higher timeout
|
||||||
*/
|
*/
|
||||||
this.timeout(20 * 1000);
|
this.timeout(20_000);
|
||||||
|
|
||||||
let headfulOptions: PuppeteerLaunchOptions | undefined;
|
let headfulOptions: PuppeteerLaunchOptions | undefined;
|
||||||
let headlessOptions: PuppeteerLaunchOptions & {headless: boolean};
|
let headlessOptions: PuppeteerLaunchOptions & {headless: boolean};
|
||||||
|
@ -35,7 +35,7 @@ import {
|
|||||||
import {dumpFrames, waitEvent} from './utils.js';
|
import {dumpFrames, waitEvent} from './utils.js';
|
||||||
|
|
||||||
const TMP_FOLDER = path.join(os.tmpdir(), 'pptr_tmp_folder-');
|
const TMP_FOLDER = path.join(os.tmpdir(), 'pptr_tmp_folder-');
|
||||||
const FIREFOX_TIMEOUT = 30 * 1000;
|
const FIREFOX_TIMEOUT = 30_000;
|
||||||
|
|
||||||
describe('Launcher specs', function () {
|
describe('Launcher specs', function () {
|
||||||
setupTestBrowserHooks();
|
setupTestBrowserHooks();
|
||||||
|
Loading…
Reference in New Issue
Block a user