Implementation:Microsoft Playwright Client Waiter
| Knowledge Sources | |
|---|---|
| Domains | Browser Automation, Async Control Flow |
| Last Updated | 2026-02-12 00:00 GMT |
Overview
Concrete tool for waiting on events with timeout, predicate filtering, and rejection conditions provided by the Playwright library.
Description
The Waiter class provides a structured way to wait for events on EventEmitter instances with support for:
- Event waiting:
waitForEvent()waits for a specific event, optionally filtering with a predicate function. It preserves the calling zone for proper async context tracking. - Timeout rejection:
rejectOnTimeout()registers a timeout that rejects the wait with aTimeoutError. - Event-based rejection:
rejectOnEvent()registers rejection when a specific event fires (e.g., rejecting when a page closes while waiting for another event). - Immediate rejection:
rejectImmediately()sets an error that causes immediate failure. - Promise racing:
waitForPromise()races the main promise against all registered failure conditions. - Logging:
log()records log messages during the wait and sends them to the server for trace/debugging. - Server integration: The constructor and disposal send
waitForEventInfomessages to the server to track wait operations in traces.
The class manages cleanup via a _dispose array and formats log recordings into error messages when waits fail.
Usage
Use the Waiter class internally when implementing waitForEvent() methods on Playwright objects. It provides a composable pattern for combining multiple rejection conditions with an event wait.
Code Reference
Source Location
- Repository: Microsoft_Playwright
- File:
packages/playwright-core/src/client/waiter.ts
Signature
export class Waiter {
constructor(channelOwner: ChannelOwner<channels.EventTargetChannel>, event: string);
static createForEvent(channelOwner: ChannelOwner<channels.EventTargetChannel>, event: string): Waiter;
async waitForEvent<T = void>(
emitter: EventEmitter,
event: string,
predicate?: (arg: T) => boolean | Promise<boolean>
): Promise<T>;
rejectOnEvent<T = void>(
emitter: EventEmitter,
event: string,
error: Error | (() => Error),
predicate?: (arg: T) => boolean | Promise<boolean>
): void;
rejectOnTimeout(timeout: number, message: string): void;
rejectImmediately(error: Error): void;
dispose(): void;
async waitForPromise<T>(promise: Promise<T>, dispose?: () => void): Promise<T>;
log(s: string): void;
}
Import
import { Waiter } from 'playwright-core/src/client/waiter';
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| channelOwner | ChannelOwner<EventTargetChannel> |
Yes | The channel owner that initiates the wait (for server-side tracking) |
| event | string |
Yes | The event name being waited for |
| emitter | EventEmitter |
Yes | The event emitter to listen on |
| predicate | Promise<boolean> | No | Optional filter predicate for the event |
| timeout | number |
Yes | Timeout in milliseconds for rejectOnTimeout |
| error | (() => Error) | Yes | Error or error factory for rejectOnEvent |
Outputs
| Name | Type | Description |
|---|---|---|
| waitForEvent() | Promise<T> |
The event argument when the event fires and the predicate passes |
| waitForPromise() | Promise<T> |
The result of the provided promise, or rejection from timeout/events |
Usage Examples
// Internal usage pattern in Playwright client classes:
async waitForEvent(event: string, options: WaitForEventOptions = {}): Promise<any> {
return await this._wrapApiCall(async () => {
const timeout = this._timeoutSettings.timeout(options);
const predicate = typeof options === 'function' ? options : options.predicate;
const waiter = Waiter.createForEvent(this, event);
waiter.rejectOnTimeout(timeout, `Timeout ${timeout}ms exceeded while waiting for event "${event}"`);
waiter.rejectOnEvent(this, Events.Page.Close, () => new TargetClosedError());
const result = await waiter.waitForEvent(this, event, predicate);
waiter.dispose();
return result;
});
}