Implementation:Puppeteer Puppeteer Bidi Realm
| Property | Value |
|---|---|
| Implementation | BidiRealm, BidiFrameRealm, BidiWorkerRealm |
| Source File | packages/puppeteer-core/src/bidi/Realm.ts
|
| Repository | puppeteer/puppeteer |
| Lines | 410 |
| License | Apache-2.0 |
| Copyright | 2024 Google Inc. |
Overview
Description
This module provides the WebDriver BiDi implementation of Puppeteer's JavaScript execution realm abstraction. It defines three classes:
BidiRealm (abstract) is the base class that wraps a low-level BiDi Realm core object and implements the core JavaScript evaluation capabilities:
evaluate()-- Evaluates a function or expression in the realm and returns the result by value (deserialized).evaluateHandle()-- Evaluates a function or expression and returns a handle (remote reference) to the result, allowing further interaction without serialization.createHandle()-- Creates aBidiJSHandleorBidiElementHandlefrom a BiDiRemoteValue. Node-type results in aBidiFrameRealmproduce element handles; all others produce JS handles.serialize()/serializeAsync()-- Serializes arguments for function calls. HandlesBidiJSHandle,BidiElementHandle, andLazyArgtypes, with validation that handles belong to the correct realm and environment.destroyHandles()-- Releases remote object handles viascript.disown.adoptHandle()/transferHandle()-- Moves handles between realms.puppeteerUtil-- Lazily injects and caches Puppeteer's internal utility script.
The realm listens for destroyed events (terminating pending tasks) and updated events (invalidating cached utilities and re-running tasks).
BidiFrameRealm extends BidiRealm for window contexts (page frames). It:
- Wraps a
WindowRealmcore object. - Installs ARIA query selector bindings (
__ariaQuerySelector,__ariaQuerySelectorAll) on the realm whenpuppeteerUtilis first accessed. - Clears document handles and binding state on realm updates (navigations).
- Implements
adoptBackendNode()for resolving CDP backend node IDs to element handles. - Exposes
sandboxandenvironment(the parentBidiFrame).
BidiWorkerRealm extends BidiRealm for dedicated and shared worker contexts. It wraps a DedicatedWorkerRealm or SharedWorkerRealm and exposes the parent BidiWebWorker as its environment. adoptBackendNode() throws since DOM nodes cannot exist in worker contexts.
Usage
Realm instances are created internally. BidiFrameRealm instances are created by BidiFrame (one default realm and one internal sandboxed realm per frame). BidiWorkerRealm instances are created by BidiWebWorker. Users interact with realms indirectly through frame.evaluate(), frame.evaluateHandle(), and related APIs.
Code Reference
Source Location
packages/puppeteer-core/src/bidi/Realm.ts (GitHub)
Signature
export abstract class BidiRealm extends Realm {
readonly realm: BidiRealmCore;
constructor(realm: BidiRealmCore, timeoutSettings: TimeoutSettings);
protected initialize(): void;
get puppeteerUtil(): Promise<BidiJSHandle<PuppeteerInjectedUtil>>;
override async evaluateHandle<Params, Func>(
pageFunction: Func | string, ...args: Params
): Promise<HandleFor<Awaited<ReturnType<Func>>>>;
override async evaluate<Params, Func>(
pageFunction: Func | string, ...args: Params
): Promise<Awaited<ReturnType<Func>>>;
createHandle(result: Bidi.Script.RemoteValue): BidiJSHandle<unknown> | BidiElementHandle<Node>;
serialize(arg: unknown): Bidi.Script.LocalValue;
async serializeAsync(arg: unknown): Promise<Bidi.Script.LocalValue>;
async destroyHandles(handles: Array<BidiJSHandle<unknown>>): Promise<void>;
override async adoptHandle<T extends JSHandle<Node>>(handle: T): Promise<T>;
override async transferHandle<T extends JSHandle<Node>>(handle: T): Promise<T>;
}
export class BidiFrameRealm extends BidiRealm {
static from(realm: WindowRealm, frame: BidiFrame): BidiFrameRealm;
declare readonly realm: WindowRealm;
get sandbox(): string | undefined;
override get environment(): BidiFrame;
override async adoptBackendNode(backendNodeId?: number): Promise<JSHandle<Node>>;
}
export class BidiWorkerRealm extends BidiRealm {
static from(
realm: DedicatedWorkerRealm | SharedWorkerRealm, worker: BidiWebWorker
): BidiWorkerRealm;
declare readonly realm: DedicatedWorkerRealm | SharedWorkerRealm;
override get environment(): BidiWebWorker;
override async adoptBackendNode(): Promise<JSHandle<Node>>; // throws
}
Import
import {BidiRealm, BidiFrameRealm, BidiWorkerRealm} from './Realm.js';
I/O Contract
Inputs
| Parameter | Type | Description |
|---|---|---|
| realm | BidiRealmCore |
The low-level BiDi realm (WindowRealm, DedicatedWorkerRealm, or SharedWorkerRealm) |
| timeoutSettings | TimeoutSettings |
Timeout configuration for the realm |
| frame (BidiFrameRealm) | BidiFrame |
The frame this realm belongs to |
| worker (BidiWorkerRealm) | BidiWebWorker |
The worker this realm belongs to |
Key Method Parameters
| Method | Parameter | Type | Description |
|---|---|---|---|
| evaluate / evaluateHandle | pageFunction | string | The function or expression to evaluate |
| evaluate / evaluateHandle | args | unknown[] |
Arguments passed to the function |
| serialize | arg | unknown |
A value to serialize for BiDi, including JSHandles, ElementHandles, or plain values |
| destroyHandles | handles | BidiJSHandle[] |
Handles to release |
| adoptBackendNode | backendNodeId | number |
CDP backend node ID to resolve |
Outputs
| Method | Return Type | Description |
|---|---|---|
| evaluate | Promise<T> |
The deserialized return value of the evaluated function |
| evaluateHandle | Promise<HandleFor<T>> |
A handle to the return value (not serialized) |
| createHandle | BidiElementHandle | A handle wrapping the remote value |
| serialize | Bidi.Script.LocalValue |
Serialized BiDi local value |
| puppeteerUtil | Promise<BidiJSHandle<PuppeteerInjectedUtil>> |
Handle to Puppeteer's injected utility object |
Usage Examples
// Evaluate an expression in the page (returns value)
const title = await page.mainFrame().evaluate(() => {
return document.title;
});
// Evaluate and get a handle (returns remote reference)
const bodyHandle = await page.mainFrame().evaluateHandle(() => {
return document.body;
});
// Use a handle as an argument
const innerHTML = await page.mainFrame().evaluate((body) => {
return body.innerHTML;
}, bodyHandle);
// Dispose of a handle when done
await bodyHandle.dispose();
// Evaluate in an isolated realm (internal realm)
// (Used internally by Puppeteer for utility operations)