Implementation:Puppeteer Puppeteer Cdp FrameManager
| Property | Value |
|---|---|
| sources | packages/puppeteer-core/src/cdp/FrameManager.ts |
| domains | Frame Tree, Navigation, Lifecycle, CDP |
| last_updated | 2026-02-12 00:00 GMT |
Overview
Description
The FrameManager class is the central coordinator for all frame-related operations within a CDP page. It manages the frame tree, handles frame lifecycle events, creates execution contexts, and coordinates with the NetworkManager for network operations.
Key responsibilities include:
- Frame tree management -- Maintaining a
FrameTreedata structure that tracks all frames. Handles frame attachment, detachment, and navigation events from CDP. - CDP event handling -- Listening to CDP events including
Page.frameAttached,Page.frameNavigated,Page.navigatedWithinDocument,Page.frameDetached,Page.frameStartedLoading,Page.frameStoppedLoading,Runtime.executionContextCreated, andPage.lifecycleEvent. - Execution context creation -- Creating
ExecutionContextinstances when CDP reports new execution contexts, and assigning them to the appropriateIsolatedWorld(MAIN_WORLD or PUPPETEER_WORLD). - Isolated world management -- Creating the Puppeteer utility isolated world (
__puppeteer_utility_world__) viaPage.addScriptToEvaluateOnNewDocumentandPage.createIsolatedWorld. - Frame swap handling -- Supporting frame tree swaps during cross-process navigations and prerendered page activations, maintaining frame identity across swaps.
- Preload scripts and bindings -- Managing scripts to evaluate on new documents and exposed function bindings across all frames.
- Network management -- Owning a
NetworkManagerinstance that handles request interception, headers, authentication, etc. - Device request prompts -- Managing
CdpDeviceRequestPromptManagerinstances per CDP session. - OOP iframe support -- Handling out-of-process iframe attachment by setting up event listeners on child target sessions.
- Client disconnect recovery -- Waiting for frame swap events after client disconnect, with a 100ms timeout before removing frames.
Usage
The FrameManager is created internally by CdpPage and is not directly exposed to users. Users interact with frames through the Page and Frame APIs.
Code Reference
Source Location: packages/puppeteer-core/src/cdp/FrameManager.ts (582 lines)
Signature:
export class FrameManager extends EventEmitter<FrameManagerEvents> {
constructor(client: CdpCDPSession, page: CdpPage, timeoutSettings: TimeoutSettings);
get timeoutSettings(): TimeoutSettings;
get networkManager(): NetworkManager;
get client(): CdpCDPSession;
async initialize(client: CDPSession, frame?: CdpFrame | null): Promise<void>;
async swapFrameTree(client: CdpCDPSession): Promise<void>;
async registerSpeculativeSession(client: CdpCDPSession): Promise<void>;
page(): CdpPage;
mainFrame(): CdpFrame;
frames(): CdpFrame[];
frame(frameId: string): CdpFrame | null;
async addExposedFunctionBinding(binding: Binding): Promise<void>;
async removeExposedFunctionBinding(binding: Binding): Promise<void>;
async evaluateOnNewDocument(source: string): Promise<NewDocumentScriptEvaluation>;
async removeScriptToEvaluateOnNewDocument(identifier: string): Promise<void>;
onAttachedToTarget(target: CdpTarget): void;
}
Import:
import { FrameManager } from 'puppeteer-core/lib/cdp/FrameManager.js';
I/O Contract
Inputs:
| Parameter | Type | Required | Description |
|---|---|---|---|
| client | CdpCDPSession |
Yes | The CDP session for the page |
| page | CdpPage |
Yes | The parent page |
| timeoutSettings | TimeoutSettings |
Yes | Timeout configuration for navigation and other operations |
| frameId | string |
Yes | Frame ID for frame lookup |
| source | string |
Yes | JavaScript source for preload scripts |
Outputs:
| Output | Type | Description |
|---|---|---|
| mainFrame() | CdpFrame |
The main frame of the page |
| frames() | CdpFrame[] |
All frames in the frame tree |
| frame() | null | A frame by its ID, or null |
| evaluateOnNewDocument() | Promise<{identifier: string}> |
The identifier for the registered preload script |
Usage Examples
// Access frames via the Page API (delegates to FrameManager)
const mainFrame = page.mainFrame();
const allFrames = page.frames();
// Find a specific frame by URL
const targetFrame = page.frames().find(frame => frame.url().includes('iframe-content'));
// Find a frame by ID
const frame = page.frames().find(f => f._id === someFrameId);
// Register a script to evaluate on every new document
const { identifier } = await page.evaluateOnNewDocument(() => {
window.__myGlobal = 'initialized';
});
// Remove the preload script
await page.removeScriptToEvaluateOnNewDocument(identifier);
// Expose a function (bindings are managed through FrameManager)
await page.exposeFunction('myFunc', (arg) => {
return `processed: ${arg}`;
});