{"slug": "speed-up-your-selenium-scripts-lightpanda-now-speaks-webdriver", "title": "Speed up your Selenium scripts: Lightpanda now speaks WebDriver", "summary": "Lightpanda 1.0 now speaks WebDriver, both classic and BiDi, making it the only browser that natively supports CDP, WebDriver and MCP, according to developer relations staffer Céline Debled. Developers can point Selenium scripts at `lightpanda serve --protocol webdriver` instead of chromedriver, or let the `lightpanda` Python package start it, and the scripts run unchanged. On the Selenium documentation tests Lightpanda supports today, it ran up to 4.4x faster than headless Chrome with 7x less memory, though WebDriver support is still in progress.", "body_md": "# Speed up your Selenium scripts: Lightpanda now speaks WebDriver\n\n### Céline Debled\n\n#### Developer Relations\n\n## TL;DR\n\nLightpanda 1.0 speaks WebDriver, classic and BiDi, making it the only browser that natively speaks every web automation protocol: CDP, WebDriver and MCP. Point your Selenium scripts at `lightpanda serve --protocol webdriver` instead of chromedriver, or let the `lightpanda` Python package start it for you, and they run unchanged. On the Selenium documentation tests Lightpanda supports today, it ran up to 4.4x faster than headless Chrome with 7x less memory. WebDriver support is still in progress, and your test suites will inform what we build next.\n\n## WebDriver, CDP and BiDi: three protocols, many clients\n\nIf you run Selenium scripts today, you already use WebDriver. **Selenium** is a client library. **WebDriver** is the protocol it speaks, a [W3C standard](https://www.w3.org/TR/webdriver1/)  that grew out of the Selenium project. Three protocols control browsers today:\n\n| Protocol | How it talks | Who defines it | Main clients | \n|---|---|---|---|\n| [WebDriver classic](https://www.w3.org/TR/webdriver1/)  | HTTP. The browser only replies, so the client polls for changes | W3C | Selenium, WebdriverIO, Nightwatch, Appium | \n| [WebDriver BiDi](https://www.w3.org/TR/webdriver-bidi/)  | WebSocket, open both ways. The browser pushes events | W3C, still a draft | Selenium 4 BiDi APIs, WebdriverIO, Puppeteer | \n| [CDP](https://chromedevtools.github.io/devtools-protocol/)  | WebSocket, open both ways. The browser pushes events | Google, for Chromium browsers | Puppeteer, Playwright, chromedp, Rod | \n\nThe protocol you pick decides what sits between your scripts and the browser.\n\nWebDriver came first. It [merged into Selenium in 2011](https://developer.chrome.com/blog/test-automation-evolution)  and became a [W3C standard](https://www.w3.org/TR/webdriver1/)  in 2018. Your test sends commands over HTTP to a driver, and each vendor ships its own: [chromedriver](https://chromium.googlesource.com/chromium/src/+/main/chrome/test/chromedriver/README.md)  for Chrome, [geckodriver](https://github.com/mozilla/geckodriver)  for Firefox, [safaridriver](https://webkit.org/blog/6900/webdriver-support-in-safari-10/)  for Safari. That driver is one more process to install and run next to every browser.\n\nIn parallel, Chrome started its own protocol. [Since 2012](https://www.igvita.com/2012/04/09/driving-google-chrome-via-websocket-api/) , the DevTools protocol (CDP) lets the inspector panel control a page over a WebSocket, so the browser can push events as they happen. It’s designed based on Chrome’s internals and covers much more than automation. In 2017 the Chrome team built Puppeteer on it. Playwright followed, and CDP became the de facto standard for automation. For a deeper look at how it works, see [CDP under the hood](https://lightpanda.io/blog/posts/cdp-under-the-hood) .\n\n[WebDriver BiDi](https://www.w3.org/TR/webdriver-bidi/) , still a W3C draft, tries to get the best of both worlds: a WebSocket for two-way communication and an open standard any browser can implement. The driver stays: with Chrome, chromedriver still opens the session and translates BiDi into CDP.\n\nWe wrote in more detail about [the web automation stack](https://lightpanda.io/blog/posts/web-automation-stack-explained)  and how it fits together as a whole.\n\n### Lightpanda natively speaks every web automation protocol\n\nWhen we started Lightpanda, we asked what a browser would look like if it were [built for machines](https://lightpanda.io/blog/posts/why-build-a-new-browser) . Our answer: no graphical rendering, and a browser your code controls directly, with no driver in between.\n\nWe started with CDP, so Puppeteer and Playwright scripts ran on Lightpanda from the start. With 1.0, Lightpanda adds WebDriver, classic and BiDi, so your Selenium suites can run on it too. It’s now the only browser that natively speaks every web automation protocol: CDP, WebDriver and MCP.\n\n## Running a Selenium test suite on Lightpanda\n\nYou need:\n\n- Python 3 with Selenium and [pytest](https://docs.pytest.org/)  :`pip install selenium pytest`\n- Lightpanda 1.0 or later (see the [installation guide](https://lightpanda.io/docs/run-locally/installation/one-liner)  ):\n\n```\ncurl -fsSL https://pkg.lightpanda.io/install.sh | bash -s \"1.0.0\"\n```\n\nThe example runs two tests against [quotes.toscrape.com](https://quotes.toscrape.com) , a public practice site. `test_login` submits the login form and waits for the Logout link. `test_js_rendered_quotes` checks quotes that JavaScript injects after the page loads.\n\n**`conftest.py`** holds the pytest fixture that opens a new WebDriver session for each test. It is the only Lightpanda-specific code: [`webdriver.Remote`](https://www.selenium.dev/documentation/webdriver/drivers/remote_webdriver/) connects Selenium to the running Lightpanda server instead of starting chromedriver.\n\n``` python\n# conftest.py\nimport pytest\nfrom selenium import webdriver\n \n \n@pytest.fixture\ndef driver():\n    # `lightpanda serve --protocol webdriver` listens on port 9222 by default.\n    d = webdriver.Remote(\n        command_executor=\"http://127.0.0.1:9222\",\n        # Selenium requires an options object; Lightpanda accepts any browser's.\n        options=webdriver.ChromeOptions(),\n    )\n    yield d\n    d.quit()\n```\n\n**`test_quotes.py`** holds the tests. They are plain Selenium and run unchanged on Chrome.\n\n``` python\n# test_quotes.py\nfrom selenium.webdriver.common.by import By\nfrom selenium.webdriver.support import expected_conditions as EC\nfrom selenium.webdriver.support.ui import WebDriverWait\n \nBASE = \"https://quotes.toscrape.com\"\n \n \ndef test_login(driver):\n    driver.get(f\"{BASE}/login\")\n    driver.find_element(By.ID, \"username\").send_keys(\"panda\")\n    driver.find_element(By.ID, \"password\").send_keys(\"secret\")\n    driver.find_element(By.CSS_SELECTOR, \"input[type=submit]\").click()\n    logout = WebDriverWait(driver, 5).until(\n        EC.presence_of_element_located((By.LINK_TEXT, \"Logout\"))\n    )\n    assert logout.text == \"Logout\"\n \n \ndef test_js_rendered_quotes(driver):\n    # Quotes on /js/ are injected by JavaScript, not in the HTML source.\n    driver.get(f\"{BASE}/js/\")\n    quotes = WebDriverWait(driver, 5).until(\n        EC.presence_of_all_elements_located((By.CSS_SELECTOR, \".quote\"))\n    )\n    assert len(quotes) == 10\n    assert driver.find_element(By.CSS_SELECTOR, \".quote .author\").text == \"Albert Einstein\"\n```\n\nStart Lightpanda in WebDriver mode, then run the suite from a second terminal:\n\n```\nlightpanda serve --protocol webdriver\npytest -v\ncollected 2 items\n\ntest_quotes.py::test_login PASSED                                        [ 50%]\ntest_quotes.py::test_js_rendered_quotes PASSED                           [100%]\n\n============================== 2 passed in 1.20s ===============================\n```\n\n### With the Lightpanda Python package\n\nIf you’d rather not install the browser yourself, the [`lightpanda` package](https://pypi.org/project/lightpanda/) bundles it and starts the server for you. Keep the same `test_quotes.py` and replace `conftest.py`:\n\n```\npip install lightpanda selenium pytest\npython\n# conftest.py\nimport pytest\nfrom lightpanda import BiDiServer\nfrom selenium import webdriver\n \n \n@pytest.fixture(scope=\"session\")\ndef server():\n    # Starts the Lightpanda binary bundled in the package.\n    with BiDiServer() as server:\n        yield server\n \n \n@pytest.fixture\ndef driver(server):\n    d = webdriver.Remote(server.http_endpoint, options=webdriver.ChromeOptions())\n    yield d\n    d.quit()\n```\n\nThen run `pytest -v`.\n\n## Benchmark: Selenium’s own tests on Chrome vs. Lightpanda\n\nWe ran the [Python examples](https://github.com/SeleniumHQ/seleniumhq.github.io/tree/trunk/examples/python)  behind the Selenium documentation. We targeted the 66 tests that use standard WebDriver commands, and only changed the driver setup in `conftest.py`. The test pages are served locally, so network time stays out of the numbers.\n\nLightpanda passes 43 of the 66 tests (vs. 65 on Chrome). The tests Lightpanda fails use features we’re still building, listed [below in what Lightpanda supports today](#what-lightpanda-10-supports-today). We timed the 43 tests that pass on both, each repeated 3 times. We ran one test at a time and 8 tests in parallel:\n\n|  | Lightpanda 1.0.0 | Chrome 154 + chromedriver | \n|---|---|---|\n| One at a time | **40.8 s, 74 MB** | 105.2 s, 552 MB | \n| 8 in parallel | **12.1 s, 97 MB** | 53.8 s, 759 MB | \n\nOne at a time, Lightpanda was 2.6x faster with 7.5x less memory. With 8 tests in parallel, it was 4.4x faster with 7.8x less memory. Each Chrome session starts its own process tree, while a Lightpanda session is a context inside one running process.\n\nThe results are medians of 5 runs on a GitHub Actions Linux runner (2 CPUs, 8 GB of RAM), against headless Chrome 154. The scripts and exact versions are in [this Gist](https://gist.github.com/cdebled/85a030b2536998fb94efa68b2bbd5184) .\n\n## Tips for running it in CI\n\nStart the server in the background before the tests. It starts almost instantly:\n\n```\nlightpanda serve --protocol webdriver &\npytest\n```\n\nRaise the session limit if your tests run in parallel. Runners such as [pytest-xdist](https://pytest-xdist.readthedocs.io/)  (`pytest -n`) or Selenium Grid open one session per worker, and Lightpanda accepts 16 at once by default. Set `--cdp-max-connections` (which covers WebDriver sessions too) to about 1.5x your worker count, because a closed session needs time to free its slot. For 32 workers:\n\n```\nlightpanda serve --protocol webdriver --cdp-max-connections 48\n```\n\nCall `driver.quit()` in every test. With Chrome, a forgotten session dies with the pytest process. With a shared Lightpanda server, it keeps its slot until the 60-second idle timeout, and enough of them make the next run fail with `too many sessions`.\n\n## What Lightpanda 1.0 supports today\n\nThe table compares what Lightpanda supports over each protocol.\n\n| Capability | Classic | BiDi | \n|---|---|---|\n| Sessions (one per test) | ✅ | ✅ | \n| Navigation | ✅ get, back, forward, refresh | ⚠️ navigate only | \n| Find elements | ✅ CSS, ID, XPath, link text | ✅ `locateNodes` | \n| Element state: text, attributes, displayed | ✅ | ✅ through JavaScript | \n| Click, type, clear | ✅ | ✅ through input actions | \n| Execute JavaScript | ✅ sync and async | ✅ evaluate, callFunction. Not yet: preload scripts | \n| Keyboard and mouse actions | ⚠️ Not yet: pen, back/forward buttons | ⚠️ Not yet: file inputs | \n| Cookies | ✅ | ❌ | \n| Waits | ⚠️ explicit only, implicit not enforced | n/a | \n| New tabs and windows | ❌ | ✅ create, close | \n| Frames | ❌ | ❌ | \n| Alerts, confirms, prompts | ❌ | ❌ | \n| Shadow DOM | ❌ | ❌ | \n| Events (console, network) | n/a | ⚠️ navigation and context events only | \n| Network interception | n/a | ❌ | \n| Screenshots | ⚠️ text render | ❌ | \n| Layout, visual checks | ❌ by design | ❌ by design | \n\nTo connect over BiDi, see our docs for [Selenium](https://lightpanda.io/docs/usage/bidi/selenium) , in JavaScript and Python, and for [Puppeteer](https://lightpanda.io/docs/usage/bidi/puppeteer) .\n\n## Tell us what your suite needs\n\nWebDriver support is new, and real test suites will inform what we build next. Run yours against Lightpanda 1.0:\n\n```\nlightpanda serve --protocol webdriver\n```\n\nIf something fails, [open an issue on GitHub](https://github.com/lightpanda-io/browser/issues) . To help us reproduce it, include:\n\n- the output of `lightpanda version` ,\n- your client and its version (for example Selenium 4.50 for Python),\n- the failing command or a minimal test, with the URL,\n- the error message, and the Lightpanda logs if you have them.\n\n## FAQ\n\n### Is Selenium the same as WebDriver?\n\nNo. WebDriver is a W3C protocol that defines how a client controls a browser. Selenium is the most widely used client library that speaks it. WebdriverIO and Appium speak the same protocol, so they can also connect to any WebDriver server, including Lightpanda.\n\n### Does Selenium use CDP or WebDriver?\n\nSelenium sends WebDriver commands. When Selenium drives Chrome, chromedriver translates those commands into CDP calls behind the scenes. Selenium 4 also exposes some CDP features directly for Chromium browsers, but the project is moving those to WebDriver BiDi, which works across browsers.\n\n### What is WebDriver BiDi?\n\nWebDriver BiDi is the bidirectional version of the WebDriver standard. It’s still a W3C draft, built on WebSocket. The browser can push events to the client, such as console messages or network activity, which classic WebDriver’s request-response model cannot do. It gives cross-browser automation the event model that used to require Chrome’s CDP.\n\n### Do I need chromedriver to use Selenium with Lightpanda?\n\nNo. Lightpanda implements the WebDriver protocol itself. Start `lightpanda serve --protocol webdriver` and connect Selenium to it with `webdriver.Remote`. Lightpanda is the only binary you install.\n\n### How much faster is Lightpanda than headless Chrome for Selenium tests?\n\nOn the 43 tests from Selenium’s documentation examples that pass on both browsers, Lightpanda 1.0.0 was 2.6x faster than headless Chrome 154 with 7.5x less memory (74 MB against 552 MB). With 8 tests in parallel, it was 4.4x faster with 7.8x less memory.\n\n### Can Lightpanda replace Chrome for every Selenium test?\n\nNo. Lightpanda has no graphical rendering, so it does not fit tests that check layout or compare pixel screenshots. Some WebDriver commands, such as frames and alerts, are not supported yet. It fits functional tests today: forms, navigation, JavaScript-built content and assertions on text and attributes.\n\n### Céline Debled\n\n#### Developer Relations\n\nCéline runs Developer Relations at Lightpanda. She started out as a full-stack web developer, then spent four years working with DevTools founders at Agoranov (a Paris startup incubator). At Lightpanda she writes the docs and demos, talks to developers building on the browser, and gets their feedback back to the engineering team. If you are stuck on something, she is the person to ask.", "url": "https://wpnews.pro/news/speed-up-your-selenium-scripts-lightpanda-now-speaks-webdriver", "canonical_source": "https://lightpanda.io/blog/posts/speed-up-your-selenium-tests", "published_at": "2026-10-06 00:00:00+00:00", "updated_at": "2026-10-07 16:46:23.099496+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools"], "entities": ["Lightpanda", "Selenium", "WebDriver", "WebDriver BiDi", "CDP", "Céline Debled", "Chrome", "chromedriver"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/speed-up-your-selenium-scripts-lightpanda-now-speaks-webdriver", "markdown": "https://wpnews.pro/news/speed-up-your-selenium-scripts-lightpanda-now-speaks-webdriver.md", "text": "https://wpnews.pro/news/speed-up-your-selenium-scripts-lightpanda-now-speaks-webdriver.txt", "jsonld": "https://wpnews.pro/news/speed-up-your-selenium-scripts-lightpanda-now-speaks-webdriver.jsonld"}}