Implementation:Puppeteer Puppeteer WaitTask
| Property | Value |
|---|---|
| sources | packages/puppeteer-core/src/common/WaitTask.ts |
| domains | Polling, Wait Mechanisms, Task Management |
| last_updated | 2026-02-12 00:00 GMT |
Overview
Description
WaitTask is an internal class that implements Puppeteer's waiting/polling mechanism for conditions in the browser. It repeatedly evaluates a function in the browser context until the function returns a truthy value or the operation times out. This is the engine behind page.waitForFunction, page.waitForSelector, and similar waiting APIs.
The module exports two classes and one interface:
WaitTaskOptions defines the configuration for a wait task:
- polling -- The polling strategy:
'raf'(requestAnimationFrame),'mutation'(MutationObserver), or a numeric interval in milliseconds. - root -- An optional root element to scope MutationObserver observations.
- timeout -- Maximum time to wait in milliseconds.
- signal -- An optional
AbortSignalto cancel the wait.
WaitTask manages the lifecycle of a single wait operation:
- On construction, it registers itself with the realm's TaskManager, sets up timeout handling, and initiates the first evaluation run.
- The rerun method creates the appropriate poller (RAFPoller, MutationPoller, or IntervalPoller) on the browser side, starts it, and waits for a result.
- The terminate method cleans up the task by removing it from the manager, clearing timeouts, disposing of the poller handle, and resolving/rejecting the result deferred.
- The getBadError method distinguishes between transient errors (execution context destroyed, context not found) that trigger a rerun, and fatal errors (frame detached) that cause termination.
TaskManager is a simple set-based manager that tracks active WaitTask instances for a realm and provides terminateAll and rerunAll methods for bulk operations during navigation and context changes.
Usage
WaitTask is used internally by Puppeteer realms to implement waiting operations. When a page navigates, the TaskManager reruns all active tasks in the new execution context. When a frame is detached, it terminates all tasks.
Code Reference
Source Location
packages/puppeteer-core/src/common/WaitTask.ts
Signature
export interface WaitTaskOptions {
polling: 'raf' | 'mutation' | number;
root?: ElementHandle<Node>;
timeout: number;
signal?: AbortSignal;
}
export class WaitTask<T = unknown> {
constructor(
world: Realm,
options: WaitTaskOptions,
fn: ((...args: unknown[]) => Promise<T>) | string,
...args: unknown[]
);
get result(): Promise<HandleFor<T>>;
rerun(): Promise<void>;
terminate(error?: Error): Promise<void>;
getBadError(error: unknown): Error | undefined;
}
export class TaskManager {
add(task: WaitTask<any>): void;
delete(task: WaitTask<any>): void;
terminateAll(error?: Error): void;
rerunAll(): Promise<void>;
}
Import
import {WaitTask, TaskManager, type WaitTaskOptions} from './WaitTask.js';
I/O Contract
| Parameter | Type | Description |
|---|---|---|
| world | Realm |
The realm (execution context) in which to evaluate the function |
| options | WaitTaskOptions |
Configuration for polling strategy, timeout, root element, and abort signal |
| fn | string | The function or expression to evaluate repeatedly |
| args | unknown[] |
Additional arguments passed to the evaluation function |
| Property/Method | Return Type | Description |
|---|---|---|
result |
Promise<HandleFor<T>> |
Resolves with a handle to the truthy return value, or rejects on timeout/error |
rerun() |
Promise<void> |
Re-evaluates the function (called on navigation) |
terminate(error?) |
Promise<void> |
Stops the task, cleans up resources, optionally rejects with error |
Usage Examples
// Internal usage within Puppeteer's Realm implementation
import {WaitTask, TaskManager} from './WaitTask.js';
// Create a task manager for a realm
const taskManager = new TaskManager();
// Create a wait task that polls for an element with requestAnimationFrame
const task = new WaitTask(
realm,
{
polling: 'raf',
timeout: 30000,
},
async () => {
return document.querySelector('.loaded');
},
);
// Wait for the result
try {
const handle = await task.result;
console.log('Element found!');
} catch (error) {
console.log('Wait task failed:', error.message);
}
// On navigation, rerun all pending tasks
await taskManager.rerunAll();
// On frame detach, terminate all tasks
taskManager.terminateAll(new Error('Frame detached'));