mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
chore: abstract web worker API (#11558)
This commit is contained in:
parent
c3000160e6
commit
af6eba4bea
@ -4,7 +4,7 @@ sidebar_label: WebWorker.evaluate
|
|||||||
|
|
||||||
# WebWorker.evaluate() method
|
# WebWorker.evaluate() method
|
||||||
|
|
||||||
If the function passed to the `worker.evaluate` returns a Promise, then `worker.evaluate` would wait for the promise to resolve and return its value. If the function passed to the `worker.evaluate` returns a non-serializable value, then `worker.evaluate` resolves to `undefined`. DevTools Protocol also supports transferring some additional values that are not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`, and bigint literals. Shortcut for `await worker.executionContext()).evaluate(pageFunction, ...args)`.
|
Evaluates a given function in the [worker](./puppeteer.webworker.md).
|
||||||
|
|
||||||
#### Signature:
|
#### Signature:
|
||||||
|
|
||||||
@ -13,22 +13,27 @@ class WebWorker {
|
|||||||
evaluate<
|
evaluate<
|
||||||
Params extends unknown[],
|
Params extends unknown[],
|
||||||
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>,
|
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>,
|
||||||
>(
|
>(func: Func | string, ...args: Params): Promise<Awaited<ReturnType<Func>>>;
|
||||||
pageFunction: Func | string,
|
|
||||||
...args: Params
|
|
||||||
): Promise<Awaited<ReturnType<Func>>>;
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
|
|
||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
| ------------ | -------------- | ----------------------------------------------- |
|
| --------- | -------------- | ----------------------------------------- |
|
||||||
| pageFunction | Func \| string | Function to be evaluated in the worker context. |
|
| func | Func \| string | Function to be evaluated. |
|
||||||
| args | Params | Arguments to pass to <code>pageFunction</code>. |
|
| args | Params | Arguments to pass into <code>func</code>. |
|
||||||
|
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
|
||||||
Promise<Awaited<ReturnType<Func>>>
|
Promise<Awaited<ReturnType<Func>>>
|
||||||
|
|
||||||
Promise which resolves to the return value of `pageFunction`.
|
The result of `func`.
|
||||||
|
|
||||||
|
## Remarks
|
||||||
|
|
||||||
|
If the given function returns a promise, [evaluate](./puppeteer.webworker.evaluate.md) will wait for the promise to resolve.
|
||||||
|
|
||||||
|
As a rule of thumb, if the return value of the given function is more complicated than a JSON object (e.g. most classes), then [evaluate](./puppeteer.webworker.evaluate.md) will \_likely\_ return some truncated value (or `{}`). This is because we are not returning the actual return value, but a deserialized version as a result of transferring the return value through a protocol to Puppeteer.
|
||||||
|
|
||||||
|
In general, you should use [evaluateHandle](./puppeteer.webworker.evaluatehandle.md) if [evaluate](./puppeteer.webworker.evaluate.md) cannot serialize the return value properly or you need a mutable [handle](./puppeteer.jshandle.md) to the return object.
|
||||||
|
@ -4,7 +4,7 @@ sidebar_label: WebWorker.evaluateHandle
|
|||||||
|
|
||||||
# WebWorker.evaluateHandle() method
|
# WebWorker.evaluateHandle() method
|
||||||
|
|
||||||
The only difference between `worker.evaluate` and `worker.evaluateHandle` is that `worker.evaluateHandle` returns in-page object (JSHandle). If the function passed to the `worker.evaluateHandle` returns a `Promise`, then `worker.evaluateHandle` would wait for the promise to resolve and return its value. Shortcut for `await worker.executionContext()).evaluateHandle(pageFunction, ...args)`
|
Evaluates a given function in the [worker](./puppeteer.webworker.md).
|
||||||
|
|
||||||
#### Signature:
|
#### Signature:
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ class WebWorker {
|
|||||||
Params extends unknown[],
|
Params extends unknown[],
|
||||||
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>,
|
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>,
|
||||||
>(
|
>(
|
||||||
pageFunction: Func | string,
|
func: Func | string,
|
||||||
...args: Params
|
...args: Params
|
||||||
): Promise<HandleFor<Awaited<ReturnType<Func>>>>;
|
): Promise<HandleFor<Awaited<ReturnType<Func>>>>;
|
||||||
}
|
}
|
||||||
@ -22,13 +22,19 @@ class WebWorker {
|
|||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
|
|
||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
| ------------ | -------------- | ----------------------------------------------- |
|
| --------- | -------------- | ----------------------------------------- |
|
||||||
| pageFunction | Func \| string | Function to be evaluated in the page context. |
|
| func | Func \| string | Function to be evaluated. |
|
||||||
| args | Params | Arguments to pass to <code>pageFunction</code>. |
|
| args | Params | Arguments to pass into <code>func</code>. |
|
||||||
|
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
|
||||||
Promise<[HandleFor](./puppeteer.handlefor.md)<Awaited<ReturnType<Func>>>>
|
Promise<[HandleFor](./puppeteer.handlefor.md)<Awaited<ReturnType<Func>>>>
|
||||||
|
|
||||||
Promise which resolves to the return value of `pageFunction`.
|
A [handle](./puppeteer.jshandle.md) to the return value of `func`.
|
||||||
|
|
||||||
|
## Remarks
|
||||||
|
|
||||||
|
If the given function returns a promise, [evaluate](./puppeteer.webworker.evaluate.md) will wait for the promise to resolve.
|
||||||
|
|
||||||
|
In general, you should use [evaluateHandle](./puppeteer.webworker.evaluatehandle.md) if [evaluate](./puppeteer.webworker.evaluate.md) cannot serialize the return value properly or you need a mutable [handle](./puppeteer.jshandle.md) to the return object.
|
||||||
|
@ -9,7 +9,7 @@ This class represents a [WebWorker](https://developer.mozilla.org/en-US/docs/Web
|
|||||||
#### Signature:
|
#### Signature:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
export declare class WebWorker extends EventEmitter<Record<EventType, unknown>>
|
export declare abstract class WebWorker extends EventEmitter<Record<EventType, unknown>>
|
||||||
```
|
```
|
||||||
|
|
||||||
**Extends:** [EventEmitter](./puppeteer.eventemitter.md)<Record<[EventType](./puppeteer.eventtype.md), unknown>>
|
**Extends:** [EventEmitter](./puppeteer.eventemitter.md)<Record<[EventType](./puppeteer.eventtype.md), unknown>>
|
||||||
@ -44,8 +44,8 @@ for (const worker of page.workers()) {
|
|||||||
|
|
||||||
## Methods
|
## Methods
|
||||||
|
|
||||||
| Method | Modifiers | Description |
|
| Method | Modifiers | Description |
|
||||||
| ----------------------------------------------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| --------------------------------------------------------------------- | --------- | --------------------------------------------------------------------- |
|
||||||
| [evaluate(pageFunction, args)](./puppeteer.webworker.evaluate.md) | | If the function passed to the <code>worker.evaluate</code> returns a Promise, then <code>worker.evaluate</code> would wait for the promise to resolve and return its value. If the function passed to the <code>worker.evaluate</code> returns a non-serializable value, then <code>worker.evaluate</code> resolves to <code>undefined</code>. DevTools Protocol also supports transferring some additional values that are not serializable by <code>JSON</code>: <code>-0</code>, <code>NaN</code>, <code>Infinity</code>, <code>-Infinity</code>, and bigint literals. Shortcut for <code>await worker.executionContext()).evaluate(pageFunction, ...args)</code>. |
|
| [evaluate(func, args)](./puppeteer.webworker.evaluate.md) | | Evaluates a given function in the [worker](./puppeteer.webworker.md). |
|
||||||
| [evaluateHandle(pageFunction, args)](./puppeteer.webworker.evaluatehandle.md) | | The only difference between <code>worker.evaluate</code> and <code>worker.evaluateHandle</code> is that <code>worker.evaluateHandle</code> returns in-page object (JSHandle). If the function passed to the <code>worker.evaluateHandle</code> returns a <code>Promise</code>, then <code>worker.evaluateHandle</code> would wait for the promise to resolve and return its value. Shortcut for <code>await worker.executionContext()).evaluateHandle(pageFunction, ...args)</code> |
|
| [evaluateHandle(func, args)](./puppeteer.webworker.evaluatehandle.md) | | Evaluates a given function in the [worker](./puppeteer.webworker.md). |
|
||||||
| [url()](./puppeteer.webworker.url.md) | | The URL of this web worker. |
|
| [url()](./puppeteer.webworker.url.md) | | The URL of this web worker. |
|
||||||
|
@ -46,7 +46,6 @@ import type {
|
|||||||
NetworkConditions,
|
NetworkConditions,
|
||||||
} from '../cdp/NetworkManager.js';
|
} from '../cdp/NetworkManager.js';
|
||||||
import type {Tracing} from '../cdp/Tracing.js';
|
import type {Tracing} from '../cdp/Tracing.js';
|
||||||
import type {WebWorker} from '../cdp/WebWorker.js';
|
|
||||||
import type {ConsoleMessage} from '../common/ConsoleMessage.js';
|
import type {ConsoleMessage} from '../common/ConsoleMessage.js';
|
||||||
import type {Device} from '../common/Device.js';
|
import type {Device} from '../common/Device.js';
|
||||||
import {TargetCloseError} from '../common/Errors.js';
|
import {TargetCloseError} from '../common/Errors.js';
|
||||||
@ -122,6 +121,7 @@ import {
|
|||||||
type AwaitedLocator,
|
type AwaitedLocator,
|
||||||
} from './locators/locators.js';
|
} from './locators/locators.js';
|
||||||
import type {Target} from './Target.js';
|
import type {Target} from './Target.js';
|
||||||
|
import type {WebWorker} from './WebWorker.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
|
@ -14,12 +14,11 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {Browser} from '../api/Browser.js';
|
import type {Browser} from './Browser.js';
|
||||||
import type {BrowserContext} from '../api/BrowserContext.js';
|
import type {BrowserContext} from './BrowserContext.js';
|
||||||
import type {Page} from '../api/Page.js';
|
|
||||||
import type {WebWorker} from '../cdp/WebWorker.js';
|
|
||||||
|
|
||||||
import type {CDPSession} from './CDPSession.js';
|
import type {CDPSession} from './CDPSession.js';
|
||||||
|
import type {Page} from './Page.js';
|
||||||
|
import type {WebWorker} from './WebWorker.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
|
144
packages/puppeteer-core/src/api/WebWorker.ts
Normal file
144
packages/puppeteer-core/src/api/WebWorker.ts
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2018 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {EventEmitter, type EventType} from '../common/EventEmitter.js';
|
||||||
|
import {TimeoutSettings} from '../common/TimeoutSettings.js';
|
||||||
|
import type {EvaluateFunc, HandleFor} from '../common/types.js';
|
||||||
|
import {withSourcePuppeteerURLIfNone} from '../common/util.js';
|
||||||
|
|
||||||
|
import type {CDPSession} from './CDPSession.js';
|
||||||
|
import type {Realm} from './Realm.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a
|
||||||
|
* {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API | WebWorker}.
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* The events `workercreated` and `workerdestroyed` are emitted on the page
|
||||||
|
* object to signal the worker lifecycle.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
*
|
||||||
|
* ```ts
|
||||||
|
* page.on('workercreated', worker =>
|
||||||
|
* console.log('Worker created: ' + worker.url())
|
||||||
|
* );
|
||||||
|
* page.on('workerdestroyed', worker =>
|
||||||
|
* console.log('Worker destroyed: ' + worker.url())
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* console.log('Current workers:');
|
||||||
|
* for (const worker of page.workers()) {
|
||||||
|
* console.log(' ' + worker.url());
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export abstract class WebWorker extends EventEmitter<
|
||||||
|
Record<EventType, unknown>
|
||||||
|
> {
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
readonly timeoutSettings = new TimeoutSettings();
|
||||||
|
|
||||||
|
readonly #url: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
constructor(url: string) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.#url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
abstract mainRealm(): Realm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URL of this web worker.
|
||||||
|
*/
|
||||||
|
url(): string {
|
||||||
|
return this.#url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The CDP session client the WebWorker belongs to.
|
||||||
|
*/
|
||||||
|
abstract get client(): CDPSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluates a given function in the {@link WebWorker | worker}.
|
||||||
|
*
|
||||||
|
* @remarks If the given function returns a promise,
|
||||||
|
* {@link WebWorker.evaluate | evaluate} will wait for the promise to resolve.
|
||||||
|
*
|
||||||
|
* As a rule of thumb, if the return value of the given function is more
|
||||||
|
* complicated than a JSON object (e.g. most classes), then
|
||||||
|
* {@link WebWorker.evaluate | evaluate} will _likely_ return some truncated
|
||||||
|
* value (or `{}`). This is because we are not returning the actual return
|
||||||
|
* value, but a deserialized version as a result of transferring the return
|
||||||
|
* value through a protocol to Puppeteer.
|
||||||
|
*
|
||||||
|
* In general, you should use
|
||||||
|
* {@link WebWorker.evaluateHandle | evaluateHandle} if
|
||||||
|
* {@link WebWorker.evaluate | evaluate} cannot serialize the return value
|
||||||
|
* properly or you need a mutable {@link JSHandle | handle} to the return
|
||||||
|
* object.
|
||||||
|
*
|
||||||
|
* @param func - Function to be evaluated.
|
||||||
|
* @param args - Arguments to pass into `func`.
|
||||||
|
* @returns The result of `func`.
|
||||||
|
*/
|
||||||
|
async evaluate<
|
||||||
|
Params extends unknown[],
|
||||||
|
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>,
|
||||||
|
>(func: Func | string, ...args: Params): Promise<Awaited<ReturnType<Func>>> {
|
||||||
|
func = withSourcePuppeteerURLIfNone(this.evaluate.name, func);
|
||||||
|
return await this.mainRealm().evaluate(func, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluates a given function in the {@link WebWorker | worker}.
|
||||||
|
*
|
||||||
|
* @remarks If the given function returns a promise,
|
||||||
|
* {@link WebWorker.evaluate | evaluate} will wait for the promise to resolve.
|
||||||
|
*
|
||||||
|
* In general, you should use
|
||||||
|
* {@link WebWorker.evaluateHandle | evaluateHandle} if
|
||||||
|
* {@link WebWorker.evaluate | evaluate} cannot serialize the return value
|
||||||
|
* properly or you need a mutable {@link JSHandle | handle} to the return
|
||||||
|
* object.
|
||||||
|
*
|
||||||
|
* @param func - Function to be evaluated.
|
||||||
|
* @param args - Arguments to pass into `func`.
|
||||||
|
* @returns A {@link JSHandle | handle} to the return value of `func`.
|
||||||
|
*/
|
||||||
|
async evaluateHandle<
|
||||||
|
Params extends unknown[],
|
||||||
|
Func extends EvaluateFunc<Params> = EvaluateFunc<Params>,
|
||||||
|
>(
|
||||||
|
func: Func | string,
|
||||||
|
...args: Params
|
||||||
|
): Promise<HandleFor<Awaited<ReturnType<Func>>>> {
|
||||||
|
func = withSourcePuppeteerURLIfNone(this.evaluateHandle.name, func);
|
||||||
|
return await this.mainRealm().evaluateHandle(func, ...args);
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
export * from './Browser.js';
|
export * from './Browser.js';
|
||||||
export * from './BrowserContext.js';
|
export * from './BrowserContext.js';
|
||||||
|
export * from './CDPSession.js';
|
||||||
export * from './Dialog.js';
|
export * from './Dialog.js';
|
||||||
export * from './ElementHandle.js';
|
export * from './ElementHandle.js';
|
||||||
export * from './Environment.js';
|
export * from './Environment.js';
|
||||||
@ -24,8 +25,8 @@ export * from './HTTPRequest.js';
|
|||||||
export * from './HTTPResponse.js';
|
export * from './HTTPResponse.js';
|
||||||
export * from './Input.js';
|
export * from './Input.js';
|
||||||
export * from './JSHandle.js';
|
export * from './JSHandle.js';
|
||||||
export * from './locators/locators.js';
|
|
||||||
export * from './Page.js';
|
export * from './Page.js';
|
||||||
export * from './Realm.js';
|
export * from './Realm.js';
|
||||||
export * from './Target.js';
|
export * from './Target.js';
|
||||||
export * from './CDPSession.js';
|
export * from './WebWorker.js';
|
||||||
|
export * from './locators/locators.js';
|
||||||
|
@ -34,7 +34,7 @@ import type {Binding} from './Binding.js';
|
|||||||
import {ExecutionContext, createCdpHandle} from './ExecutionContext.js';
|
import {ExecutionContext, createCdpHandle} from './ExecutionContext.js';
|
||||||
import type {CdpFrame} from './Frame.js';
|
import type {CdpFrame} from './Frame.js';
|
||||||
import type {MAIN_WORLD, PUPPETEER_WORLD} from './IsolatedWorlds.js';
|
import type {MAIN_WORLD, PUPPETEER_WORLD} from './IsolatedWorlds.js';
|
||||||
import type {WebWorker} from './WebWorker.js';
|
import type {CdpWebWorker} from './WebWorker.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
@ -69,10 +69,10 @@ export class IsolatedWorld extends Realm {
|
|||||||
return this.#bindings;
|
return this.#bindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly #frameOrWorker: CdpFrame | WebWorker;
|
readonly #frameOrWorker: CdpFrame | CdpWebWorker;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
frameOrWorker: CdpFrame | WebWorker,
|
frameOrWorker: CdpFrame | CdpWebWorker,
|
||||||
timeoutSettings: TimeoutSettings
|
timeoutSettings: TimeoutSettings
|
||||||
) {
|
) {
|
||||||
super(timeoutSettings);
|
super(timeoutSettings);
|
||||||
@ -80,7 +80,7 @@ export class IsolatedWorld extends Realm {
|
|||||||
this.frameUpdated();
|
this.frameUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
get environment(): CdpFrame | WebWorker {
|
get environment(): CdpFrame | CdpWebWorker {
|
||||||
return this.#frameOrWorker;
|
return this.#frameOrWorker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ import type {CdpTarget} from './Target.js';
|
|||||||
import type {TargetManager} from './TargetManager.js';
|
import type {TargetManager} from './TargetManager.js';
|
||||||
import {TargetManagerEvent} from './TargetManager.js';
|
import {TargetManagerEvent} from './TargetManager.js';
|
||||||
import {Tracing} from './Tracing.js';
|
import {Tracing} from './Tracing.js';
|
||||||
import {WebWorker} from './WebWorker.js';
|
import {CdpWebWorker} from './WebWorker.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
@ -133,7 +133,7 @@ export class CdpPage extends Page {
|
|||||||
#exposedFunctions = new Map<string, string>();
|
#exposedFunctions = new Map<string, string>();
|
||||||
#coverage: Coverage;
|
#coverage: Coverage;
|
||||||
#viewport: Viewport | null;
|
#viewport: Viewport | null;
|
||||||
#workers = new Map<string, WebWorker>();
|
#workers = new Map<string, CdpWebWorker>();
|
||||||
#fileChooserDeferreds = new Set<Deferred<FileChooser>>();
|
#fileChooserDeferreds = new Set<Deferred<FileChooser>>();
|
||||||
#sessionCloseDeferred = Deferred.create<never, TargetCloseError>();
|
#sessionCloseDeferred = Deferred.create<never, TargetCloseError>();
|
||||||
#serviceWorkerBypassed = false;
|
#serviceWorkerBypassed = false;
|
||||||
@ -352,7 +352,7 @@ export class CdpPage extends Page {
|
|||||||
assert(session instanceof CdpCDPSession);
|
assert(session instanceof CdpCDPSession);
|
||||||
this.#frameManager.onAttachedToTarget(session._target());
|
this.#frameManager.onAttachedToTarget(session._target());
|
||||||
if (session._target()._getTargetInfo().type === 'worker') {
|
if (session._target()._getTargetInfo().type === 'worker') {
|
||||||
const worker = new WebWorker(
|
const worker = new CdpWebWorker(
|
||||||
session,
|
session,
|
||||||
session._target().url(),
|
session._target().url(),
|
||||||
this.#addConsoleMessage.bind(this),
|
this.#addConsoleMessage.bind(this),
|
||||||
@ -512,7 +512,7 @@ export class CdpPage extends Page {
|
|||||||
return this.#frameManager.frames();
|
return this.#frameManager.frames();
|
||||||
}
|
}
|
||||||
|
|
||||||
override workers(): WebWorker[] {
|
override workers(): CdpWebWorker[] {
|
||||||
return Array.from(this.#workers.values());
|
return Array.from(this.#workers.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ import {Deferred} from '../util/Deferred.js';
|
|||||||
import {CdpCDPSession} from './CDPSession.js';
|
import {CdpCDPSession} from './CDPSession.js';
|
||||||
import {CdpPage} from './Page.js';
|
import {CdpPage} from './Page.js';
|
||||||
import type {TargetManager} from './TargetManager.js';
|
import type {TargetManager} from './TargetManager.js';
|
||||||
import {WebWorker} from './WebWorker.js';
|
import {CdpWebWorker} from './WebWorker.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
@ -276,9 +276,9 @@ export class DevToolsTarget extends PageTarget {}
|
|||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export class WorkerTarget extends CdpTarget {
|
export class WorkerTarget extends CdpTarget {
|
||||||
#workerPromise?: Promise<WebWorker>;
|
#workerPromise?: Promise<CdpWebWorker>;
|
||||||
|
|
||||||
override async worker(): Promise<WebWorker | null> {
|
override async worker(): Promise<CdpWebWorker | null> {
|
||||||
if (!this.#workerPromise) {
|
if (!this.#workerPromise) {
|
||||||
const session = this._session();
|
const session = this._session();
|
||||||
// TODO(einbinder): Make workers send their console logs.
|
// TODO(einbinder): Make workers send their console logs.
|
||||||
@ -287,7 +287,7 @@ export class WorkerTarget extends CdpTarget {
|
|||||||
? Promise.resolve(session)
|
? Promise.resolve(session)
|
||||||
: this._sessionFactory()(/* isAutoAttachEmulated=*/ false)
|
: this._sessionFactory()(/* isAutoAttachEmulated=*/ false)
|
||||||
).then(client => {
|
).then(client => {
|
||||||
return new WebWorker(
|
return new CdpWebWorker(
|
||||||
client,
|
client,
|
||||||
this._getTargetInfo().url,
|
this._getTargetInfo().url,
|
||||||
() => {} /* consoleAPICalled */,
|
() => {} /* consoleAPICalled */,
|
||||||
|
@ -17,11 +17,10 @@ import type {Protocol} from 'devtools-protocol';
|
|||||||
|
|
||||||
import type {CDPSession} from '../api/CDPSession.js';
|
import type {CDPSession} from '../api/CDPSession.js';
|
||||||
import type {Realm} from '../api/Realm.js';
|
import type {Realm} from '../api/Realm.js';
|
||||||
|
import {WebWorker} from '../api/WebWorker.js';
|
||||||
import type {ConsoleMessageType} from '../common/ConsoleMessage.js';
|
import type {ConsoleMessageType} from '../common/ConsoleMessage.js';
|
||||||
import {EventEmitter, type EventType} from '../common/EventEmitter.js';
|
|
||||||
import {TimeoutSettings} from '../common/TimeoutSettings.js';
|
import {TimeoutSettings} from '../common/TimeoutSettings.js';
|
||||||
import type {EvaluateFunc, HandleFor} from '../common/types.js';
|
import {debugError} from '../common/util.js';
|
||||||
import {debugError, withSourcePuppeteerURLIfNone} from '../common/util.js';
|
|
||||||
|
|
||||||
import {ExecutionContext} from './ExecutionContext.js';
|
import {ExecutionContext} from './ExecutionContext.js';
|
||||||
import {IsolatedWorld} from './IsolatedWorld.js';
|
import {IsolatedWorld} from './IsolatedWorld.js';
|
||||||
@ -44,53 +43,20 @@ export type ExceptionThrownCallback = (
|
|||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represents a
|
* @internal
|
||||||
* {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API | WebWorker}.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* The events `workercreated` and `workerdestroyed` are emitted on the page
|
|
||||||
* object to signal the worker lifecycle.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
*
|
|
||||||
* ```ts
|
|
||||||
* page.on('workercreated', worker =>
|
|
||||||
* console.log('Worker created: ' + worker.url())
|
|
||||||
* );
|
|
||||||
* page.on('workerdestroyed', worker =>
|
|
||||||
* console.log('Worker destroyed: ' + worker.url())
|
|
||||||
* );
|
|
||||||
*
|
|
||||||
* console.log('Current workers:');
|
|
||||||
* for (const worker of page.workers()) {
|
|
||||||
* console.log(' ' + worker.url());
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @public
|
|
||||||
*/
|
*/
|
||||||
export class WebWorker extends EventEmitter<Record<EventType, unknown>> {
|
export class CdpWebWorker extends WebWorker {
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
readonly timeoutSettings = new TimeoutSettings();
|
|
||||||
|
|
||||||
#world: IsolatedWorld;
|
#world: IsolatedWorld;
|
||||||
#client: CDPSession;
|
#client: CDPSession;
|
||||||
#url: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
constructor(
|
constructor(
|
||||||
client: CDPSession,
|
client: CDPSession,
|
||||||
url: string,
|
url: string,
|
||||||
consoleAPICalled: ConsoleAPICalledCallback,
|
consoleAPICalled: ConsoleAPICalledCallback,
|
||||||
exceptionThrown: ExceptionThrownCallback
|
exceptionThrown: ExceptionThrownCallback
|
||||||
) {
|
) {
|
||||||
super();
|
super(url);
|
||||||
this.#client = client;
|
this.#client = client;
|
||||||
this.#url = url;
|
|
||||||
this.#world = new IsolatedWorld(this, new TimeoutSettings());
|
this.#world = new IsolatedWorld(this, new TimeoutSettings());
|
||||||
|
|
||||||
this.#client.once('Runtime.executionContextCreated', async event => {
|
this.#client.once('Runtime.executionContextCreated', async event => {
|
||||||
@ -117,78 +83,11 @@ export class WebWorker extends EventEmitter<Record<EventType, unknown>> {
|
|||||||
this.#client.send('Runtime.enable').catch(debugError);
|
this.#client.send('Runtime.enable').catch(debugError);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
mainRealm(): Realm {
|
mainRealm(): Realm {
|
||||||
return this.#world;
|
return this.#world;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The URL of this web worker.
|
|
||||||
*/
|
|
||||||
url(): string {
|
|
||||||
return this.#url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The CDP session client the WebWorker belongs to.
|
|
||||||
*/
|
|
||||||
get client(): CDPSession {
|
get client(): CDPSession {
|
||||||
return this.#client;
|
return this.#client;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* If the function passed to the `worker.evaluate` returns a Promise, then
|
|
||||||
* `worker.evaluate` would wait for the promise to resolve and return its
|
|
||||||
* value. If the function passed to the `worker.evaluate` returns a
|
|
||||||
* non-serializable value, then `worker.evaluate` resolves to `undefined`.
|
|
||||||
* DevTools Protocol also supports transferring some additional values that
|
|
||||||
* are not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`, and
|
|
||||||
* bigint literals.
|
|
||||||
* Shortcut for `await worker.executionContext()).evaluate(pageFunction, ...args)`.
|
|
||||||
*
|
|
||||||
* @param pageFunction - Function to be evaluated in the worker context.
|
|
||||||
* @param args - Arguments to pass to `pageFunction`.
|
|
||||||
* @returns Promise which resolves to the return value of `pageFunction`.
|
|
||||||
*/
|
|
||||||
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 await this.mainRealm().evaluate(pageFunction, ...args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The only difference between `worker.evaluate` and `worker.evaluateHandle`
|
|
||||||
* is that `worker.evaluateHandle` returns in-page object (JSHandle). If the
|
|
||||||
* function passed to the `worker.evaluateHandle` returns a `Promise`, then
|
|
||||||
* `worker.evaluateHandle` would wait for the promise to resolve and return
|
|
||||||
* its value. Shortcut for
|
|
||||||
* `await worker.executionContext()).evaluateHandle(pageFunction, ...args)`
|
|
||||||
*
|
|
||||||
* @param pageFunction - Function to be evaluated in the page context.
|
|
||||||
* @param args - Arguments to pass to `pageFunction`.
|
|
||||||
* @returns Promise which resolves to the return value of `pageFunction`.
|
|
||||||
*/
|
|
||||||
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 await this.mainRealm().evaluateHandle(pageFunction, ...args);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import expect from 'expect';
|
import expect from 'expect';
|
||||||
import type {WebWorker} from 'puppeteer-core/internal/cdp/WebWorker.js';
|
import type {WebWorker} from 'puppeteer-core/internal/api/WebWorker.js';
|
||||||
import type {ConsoleMessage} from 'puppeteer-core/internal/common/ConsoleMessage.js';
|
import type {ConsoleMessage} from 'puppeteer-core/internal/common/ConsoleMessage.js';
|
||||||
|
|
||||||
import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
|
import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
|
||||||
|
Loading…
Reference in New Issue
Block a user