Implementation:Puppeteer Puppeteer Cdp ElementHandle
| Property | Value |
|---|---|
| sources | packages/puppeteer-core/src/cdp/ElementHandle.ts
|
| domains | CDP, DOM, Element Interaction |
| last_updated | 2026-02-12 00:00 GMT |
Overview
Description
The CdpElementHandle class is the CDP-specific implementation of the abstract ElementHandle base class. It wraps a remote DOM element referenced through the Chrome DevTools Protocol and provides methods for interacting with it:
- contentFrame() -- Resolves the content frame for
<iframe>elements by callingDOM.describeNodeto retrieve theframeId. - scrollIntoView() -- Scrolls the element into the viewport using
DOM.scrollIntoViewIfNeeded, with a fallback to the base classElement.scrollIntoViewimplementation. - uploadFile() -- Handles file input uploads via
DOM.setFileInputFiles. Supports multi-file uploads for<input multiple>, resolves relative paths, and handles the edge case of clearing files (zero-length array) by manually setting an emptyFileList. - autofill() -- Triggers autofill for credit card fields via
Autofill.trigger. - queryAXTree() -- Queries the accessibility tree via
Accessibility.queryAXTree, filtering out ignored nodes and non-element roles (StaticText, InlineTextBox). - backendNodeId() -- Returns the backend node ID via
DOM.describeNode, caching the result for subsequent calls.
The class delegates JavaScript handle operations to an inner CdpJSHandle.
Usage
CdpElementHandle instances are created internally by Puppeteer when element references are returned from page evaluations, selector queries, or frame operations in CDP mode. Users interact with them through the public ElementHandle API.
Code Reference
Source Location
packages/puppeteer-core/src/cdp/ElementHandle.ts (216 lines)
Signature
export class CdpElementHandle<
ElementType extends Node = Element,
> extends ElementHandle<ElementType> {
constructor(world: IsolatedWorld, remoteObject: Protocol.Runtime.RemoteObject);
get realm(): IsolatedWorld;
get client(): CDPSession;
get frame(): CdpFrame;
remoteObject(): Protocol.Runtime.RemoteObject;
async contentFrame(): Promise<CdpFrame | null>;
async scrollIntoView(): Promise<void>;
async uploadFile(...files: string[]): Promise<void>;
async autofill(data: AutofillData): Promise<void>;
async *queryAXTree(name?: string, role?: string): AwaitableIterable<ElementHandle<Node>>;
async backendNodeId(): Promise<number>;
}
Import
import { CdpElementHandle } from '../cdp/ElementHandle.js';
I/O Contract
contentFrame
| Direction | Name | Type | Description |
|---|---|---|---|
| Output | result | null> | The content frame if the element is an iframe, or null |
uploadFile
| Direction | Name | Type | Description |
|---|---|---|---|
| Input | files | string[] |
File paths to upload; relative paths are resolved to absolute |
| Output | result | Promise<void> |
Resolves when files are set on the input element |
| Error | AssertionError | Error |
Thrown if multiple files are provided for a non-multiple input |
autofill
| Direction | Name | Type | Description |
|---|---|---|---|
| Input | data | AutofillData |
Contains creditCard information for autofill
|
| Output | result | Promise<void> |
Resolves when autofill is triggered via CDP |
queryAXTree
| Direction | Name | Type | Description |
|---|---|---|---|
| Input | name | undefined | Accessible name to filter by |
| Input | role | undefined | ARIA role to filter by |
| Output | result | AwaitableIterable<ElementHandle<Node>> |
Matching accessible element handles, excluding StaticText and InlineTextBox roles |
backendNodeId
| Direction | Name | Type | Description |
|---|---|---|---|
| Output | result | Promise<number> |
The CDP backend node ID, cached after first retrieval |
Usage Examples
// Upload a file to a file input
const fileInput = await page.$('input[type="file"]');
await fileInput.uploadFile('/path/to/file.pdf');
// Get the content frame of an iframe
const iframe = await page.$('iframe');
const frame = await iframe.contentFrame();
await frame.click('button');
// Scroll element into view
const element = await page.$('.below-fold');
await element.scrollIntoView();
// Query the accessibility tree
const handle = await page.$('form');
for await (const axNode of handle.queryAXTree('Submit', 'button')) {
console.log(axNode);
}
// Autofill a credit card form field
const cardInput = await page.$('#card-number');
await cardInput.autofill({
creditCard: {
number: '4111111111111111',
name: 'John Doe',
expiryMonth: '12',
expiryYear: '2030',
cvc: '123',
},
});