Modern QA2026Обзор протокола WebDriver BiDi
Join

Course01 Agent Skills for Browser Automation

Cutting-edge · Chapter 01

Обзор протокола 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, который может измениться без предупреждения.»