Implementation:Webdriverio Webdriverio BidiCore Class
| Knowledge Sources | |
|---|---|
| Domains | Bidi_Protocol, WebSocket |
| Last Updated | 2026-02-12 00:00 GMT |
Overview
The BidiCore class manages the WebSocket connection for the WebDriver Bidi protocol, providing low-level send() and sendAsync() methods for issuing commands and receiving responses.
Description
BidiCore is the base class for BidiHandler and encapsulates all WebSocket lifecycle management for WebDriver Bidi communication. It maintains a private WebSocket instance, a pending commands map keyed by auto-incrementing IDs, and a connection state flag. The connect() method establishes the WebSocket using the environment-specific createBidiConnection() factory, while close() tears it down. The send() method sends a command and awaits the response with a 60-second timeout, throwing enriched errors that include driver stack traces on failure. The sendAsync() method sends a command fire-and-forget style, returning only the command ID. A companion parseBidiCommand() function formats log output, abbreviating long script bodies for readability.
The class also emits bidiCommand and bidiResult events on the attached Client instance for observability, and supports reconnection to a different WebSocket URL via reconnect().
Usage
Use BidiCore as the foundation for Bidi communication. It is not instantiated directly; instead, BidiHandler extends it and adds protocol-specific command methods. The send() method is called internally by every handler method.
Code Reference
Source Location
- Repository: Webdriverio_Webdriverio
- File: packages/webdriver/src/bidi/core.ts
Signature
export class BidiCore {
client: Client | undefined
constructor(webSocketUrl: string, opts?: ClientOptions)
public attachClient(client: Client): void
public async connect(): Promise<boolean>
public close(): void
public reconnect(webSocketUrl: string, opts?: ClientOptions): Promise<boolean>
waitForConnected(): Promise<boolean>
get socket(): WebSocket | undefined
get isConnected(): boolean
public async send(params: Omit<CommandData, 'id'>): Promise<CommandResponse>
public sendAsync(params: Omit<CommandData, 'id'>): number
}
export function parseBidiCommand(params: Omit<CommandData, 'id'>): [string, string]
Import
import { BidiCore } from './bidi/core.js'
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| webSocketUrl | string |
Yes | The WebSocket URL to connect to (e.g., ws://127.0.0.1:9222/session/...).
|
| opts | ClientOptions |
No | Optional WebSocket client options (e.g., rejectUnauthorized, custom headers).
|
| params (send/sendAsync) | Omit<CommandData, 'id'> |
Yes | The Bidi command to send, containing method and params fields.
|
Outputs
| Name | Type | Description |
|---|---|---|
| connect() | Promise<boolean> |
Resolves to true if the WebSocket connection was successfully established.
|
| send() | Promise<CommandResponse> |
Resolves with the typed command response, or throws on error/timeout (60s). |
| sendAsync() | number |
Returns the numeric command ID for the sent message (fire-and-forget). |
| parseBidiCommand() | [string, string] |
Returns a tuple of [command name, formatted parameters string] for logging. |
Usage Examples
import { BidiCore, parseBidiCommand } from './bidi/core.js'
// Create and connect a BidiCore instance
const core = new BidiCore('ws://127.0.0.1:9222/session/abc123/se/bidi', {
rejectUnauthorized: false
});
await core.connect();
// Send a command and await the response
const response = await core.send({
method: 'session.status',
params: {}
});
console.log(response.result); // { ready: true, message: '...' }
// Send a command asynchronously (fire-and-forget)
const commandId = core.sendAsync({
method: 'browsingContext.navigate',
params: { context: 'ctx-1', url: 'https://example.com' }
});
// Wait for the connection to be ready
await core.waitForConnected();
// Reconnect to a new session
await core.reconnect('ws://127.0.0.1:9222/session/newId/se/bidi');
// Close the connection
core.close();