QA Engineer Skills 2026QA-2026Vibium Extension Commands: Custom BiDi Protocol Extensions

Vibium Extension Commands: Custom BiDi Protocol Extensions

How WebDriver BiDi Supports Extensions

The WebDriver BiDi specification explicitly allows implementations to define custom commands:

"An implementation may define extension modules. These must have a module name that contains a single colon ':' character."

Vibium defines three extension commands that are handled by the Go binary (clicker), not forwarded to Chrome:

Command Parameters Description
vibium:find context, selector, timeout Wait for element to exist
vibium:click context, selector, timeout Wait for actionable, then click
vibium:type context, selector, text, timeout Wait for actionable, then type

Message Flow

Standard BiDi Command (Pass-Through)

Client                      Clicker Proxy                      Chrome
  │                               │                               │
  │── browsingContext.navigate ──►│                               │
  │                               │── browsingContext.navigate ──►│
  │                               │◄── success ───────────────────│
  │◄── success ───────────────────│                               │

Standard BiDi commands pass straight through the proxy.

Vibium Extension Command (Intercepted)

Client                    Clicker Proxy                   Chrome
  │                           │                              │
  │── vibium:click ──────────►│                              │
  │                           │                              │
  │                           │  ┌─ ACTIONABILITY LOOP ──┐   │
  │                           │  │                       │   │
  │                           │──│─ script.callFunction ─│──►│  (visible check)
  │                           │◄─│─ result ──────────────│───│
  │                           │──│─ script.callFunction ─│──►│  (stable check T1)
  │                           │◄─│─ result ──────────────│───│
  │                           │  │  sleep 50ms           │   │
  │                           │──│─ script.callFunction ─│──►│  (stable check T2)
  │                           │◄─│─ result ──────────────│───│
  │                           │──│─ script.callFunction ─│──►│  (receivesEvents)
  │                           │◄─│─ result ──────────────│───│
  │                           │──│─ script.callFunction ─│──►│  (enabled)
  │                           │◄─│─ result ──────────────│───│
  │                           │  └───────────────────────┘   │
  │                           │                              │
  │                           │── input.performActions ─────►│  (actual click)
  │                           │◄── success ──────────────────│
  │                           │                              │
  │◄── success ───────────────│                              │

The proxy intercepts vibium:* commands, runs multiple BiDi sub-commands against Chrome, and returns a single success/error to the client.


Implementation Details

Request Format

{
  "id": 1,
  "method": "vibium:click",
  "params": {
    "context": "browsing-context-id-123",
    "selector": "button.submit",
    "timeout": 30000
  }
}

Success Response

{
  "id": 1,
  "type": "success",
  "result": {
    "clicked": true
  }
}

Error Response (Timeout)

{
  "id": 1,
  "type": "error",
  "error": {
    "error": "timeout",
    "message": "timeout after 30s waiting for 'button.submit': check 'ReceivesEvents' failed — obscured by div.modal-overlay"
  }
}

Code Location in the Repository

Client side (sending commands):

  • clients/javascript/src/vibe.ts#L69client.send('vibium:find', { ... })

Server side (handling commands):

  • clicker/internal/proxy/router.go#L150 — Router dispatches vibium:find to handler
  • clicker/internal/proxy/router.go#L303handleVibiumFind() implementation

The Router Pattern

// Simplified from router.go
func (r *Router) OnClientMessage(msg []byte) {
    var req struct {
        Method string `json:"method"`
        // ...
    }
    json.Unmarshal(msg, &req)

    switch req.Method {
    case "vibium:find":
        r.handleVibiumFind(req)
    case "vibium:click":
        r.handleVibiumClick(req)
    case "vibium:type":
        r.handleVibiumType(req)
    default:
        // Standard BiDi command — forward to Chrome
        r.forwardToChrome(msg)
    }
}

Adding Your Own Extension Command

If you needed a custom command (e.g., vibium:drag):

  1. Client sends {"method": "vibium:drag", "params": {...}}
  2. Add a case in router.go's OnClientMessage switch
  3. Implement handler that uses standard BiDi commands internally
  4. Call sendSuccess() or sendError() to respond

Why This Architecture Matters

For Clients: Simplicity

The JavaScript client's click implementation is trivial:

async click(options?: { timeout?: number }): Promise<void> {
  await this.client.send('vibium:click', {
    context: this.context,
    selector: this.selector,
    timeout: options?.timeout,
  });
}

No retry loops, no actionability checks, no complex state management. Just send a command and wait.

For the CLI: Same Simplicity

When you run vibe-check click "button", the CLI:

  1. Connects to the daemon's WebSocket
  2. Sends vibium:click with the selector
  3. Waits for success or error
  4. Prints result and exits

The CLI is just another BiDi client.

For the Skill: Maximum Token Efficiency

The agent runs Bash("vibe-check click 'button'") and gets back either:

  • Exit code 0 + minimal output (success)
  • Exit code 1 + descriptive error (failure)

No JSON schema overhead. No accessibility trees. Just a shell command and its output.


Comparison with Playwright's Approach

Aspect Playwright Vibium
Protocol CDP (Chrome DevTools Protocol) WebDriver BiDi
Extension mechanism Not standardized (CDP is Chrome-internal) W3C standard extension points
Actionability location Client library Server proxy
Cross-browser Via protocol abstraction layer Via BiDi standard (native)
Custom commands Library methods BiDi extension commands

Vibium's approach is more aligned with web standards. As BiDi matures and more browsers implement it natively, Vibium's protocol extensions can potentially be standardized.


Interview Talking Point

"Vibium extends the WebDriver BiDi protocol with custom commands — vibium:find, vibium:click, vibium:type — using the spec's official extension mechanism. The Go binary acts as a BiDi proxy: standard commands pass through to Chrome, while vibium:* commands are intercepted and handled server-side. A single vibium:click on the wire triggers a multi-step actionability loop — five checks in a polling loop, then the actual click via BiDi's input.performActions. This means clients send one message and get one response, with all the complexity hidden in the proxy. It's a clean separation of concerns: the protocol handles transport, the proxy handles intelligence, the client handles UX."