Обзор протокола WebDriver BiDi
Updated Jul 2026
Что это такое
WebDriver BiDi (Bidirectional) — это стандарт W3C для автоматизации браузера. Он объединяет:
- Стандартизацию WebDriver (W3C, кросс-браузерность)
- Двунаправленность CDP (WebSocket, события, реальное время)
Формат сообщений
Вся коммуникация — JSON через WebSocket.
Клиент → Браузер (команды)
{
"id": 1,
"method": "browsingContext.navigate",
"params": {
"context": "context-id-123",
"url": "https://example.com",
"wait": "complete"
}
}
Браузер → Клиент (ответы)
{
"id": 1,
"type": "success",
"result": {
"navigation": "nav-id-456",
"url": "https://example.com"
}
}
Браузер → Клиент (события — незапрошенные)
{
"method": "log.entryAdded",
"params": {
"level": "error",
"text": "Uncaught TypeError: Cannot read property 'foo' of undefined",
"timestamp": 1707500000000
}
}
События отправляются браузером без запроса клиента — это и есть «двунаправленная» часть.
Основные модули
Модуль Session
Управляет соединением между клиентом и браузером.
// Create session
{"id": 1, "method": "session.new", "params": {"capabilities": {}}}
// Subscribe to events
{"id": 2, "method": "session.subscribe", "params": {"events": ["log.entryAdded"]}}
Модуль Browsing Context
Управляет вкладками, iframe и навигацией.
// Navigate
{"id": 3, "method": "browsingContext.navigate", "params": {"context": "ctx-1", "url": "https://example.com"}}
// Get tree (all tabs and iframes)
{"id": 4, "method": "browsingContext.getTree", "params": {}}
// Create new tab
{"id": 5, "method": "browsingContext.create", "params": {"type": "tab"}}
// Close tab
{"id": 6, "method": "browsingContext.close", "params": {"context": "ctx-1"}}
Модуль Script
Выполнение JavaScript в контексте браузера.
// Evaluate expression
{"id": 7, "method": "script.evaluate", "params": {
"expression": "document.title",
"target": {"context": "ctx-1"},
"awaitPromise": true
}}
// Call function (more powerful - can pass arguments)
{"id": 8, "method": "script.callFunction", "params": {
"functionDeclaration": "(selector) => document.querySelector(selector)?.textContent",
"arguments": [{"type": "string", "value": "h1"}],
"target": {"context": "ctx-1"},
"awaitPromise": true
}}
Модуль Input
Имитация пользовательского ввода (мышь, клавиатура).
// Click at coordinates
{"id": 9, "method": "input.performActions", "params": {
"context": "ctx-1",
"actions": [{
"type": "pointer",
"id": "mouse",
"actions": [
{"type": "pointerMove", "x": 200, "y": 300},
{"type": "pointerDown", "button": 0},
{"type": "pointerUp", "button": 0}
]
}]
}}
// Type text
{"id": 10, "method": "input.performActions", "params": {
"context": "ctx-1",
"actions": [{
"type": "key",
"id": "keyboard",
"actions": [
{"type": "keyDown", "value": "H"},
{"type": "keyUp", "value": "H"},
{"type": "keyDown", "value": "i"},
{"type": "keyUp", "value": "i"}
]
}]
}}
Модуль Network (будущее)
Перехват и инспекция сетевых запросов.
// Enable network tracking
{"id": 11, "method": "network.addIntercept", "params": {
"phases": ["beforeRequestSent"]
}}
// Event: request made
{"method": "network.beforeRequestSent", "params": {
"request": {"url": "https://api.example.com/data", "method": "GET"}
}}
Модуль Log
События консольного лога, отправляемые браузером.
// Subscribe
{"id": 12, "method": "session.subscribe", "params": {"events": ["log.entryAdded"]}}
// Event received
{"method": "log.entryAdded", "params": {
"level": "error",
"text": "TypeError: x is not a function",
"source": {"realm": "realm-1"},
"timestamp": 1707500000000
}}
Сессии
Стандартная сессия (через HTTP-обновление)
Client Browser
│ │
│── HTTP POST /session ───────────────────────►│
│ {"capabilities": {"webSocketUrl": true}} │
│◄── HTTP 200 ─────────────────────────────────│
│ {"sessionId": "...", "webSocketUrl": "ws://..."}
│ │
│── WebSocket connect ────────────────────────►│
│◄── WebSocket connected ──────────────────────│
│ │
│ Now use BiDi commands... │
BiDi-Only сессия (прямой WebSocket)
Client Browser
│ │
│── WebSocket connect to ws://.../ ───────────►│
│◄── WebSocket connected ──────────────────────│
│ │
│── session.new ──────────────────────────────►│
│◄── session.new result ───────────────────────│
│ │
│ Now use BiDi commands... │
Ключевые концепции
Browsing Context
«Browsing context» — это вкладка или iframe. Каждый имеет уникальный идентификатор.
Browser
├── Context "ctx-1" (Tab 1 - https://example.com)
│ ├── Context "ctx-2" (iframe - ad)
│ └── Context "ctx-3" (iframe - widget)
└── Context "ctx-4" (Tab 2 - https://docs.example.com)
User Context
Пользовательские контексты обеспечивают изоляцию (аналогично профилям инкогнито):
// Create isolated context
{"id": 1, "method": "browser.createUserContext", "params": {}}
// Create tab in isolated context
{"id": 2, "method": "browsingContext.create", "params": {
"type": "tab",
"userContext": "user-ctx-1"
}}
Подписки на события
Клиенты должны явно подписываться на нужные им события:
// Subscribe to console logs and network events
{"id": 1, "method": "session.subscribe", "params": {
"events": ["log.entryAdded", "network.beforeRequestSent"],
"contexts": ["ctx-1"] // Optional: only for specific tab
}}
Поддержка браузерами (2026)
| Браузер | Поддержка BiDi | Драйвер |
|---|---|---|
| Chrome | Полная | chromedriver |
| Firefox | Полная (нативная) | Отдельный драйвер не нужен |
| Edge | Полная (на основе Chromium) | edgedriver |
| Safari | Частичная | safaridriver |
Как Vibium вписывается
Бинарный файл clicker от Vibium — это BiDi-прокси, который располагается между клиентами и Chrome:
Client ──WebSocket──► Clicker Proxy ──WebSocket──► Chrome
│
├── Forwards standard BiDi commands
├── Intercepts vibium:* extension commands
├── Runs actionability checks via script.callFunction
└── Performs clicks via input.performActions
Паттерн прокси означает:
- Клиенты не должны знать BiDi-эндпоинт Chrome напрямую
- Пользовательские команды (vibium:click и т.д.) прозрачны для клиента
- Прокси может добавлять функции (авто-ожидание, скриншоты) без изменения протокола
Тезис для собеседования
«WebDriver BiDi — это W3C-преемник как классического WebDriver, так и CDP. Он использует WebSocket для двунаправленного JSON-обмена сообщениями — клиент может отправлять команды, И браузер может передавать события. Протокол организован в модули: session, browsing context, script, input, network и log. Vibium использует BiDi как транспортный уровень, а Go-бинарник выступает прокси, который пропускает стандартные команды и перехватывает пользовательские расширения
vibium:*. Ключевое преимущество перед CDP — стандартизация: BiDi — это спецификация W3C с поддержкой всех основных производителей браузеров, а не внутренний протокол Google, который может измениться без предупреждения.»