Skip to Content
UsageBiDiSelenium

Selenium (BiDi)

Use Lightpanda with Selenium over WebDriver BiDi. Lightpanda only implements the BiDi handshake of the classic WebDriver protocol, not full classic automation, so a session is created the normal Selenium way but driven with BiDi commands (browsingContext, script) instead of driver.get() or driver.findElement().

⚠️

BiDi support is new and covers less than CDP: only browsingContext and a subset of script are implemented.

Start Lightpanda with the webdriver protocol enabled (find all options in the serve command reference):

lightpanda serve --host 127.0.0.1 --port 9222 --protocol webdriver

Request a BiDi session by setting the webSocketUrl capability to true (browserName can be any value; Lightpanda reports itself back regardless), then drive it with BiDi commands:

npm install selenium-webdriver
'use strict' import { Builder, Capabilities } from 'selenium-webdriver' import { BrowsingContext } from 'selenium-webdriver/bidi/generated/browsing_context.js' import { Script } from 'selenium-webdriver/bidi/generated/script.js' const caps = new Capabilities() caps.set('browserName', 'lightpanda') caps.set('webSocketUrl', true) const driver = await new Builder() .usingServer('http://127.0.0.1:9222') .withCapabilities(caps) .build() const bidi = await driver.getBidi() await bidi.waitForConnection() const browsingContext = new BrowsingContext(bidi) const script = new Script(bidi) const { context } = await browsingContext.create({ type: 'tab' }) await browsingContext.navigate({ context, url: 'https://wikipedia.com/', wait: 'complete' }) const title = await script.evaluate({ expression: 'document.title', target: { context }, awaitPromise: false, }) console.log(title.result.value) await browsingContext.close({ context }) await driver.quit()