Doramagic Project Pack · Human Manual
puppeteer
Puppeteer is a Node.js library that provides a high-level API to control Chrome, Firefox, or other browsers via the DevTools Protocol and WebDriver BiDi. It enables developers to automate ...
Getting Started
Related topics: System Architecture
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: System Architecture
Getting Started
Overview
Puppeteer is a Node.js library that provides a high-level API to control Chrome, Firefox, or other browsers via the DevTools Protocol and WebDriver BiDi. It enables developers to automate browser tasks programmatically, including web scraping, page interactions, performance monitoring, and automated testing.
This guide covers the essential steps to install, configure, and run your first Puppeteer script.
Installation
Prerequisites
| Requirement | Details |
|---|---|
| Node.js | Compatible version specified in package.json engines field |
| Package Manager | npm, yarn, or pnpm |
| System Dependencies | OS-specific tools (see below) |
System Requirements by Browser
For Firefox downloads:
- Linux builds:
xzandbzip2utilities required for.tar.gzand.tar.bz2archives - MacOS builds:
hdiutilrequired for.dmgarchives
For Chrome downloads:
- Linux/MacOS:
unzip - Windows:
tar.exe
Installing Puppeteer
There are two primary packages available:
# Full package - downloads compatible Chrome during installation
npm i puppeteer
# Core package - library only, without downloading Chrome
npm i puppeteer-core
When installing puppeteer, the installation script (install.mjs) automatically downloads a compatible Chrome binary for your platform. The puppeteer-core package is designed for scenarios where you already have a browser installation or want to use a custom browser path.
Using Alternative Package Managers
Puppeteer supports installation via different package managers:
# Using npm
npm i puppeteer
# Using yarn
yarn add puppeteer
# Using pnpm
pnpm add puppeteer
Quick Start Example
The following example demonstrates a complete workflow: launching a browser, navigating to a page, interacting with elements, and extracting data.
import puppeteer from 'puppeteer';
// Or import puppeteer from 'puppeteer-core';
// Launch the browser and open a new blank page
const browser = await puppeteer.launch();
const page = await browser.newPage();
// Navigate the page to a URL
await page.goto('https://developer.chrome.com/');
// Set the screen size
await page.setViewport({width: 1080, height: 1024});
// Open the search menu using the keyboard
await page.keyboard.press('/');
// Type into search box using accessible input name
await page.locator('::-p-aria(Search)').fill('automate beyond recorder');
// Wait and click on first result
await page.locator('.devsite-result-item-link').click();
// Locate the full title with a unique string
const textSelector = await page
.locator('::-p-text(Customize and automate)')
.waitHandle();
const fullTitle = await textSelector?.evaluate(el => el.textContent);
// Print the full title
console.log('The title of this blog post is "%s".', fullTitle);
await browser.close();
Sources: README.md:1-40
Browser Launch Configuration
Basic Launch Options
The puppeteer.launch() method accepts a configuration object:
| Parameter | Type | Default | Description | |
|---|---|---|---|---|
headless | `boolean \ | 'new'` | true | Run browser in headless mode |
executablePath | string | auto-detected | Path to browser executable | |
args | string[] | [] | Additional CLI arguments | |
protocolTimeout | number | 30000 | Protocol timeout in ms |
Common Launch Arguments
const browser = await puppeteer.launch({
headless: false,
args: [
'--no-sandbox', // Required for some container environments
'--disable-setuid-sandbox',
'--disable-dev-shm-usage'
]
});
Core Concepts
Page Navigation
The page.goto() method navigates to a specified URL:
await page.goto('https://example.com', {
waitUntil: 'networkidle2' // Wait until network is idle
});
Viewport Configuration
Control the visible area of the page:
await page.setViewport({
width: 1920,
height: 1080,
deviceScaleFactor: 2 // For high-DPI screenshots
});
Locators
Puppeteer provides a locator-based API for waiting and interacting with elements:
| Selector Type | Example | Description |
|---|---|---|
| CSS | 'div.class-name' | Standard CSS selector |
| Text | '::-p-text(Content)' | Match by visible text |
| ARIA | '::-p-aria(Role)' | Accessible ARIA selector |
| XPath | '::-p-xpath(//div)' | XPath expression |
| Shadow DOM | Combined selectors | Query across shadow roots |
Sources: packages/puppeteer-core/src/api/locators/locators.ts:1-50
Evaluating JavaScript in Page Context
Execute code within the browser environment:
// Simple evaluation
const title = await page.evaluate(() => document.title);
// With arguments
const links = await page.evaluate(
(maxCount) => {
return Array.from(document.querySelectorAll('a'))
.slice(0, maxCount)
.map(a => a.href);
},
10 // maxCount argument
);
// Handle evaluation for complex objects
const handle = await page.evaluateHandle(() => document.body);
Sources: packages/puppeteer-core/src/api/Page.ts:1-60
Exposing Functions to the Page
Expose Node.js functions to be called from browser context:
import fs from 'node:fs';
await page.exposeFunction('readfile', async filePath => {
return new Promise((resolve, reject) => {
fs.readFile(filePath, 'utf8', (err, text) => {
if (err) reject(err);
else resolve(text);
});
});
});
// Now callable from page context
await page.evaluate(async () => {
const content = await window.readfile('/etc/hosts');
console.log(content);
});
Sources: packages/puppeteer-core/src/api/Page.ts:1-35
Workflow Diagram
graph TD
A[Start] --> B[Install Puppeteer]
B --> C[puppeteer.launch]
C --> D[Create Page]
D --> E[Configure Viewport]
E --> F[Navigate to URL]
F --> G{Interact with Page}
G -->|Click| H[Locate Element]
G -->|Type| I[Fill Input]
G -->|Extract| J[Evaluate JavaScript]
H --> K[Perform Action]
I --> K
J --> L[Extract Data]
K --> M{More Actions?}
M -->|Yes| G
M -->|No| N[Close Browser]
L --> NMedia Emulation
Emulate Media Types
Test how pages render under different media conditions:
await page.emulateMediaType('print');
// Now matchMedia queries return print styles
await page.evaluate(() => matchMedia('print').matches); // true
// Reset to default
await page.emulateMediaType(null);
Emulate CSS Media Features
await page.emulateMediaFeatures([
{name: 'prefers-color-scheme', value: 'dark'},
{name: 'prefers-color-scheme', value: 'light'}
]);
CPU Throttling
Emulate slow devices for performance testing:
// 2x slowdown
await page.emulateCPUThrottling(2);
// Disable throttling
await page.emulateCPUThrottling(null);
Sources: packages/puppeteer-core/src/api/Page.ts:1-30
Browser Management CLI
The @puppeteer/browsers package provides CLI tools for managing browser installations:
# List installed browsers
npx @puppeteer/browsers list
# Clear all installed browsers
npx @puppeteer/browsers clear
# Install specific versions
npx @puppeteer/browsers install chrome@stable
npx @puppeteer/browsers install chromedriver@116
# Install specific milestone
npx @puppeteer/browsers install chrome@117
Sources: packages/browsers/README.md:1-50
Docker Usage
Puppeteer can be containerized for CI/CD environments:
Building the Image
docker build -t puppeteer-chrome-linux .
Running with Docker
docker run -i --init --rm \
--cap-add=SYS_ADMIN \
--name puppeteer-chrome \
puppeteer-chrome-linux \
node -e "`cat test/smoke-test.js`"
Note: The --cap-add=SYS_ADMIN capability enables Chrome sandbox for enhanced security. Alternatively, start with --no-sandbox flag.
Sources: docker/README.md:1-30
Debugging
Enable debug logging to troubleshoot issues:
// Enable specific channel
window.__PUPPETEER_DEBUG='Page';
// Enable all channels
window.__PUPPETEER_DEBUG='*';
// Enable pattern matching
window.__PUPPETEER_DEBUG='foo*'; // Matches 'foo', 'foobar', etc.
In Node.js environment:
import {debug} from './common/Debug.js';
const log = debug('Page');
log('new page created');
// Output: "Page: new page created"
Sources: packages/puppeteer-core/src/common/Debug.ts:1-50
MCP Integration
Puppeteer supports the Model Context Protocol for AI-assisted browser automation:
Installation
npm install chrome-devtools-mcp
WebMCP Support
Puppeteer also includes experimental support for the WebMCP API, enabling AI agents to interact with browser automation:
Sources: README.md:1-25
Next Steps
| Topic | Description |
|---|---|
| Locators | Advanced element location strategies |
| Selectors | CSS, text, ARIA, and XPath selectors |
| Page Interactions | Clicking, typing, scrolling |
| BiDi Protocol | WebDriver BiDi support |
| Chrome Extensions | Extension automation |
| API Reference | Complete API documentation |
Sources: [README.md:1-40]()
System Architecture
Related topics: Package Structure, CDP Implementation, WebDriver BiDi Implementation
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Package Structure, CDP Implementation, WebDriver BiDi Implementation
System Architecture
Puppeteer is a high-level API that provides a programmatic interface for controlling Chrome/Chromium browsers. The system architecture is designed to abstract browser automation complexities while supporting multiple protocol backends.
Architecture Overview
Puppeteer uses a dual-protocol architecture that supports both Chrome DevTools Protocol (CDP) and WebDriver BiDi (BiDirectional) protocols. This design enables flexibility in browser automation while maintaining a consistent high-level API for users.
graph TD
subgraph "User Layer"
User["User Code"]
end
subgraph "Public API Layer"
Puppeteer["puppeteer/puppeteer-core"]
Page["Page API"]
Browser["Browser API"]
end
subgraph "Protocol Abstraction Layer"
CDP["CDP Implementation"]
BiDi["BiDi Implementation"]
end
subgraph "Protocol Communication"
CDP_Protocol["Chrome DevTools Protocol"]
WebDriver_BiDi["WebDriver BiDi"]
end
subgraph "Browser Layer"
Chrome["Chrome/Chromium"]
Firefox["Firefox"]
end
User --> Puppeteer
Puppeteer --> Page
Puppeteer --> Browser
Page --> CDP
Page --> BiDi
CDP --> CDP_Protocol
BiDi --> WebDriver_BiDi
CDP_Protocol --> Chrome
WebDriver_BiDi --> Chrome
WebDriver_BiDi --> FirefoxCore Entry Points
The main entry point for Puppeteer is defined in index.ts, which exports all public APIs and types. The system provides two primary packages:
| Package | Purpose | Browser Download |
|---|---|---|
puppeteer | Full package with bundled Chrome | Yes (automatic) |
puppeteer-core | Library-only, no browser download | No |
Sources: packages/puppeteer-core/src/index.ts
Protocol Implementations
Chrome DevTools Protocol (CDP)
CDP is the native Chrome debugging protocol. The CDP implementation provides direct access to Chrome's debugging features through the CDPSession interface.
Key Components:
| Component | File | Purpose |
|---|---|---|
CDPPuppeteer | cdp.ts | Main entry point for CDP-based browser control |
CDPExecutionContext | ExecutionContext.ts | Executes JavaScript in page context |
CDPBrowserContext | cdp.ts | Manages browser contexts via CDP |
CDPPage | cdp.ts | Page implementation using CDP |
Sources: packages/puppeteer-core/src/cdp/cdp.ts
CDP Execution Flow:
sequenceDiagram
participant User as User Code
participant Page as CDP Page
participant Context as CDP ExecutionContext
participant Client as CDPSession
participant Chrome as Chrome Browser
User->>Page: evaluate(pageFunction)
Page->>Context: evaluate(pageFunction)
Context->>Client: send(Runtime.evaluate)
Client->>Chrome: Runtime.evaluate
Chrome-->>Client: result
Client-->>Context: result
Context-->>Page: HandleFor<T>
Page-->>User: Awaited<ReturnType<T>>The CDP implementation evaluates page functions by stringifying them and sending them via Runtime.evaluate or Runtime.callFunctionOn CDP commands. The source URL comment is injected for better debugging support.
Sources: packages/puppeteer-core/src/cdp/ExecutionContext.ts:1-50
WebDriver BiDi Protocol
WebDriver BiDi is a cross-browser protocol specification that provides a standardized bidirectional communication interface.
| Component | File | Purpose |
|---|---|---|
BiDiPuppeteer | bidi.ts | Main entry point for BiDi-based browser control |
Realm | Realm.ts | BiDi execution environment |
BiDiBrowserContext | bidi.ts | Manages browser contexts via BiDi |
BiDiPage | bidi.ts | Page implementation using BiDi |
Sources: packages/puppeteer-core/src/bidi/bidi.ts
BiDi Realm Architecture:
The Realm class provides the execution context for BiDi-based browser automation. It includes a lazy-loaded puppeteerUtil that handles internal Puppeteer operations:
class Realm {
internalPuppeteerUtil?: Promise<BidiJSHandle<PuppeteerInjectedUtil>>;
get puppeteerUtil(): Promise<BidiJSHandle<PuppeteerInjectedUtil>> {
// Lazy initialization with caching
}
async evaluateHandle(pageFunction, ...args): Promise<HandleFor<T>>;
async evaluate(pageFunction, ...args): Promise<Awaited<T>>;
}
Sources: packages/puppeteer-core/src/bidi/Realm.ts:1-60
Abstract API Layer
The API layer defines abstract interfaces that both protocol implementations must fulfill.
Page Abstraction
The Page class is the central abstraction for browser tabs/pages:
classDiagram
class Page {
<<abstract>>
+exposeFunction(name, pptrFunction)
+$$eval(selector, pageFunction)
+emulateMediaType(type)
+emulateCPUThrottling(factor)
+locator(selector) Locator
-_isDragging: boolean
-_timeoutSettings: TimeoutSettings
}
class CDPPage {
+exposeFunction(name, pptrFunction)
+$$eval(selector, pageFunction)
}
class BiDiPage {
+exposeFunction(name, pptrFunction)
+$$eval(selector, pageFunction)
}
Page <|-- CDPPage
Page <|-- BiDiPageKey Page features:
| Feature | Description | Source |
|---|---|---|
exposeFunction | Exposes a function to the page's JavaScript context | Page.ts |
$$eval | Evaluates a function on matching elements | Page.ts |
emulateMediaType | Emulates CSS media type | Page.ts |
emulateCPUThrottling | Simulates slow CPUs | Page.ts |
Locator System
The Locator API provides a modern, promise-based approach to element finding with automatic retry logic.
graph TD
Locator["Locator<T>"]
FunctionLocator["FunctionLocator<T>"]
DelegatedLocator["DelegatedLocator<T, U>"]
Page["Page"]
Frame["Frame"]
Page --> Locator
Frame --> Locator
Locator <|-- FunctionLocator
Locator <|-- DelegatedLocator
DelegatedLocator --> Locator
FunctionLocator: "_func: () => Awaitable<T>"
DelegatedLocator: "#delegate: Locator<T>"Locator Types:
| Type | Purpose | Key Methods |
|---|---|---|
Locator<T> | Base locator class | wait(), map(), filter() |
FunctionLocator<T> | Locates elements using a predicate function | Uses waitForFunction internally |
DelegatedLocator<T, U> | Wraps another locator with transformation | Delegates to another locator |
Sources: packages/puppeteer-core/src/api/locators/locators.ts
Event System
Puppeteer uses an event-driven architecture based on EventEmitter:
graph LR
Page["Page (EventEmitter)"]
Request["Request Event"]
Response["Response Event"]
Console["Console Event"]
Page --> |emit| Request
Page --> |emit| Response
Page --> |emit| Console
User1["page.on('request', handler)"]
User2["page.on('response', handler)"]
User3["page.on('console', handler)"]
Request --> User1
Response --> User2
Console --> User3The Page class extends EventEmitter<PageEvents> and emits events documented in the PageEvent enum:
page.once('load', () => console.log('Page loaded!'));
page.on('request', logRequest);
page.off('request', logRequest);
Sources: packages/puppeteer-core/src/api/Page.ts:1-100
Lazy Evaluation (LazyArg)
The LazyArg system enables deferred argument evaluation within page context:
graph TD
User["User Code"]
Lazy["LazyArg.create(callback)"]
Context["PuppeteerUtilWrapper"]
Eval["evaluate()"]
User --> Lazy
Lazy --> Eval
Eval --> Context
Context --> |get| Lazyclass LazyArg<T, Context = PuppeteerUtilWrapper> {
static create = <T>(
get: (context: PuppeteerUtilWrapper) => Promise<T> | T
): T => {
return new LazyArg(get) as unknown as T;
};
async get(context: Context): Promise<T> {
return await this.#get(context);
}
}
Sources: packages/puppeteer-core/src/common/LazyArg.ts
Device Emulation
Puppeteer provides pre-configured device profiles for emulation:
import {KnownDevices} from 'puppeteer';
const iPhone = KnownDevices['iPhone 15 Pro'];
const page = await browser.newPage();
await page.emulate(iPhone);
| Category | Devices Included |
|---|---|
| iPhone | iPhone 4, 5, 6, 7, 8, X, 11, 12, 13, 14, 15 series |
| iPad | Various iPad models |
| Android | Nexus, Pixel devices |
| Desktop | Chrome, Firefox, Safari viewports |
Sources: packages/puppeteer-core/src/common/Device.ts
Debug System
The debug module provides channel-based logging:
const log = debug('Page');
log('new page created');
// Output: "Page: new page created"
Configuration:
| Environment Variable | Effect |
|---|---|
window.__PUPPETEER_DEBUG='*' | Enable all logging |
window.__PUPPETEER_DEBUG='foo' | Log only 'foo' channel |
window.__PUPPETEER_DEBUG='foo*' | Log all channels starting with 'foo' |
Sources: packages/puppeteer-core/src/common/Debug.ts
Architecture Summary
graph TD
subgraph "User Applications"
Scripts["Automation Scripts"]
Tests["Test Frameworks"]
Scrapers["Web Scrapers"]
end
subgraph "puppeteer/puppeteer-core"
API["Public API (Page, Browser, Frame)"]
Locator["Locator API"]
Event["Event System"]
end
subgraph "Protocol Adapters"
CDP["CDP Adapter"]
BiDi["BiDi Adapter"]
end
subgraph "Browser Runtimes"
Chrome["Chrome/Chromium"]
Firefox["Firefox"]
Edge["Edge"]
end
Scripts --> API
Tests --> API
Scrapers --> API
API --> Locator
API --> Event
API --> CDP
API --> BiDi
CDP --> Chrome
CDP --> Edge
BiDi --> Chrome
BiDi --> Firefox
BiDi --> EdgeKey Design Principles
- Protocol Abstraction: Both CDP and BiDi provide equivalent functionality through a unified API
- Lazy Evaluation: Arguments are evaluated only when needed within the browser context
- Event-Driven: Asynchronous operations use observable patterns for extensibility
- Device Emulation: Built-in device profiles ensure consistent cross-device testing
- Debugging Support: Channel-based logging enables granular troubleshooting
Sources: [packages/puppeteer-core/src/index.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/index.ts)
Package Structure
Related topics: System Architecture, Browser Launching
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: System Architecture, Browser Launching
Package Structure
Puppeteer is a comprehensive Node.js library that provides a high-level API to control Chrome, Firefox, and other browsers via the DevTools Protocol. The project is organized as a monorepo containing multiple packages that serve distinct purposes while maintaining a cohesive architecture.
Overview
The Puppeteer repository follows a multi-package architecture designed to separate concerns between browser automation logic, browser launching utilities, and framework-specific integrations.
graph TD
A[Puppeteer Core] --> B[Browser Launchers]
A --> C[Page API]
A --> D[Locator API]
B --> E[Chrome Driver]
B --> F[Firefox Driver]
C --> G[CDP Execution]
D --> H[Locator Implementations]Package Organization
The repository contains the following primary packages located in the packages/ directory:
| Package | Purpose | Entry Point |
|---|---|---|
puppeteer | Full Puppeteer distribution with bundled Chrome | Main npm package |
puppeteer-core | Core library without browser binaries | src/puppeteer-core.ts |
@puppeteer/browsers | Browser management CLI and API | packages/browsers/src/main.ts |
ng-schematics | Angular schematics for Puppeteer | Angular integration |
puppeteer-core
The puppeteer-core package serves as the foundation for all browser automation functionality. It provides the complete API surface for launching browsers, creating pages, and executing automation tasks.
Location: packages/puppeteer-core/
Key Characteristics:
- Does not download browser binaries during installation
- Compatible with any browser implementation that supports DevTools Protocol
- Requires explicit
executablePathconfiguration when not using bundled browsers
Source Files:
| File | Purpose |
|---|---|
src/puppeteer-core.ts | Main entry point, exports primary API |
src/puppeteer-core-browser.ts | Browser class implementation |
src/api/Page.ts | Abstract Page class definition |
src/api/locators/locators.ts | Locator implementations |
src/common/Configuration.ts | Configuration interfaces |
src/cdp/ExecutionContext.ts | CDP execution context |
The package exports key classes including Browser, Page, Frame, Locator, and various configuration types that enable programmatic browser control.
Browser Launchers (`@puppeteer/browsers`)
The @puppeteer/browsers package provides both a CLI interface and programmatic API for managing browser installations. It handles downloading, caching, and launching of browser binaries.
CLI Commands:
| Command | Description |
|---|---|
npx @puppeteer/browsers install | Download browser binaries |
npx @puppeteer/browsers clear | Remove installed browsers |
npx @puppeteer/browsers list | Display installed browsers |
npx @puppeteer/browsers launch | Launch a specific browser |
Supported Browsers:
- Chrome for Testing (Stable, Beta, Dev, Canary)
- ChromeDriver (matching versions)
- Firefox
Installation Examples:
# Install latest stable Chrome
npx @puppeteer/browsers install chrome@stable
# Install specific version
npx @puppeteer/browsers install [email protected]
# Install latest ChromeDriver for Canary
npx @puppeteer/browsers install chromedriver@canary
Angular Schematics (`ng-schematics`)
The ng-schematics package provides Angular-specific tooling for integrating Puppeteer into Angular projects through the Angular CLI.
Location: packages/ng-schematics/package.json
This package enables Angular developers to scaffold and configure Puppeteer within their applications using standard Angular CLI commands.
Module Architecture
Core API Structure
The Puppeteer Core API is organized hierarchically with clear separation between different functional areas:
graph BT
A[Browser] --> B[Page]
A --> C[Target]
B --> D[Frame]
B --> E[Locator]
D --> F[ExecutionContext]
F --> G[JSHandle]Key Entry Points
The main entry point packages/puppeteer-core/src/puppeteer-core.ts exports all public APIs:
puppeteer.launch()- Launch a browser instancepuppeteer.connect()- Connect to an existing browserBrowserclass - Represents a browser instancePageclass - Represents a single page or tabFrameclass - Represents an iframe within a pageLocatorclasses - Fluent locator implementations for element queries
The browser-specific entry point packages/puppeteer-core/src/puppeteer-core-browser.ts provides implementation details for browser lifecycle management.
Common Utilities
Several utility modules support the core functionality:
| Module | Location | Purpose |
|---|---|---|
LazyArg | src/common/LazyArg.ts | Deferred argument evaluation for page functions |
Device | src/common/Device.ts | Predefined device descriptors for emulation |
Debug | src/common/Debug.ts | Debug logging infrastructure |
Configuration | src/common/Configuration.ts | Global and per-browser configuration |
Launch Options
Browser launch behavior is configured through LaunchOptions interface in packages/puppeteer-core/src/node/LaunchOptions.ts:
| Option | Type | Default | Description | |
|---|---|---|---|---|
executablePath | string | bundled | Path to browser executable | |
ignoreDefaultArgs | `boolean \ | string[]` | false | Skip default arguments |
enableExtensions | `boolean \ | string[]` | - | Enable browser extensions |
handleSIGINT | boolean | true | Close on Ctrl+C | |
handleSIGTERM | boolean | true | Close on SIGTERM | |
handleSIGHUP | boolean | true | Close on SIGHUP | |
timeout | number | 30000 | Startup timeout in ms |
Directory Structure
puppeteer/
├── packages/
│ ├── puppeteer-core/
│ │ ├── src/
│ │ │ ├── api/ # Public API definitions
│ │ │ │ ├── Page.ts
│ │ │ │ └── locators/
│ │ │ ├── cdp/ # CDP-specific implementations
│ │ │ ├── common/ # Shared utilities
│ │ │ ├── injected/ # Injected scripts
│ │ │ └── node/ # Node.js specific code
│ │ └── package.json
│ ├── browsers/
│ │ ├── src/
│ │ │ └── main.ts # CLI entry point
│ │ └── README.md
│ └── ng-schematics/
├── examples/ # Official usage examples
├── website/ # Documentation site
├── docker/ # Docker configuration
└── tools/ # Development tools
Configuration System
Global Configuration
Configuration is defined through ChromeSettings, FirefoxSettings, and related interfaces in Configuration.ts:
interface ChromeSettings {
skipDownload?: boolean;
// URL prefix for browser downloads
}
Environment Variable Overrides
| Variable | Configuration Property |
|---|---|
PUPPETEER_SKIP_DOWNLOAD | skipDownload |
PUPPETEER_TMP_DIR | temporaryDirectory |
PUPPETEER_CHROME_SKIP_DOWNLOAD | chrome.skipDownload |
PUPPETEER_CHROME_DOWNLOAD_BASE_URL | chrome.downloadBaseUrl |
Integration Patterns
Direct Usage (puppeteer-core)
import puppeteer from 'puppeteer-core';
const browser = await puppeteer.launch({
executablePath: '/path/to/browser'
});
Full Distribution (puppeteer)
import puppeteer from 'puppeteer';
// Automatically downloads and uses bundled Chrome
const browser = await puppeteer.launch();
Debug Support
Puppeteer includes a debug logging system controlled via the __PUPPETEER_DEBUG environment variable:
# Enable all debug channels
window.__PUPPETEER_DEBUG='*'
# Enable specific channel
window.__PUPPETEER_DEBUG='Page'
# Enable channel prefix matching
window.__PUPPETEER_DEBUG='Page*'
The debug utility is implemented in packages/puppeteer-core/src/common/Debug.ts.
Browser Support Matrix
| Browser | Protocol | Package Support |
|---|---|---|
| Chrome | CDP | Full |
| Chromium | CDP | Full |
| Firefox | CDP | Experimental |
| Edge | CDP | Via Chrome compatibility |
Additional Resources
The repository also includes:
- Examples (
examples/): Working code samples demonstrating various Puppeteer features - Website (
website/): Documentation site built with Docusaurus 3 - Docker (
docker/): Containerization support for browser execution - ESLint Tools (
tools/eslint/): Custom ESLint rules for code quality
Version Compatibility
Puppeteer maintains backward compatibility within major versions. The puppeteer-core package is guaranteed to work with any browser that implements the required DevTools Protocol capabilities, though optimal compatibility is achieved with bundled browser versions.
Source: https://github.com/puppeteer/puppeteer / Human Manual
Protocol Implementations
Related topics: CDP Implementation, WebDriver BiDi Implementation
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: CDP Implementation, WebDriver BiDi Implementation
Protocol Implementations
Puppeteer provides abstraction layers over two browser automation protocols: the Chrome DevTools Protocol (CDP) and WebDriver BiDi. These protocol implementations form the foundation of how Puppeteer communicates with browsers, enabling code execution, DOM manipulation, and browser control.
Architecture Overview
Puppeteer's protocol layer sits between the high-level API (Page, Frame, etc.) and the underlying browser connections. The architecture uses a dual-protocol approach where both CDP and BiDi implementations share common interfaces while providing protocol-specific behaviors.
graph TD
subgraph "High-Level API"
Page[Page.ts]
Frame[Frame.ts]
end
subgraph "Protocol Abstraction Layer"
ExecutionContext[ExecutionContext.ts<br/>CDP]
Realm[Realm.ts<br/>BiDi]
end
subgraph "Connection Layer"
CDP_Conn[CDP Connection]
BiDi_Conn[BiDi Connection]
end
subgraph "Browser"
Chrome[Chrome/Chromium]
Firefox[Firefox]
WebKit[WebKit]
end
Page --> ExecutionContext
Page --> Realm
ExecutionContext --> CDP_Conn
Realm --> BiDi_Conn
CDP_Conn --> Chrome
BiDi_Conn --> Firefox
BiDi_Conn --> WebKitChrome DevTools Protocol (CDP) Implementation
The CDP implementation is located in packages/puppeteer-core/src/cdp/ and provides deep integration with Chrome/Chromium browsers. CDP offers rich capabilities including precise execution context management, detailed debugging features, and direct access to browser internals.
CDP Execution Context
The ExecutionContext class in packages/puppeteer-core/src/cdp/ExecutionContext.ts handles code evaluation within browser contexts:
// Simplified from ExecutionContext.ts
async evaluate<T>(
returnByValue: boolean,
pageFunction: Func | string,
...args: Params
): Promise<HandleFor<Awaited<ReturnType<Func>>> | Awaited<ReturnType<Func>>> {
const sourceUrlComment = getSourceUrlComment(
getSourcePuppeteerURLIfAvailable(pageFunction)?.toString() ??
PuppeteerURL.INTERNAL_URL,
);
if (isString(pageFunction)) {
const contextId = this.#id;
const expression = pageFunction;
const expressionWithSourceUrl = SOURCE_URL_REGEX.test(expression)
? expression
: `${expression}\n${sourceUrlComment}\n`;
const {exceptionDetails, result: remoteObject} = await this.#client
.send('Runtime.evaluate', {
expression: expressionWithSourceUrl,
contextId,
returnByValue,
awaitPromise: true,
userGesture: true,
})
.catch(rewriteError);
if (exceptionDetails) {
throw createEvaluationError(exceptionDetails);
}
// ...
}
}
Sources: packages/puppeteer-core/src/cdp/ExecutionContext.ts:1-50
CDP Connection
The CDP Connection manages the WebSocket-based communication channel to the browser's DevTools endpoint. This implementation handles message routing, callback management, and protocol event distribution.
WebDriver BiDi Implementation
The BiDi implementation follows the WebDriver BiDi specification and is organized into two layers:
packages/puppeteer-core/src/bidi/- Puppeteer's BiDi abstractionspackages/puppeteer-core/src/bidi/core/- Spec-compliant WebDriver BiDi core
BiDi Design Principles
According to packages/puppeteer-core/src/bidi/core/README.md:
bidi/coreattempts to implement WebDriver BiDi comprehensively, but minimally- All objects and events in WebDriver BiDi are implemented as a graph where objects are nodes and events are edges
- The implementation always follows the spec and never Puppeteer's specific needs
- This ensures that bugs can be precisely identified as either spec issues or Puppeteer workarounds
Sources: packages/puppeteer-core/src/bidi/core/README.md:1-30
BiDi Realm
The BiDi Realm class in packages/puppeteer-core/src/bidi/Realm.ts provides the execution environment for BiDi-based evaluations:
// Simplified from Realm.ts
class Realm extends EventEmitter<RealmEvents> {
internalPuppeteerUtil?: Promise<BidiJSHandle<PuppeteerInjectedUtil>>;
get puppeteerUtil(): Promise<BidiJSHandle<PuppeteerInjectedUtil>> {
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<
BidiJSHandle<PuppeteerInjectedUtil>
>;
});
}, !this.internalPuppeteerUtil);
return this.internalPuppeteerUtil as Promise<
BidiJSHandle<PuppeteerInjectedUtil>
>;
}
}
Sources: packages/puppeteer-core/src/bidi/Realm.ts:1-40
Script Injection System
The ScriptInjector class (packages/puppeteer-core/src/common/ScriptInjector.ts) handles the injection of utility scripts required by both protocol implementations. It maintains a set of amendments that get applied to the injected script:
export class ScriptInjector {
#updated = false;
#amendments = new Set<string>();
append(statement: string): void {
this.#update(() => {
this.#amendments.add(statement);
});
}
inject(inject: (script: string) => void, force = false): void {
if (this.#updated || force) {
inject(this.#get());
}
this.#updated = false;
}
#get(): string {
return `(() => {
const module = {};
${injectedSource}
${[...this.#amendments]
.map(statement => {
return `(${statement})(module.exports.default);`;
})
.join('')}
return module.exports.default;
})()`;
}
}
export const scriptInjector = new ScriptInjector();
Sources: packages/puppeteer-core/src/common/ScriptInjector.ts:1-50
LazyArg Pattern
The LazyArg class provides a mechanism for lazy evaluation of arguments passed to page functions. This is essential for protocol implementations as it defers the resolution of context-dependent values:
export class LazyArg<T, Context = PuppeteerUtilWrapper> {
static create = <T>(
get: (context: PuppeteerUtilWrapper) => Promise<T> | T,
): T => {
return new LazyArg(get) as unknown as T;
};
#get: (context: Context) => Promise<T> | T;
private constructor(get: (context: Context) => Promise<T> | T) {
this.#get = get;
}
async get(context: Context): Promise<T> {
return await this.#get(context);
}
}
Sources: packages/puppeteer-core/src/common/LazyArg.ts:1-30
Protocol Selection and Configuration
The protocol implementation is selected based on browser type and configuration. The Page class in packages/puppeteer-core/src/api/Page.ts defines the abstract interface that both protocol implementations satisfy:
export abstract class Page extends EventEmitter<PageEvents> {
_isDragging = false;
_timeoutSettings = new TimeoutSettings();
_tabId = '';
#requestHandlers = new WeakMap<Handler<HTTPRequest>, Handler<HTTPRequest>>();
}
Sources: packages/puppeteer-core/src/api/Page.ts:100-130
Key Differences Between Protocols
| Feature | CDP | BiDi |
|---|---|---|
| Browser Support | Chrome, Chromium | Firefox, WebKit, Chrome |
| Architecture | WebSocket-based | WebSocket + JSON commands |
| Spec Compliance | Chrome-specific | Cross-browser standard |
| Execution Model | Direct context switching | Realm-based isolation |
| Debugging | Deep DevTools integration | Standard WebDriver interface |
Event Flow Comparison
graph LR
subgraph "CDP Flow"
CDP1[Page Event] --> CDP2[Emulation Context]
CDP2 --> CDP3[Request Handler]
end
subgraph "BiDi Flow"
BiDi1[Page Event] --> BiDi2[Realm]
BiDi2 --> BiDi3[Script Injector]
BiDi3 --> BiDi4[BiDi Command]
endSummary
Puppeteer's protocol implementations provide a unified abstraction over CDP and WebDriver BiDi:
- CDP Implementation offers deep Chrome integration with precise context management
- BiDi Implementation provides cross-browser compatibility following the WebDriver BiDi specification
- ScriptInjector manages utility script injection for both protocols
- LazyArg enables lazy evaluation of protocol-dependent arguments
- The dual-protocol architecture allows Puppeteer to target different browsers while maintaining a consistent high-level API
Source: https://github.com/puppeteer/puppeteer / Human Manual
CDP Implementation
Related topics: System Architecture, Page API
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: System Architecture, Page API
CDP Implementation
Overview
The Chrome DevTools Protocol (CDP) is the core communication mechanism that enables Puppeteer to interact with Chromium-based browsers. The CDP Implementation in Puppeteer provides a comprehensive abstraction layer over the raw CDP protocol, enabling high-level browser automation operations such as page navigation, JavaScript execution, network interception, and device emulation.
Puppeteer's CDP implementation is located in packages/puppeteer-core/src/cdp/ and consists of multiple interconnected modules that handle different aspects of browser automation.
Sources: packages/puppeteer-core/src/cdp/Connection.ts:1-50
Architecture
High-Level Component Architecture
graph TD
subgraph "CDP Implementation Layer"
Connection[CdpConnection]
Session[CdpSession]
Browser[CdpBrowser]
Page[CdpPage]
NetworkManager[NetworkManager]
FrameManager[FrameManager]
end
subgraph "Core CDP Components"
BrowserConnector[BrowserConnector]
Target[CDPTarget]
Accessibility[Accessibility]
Input[Input]
end
subgraph "Protocol Layer"
ProtocolCommands[CDP Protocol Commands]
EventEmitters[Event Emitters]
MessageHandlers[Message Handlers]
end
Connection --> Session
Session --> Browser
Browser --> Page
Browser --> NetworkManager
Browser --> FrameManager
Session --> Target
Connection --> BrowserConnectorModule Responsibilities
| Module | Purpose | Key Responsibilities |
|---|---|---|
Connection.ts | WebSocket communication | Establishes/manages WebSocket connection, routes messages, handles reconnection |
CdpSession.ts | CDP session management | Creates/sends CDP commands, receives events, manages message IDs |
Browser.ts | Browser lifecycle | Manages browser process, targets, pages, contexts |
Page.ts | Page automation | Navigation, frame management, viewport, emulation |
NetworkManager.ts | Network interception | Request/response interception, authentication handling |
FrameManager.ts | Frame hierarchy | Main frame, child frames, navigation tracking |
ExecutionContext.ts | JS execution | Evaluates JavaScript, manages handles |
Sources: packages/puppeteer-core/src/cdp/Browser.ts:1-100
Connection Management
WebSocket-Based Communication
The CdpConnection class establishes a WebSocket connection to the browser's DevTools endpoint. This is the foundational transport layer for all CDP communication.
sequenceDiagram
participant Puppeteer as Puppeteer Client
participant WS as WebSocket
participant Browser as Chrome/Chromium
Puppeteer->>WS: Connect to DevTools URL
WS->>Puppeteer: Connection established
Puppeteer->>Browser: CDP Command (method, params, id)
Browser->>Puppeteer: CDP Response (id, result)
Browser->>Puppeteer: CDP Event (method, params)Connection Lifecycle
The connection management follows a defined lifecycle:
- Initialization: Establish WebSocket connection to the browser's remote debugging URL
- Session Creation: Create
CdpSessioninstances for different targets - Message Routing: Route CDP commands and events between client and browser
- Disconnection Handling: Gracefully handle disconnection and cleanup
- Reconnection: Support for reconnection scenarios
Sources: packages/puppeteer-core/src/cdp/Connection.ts:50-150
Session Management
CdpSession Implementation
The CdpSession class represents an active CDP session bound to a specific browser target. It handles:
- Command Dispatch: Sending CDP method calls with parameters
- Event Subscription: Listening for CDP events from the browser
- Message Correlation: Matching responses to requests using message IDs
- Session Lifecycle: Creating and disposing sessions
// Simplified session structure
class CdpSession {
#connection: CdpConnection;
#sessionId: string;
#messageHandlers: Map<string, EventEmitter>;
async send<T>(method: string, params?: object): Promise<T>;
on(event: string, handler: Function): void;
off(event: string, handler: Function): void;
detach(): Promise<void>;
}
Message Flow
graph LR
subgraph "Client Side"
CMD[CDP Command]
RES[CDP Response]
EVT[CDP Event]
end
subgraph "Transport"
WS[WebSocket]
end
subgraph "Browser Side"
CDP[CDP Runtime]
TGT[Target]
end
CMD -->|send method| WS
WS -->|route| CDP
CDP -->|response id| WS
WS -->|response| RES
TGT -->|emit event| CDP
CDP -->|event| WS
WS -->|event| EVTSources: packages/puppeteer-core/src/cdp/CdpSession.ts:1-80
Browser Implementation
CdpBrowser Class
The CdpBrowser class provides the high-level browser interface, implementing the Browser interface defined in the API layer. It coordinates multiple CDP sessions and manages browser targets.
classDiagram
class CdpBrowser {
+connection_: CdpConnection
+browserContext_: BrowserContext
+_targets: Map~string, CdpTarget~
+_ignoreHTTPSErrors: boolean
+_defaultViewport: Viewport | null
+newPage(): Promise~CdpPage~
+createIncognitoBrowserContext(): BrowserContext
+disconnect(): void
+wsEndpoint(): string
}
class CdpTarget {
+_browserContext: BrowserContext
+_session: CdpSession
+_initialized: Promise~void~
+_closeCallback: Function
+initialize(): Promise~void~
}
CdpBrowser --> CdpTarget
CdpTarget --> CdpSessionTarget Management
Browser targets represent different browsing contexts managed by Chromium:
| Target Type | Description | Creation Method |
|---|---|---|
| Browser Target | Main browser process | Auto-created on connection |
| Page Target | Single page/tab | Target.createTarget |
| Service Worker | Background script | Auto-created for SWs |
| BrowserContext | Isolated profile | Browser.createIncognitoContext |
Sources: packages/puppeteer-core/src/cdp/Browser.ts:100-250
Page Implementation
CdpPage Class
The CdpPage class extends the abstract Page class and implements page-specific CDP operations. It provides methods for:
- Navigation:
goto(),goBack(),goForward(),reload() - Content Operations:
setContent(),content() - Viewport Management:
setViewport(), viewport settings - Frame Access:
mainFrame(),frames(),frame() - Device Emulation:
emulate(),emulateMediaType(),emulateTimezone()
graph TD
subgraph "CdpPage"
PageAPI[Page Interface]
Navigation[Navigation Manager]
Emulation[Emulation Manager]
Screenshot[Screenshot Handler]
end
subgraph "CDP Sessions"
PageSession[Page Target Session]
FrameSession[Frame Session]
end
PageAPI --> Navigation
PageAPI --> Emulation
PageAPI --> Screenshot
Navigation --> PageSession
Emulation --> PageSession
FrameSession --> FrameManagerPage Lifecycle Events
| Event | Trigger | Use Case |
|---|---|---|
load | Page load complete | Wait for full page |
domcontentloaded | DOM ready | Early interaction |
networkidle | No network for 500ms | Wait for API calls |
framenavigated | Frame navigation complete | Frame sync |
request/requestfailed/response | Network events | Intercept/modify requests |
Sources: packages/puppeteer-core/src/cdp/Page.ts:1-150
Network Management
NetworkManager Class
The NetworkManager handles all network-related CDP events and provides the interception infrastructure for page.setRequestInterception().
graph TD
subgraph "NetworkManager"
RequestInterceptor[Request Interceptor]
AuthHandler[Auth Handler]
CacheManager[Cache Manager]
end
subgraph "CDP Events"
REQ[Network.requestWillBeSent]
RES[Network.responseReceived]
ERR[Network.requestFailed]
CMPL[Network.loadingFinished]
end
subgraph "Public API"
Interception[setRequestInterception]
Auth[authenticate]
Offline[setOfflineMode]
end
REQ --> RequestInterceptor
RequestInterceptor --> Interception
Auth --> AuthHandler
AuthHandler --> REQRequest Interception Flow
sequenceDiagram
participant Browser as Browser
participant NM as NetworkManager
participant Interceptor as User Interceptor
participant CDP as CDP Session
Browser->>NM: requestWillBeSent
NM->>Interceptor: intercept callback
Interceptor->>NM: continue/abort/respond
NM->>CDP: Network.continueRequest
NM->>CDP: Network.failRequest
NM->>CDP: Network.fulfillRequestAuthentication Handler
The NetworkManager includes authentication handling for HTTP Basic/Digest auth:
interface AuthCredentials {
username: string;
password: string;
}
class NetworkManager {
#authCredentials?: AuthCredentials;
#pendingAuthRequests: Map<string, InterceptionHandle>;
setAuthCredentials(credentials: AuthCredentials): void;
clearAuthCredentials(): void;
}
Sources: packages/puppeteer-core/src/cdp/NetworkManager.ts:1-200
Frame Management
FrameManager Class
The FrameManager maintains the frame hierarchy and tracks frame lifecycle events. It handles:
- Frame Tree Construction: Building and maintaining the document frame hierarchy
- Navigation Tracking: Tracking frame-level navigation events
- Detached Frame Cleanup: Cleaning up frames when their documents unload
- Frame Communication: Managing frame-specific CDP sessions
graph TD
subgraph "FrameManager"
FT[Frame Tree]
EH[Event Handler]
NC[Navigation Checker]
end
subgraph "Frame Types"
MF[Main Frame]
IF[iframe]
SF[Shadow Frame]
end
FT --> MF
FT --> IF
FT --> SF
EH -->|events| FT
NC -->|nav events| FTFrame Hierarchy
| Frame Type | CDP Target | Session | Characteristics |
|---|---|---|---|
| Main Frame | Page target | Primary session | Top-level document |
| Subframe | Auto-created | Linked to parent | Cross-origin isolation |
| Worker | ServiceWorker target | Separate session | No DOM access |
Sources: packages/puppeteer-core/src/cdp/FrameManager.ts:1-180
Execution Context
CdpExecutionContext
The execution context in CDP is the JavaScript execution environment within a frame. The ExecutionContext class provides:
- JavaScript Evaluation:
evaluate()andevaluateHandle()methods - Handle Management: Creating and managing JSHandle instances
- Remote Object Conversion: Converting CDP RemoteObjects to JSHandles
graph LR
subgraph "User Code"
FN[Function/Expression]
end
subgraph "Puppeteer"
EVAL[evaluate]
LAZY[LazyArg]
HANDLE[JsHandle]
end
subgraph "CDP"
RTE[Runtime.evaluate]
CALL[Runtime.callFunctionOn]
RO[RemoteObject]
end
FN --> EVAL
EVAL --> RTE
EVAL --> CALL
CALL --> LAZY
RTE --> RO
CALL --> RO
RO --> HANDLESource URL Handling
Puppeteer injects source URL comments into evaluated code for better debugging:
const SOURCE_URL_COMMENT = '//# sourceURL=__puppeteer_evaluation_script__';
This enables:
- Proper stack traces in console errors
- Source map resolution in DevTools
- Better debugging experience for evaluated code
Sources: packages/puppeteer-core/src/cdp/ExecutionContext.ts:30-120
Key CDP Methods Used
Browser-Level Methods
| Method | Category | Purpose |
|---|---|---|
Target.createTarget | Target | Create new page/tab |
Target.attachToTarget | Target | Attach to existing target |
Browser.close | Browser | Close browser |
Browser.getVersion | Browser | Get browser info |
Page-Level Methods
| Method | Category | Purpose |
|---|---|---|
Page.navigate | Navigation | Navigate to URL |
Page.setDocumentContent | Content | Set HTML content |
Page.captureScreenshot | Screenshot | Take screenshot |
Page.setViewport | Emulation | Set viewport dimensions |
Network Methods
| Method | Category | Purpose |
|---|---|---|
Network.setRequestInterception | Interception | Enable request interception |
Network.continueRequest | Interception | Continue intercepted request |
Network.fulfillRequest | Interception | Respond with custom data |
Network.getResponseBody | Response | Get response body |
Runtime Methods
| Method | Category | Purpose |
|---|---|---|
Runtime.evaluate | Evaluation | Execute expression |
Runtime.callFunctionOn | Evaluation | Call function on object |
Runtime.queryObjects | Inspection | Query JS objects |
Sources: packages/puppeteer-core/src/cdp/Page.ts:200-350
Event Flow Architecture
graph TD
subgraph "Browser Events"
NE[Navigation Event]
RE[Resource Event]
EE[Execution Event]
end
subgraph "CDP Events"
CDP_NE[Page.frameNavigated]
CDP_RE[Network.requestWillBeSent]
CDP_EE[Runtime.executionContextCreated]
end
subgraph "Puppeteer Events"
P_E[page.on Event]
CB[Event Callback]
end
NE -->|triggers| CDP_NE
RE -->|triggers| CDP_RE
EE -->|triggers| CDP_EE
CDP_NE -->|emitted| P_E
CDP_RE -->|emitted| P_E
CDP_EE -->|emitted| P_E
P_E -->|invokes| CBError Handling
Error Rewriting
Puppeteer rewrites CDP errors to provide more meaningful error messages:
function rewriteError(error: Error, message: string): never {
throw new Error(`${message}: ${error.message}`);
}
Evaluation Errors
JavaScript evaluation errors are converted to Error instances with detailed information:
function createEvaluationError(exceptionDetails: ExceptionDetails): Error {
const error = new Error();
error.name = exceptionDetails.exception?.className ?? 'Error';
error.message = exceptionDetails.exception?.description
?? exceptionDetails.text;
return error;
}
Sources: packages/puppeteer-core/src/cdp/ExecutionContext.ts:60-90
Configuration Options
Launch Options Related to CDP
| Option | Type | Default | Description |
|---|---|---|---|
executablePath | string | bundled browser | Path to browser executable |
channel | ChromeReleaseChannel | auto | Chrome update channel |
browser | SupportedBrowser | chrome | Browser to use |
timeout | number | 30000 | Browser launch timeout |
protocolTimeout | number | undefined | CDP protocol timeout |
Browser Configuration
| Setting | Environment Variable | Description |
|---|---|---|
defaultBrowser | PUPPETEER_DEFAULT_BROWSER | Default browser to use |
temporaryDirectory | PUPPETEER_TMP_DIR | Temp directory for downloads |
skipDownload | PUPPETEER_SKIP_DOWNLOAD | Skip browser download |
logLevel | PUPPETEER_LOG_LEVEL | Logging level |
Sources: packages/puppeteer-core/src/node/LaunchOptions.ts:1-100
See Also
Sources: [packages/puppeteer-core/src/cdp/Connection.ts:1-50]()
WebDriver BiDi Implementation
Related topics: System Architecture, Protocol Implementations
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: System Architecture, Protocol Implementations
WebDriver BiDi Implementation
Overview
WebDriver BiDi (Bidirectional Protocol) is a W3C-standardized protocol that enables bidirectional communication between browser automation tools and web browsers. Puppeteer's WebDriver BiDi implementation provides a modern, cross-browser automation interface built on the WebDriver protocol specification.
The implementation exists as a first-class protocol option alongside CDP (Chrome DevTools Protocol), with deep integration into Puppeteer's core architecture.
Architecture Principles
The bidi/core module follows specific architectural guidelines that distinguish it from higher-level Puppeteer abstractions:
| Principle | Description |
|---|---|
| Spec Compliance | bidi/core always follows the WebDriver BiDi specification, never Puppeteer's needs |
| No Workarounds | Spec deviations are never masked; instead, workarounds belong in upper layers |
| Comprehensive Minimalism | All required nodes and edges in the protocol graph are implemented fully |
| Event Integrity | Events are never composed or duplicated; navigation flows must follow the correct event sequence |
Sources: packages/puppeteer-core/src/bidi/core/README.md
Event Flow Integrity
A critical principle is that events must follow proper WebDriver BiDi semantics. For navigation events:
- Fragment navigations must emit events through the complete chain:
fragment navigation → navigation → browsing context - Direct emission to browsing context without intermediate events is prohibited
- This ensures that consumers receive semantically correct event sequences matching the protocol specification
Protocol Connection Architecture
graph TD
A[Puppeteer Application] --> B[BrowserLauncher]
B --> C{PUPPETEER_WEBDRIVER_BIDI_ONLY}
C -->|true| D[BiDi Only Mode]
C -->|false| E[CDP + BiDi Hybrid Mode]
D --> F[BiDi.connectBidiOverCdp]
E --> G[CDP Connection]
G --> H[BiDi.connectBidiOverCdp]
F --> I[BidiBrowser Instance]
H --> IBiDi over CDP Bridge
When using WebDriver BiDi with browsers that primarily support CDP (like Chrome), Puppeteer establishes a CDP connection and wraps it with BiDi protocol support:
const bidiOnly = process.env['PUPPETEER_WEBDRIVER_BIDI_ONLY'] === 'true';
const BiDi = await import('../bidi/bidi.js');
const bidiConnection = await BiDi.connectBidiOverCdp(cdpConnection);
return await BiDi.BidiBrowser.create({
connection: bidiConnection,
// Do not provide CDP connection to Browser if BiDi-only mode is enabled
cdpConnection: bidiOnly ? undefined : cdpConnection,
closeCallback,
process: browserProcess.nodeProcess,
defaultViewport: opts.defaultViewport,
acceptInsecureCerts: opts.acceptInsecureCerts,
networkEnabled: opts.networkEnabled,
issuesEnabled: opts.issuesEnabled,
});
Sources: packages/puppeteer-core/src/node/BrowserLauncher.ts:1-28
WebDriver BiDi Capabilities
When connecting with WebDriver BiDi protocol, capabilities can be specified:
interface SupportedWebDriverCapabilities {
webDriverBiDi?: {
// BiDi-specific capabilities passed to session.new
};
}
The capabilities option allows passing WebDriver BiDi capabilities during connection establishment:
Headers to use for the web socket connection. Only works in the Node.js environment.
WebDriver BiDi capabilities passed to BiDisession.new. Only works forprotocol="webDriverBiDi"andPuppeteer.connect.
Sources: packages/puppeteer-core/src/common/ConnectOptions.ts:1-50
Target Model
Puppeteer's BiDi implementation extends the abstract Target class with browser-specific target types:
BidiBrowserTarget
Represents the browser-level target in WebDriver BiDi context:
export class BidiBrowserTarget extends Target {
#browser: BidiBrowser;
override type(): TargetType {
return TargetType.BROWSER;
}
override browser(): BidiBrowser {
return this.#browser;
}
override browserContext(): BidiBrowserContext {
return this.#browser.defaultBrowserContext();
}
}
Unsupported operations throw UnsupportedOperation:
asPage()- Not supported at browser target levelcreateCDPSession()- CDP sessions not available in BiDi-only targetsopener()- Not applicable to browser targets
Sources: packages/puppeteer-core/src/bidi/Target.ts:1-50
BidiPageTarget
Represents individual page targets within the browser context. Extends the base Target with page-specific behavior through composition with BidiPage.
Console Message Handling
WebDriver BiDi requires conversion between BiDi console event levels and Puppeteer's internal representation:
export function convertConsoleMessageLevel(method: string): ConsoleMessageType {
switch (method) {
case 'group':
return 'startGroup';
case 'groupCollapsed':
return 'startGroupCollapsed';
case 'groupEnd':
return 'endGroup';
default:
return method as ConsoleMessageType;
}
}
This mapping ensures that BiDi's console event semantics align with Puppeteer's console message types.
Sources: packages/puppeteer-core/src/bidi/util.ts:1-40
Stack Trace Extraction
Console messages can include stack trace information extracted from BiDi protocol responses:
export function getStackTraceLocations(
stackTrace?: Bidi.Script.StackTrace,
): ConsoleMessageLocation[] {
const stackTraceLocations: ConsoleMessageLocation[] = [];
if (stackTrace) {
for (const callFrame of stackTrace.callFrames) {
stackTraceLocations.push({
url: callFrame.url,
lineNumber: callFrame.lineNumber,
columnNumber: callFrame.columnNumber,
});
}
}
return stackTraceLocations;
}
Firefox-Specific Configuration
Firefox has native WebDriver BiDi support and provides specific preferences configuration:
| Preference | Value | Purpose |
|---|---|---|
fission.bfcacheInParent | undefined | BFCache behavior |
fission.webContentIsolationStrategy | 0 | Process isolation strategy |
Blocklist and Allowlist
Firefox's WebDriver BiDi implementation supports blocklist/allowlist configuration through preferences. However, these are only supported with the CDP protocol:
it('should reject blocklist for the default Firefox WebDriver BiDi protocol', async () => {
const launcher = new FirefoxLauncher({} as PuppeteerNode);
await expect(
launcher.launch({
blocklist: ['https://example.com/*'],
}),
).rejects.toThrow(
'blocklist and allowlist are only supported with the CDP protocol',
);
});
Sources: packages/puppeteer-core/src/node/FirefoxLauncher.test.ts:1-40
Core Components
| Component | File | Responsibility |
|---|---|---|
| Browser | bidi/Browser.ts | Main browser instance management |
| BrowsingContext | bidi/core/BrowsingContext.ts | Tab/window context handling |
| Navigation | bidi/core/Navigation.ts | Navigation event handling |
| Page | bidi/Page.ts | Page-level operations |
| Realm | bidi/Realm.ts | JavaScript execution contexts |
Protocol Modes
Puppeteer supports three protocol configuration modes:
graph LR
A[Default] --> B[CDP + BiDi]
C[PUPPETEER_WEBDRIVER_BIDI_ONLY=true] --> D[BiDi Only]
E[protocol=webDriverBiDi] --> D| Mode | CDP Available | BiDi Available | Use Case |
|---|---|---|---|
| Default | Yes | Yes (via bridge) | Chrome automation |
| BiDi Only | No | Yes | Pure spec compliance |
| WebDriver BiDi | No | Native | Firefox automation |
Summary
The WebDriver BiDi implementation in Puppeteer provides:
- Standards-compliant protocol support through the
bidi/coremodule following W3C WebDriver BiDi specification - Flexible connection architecture supporting CDP bridge and native BiDi modes
- Browser-agnostic target model with proper abstraction layers
- Event integrity ensuring semantically correct event sequences per protocol spec
- Cross-browser compatibility with native Firefox BiDi support and Chrome CDP bridging
Sources: [packages/puppeteer-core/src/bidi/core/README.md]()
Page API
Related topics: Locators and Element Handles, Input Handling
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Locators and Element Handles, Input Handling
Page API
The Page API is the core interface in Puppeteer for interacting with browser pages and tabs. It provides methods for navigating pages, interacting with DOM elements, evaluating JavaScript, handling events, and emulating various browser environments and device characteristics.
Overview
The Page API serves as the primary abstraction for browser page operations in Puppeteer. A Page instance represents a single tab or window within a browser instance, offering a comprehensive set of methods to control page behavior, extract data, and automate interactions.
graph TD
A[Browser Instance] --> B[Page API]
B --> C[Navigation]
B --> D[DOM Interaction]
B --> E[JavaScript Evaluation]
B --> F[Event Handling]
B --> G[Device Emulation]
C --> C1[goto, back, forward, reload]
D --> D1[$, $$, locator]
E --> E1[evaluate, exposeFunction]
F --> F1[on, once, off]
G --> G1[emulateMediaType, emulate]Sources: packages/puppeteer-core/src/api/Page.ts:1-50
Core Architecture
Class Hierarchy
The Page class extends EventEmitter and serves as an abstract base class implemented by both CDP (Chrome DevTools Protocol) and WebDriver BiDi backends:
classDiagram
class EventEmitter~PageEvents~ {
<<abstract>>
}
class Page {
<<abstract>>
+_isDragging: boolean
+_timeoutSettings: TimeoutSettings
+_tabId: string
+exposeFunction()
+metrics()
+captureHeapSnapshot()
+emulateMediaType()
+emulateCPUThrottling()
+emulateMediaFeatures()
}
class CDPPage {
+implementation
}
class BiDiPage {
+implementation
}
EventEmitter <|-- Page
Page <|-- CDPPage
Page <|-- BiDiPageSources: packages/puppeteer-core/src/api/Page.ts:200-230
Internal State Management
The Page class maintains several internal state properties:
| Property | Type | Purpose |
|---|---|---|
_isDragging | boolean | Tracks drag state for mouse interactions |
_timeoutSettings | TimeoutSettings | Manages timeout configuration for operations |
_tabId | string | Browser-specific tab identifier |
#inflight$ | ReplaySubject<number> | Tracks in-flight request count |
#requestHandlers | WeakMap | Maps request handlers for monitoring |
Sources: packages/puppeteer-core/src/api/Page.ts:200-215
Navigation API
Basic Navigation Methods
The Page API provides fundamental navigation methods for controlling page loading:
goto(url)- Navigate to a URLreload()- Reload the current pagegoBack()- Navigate to the previous page in historygoForward()- Navigate to the next page in historyclose()- Close the page
URL Property
The url() method returns the current page URL as a shortcut for page.mainFrame().url():
const currentUrl = await page.url();
Sources: packages/puppeteer-core/src/api/Page.ts:280-295
JavaScript Evaluation
evaluate Method
The evaluate method executes JavaScript code in the page context. It supports both string expressions and function-based evaluation.
Sources: packages/puppeteer-core/src/cdp/ExecutionContext.ts:30-60
evaluate with Parameters
When passing arguments to page functions, Puppeteer serializes them using a specialized mechanism:
await page.evaluate(
(text, inputValue) => {
document.querySelector(text).value = inputValue;
},
'selector',
'value'
);
Sources: packages/puppeteer-core/src/cdp/ExecutionContext.ts:45-55
Source URL Comment Injection
Puppeteer automatically injects source URL comments into evaluated code to enable better debugging and source map support:
const sourceUrlComment = getSourceUrlComment(
getSourcePuppeteerURLIfAvailable(pageFunction)?.toString() ??
PuppeteerURL.INTERNAL_URL,
);
The injection follows this pattern:
- Check if the expression already contains a source URL
- If not, append the source URL comment to the expression
- Include this comment in the CDP
Runtime.evaluatecall
Sources: packages/puppeteer-core/src/cdp/ExecutionContext.ts:35-45
exposeFunction API
The exposeFunction method allows exposing Node.js functions to the page's JavaScript context as window[name]:
Signature
abstract exposeFunction(
name: string,
pptrFunction: Function | {default: Function}
): Promise<void>;
Usage Example
const browser = await puppeteer.launch();
const page = await browser.newPage();
page.on('console', msg => console.log(msg.text()));
await page.exposeFunction('readfile', async filePath => {
return fs.readFileSync(filePath, 'utf8');
});
await page.evaluate(async () => {
const content = await window.readfile('/etc/hosts');
console.log(content);
});
await browser.close();
Parameters
| Parameter | Type | Description | |
|---|---|---|---|
name | string | Name of the function on the window object | |
pptrFunction | `Function \ | {default: Function}` | Callback function executed in Puppeteer's Node.js context |
Sources: packages/puppeteer-core/src/api/Page.ts:140-175
Device Emulation
Emulate Media Type
The emulateMediaType method emulates CSS media type on the page:
await page.emulateMediaType('print');
await page.evaluate(() => matchMedia('print').matches); // true
await page.emulateMediaType(null); // Reset to default
Sources: packages/puppeteer-core/src/api/Page.ts:320-345
Emulate Media Features
The emulateMediaFeatures method emulates CSS media features:
await page.emulateMediaFeatures([
{ name: 'prefers-color-scheme', value: 'dark' },
]);
Sources: packages/puppeteer-core/src/api/Page.ts:345-360
Known Devices
Puppeteer provides a predefined set of device descriptors via KnownDevices:
import { KnownDevices } from 'puppeteer';
const iPhone = KnownDevices['iPhone 15 Pro'];
await page.emulate(iPhone);
Sources: packages/puppeteer-core/src/common/Device.ts:1-30
CPU Throttling
The emulateCPUThrottling method enables CPU throttling to simulate slow CPUs:
// No throttling (1x speed)
await page.emulateCPUThrottling(1);
// 2x slowdown
await page.emulateCPUThrottling(2);
// Disable throttling
await page.emulateCPUThrottling(null);
Sources: packages/puppeteer-core/src/api/Page.ts:355-360
Metrics API
The metrics() method returns performance metrics from the browser:
Returned Metrics
| Metric | Description |
|---|---|
Timestamp | Monotonic timestamp when sample was taken |
Documents | Number of documents in the page |
Frames | Number of frames in the page |
JSEventListeners | Number of JavaScript event listeners |
Nodes | Number of DOM nodes |
LayoutCount | Total full or partial page layouts |
RecalcStyleCount | Total style recalculations |
LayoutDuration | Combined layout duration |
RecalcStyleDuration | Combined style recalculation duration |
ScriptDuration | Combined JavaScript execution duration |
TaskDuration | Combined browser task duration |
JSHeapUsedSize | Used JavaScript heap size |
JSHeapTotalSize | Total JavaScript heap size |
Sources: packages/puppeteer-core/src/api/Page.ts:260-280
Heap Snapshot
The captureHeapSnapshot method captures a snapshot of the JavaScript heap:
await page.captureHeapSnapshot({ path: 'screenshot.png' });
Sources: packages/puppeteer-core/src/api/Page.ts:285-290
Locator API
The Page API integrates with Puppeteer's Locator API for reliable element interactions:
Available Locator Methods
// Query elements using various selector types
const element = page.locator('button.submit');
const elements = page.locator('.item');
// ARIA selectors
const searchInput = page.locator('::-p-aria(Search)');
// Text selectors
const title = page.locator('::-p-text(Customize and automate)');
// XPath selectors
const para = page.locator('::-p-xpath(//p[@class="intro"])');
// CSS with pierce (shadow DOM)
const shadowElement = page.locator(':scope >>> .shadow-content');
Sources: packages/puppeteer-core/src/api/locators/locators.ts:1-50
LazyArg System
The LazyArg system provides lazy evaluation of arguments passed to page functions:
export class LazyArg<T, Context = PuppeteerUtilWrapper> {
static create = <T>(
get: (context: PuppeteerUtilWrapper) => Promise<T> | T
): T => {
return new LazyArg(get) as unknown as T;
};
async get(context: Context): Promise<T> {
return await this.#get(context);
}
}
This allows arguments to be evaluated on-demand in the browser context, avoiding serialization issues with complex objects.
Sources: packages/puppeteer-core/src/common/LazyArg.ts:1-40
Event Handling
The Page class extends EventEmitter and emits various events documented in the PageEvent enum:
Basic Event Usage
// Listen for a single event
page.once('load', () => console.log('Page loaded!'));
// Listen for ongoing events
page.on('request', request => {
console.log('Request:', request.url());
});
// Unsubscribe from events
function logRequest(request) {
console.log('A request was made:', request.url());
}
page.on('request', logRequest);
page.off('request', logRequest);
Sources: packages/puppeteer-core/src/api/Page.ts:180-200
Error Handling
Evaluation Errors
When JavaScript evaluation fails, Puppeteer throws a descriptive error:
const { exceptionDetails, result } = await this.#client.send(
'Runtime.evaluate',
{
expression: expressionWithSourceUrl,
contextId,
returnByValue,
awaitPromise: true,
userGesture: true,
}
).catch(rewriteError);
if (exceptionDetails) {
throw createEvaluationError(exceptionDetails);
}
Sources: packages/puppeteer-core/src/cdp/ExecutionContext.ts:50-65
Implementation Backends
CDP (Chrome DevTools Protocol) Backend
The CDP implementation uses Chrome's native DevTools Protocol for communication:
- Located in
packages/puppeteer-core/src/cdp/Page.ts - Direct protocol-level control
- Lower-level access to browser features
WebDriver BiDi Backend
The BiDi implementation provides cross-browser compatibility:
- Located in
packages/puppeteer-core/src/bidi/Page.ts - Standardized WebDriver protocol
- Broader browser support
Summary
The Page API provides a comprehensive abstraction layer for browser page automation in Puppeteer. Key capabilities include:
| Category | Features |
|---|---|
| Navigation | URL access, goto, reload, back, forward |
| JavaScript | evaluate, exposeFunction, handle serialization |
| Emulation | Media types, media features, CPU throttling, device profiles |
| Metrics | Performance metrics, heap snapshots |
| Interaction | Locators, event handling, drag simulation |
| State | Timeout settings, tab identification, request tracking |
The abstract Page class is implemented by both CDP and BiDi backends, ensuring flexibility and cross-browser compatibility while maintaining a consistent API surface for users.
Source: https://github.com/puppeteer/puppeteer / Human Manual
Locators and Element Handles
Related topics: Page API, Input Handling
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Page API, Input Handling
Locators and Element Handles
Overview
Puppeteer provides two complementary mechanisms for interacting with DOM elements in a browser page: Locators and Element Handles. Both serve the purpose of referencing and manipulating elements, but they differ significantly in their design philosophy, retry behavior, and use cases.
- Element Handles provide direct, immediate references to DOM elements. They are point-in-time references that do not automatically retry if elements become stale or unavailable.
- Locators are designed for reliability and resilience. They automatically retry actions until the element is in the correct state, making them ideal for modern web applications with dynamic content.
Sources: packages/puppeteer-core/src/api/ElementHandle.ts:1-50
graph TD
A[User Code] --> B{Choose Strategy}
B --> C[ElementHandle]
B --> D[Locator]
C --> E[Direct DOM Reference]
C --> F[No Auto-Retry]
D --> G[Query Strategy + Retry Logic]
D --> H[State Awareness]
D --> I[Action Chaining]Element Handles
Purpose and Scope
Element Handles are direct references to DOM elements obtained through query methods like page.$() or page.$$(). They provide low-level access to elements but require manual management of element lifecycle.
Sources: packages/puppeteer-core/src/api/ElementHandle.ts:40-60
Class Definition
export abstract class ElementHandle<
ElementType extends Node = Element,
> extends JSHandle<ElementType> {
/**
* @internal
*/
declare [_isElementHandle]: boolean;
/**
* @internal
* Cached isolatedHandle to prevent
* trying to adopt it multiple times
*/
isolatedHandle?: typeof this;
/**
* @internal
*/
protected readonly handle;
}
Sources: packages/puppeteer-core/src/api/ElementHandle.ts:40-58
Key Characteristics
| Characteristic | Description |
|---|---|
| Lifecycle | Auto-disposed when frame navigates or context is destroyed |
| Garbage Collection | Prevents GC while handle exists unless explicitly disposed |
| Type Safety | Generic type parameter for element type (e.g., ElementHandle<HTMLSelectElement>) |
| Usage | Used as arguments in Page.$eval and Page.evaluate |
Query Methods
Element Handles can be created using the following Page/Frame methods:
| Method | Returns | Description | |
|---|---|---|---|
page.$(selector) | `ElementHandle \ | null` | First element matching selector |
page.$$(selector) | ElementHandle[] | All elements matching selector | |
frame.$(selector) | `ElementHandle \ | null` | First element in frame |
frame.$$(selector) | ElementHandle[] | All elements in frame |
Sources: packages/puppeteer-core/src/api/Frame.ts:100-130
Memory Management with `using`
Puppeteer provides an ESLint rule to enforce proper disposal of Element Handles using the using keyword. This ensures handles are automatically cleaned up when they go out of scope.
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
// Using 'using' ensures proper cleanup
using element = await page.$('a');
await element.click();
Sources: tools/eslint/src/use-using.ts:1-50
const usingSymbols = ['ElementHandle', 'JSHandle'];
Sources: tools/eslint/src/use-using.ts:12
Locators
Purpose and Design Philosophy
Locators are Puppeteer's recommended approach for element interaction. They encapsulate both the query strategy and retry logic, providing a robust way to handle flaky tests in modern web applications where elements may appear, disappear, or change state dynamically.
Sources: packages/puppeteer-core/src/api/Page.ts:1-100
Locator API
Locators are created through the locator() method on Page or Frame:
locator<Selector extends string>(
selector: Selector,
): Locator<NodeFor<Selector>>;
locator<Ret>(func: () => Awaitable<Ret>): Locator<Ret>;
Supported Selector Types
Puppeteer supports multiple selector types that can be used with both Element Handles and Locators:
| Selector Type | Syntax | Description |
|---|---|---|
| CSS | '<css>' | Standard CSS selectors |
| Text | ::-p-text(<text>) | Elements containing text |
| ARIA | ::-p-aria(<role>[name]) | Accessibility-based selection |
| XPath | xpath=<xpath> | XPath expressions |
| Pierce | >>> <selector> | Cross-shadow-DOM queries |
| Custom | Custom prefix | User-defined query handlers |
Sources: packages/puppeteer-core/src/common/CSSQueryHandler.ts
Query Handlers Architecture
Query handlers are the pluggable components that process different selector types.
classDiagram
class QueryHandler {
<<interface>>
+query(page, selector)
+queryAll(page, selector)
}
class CSSQueryHandler {
+query(page, selector)
+queryAll(page, selector)
}
class AriaQueryHandler {
+query(page, selector)
+queryAll(page, selector)
}
class CustomQueryHandler {
+query(page, selector)
+queryAll(page, selector)
}
class XPathQueryHandler {
+query(page, selector)
+queryAll(page, selector)
}
QueryHandler <|.. CSSQueryHandler
QueryHandler <|.. AriaQueryHandler
QueryHandler <|.. CustomQueryHandler
QueryHandler <|.. XPathQueryHandlerCSS Query Handler
The CSS Query Handler processes standard CSS selectors and is the default handler for selectors without a prefix.
// Internal implementation delegates to injected PQuerySelector
export class CSSQueryHandler extends QueryHandler {
#pquerySelector: PQuerySelector;
// Uses PuppeteerInjectedScript for DOM queries
}
Sources: packages/puppeteer-core/src/common/CSSQueryHandler.ts
Aria Query Handler
The ARIA Query Handler enables selection based on accessibility attributes:
// Select by role and optional name
await page.locator('::-p-aria(Search)').fill('query');
await page.locator('::-p-aria(Submit button[name])').click();
Sources: packages/puppeteer-core/src/common/AriaQueryHandler.ts
Custom Query Handlers
Puppeteer allows registration of custom query handlers for domain-specific selectors:
page.customQueryHandlers.set('mySelector', {
queryOne: (self, selector) => { /* ... */ },
queryAll: (self, selector) => { /* ... */ },
});
Comparison: Locators vs Element Handles
| Aspect | Element Handles | Locators |
|---|---|---|
| Retry Behavior | None - immediate result | Automatic retry until element ready |
| State Awareness | None | Tracks element state |
| Flakiness Handling | Manual | Built-in |
| Performance | Faster for single operation | Slight overhead for retry logic |
| Use Case | Simple scripts, single operations | Dynamic applications, tests |
| Stale Element Handling | Manual detection and re-query | Automatic re-query |
graph LR
A[Action Request] --> B{Locator}
B --> C{Element visible?}
C -->|No| D[Wait & Retry]
D --> C
C -->|Yes| E[Perform Action]
F[Action Request] --> G{ElementHandle}
G --> H[Immediate Result]
H --> I[Perform Action]
I --> J{Still valid?}
J -->|No| K[StaleElementReference Error]Best Practices
When to Use Locators
- Recommended for most use cases
- Testing modern web applications with dynamic content
- When element availability timing is uncertain
- Building resilient automation scripts
When to Use Element Handles
- Quick scripts with predictable DOM
- When performance is critical
- Low-level DOM manipulation
- Integration with other libraries expecting handles
Memory Management
Always dispose of handles to prevent memory leaks:
// Using async disposal
const handle = await page.$('div');
try {
// Work with handle
} finally {
await handle.dispose();
}
// Or use 'using' keyword where supported
using element = await page.$('a');
ESLint Integration
Enable the use-using rule to enforce proper handle disposal:
{
"rules": {
"@puppeteer/use-using": "error"
}
}
Sources: tools/eslint/src/use-using.ts:20-60
Examples
Basic Element Handle Usage
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
// Single element
const hrefElement = await page.$('a');
await hrefElement.click();
// Multiple elements
const links = await page.$$('a');
for (const link of links) {
const text = await link.evaluate(el => el.textContent);
console.log(text);
}
await browser.close();
Sources: packages/puppeteer-core/src/api/ElementHandle.ts:10-30
Locator with Action Chaining
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
// Chain actions on locator
await page.locator('::-p-aria(Search)').fill('query');
await page.locator('.devsite-result-item-link').click();
// Wait for element with locator
const textSelector = await page
.locator('::-p-text(Customize and automate)')
.waitHandle();
await browser.close();
Using $$eval for Batch Operations
const allInputValues = await page.$$eval('input', elements =>
elements.map(e => e.textContent),
);
Sources: packages/puppeteer-core/src/api/Page.ts:1-50
Architecture Summary
graph TD
subgraph "User Layer"
A[page.$()]
B[page.locator()]
C[frame.$$()]
end
subgraph "Query Handler Layer"
D[CSSQueryHandler]
E[AriaQueryHandler]
F[CustomQueryHandler]
G[XPathQueryHandler]
end
subgraph "Execution Layer"
H[CDP Protocol]
I[BiDi Protocol]
end
A --> D
B --> D
B --> E
C --> F
D --> H
D --> I
E --> H
F --> H
style A fill:#e1f5fe
style B fill:#e8f5e8
style D fill:#fff3e0
style E fill:#fff3e0See Also
Sources: [packages/puppeteer-core/src/api/ElementHandle.ts:1-50]()
Input Handling
Related topics: Locators and Element Handles, Page API
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Locators and Element Handles, Page API
Input Handling
Input Handling in Puppeteer provides a unified API for simulating user interactions with web pages, including keyboard input, mouse operations, touch gestures, and drag-and-drop actions. The system abstracts away protocol-level differences between Chrome DevTools Protocol (CDP) and WebDriver BiDi, providing developers with a consistent interface for browser automation.
Architecture Overview
Puppeteer's Input Handling system follows a layered architecture:
graph TD
A[User Code] --> B[Page API / ElementHandle API]
B --> C[Protocol-Agnostic Input Interface]
C --> D[CDP Implementation<br/>packages/puppeteer-core/src/cdp/Input.ts]
C --> E[BiDi Implementation<br/>packages/puppeteer-core/src/bidi/Input.ts]
D --> F[Chrome DevTools Protocol]
E --> G[WebDriver BiDi Protocol]
F --> H[Browser Instance]
G --> HThe system is organized around three core input interfaces defined in the abstract layer:
| Interface | Purpose |
|---|---|
Keyboard | Simulates keyboard input including key presses, typing, and modifier keys |
Mouse | Controls mouse movement, clicking, and wheel scrolling |
Touch | Simulates touch-based interactions on mobile devices |
DragAndDrop | Manages drag source and drop target operations |
Sources: packages/puppeteer-core/src/api/Input.ts:1-200
Keyboard Input
Keyboard Interface Methods
The Keyboard interface provides four primary methods for simulating keyboard input:
| Method | Description |
|---|---|
down(key, options?) | Presses a key down without releasing it |
up(key) | Releases a pressed key |
type(text, options?) | Types text character by character |
press(key, options?) | Combines down + up (with optional delay) |
Sources: packages/puppeteer-core/src/api/Input.ts:47-75
Key Input Values
Puppeteer uses the KeyInput enum to define all supported keyboard keys. Common values include:
- Modifier Keys:
Alt,Control,Meta,Shift - Arrow Keys:
ArrowUp,ArrowDown,ArrowLeft,ArrowRight - Function Keys:
F1throughF12 - Special Keys:
Enter,Tab,Escape,Backspace,Delete,Space - Alpha-Numeric: Standard letter and number keys (e.g.,
a,A,1)
Type vs Press
The type() method sends keydown, keypress/input, and keyup events for each character in the text. Unlike press(), modifier keys do not affect type() - holding Shift will not type uppercase characters.
await page.keyboard.type('Hello'); // Types instantly
await page.keyboard.type('World', {delay: 100}); // Types with 100ms between each key
The press() method is a shortcut combining down() and up(). If the key is a single character with no modifiers besides Shift, a keypress/input event is also generated.
await page.keyboard.press('Enter');
await page.keyboard.press('Control', {delay: 100});
await page.keyboard.press('KeyA', {text: 'a'});
Sources: packages/puppeteer-core/src/api/Input.ts:35-75
Keyboard Options
| Option | Type | Description |
|---|---|---|
delay | number | Time in milliseconds between keydown and keyup (default: 0) |
text | string | Forces an input event with this text |
commands | string[] | Browser command names for keyboard shortcuts |
Sources: packages/puppeteer-core/src/api/Input.ts:26-33
Mouse Input
Mouse Interface Methods
The Mouse interface provides precise control over cursor movement and clicking:
| Method | Description |
|---|---|
move(x, y, options?) | Moves the mouse to the specified coordinates |
down(options?) | Presses the mouse button |
up(options?) | Releases the mouse button |
click(x, y, options?) | Performs a full click (down + up) at coordinates |
wheel(options?) | Scrolls the page |
Sources: packages/puppeteer-core/src/api/Input.ts:92-132
Mouse Click Options
| Option | Type | Default | Description |
|---|---|---|---|
button | MouseButton | 'left' | Which button to click |
clickCount | number | 1 | Number of clicks (for double-click) |
delay | number | 0 | Delay between mousedown and mouseup in ms |
Sources: packages/puppeteer-core/src/api/Input.ts:135-155
Mouse Move Options
| Option | Type | Default | Description |
|---|---|---|---|
steps | number | 1 | Number of intermediate mouse moves for smooth transitions |
Sources: packages/puppeteer-core/src/api/Input.ts:157-170
Mouse Wheel Options
| Option | Type | Default | Description |
|---|---|---|---|
deltaX | number | 0 | Horizontal scroll amount |
deltaY | number | 0 | Vertical scroll amount |
Sources: packages/puppeteer-core/src/api/Input.ts:172-187
Click Workflow
sequenceDiagram
participant User
participant Mouse as Mouse Interface
participant Page as Page
User->>Mouse: click(x, y, {button: 'left', clickCount: 2})
Mouse->>Page: mouseMoved(x, y)
Mouse->>Page: mousePressed(x, y, button: 'left', clickCount: 1)
Mouse->>Page: mouseReleased(x, y, button: 'left', clickCount: 1)
Mouse->>Page: mousePressed(x, y, button: 'left', clickCount: 2)
Mouse->>Page: mouseReleased(x, y, button: 'left', clickCount: 2)Touch Input
The Touch interface simulates touch interactions for mobile device testing:
| Method | Description |
|---|---|
tap(x, y) | Performs a tap at the specified coordinates |
touchStart(x, y) | Starts a touch at the coordinates |
touchMove(x, y) | Moves the touch to new coordinates |
touchEnd() | Ends the current touch sequence |
Sources: packages/puppeteer-core/src/api/Input.ts:194-210
Drag and Drop
The DragAndDrop interface handles drag interactions:
| Method | Description |
|---|---|
drag(source, destination) | Drags from source to destination, returns drag data |
drop(x, y, data) | Drops data at the specified coordinates |
Sources: packages/puppeteer-core/src/api/Input.ts:212-220
High-Level Element Interactions
For common use cases, Puppeteer provides convenience methods on Page and ElementHandle that handle input internally.
Page-Level Input
The Page class exposes input methods that operate on the main frame:
// Type text into an element
await page.type('#mytextarea', 'Hello');
await page.type('#mytextarea', 'World', {delay: 100});
// Press a special key
await page.keyboard.press('Enter');
await page.keyboard.press('ArrowDown');
Sources: packages/puppeteer-core/src/api/Page.ts:1800-1820
ElementHandle Input
ElementHandle provides element-specific input methods:
const element = await page.$('#input-field');
// Focus the element and type
await element.type('Hello');
// Focus the element and press a key
await element.press('Enter');
Both methods automatically focus the element before performing the input action:
async type(
text: string,
options?: Readonly<KeyboardTypeOptions>,
): Promise<void> {
await this.focus();
await this.frame.page().keyboard.type(text, options);
}
async press(
key: KeyInput,
options?: Readonly<KeyPressOptions>,
): Promise<void> {
await this.focus();
await this.frame.page().keyboard.press(key, options);
}
Sources: packages/puppeteer-core/src/api/ElementHandle.ts:620-640
Implementation Strategies
CDP Implementation
The Chrome DevTools Protocol implementation translates abstract input calls into CDP commands:
Input.dispatchMouseEventfor mouse operationsInput.dispatchKeyEventfor keyboard operations- Direct touch event dispatching
The CDP implementation handles the translation of keyboard codes using US keyboard layout definitions.
BiDi Implementation
The WebDriver BiDi implementation uses the BiDi specification's input module:
- Maps to BiDi
input.performActionscommand - Handles serialization of input actions across the protocol wire
US Keyboard Layout
The USKeyboardLayout module provides key code mappings for US keyboards:
export const USKeyboardLayout: Map<string, number> = new Map([
['a', 0x61],
['A', 0x41],
['b', 0x62],
// ... additional mappings
]);
Sources: packages/puppeteer-core/src/common/USKeyboardLayout.ts:1-100
Best Practices
- Use
press()for special keys: Instead oftype()for special characters, usepress()with key names likeEnter,Tab, orEscape.
- Add delays for realistic simulation: When testing UI behavior that depends on timing, use the
delayoption:
``typescript await page.type('#search', 'query', {delay: 100}); ``
- Focus elements before typing: When using
ElementHandleinput methods, the element is automatically focused. For direct keyboard access, ensure the target is focused first.
- Use
click()overdown()/up(): Theclick()method handles the complete click lifecycle and is less error-prone.
- Consider
LocatorAPI for reliability: For improved reliability in element interactions, consider using Puppeteer's experimental Locators API.
Related Components
| Component | Purpose |
|---|---|
Page | Exposes input methods on the main frame |
ElementHandle | Element-specific keyboard input |
Frame | Frame-level input access |
Keyboard | Low-level keyboard simulation |
Mouse | Low-level mouse control |
Touch | Touch interaction simulation |
DragAndDrop | Drag and drop operations |
Sources: [packages/puppeteer-core/src/api/Input.ts:1-200]()
Browser Launching
Related topics: Package Structure
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Package Structure
Browser Launching
Overview
Browser launching is a core system in Puppeteer that handles the initialization and lifecycle management of browser instances. This system provides a unified interface for launching different browser types (Chrome, Firefox) while abstracting platform-specific details and managing process signals, timeouts, and executable paths.
The browser launching subsystem consists of several key components:
- BrowserLauncher: Abstract base class defining the launching interface
- ChromeLauncher: Implementation for Chrome/Chromium-based browsers
- FirefoxLauncher: Implementation for Firefox
- @puppeteer/browsers: Standalone package for programmatic browser management
Architecture
Class Hierarchy
graph TD
A[BrowserLauncher] --> B[ChromeLauncher]
A --> C[FirefoxLauncher]
D[launch.ts] --> E[Browser Process]
F[install.ts] --> G[Browser Binaries]
style A fill:#e1f5fe
style B fill:#e8f5e8
style C fill:#fff3e0Browser Launch Flow
sequenceDiagram
participant User
participant Puppeteer
participant BrowserLauncher
participant BrowserProcess
participant CDP
User->>Puppeteer: puppeteer.launch(options)
Puppeteer->>BrowserLauncher: createLauncher(options)
BrowserLauncher->>BrowserLauncher: resolveExecutablePath()
BrowserLauncher->>BrowserLauncher: buildArguments()
BrowserLauncher->>BrowserProcess: spawn(executable, args)
BrowserProcess-->>BrowserLauncher: process started
BrowserLauncher->>BrowserLauncher: setupSignalHandlers()
BrowserLauncher->>CDP: connect(wsEndpoint)
CDP-->>Puppeteer: Browser instance
User->>Puppeteer: browser operations
User->>Puppeteer: browser.close()
Puppeteer->>BrowserProcess: terminate()Launch Options
The LaunchOptions interface defines all configuration parameters available when launching a browser. These options control executable selection, argument passing, signal handling, and timeout behavior.
Core Configuration
| Option | Type | Default | Description | |
|---|---|---|---|---|
executablePath | string | bundled browser | Path to a specific browser executable. When using this, Puppeteer cannot guarantee compatibility. | |
ignoreDefaultArgs | `boolean \ | string[]` | false | Controls whether default arguments are passed to the browser. Array mode filters specific args. |
enableExtensions | `boolean \ | string[]` | false | Enables browser extensions. String array loads extensions from paths. |
Signal Handling
Puppeteer manages browser process lifecycle through POSIX signal handling:
| Option | Type | Default | Description |
|---|---|---|---|
handleSIGINT | boolean | true | Close browser on Ctrl+C (SIGINT) |
handleSIGTERM | boolean | true | Close browser on termination signal (SIGTERM) |
handleSIGHUP | boolean | true | Close browser on terminal hangup (SIGHUP) |
Timeout Configuration
| Option | Type | Default | Description |
|---|---|---|---|
timeout | number | 30,000 (30 seconds) | Maximum time in milliseconds to wait for browser startup. Pass 0 to disable timeout. |
Browser Installation
CLI Installation
The @puppeteer/browsers package provides command-line tools for downloading and managing browser binaries:
# Download latest stable Chrome
npx @puppeteer/browsers install chrome@stable
# Download specific version
npx @puppeteer/browsers install [email protected]
# Download by milestone
npx @puppeteer/browsers install chrome@117
# Download ChromeDriver
npx @puppeteer/browsers install chromedriver@canary
# List installed browsers
npx @puppeteer/browsers list
# Clear all browsers
npx @puppeteer/browsers clear
Configuration Options
The Configuration interface controls download behavior:
| Option | Environment Variable | Default | Description |
|---|---|---|---|
skipDownload | PUPPETEER_SKIP_DOWNLOAD | false | Skip browser download during installation |
temporaryDirectory | PUPPETEER_TMP_DIR | os.tmpdir() | Directory for temporary files |
logLevel | - | warn | Logging level: silent, error, warn |
Browser-Specific Settings
Each browser type supports independent configuration:
| Browser | Skip Download Env Var | Download Base URL Env Var | Version Env Var |
|---|---|---|---|
| Chrome | PUPPETEER_CHROME_SKIP_DOWNLOAD | PUPPETEER_CHROME_DOWNLOAD_BASE_URL | PUPPETEER_CHROME_VERSION |
| Chrome Headless Shell | PUPPETEER_CHROME_HEADLESS_SHELL_SKIP_DOWNLOAD | PUPPETEER_CHROME_HEADLESS_SHELL_DOWNLOAD_BASE_URL | - |
| Firefox | PUPPETEER_FIREFOX_SKIP_DOWNLOAD | PUPPETEER_FIREFOX_DOWNLOAD_BASE_URL | PUPPETEER_FIREFOX_VERSION |
Download Base URLs
| Browser | Default URL |
|---|---|
| Chrome | https://storage.googleapis.com/chrome-for-testing-public |
| Firefox | https://archive.mozilla.org/pub/firefox/releases |
Chrome Launcher
The ChromeLauncher handles launching Chrome and Chromium-based browsers. It manages the Chrome DevTools Protocol (CDP) connection and applies Chrome-specific default arguments.
Key Responsibilities
- Executable Resolution: Locates the Chrome executable based on platform and configuration
- Argument Construction: Builds the complete argument list including default Chrome flags
- Profile Management: Creates temporary user data directories for isolated browser contexts
- CDP Connection: Establishes WebSocket connection to the browser's DevTools interface
Default Arguments
Chrome Launcher automatically includes secure defaults:
--no-sandbox(when not running as root on Linux)--disable-dev-shm-usage(prevents crashes in Docker environments)- Remote debugging port selection
Firefox Launcher
The FirefoxLauncher provides Firefox-specific launching capabilities with support for Mozilla's remote debugging protocol.
Differences from Chrome
- Uses Firefox's built-in DevTools protocol instead of CDP
- Handles Firefox-specific argument syntax
- Manages Firefox profile creation and cleanup
Browser Management
Programmatic Browser Management
The @puppeteer/browsers package allows programmatic browser control:
import {install, launch, clear, Browser} from '@puppeteer/browsers';
async function setupBrowser() {
// Install browser
const installOpts = {
browser: Browser.CHROME,
buildId: 'stable',
cacheDir: './browser-cache'
};
await install(installOpts);
// Launch browser
const launchOpts = {
executablePath: await getExecutablePath(installOpts),
args: ['--no-sandbox']
};
const browserProcess = await launch(launchOpts);
return browserProcess;
}
Browser Cleanup
Browsers installed by Puppeteer can be automatically cleaned up during version updates:
graph TD
A[Puppeteer Launch] --> B[Load Installed Browsers]
B --> C{Is Browser Current?}
C -->|Yes| D[Keep Browser]
C -->|No| E[Uninstall Old Build]
F[New Version Available] --> CThe cleanup process:
- Compares installed browser versions against Puppeteer's pinned versions
- Identifies browsers no longer managed by current Puppeteer
- Removes outdated browser builds using
uninstall()withbuildIdandplatform
Signal Handling Lifecycle
stateDiagram-v2
[*] --> Launching: launch()
Launching --> Running: Browser Started
Running --> Closing: close() / SIGINT / SIGTERM / SIGHUP
Closing --> [*]: Process Terminated
Running --> Running: New Page CreatedSignal Handler Configuration
| Signal | Default | Purpose |
|---|---|---|
SIGINT | Enabled | Ctrl+C interruption |
SIGTERM | Enabled | Process termination |
SIGHUP | Enabled | Terminal disconnect |
Disabling signal handlers is possible but not recommended as it may leave orphaned browser processes:
const browser = await puppeteer.launch({
handleSIGINT: false,
handleSIGTERM: false,
handleSIGHUP: false
});
Timeout Behavior
graph LR
A[launch()] --> B{timeout > 0?}
B -->|Yes| C[Wait ms]
B -->|No| D[No Timeout]
C --> E{Browser Ready?}
E -->|Yes| F[Return Browser]
E -->|No| G[Throw Timeout Error]
D --> FTimeout of 0 disables the startup timeout entirely, useful for:
- Debugging launch issues
- Slow systems with many browser dependencies
- Long initialization sequences
Best Practices
- Always use
await browser.close()to properly terminate browser processes - Set reasonable timeouts for production environments
- Use bundled browsers for guaranteed compatibility
- Enable signal handlers (default) for clean shutdowns
- Use
--no-sandboxonly when necessary for containerized environments
Related Components
| Component | Purpose |
|---|---|
Page | Browser page/tab abstraction |
BrowserContext | Isolated browser sessions |
HTTPRequest/HTTPResponse | Network request handling |
TimeoutSettings | Configurable timeout management |
Source References
- Launch options definition:
packages/puppeteer-core/src/node/LaunchOptions.ts:1-50 - Browser launcher base:
packages/puppeteer-core/src/node/BrowserLauncher.ts - Chrome-specific launch:
packages/puppeteer-core/src/node/ChromeLauncher.ts - Firefox-specific launch:
packages/puppeteer-core/src/node/FirefoxLauncher.ts - Browser installation:
packages/browsers/src/install.ts - Browser launch process:
packages/browsers/src/launch.ts - CLI definitions:
packages/browsers/src/CLI.ts:1-60
Source: https://github.com/puppeteer/puppeteer / Human Manual
Doramagic Pitfall Log
Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.
First-time setup may fail or require extra isolation and rollback planning.
First-time setup may fail or require extra isolation and rollback planning.
The project may affect permissions, credentials, data exposure, or host boundaries.
The project may affect permissions, credentials, data exposure, or host boundaries.
Doramagic Pitfall Log
Doramagic extracted 16 source-linked risk signals. Review them before installing or handing real data to the project.
1. Installation risk: Chrome Canary/Firefox Nightly test results
- Severity: high
- Finding: Installation risk is backed by a source signal: Chrome Canary/Firefox Nightly test results. Treat it as a review item until the current version is checked.
- User impact: First-time setup may fail or require extra isolation and rollback planning.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/puppeteer/puppeteer/issues/12379
2. Installation risk: Puppeteer v25
- Severity: high
- Finding: Installation risk is backed by a source signal: Puppeteer v25. Treat it as a review item until the current version is checked.
- User impact: First-time setup may fail or require extra isolation and rollback planning.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/puppeteer/puppeteer/issues/14342
3. Security or permission risk: [Bug]: GHSA issued a false malicious package alert for puppeteer
- Severity: high
- Finding: Security or permission risk is backed by a source signal: [Bug]: GHSA issued a false malicious package alert for puppeteer. Treat it as a review item until the current version is checked.
- User impact: The project may affect permissions, credentials, data exposure, or host boundaries.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/puppeteer/puppeteer/issues/14986
4. Security or permission risk: [Task]: Flaky `[fixtures.spec] Fixtures should dump browser process stderr`
- Severity: high
- Finding: Security or permission risk is backed by a source signal: [Task]: Flaky
[fixtures.spec] Fixtures should dump browser process stderr. Treat it as a review item until the current version is checked. - User impact: The project may affect permissions, credentials, data exposure, or host boundaries.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/puppeteer/puppeteer/issues/14774
5. Installation risk: [Bug]: @puppeteer/browsers silently corrupts Chrome cache on Node.js 26 (extract-zip 2.0.1)
- Severity: medium
- Finding: Installation risk is backed by a source signal: [Bug]: @puppeteer/browsers silently corrupts Chrome cache on Node.js 26 (extract-zip 2.0.1). Treat it as a review item until the current version is checked.
- User impact: First-time setup may fail or require extra isolation and rollback planning.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/puppeteer/puppeteer/issues/14957
6. Installation risk: [Bug]: `setViewport` crashes on Firefox if uncaught
- Severity: medium
- Finding: Installation risk is backed by a source signal: [Bug]:
setViewportcrashes on Firefox if uncaught. Treat it as a review item until the current version is checked. - User impact: First-time setup may fail or require extra isolation and rollback planning.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/puppeteer/puppeteer/issues/14989
7. Installation risk: [Bug]: chrome binary is not present when installing latest chrome
- Severity: medium
- Finding: Installation risk is backed by a source signal: [Bug]: chrome binary is not present when installing latest chrome. Treat it as a review item until the current version is checked.
- User impact: First-time setup may fail or require extra isolation and rollback planning.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/puppeteer/puppeteer/issues/14988
8. Installation risk: [Feature]: Make proxy-agent dependency optional
- Severity: medium
- Finding: Installation risk is backed by a source signal: [Feature]: Make proxy-agent dependency optional. Treat it as a review item until the current version is checked.
- User impact: First-time setup may fail or require extra isolation and rollback planning.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/puppeteer/puppeteer/issues/13775
9. Installation risk: browsers: v3.0.0
- Severity: medium
- Finding: Installation risk is backed by a source signal: browsers: v3.0.0. Treat it as a review item until the current version is checked.
- User impact: First-time setup may fail or require extra isolation and rollback planning.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/puppeteer/puppeteer/releases/tag/browsers-v3.0.0
10. Capability assumption: browsers: v3.0.2
- Severity: medium
- Finding: Capability assumption is backed by a source signal: browsers: v3.0.2. Treat it as a review item until the current version is checked.
- User impact: The project should not be treated as fully validated until this signal is reviewed.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/puppeteer/puppeteer/releases/tag/browsers-v3.0.2
11. Capability assumption: puppeteer-core: v25.0.2
- Severity: medium
- Finding: Capability assumption is backed by a source signal: puppeteer-core: v25.0.2. Treat it as a review item until the current version is checked.
- User impact: The project should not be treated as fully validated until this signal is reviewed.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-core-v25.0.2
12. Capability assumption: README/documentation is current enough for a first validation pass.
- Severity: medium
- Finding: README/documentation is current enough for a first validation pass.
- User impact: The project should not be treated as fully validated until this signal is reviewed.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: capability.assumptions | github_repo:90796663 | https://github.com/puppeteer/puppeteer | README/documentation is current enough for a first validation pass.
Source: Doramagic discovery, validation, and Project Pack records
Community Discussion Evidence
These external discussion links are review inputs, not standalone proof that the project is production-ready.
Count of project-level external discussion links exposed on this manual page.
Open the linked issues or discussions before treating the pack as ready for your environment.
Community Discussion Evidence
Doramagic exposes project-level community discussion separately from official documentation. Review these links before using puppeteer with real data or production workflows.
- [[Bug]: GHSA issued a false malicious package alert for puppeteer](https://github.com/puppeteer/puppeteer/issues/14986) - github / github_issue
- Chrome Canary/Firefox Nightly test results - github / github_issue
- [[Bug]:
setViewportcrashes on Firefox if uncaught](https://github.com/puppeteer/puppeteer/issues/14989) - github / github_issue - [[Bug]: chrome binary is not present when installing latest chrome](https://github.com/puppeteer/puppeteer/issues/14988) - github / github_issue
- [[Bug]: @puppeteer/browsers silently corrupts Chrome cache on Node.js 26](https://github.com/puppeteer/puppeteer/issues/14957) - github / github_issue
- [[Task]: Flaky `[fixtures.spec] Fixtures should dump browser process stde](https://github.com/puppeteer/puppeteer/issues/14774) - github / github_issue
- [[Feature]: Reducing dependencies](https://github.com/puppeteer/puppeteer/issues/13552) - github / github_issue
- [[Feature]: Make proxy-agent dependency optional](https://github.com/puppeteer/puppeteer/issues/13775) - github / github_issue
- Puppeteer v25 - github / github_issue
- puppeteer-core: v25.0.2 - github / github_release
- browsers: v3.0.2 - github / github_release
- puppeteer-core: v25.0.1 - github / github_release
Source: Project Pack community evidence and pitfall evidence