A high-level API to control headless Chrome over the DevTools Protocol
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Direct element manipulation through ElementHandle for precise control over DOM elements with property access, interaction methods, and visual feedback.
Handle to a DOM element providing direct access to element properties and methods.
/**
* Handle to a DOM element in the page
* Extends JSHandle with element-specific functionality
*/
class ElementHandle extends JSHandle<Element> {
/**
* Find child element matching selector
* @param selector - CSS selector
* @returns Promise resolving to ElementHandle or null
*/
$(selector: string): Promise<ElementHandle | null>;
/**
* Find all child elements matching selector
* @param selector - CSS selector
* @returns Promise resolving to array of ElementHandles
*/
$$(selector: string): Promise<ElementHandle[]>;
/**
* Evaluate function on child element
* @param selector - CSS selector
* @param pageFunction - Function to evaluate
* @param args - Arguments to pass to function
* @returns Promise resolving to function result
*/
$eval<R>(
selector: string,
pageFunction: (element: Element, ...args: any[]) => R,
...args: any[]
): Promise<R>;
/**
* Evaluate function on all child elements
* @param selector - CSS selector
* @param pageFunction - Function to evaluate
* @param args - Arguments to pass to function
* @returns Promise resolving to function result
*/
$$eval<R>(
selector: string,
pageFunction: (elements: Element[], ...args: any[]) => R,
...args: any[]
): Promise<R>;
}User interaction methods for clicking, typing, and form manipulation.
/**
* Click the element
* @param options - Click options
* @returns Promise that resolves when click completes
*/
click(options?: ClickOptions): Promise<void>;
/**
* Focus the element
* @returns Promise that resolves when focus completes
*/
focus(): Promise<void>;
/**
* Hover over the element
* @returns Promise that resolves when hover completes
*/
hover(): Promise<void>;
/**
* Tap the element (touch interaction)
* @returns Promise that resolves when tap completes
*/
tap(): Promise<void>;
/**
* Type text into the element
* @param text - Text to type
* @param options - Typing options
* @returns Promise that resolves when typing completes
*/
type(text: string, options?: TypeOptions): Promise<void>;
/**
* Press a key while element is focused
* @param key - Key to press
* @param options - Press options
* @returns Promise that resolves when key press completes
*/
press(key: KeyInput, options?: PressOptions): Promise<void>;
/**
* Select options in select element
* @param values - Option values to select
* @returns Promise resolving to selected values
*/
select(...values: string[]): Promise<string[]>;
interface ClickOptions {
/** Mouse button to use */
button?: "left" | "right" | "middle";
/** Number of clicks */
clickCount?: number;
/** Delay between mousedown and mouseup */
delay?: number;
/** Offset from element center */
offset?: {x: number; y: number};
}
interface TypeOptions {
/** Delay between key presses */
delay?: number;
}
interface PressOptions {
/** Delay before releasing key */
delay?: number;
/** Text to insert (for printable keys) */
text?: string;
}Usage Examples:
// Get element handle
const button = await page.$("#submit-button");
if (button) {
// Click element
await button.click();
// Click with options
await button.click({
button: "right", // Right click
clickCount: 2, // Double click
delay: 100 // 100ms between mousedown/mouseup
});
}
// Type into input field
const input = await page.$("#email");
if (input) {
await input.focus();
await input.type("user@example.com", { delay: 50 });
await input.press("Enter");
}
// Select dropdown options
const select = await page.$("#country");
if (select) {
await select.select("US", "CA"); // Multi-select
}Comprehensive drag and drop functionality for complex interactions.
/**
* Start drag operation from element
* @param target - Target coordinates
* @returns Promise resolving to drag data
*/
drag(target: Point): Promise<Protocol.Input.DragData>;
/**
* Trigger drag enter event
* @param data - Drag data from drag operation
* @returns Promise that resolves when drag enter completes
*/
dragEnter(data?: Protocol.Input.DragData): Promise<void>;
/**
* Trigger drag over event
* @param data - Drag data from drag operation
* @returns Promise that resolves when drag over completes
*/
dragOver(data?: Protocol.Input.DragData): Promise<void>;
/**
* Trigger drop event
* @param data - Drag data from drag operation
* @returns Promise that resolves when drop completes
*/
drop(data?: Protocol.Input.DragData): Promise<void>;
/**
* Drag element to target element
* @param target - Target element to drop on
* @param options - Drag options
* @returns Promise that resolves when drag and drop completes
*/
dragAndDrop(
target: ElementHandle,
options?: {delay?: number}
): Promise<void>;
interface Point {
x: number;
y: number;
}Usage Examples:
// Simple drag and drop between elements
const source = await page.$("#draggable");
const target = await page.$("#dropzone");
if (source && target) {
await source.dragAndDrop(target);
}
// Manual drag and drop with custom control
const dragHandle = await page.$("#drag-handle");
if (dragHandle) {
// Start drag
const dragData = await dragHandle.drag({ x: 100, y: 100 });
// Simulate drag over target
const dropTarget = await page.$("#drop-target");
if (dropTarget) {
await dropTarget.dragOver(dragData);
await dropTarget.drop(dragData);
}
}Touch-specific interactions for mobile and tablet interfaces.
/**
* Start touch interaction
* @returns Promise resolving to TouchHandle
*/
touchStart(): Promise<TouchHandle>;
/**
* Move touch to coordinates
* @param target - Target coordinates
* @returns Promise that resolves when touch move completes
*/
touchMove(target: Point): Promise<void>;
/**
* End touch interaction
* @returns Promise that resolves when touch end completes
*/
touchEnd(): Promise<void>;
interface TouchHandle {
/** Move touch to new coordinates */
move(point: Point): Promise<void>;
/** End the touch */
end(): Promise<void>;
}Usage Examples:
// Touch interactions for mobile
const touchElement = await page.$("#mobile-button");
if (touchElement) {
// Simple tap
await touchElement.tap();
// Complex touch gestures
const touch = await touchElement.touchStart();
await touch.move({ x: 100, y: 0 }); // Swipe right
await touch.end();
}Access element dimensions, visibility, and layout information.
/**
* Get element bounding box
* @returns Promise resolving to bounding box or null if not visible
*/
boundingBox(): Promise<BoundingBox | null>;
/**
* Get element box model (including padding, border, margin)
* @returns Promise resolving to box model or null
*/
boxModel(): Promise<BoxModel | null>;
/**
* Get content frame for iframe elements
* @returns Promise resolving to Frame or null
*/
contentFrame(): Promise<Frame | null>;
/**
* Check if element is visible
* @returns Promise resolving to true if visible
*/
isVisible(): Promise<boolean>;
/**
* Check if element is hidden
* @returns Promise resolving to true if hidden
*/
isHidden(): Promise<boolean>;
/**
* Check if element intersects with viewport
* @param options - Intersection options
* @returns Promise resolving to true if intersecting
*/
isIntersectingViewport(options?: {threshold?: number}): Promise<boolean>;
interface BoundingBox {
/** X coordinate of top-left corner */
x: number;
/** Y coordinate of top-left corner */
y: number;
/** Width of element */
width: number;
/** Height of element */
height: number;
}
interface BoxModel {
/** Content box */
content: Quad;
/** Padding box */
padding: Quad;
/** Border box */
border: Quad;
/** Margin box */
margin: Quad;
/** Element width */
width: number;
/** Element height */
height: number;
}
interface Quad {
/** Array of 8 numbers representing 4 points (x1,y1,x2,y2,x3,y3,x4,y4) */
quad: number[];
}Usage Examples:
const element = await page.$("#content");
if (element) {
// Get element dimensions
const box = await element.boundingBox();
if (box) {
console.log(`Element is ${box.width}x${box.height} at (${box.x}, ${box.y})`);
}
// Check visibility
const isVisible = await element.isVisible();
const isHidden = await element.isHidden();
console.log(`Visible: ${isVisible}, Hidden: ${isHidden}`);
// Check if in viewport
const inViewport = await element.isIntersectingViewport();
const partiallyVisible = await element.isIntersectingViewport({ threshold: 0.5 });
// Get detailed box model
const boxModel = await element.boxModel();
if (boxModel) {
console.log(`Content: ${boxModel.width}x${boxModel.height}`);
}
}
// Handle iframe content
const iframe = await page.$("iframe");
if (iframe) {
const frame = await iframe.contentFrame();
if (frame) {
// Interact with iframe content
await frame.click("#button-in-iframe");
}
}Capture visual representations of specific elements.
/**
* Take screenshot of element
* @param options - Screenshot options
* @returns Promise resolving to image buffer
*/
screenshot(options?: ScreenshotOptions): Promise<Uint8Array>;
interface ScreenshotOptions {
/** Path to save screenshot */
path?: string;
/** Image type */
type?: "png" | "jpeg" | "webp";
/** Image quality (0-100, JPEG only) */
quality?: number;
/** Omit background (PNG only) */
omitBackground?: boolean;
/** Capture beyond device screen size */
captureBeyondViewport?: boolean;
/** Encoding format */
encoding?: "base64" | "binary";
}Usage Examples:
const element = await page.$("#chart");
if (element) {
// Take PNG screenshot
const buffer = await element.screenshot();
// Save to file with options
await element.screenshot({
path: "element.png",
type: "png",
omitBackground: true
});
// Get base64 encoded image
const base64 = await element.screenshot({
encoding: "base64",
type: "jpeg",
quality: 80
});
}Control element scrolling and viewport positioning.
/**
* Scroll element into view
* @returns Promise that resolves when scrolling completes
*/
scrollIntoView(): Promise<void>;Usage Examples:
const element = await page.$("#footer-content");
if (element) {
// Scroll element into view
await element.scrollIntoView();
// Wait a moment for scroll animation
await page.waitForTimeout(500);
// Then interact with element
await element.click();
}Specialized form handling including autofill functionality.
/**
* Autofill form element with provided data
* @param data - Autofill data
* @returns Promise that resolves when autofill completes
*/
autofill(data: AutofillData): Promise<void>;
interface AutofillData {
/** Form fields to fill */
fields: Array<{
/** Field name */
name: string;
/** Field value */
value: string;
}>;
}Usage Examples:
const form = await page.$("form");
if (form) {
// Autofill form
await form.autofill({
fields: [
{ name: "firstName", value: "John" },
{ name: "lastName", value: "Doe" },
{ name: "email", value: "john@example.com" }
]
});
}Convert ElementHandle to modern Locator API for enhanced reliability.
/**
* Convert ElementHandle to Locator
* @returns Locator instance for this element
*/
asLocator(): Locator<Element>;Usage Examples:
const element = await page.$("#dynamic-content");
if (element) {
// Convert to locator for better reliability
const locator = element.asLocator();
// Use locator methods with automatic retries
await locator.click();
await locator.fill("new value");
}Properly clean up element handles to prevent memory leaks.
/**
* Dispose of element handle and release browser resources
* @returns Promise that resolves when disposal completes
*/
dispose(): Promise<void>;Usage Examples:
const elements = await page.$$(".temporary-elements");
// Process elements
for (const element of elements) {
const text = await element.evaluate(el => el.textContent);
console.log(text);
// Dispose when done
await element.dispose();
}Handle to JavaScript objects in the browser context, providing access to properties and evaluation capabilities.
Access properties and evaluate functions on JavaScript objects.
/**
* Handle to a JavaScript object in browser context
*/
class JSHandle<T = any> {
/** Get property by name */
getProperty(propertyName: string): Promise<JSHandle>;
/** Get all properties as Map */
getProperties(): Promise<Map<string, JSHandle>>;
/** Evaluate function with this handle as context */
evaluate<R>(
pageFunction: (obj: T, ...args: any[]) => R,
...args: any[]
): Promise<R>;
/** Evaluate function and return handle to result */
evaluateHandle<R>(
pageFunction: (obj: T, ...args: any[]) => R,
...args: any[]
): Promise<JSHandle<R>>;
/** Get JSON representation of object */
jsonValue(): Promise<T>;
/** Convert to ElementHandle if object is an Element */
asElement(): ElementHandle | null;
/** Get string representation */
toString(): string;
/** Dispose handle and release browser resources */
dispose(): Promise<void>;
}Usage Examples:
// Get handle to window object
const windowHandle = await page.evaluateHandle(() => window);
// Access properties
const locationHandle = await windowHandle.getProperty("location");
const href = await locationHandle.jsonValue();
console.log("Current URL:", href);
// Get all properties
const windowProps = await windowHandle.getProperties();
for (const [name, handle] of windowProps) {
console.log(`Property: ${name}`);
await handle.dispose(); // Clean up
}
// Evaluate with handle context
const result = await windowHandle.evaluate((win) => {
return {
width: win.innerWidth,
height: win.innerHeight,
userAgent: win.navigator.userAgent
};
});
// Handle arrays and complex objects
const arrayHandle = await page.evaluateHandle(() => [1, 2, 3, 4, 5]);
const sum = await arrayHandle.evaluate((arr) =>
arr.reduce((total, num) => total + num, 0)
);
console.log("Sum:", sum); // 15
// Convert to element if possible
const elementHandle = await page.evaluateHandle(() => document.body);
const element = elementHandle.asElement();
if (element) {
await element.click();
}
// Clean up handles
await windowHandle.dispose();
await locationHandle.dispose();
await arrayHandle.dispose();Install with Tessl CLI
npx tessl i tessl/npm-puppeteer