Alternative Browser Engines
Playwright drives full Chromium, Firefox and WebKit: the most accurate way to test what users see, at the cost of a heavy browser per worker. Alternative engines trade part of that accuracy for speed, a small footprint, or cloud scale. They are a good fit for functional tests (text appears, form submits, redirect happens, cookie is set) and a poor one for anything visual.
Your tests do not change. I.amOnPage, I.click, I.fillField, I.see, I.seeElement and the rest of the I.* web API work the same; you only swap the helper in the config. All engines below speak Chrome DevTools Protocol, so there is no npx playwright install step.
Compared to Playwright, none of them supports iframes (switchTo), multiple tabs, popups, dragAndDrop, moveCursorTo, or Playwright-only APIs such as usePlaywrightTo and mockRoute. Tag scenarios that need those and skip them on the alternative engine:
npx codeceptjs run --grep @playwright-only --invertTo see which I.* actions the configured engine supports:
npx codeceptjs listObscura
Section titled “Obscura”Obscura is a lightweight open-source browser with a real V8 engine and its own rendering engine, distributed as a single binary for Linux, macOS and Windows. Unlike Lightpanda it renders: layout, visibility checks, screenshots and the screencast plugin work.
Limitations:
attachFiledoes not upload files.- Clicks inside nested shadow DOM do not work.
focusandblurhave no effect.- Clipboard actions do not work.
- A
<select multiple>submits only its first selected option. - An element inside a
visibility: hiddenparent is reported as visible. - Some computed styles (
cursor,user-select) differ from Chromium. - Rich text editors TinyMCE, Trix, Monaco and ProseMirror do not work.
Install Obscura following the official instructions and put obscura on PATH. Then enable the helper:
export const config = { helpers: { Obscura: { url: 'http://localhost:3000', }, },}If the binary is not on PATH, set binaryPath in the config or the OBSCURA_PATH environment variable.
npx codeceptjs runThe helper starts obscura serve on a free port before the first test and stops it after the last one, like Playwright manages Chromium. Each worker gets its own instance:
npx codeceptjs run-workers 8To connect to an Obscura you started yourself, set endpoint; the helper then never starts or stops it:
obscura serve --port 9222 --allow-private-network --allow-file-accessObscura: { url: 'http://localhost:3000', endpoint: 'http://127.0.0.1:9222',}All options: Obscura helper reference.
Lightpanda
Section titled “Lightpanda”Lightpanda is an open-source headless browser built from scratch for automation. It runs your app’s JavaScript in V8 but never paints anything, which makes it start in milliseconds and use a fraction of Chromium’s memory. It computes enough layout for seeElement, waitForVisible and other visibility checks.
Limitations:
- No screenshots:
saveScreenshot, failure screenshots and thescreencastplugin do not work. - No scrolling:
scrollToandscrollPageToBottomhave no effect. clickXYdoes not work.- Clipboard actions do not work.
- Computed styles cover
display,visibilityandopacity; other CSS properties are unreliable. - Rich text editors TinyMCE, Trix and Monaco do not work.
- Linux and macOS only; on Windows use WSL2.
- Licensed under AGPL-3.0. It runs as a separate process, so it does not affect the license of your tests.
Install Lightpanda following the official instructions and put lightpanda on PATH. Then enable the helper:
export const config = { helpers: { Lightpanda: { url: 'http://localhost:3000', }, },}If the binary is not on PATH, set binaryPath in the config or the LIGHTPANDA_PATH environment variable.
npx codeceptjs runThe helper starts lightpanda serve on a free port with telemetry turned off, and stops it after the last test. Each worker gets its own instance:
npx codeceptjs run-workers 8To connect to a Lightpanda you started yourself, set endpoint; the helper then never starts or stops it:
LIGHTPANDA_DISABLE_TELEMETRY=true lightpanda serve --host 127.0.0.1 --port 9222Lightpanda: { url: 'http://localhost:3000', endpoint: 'http://127.0.0.1:9222',}All options: Lightpanda helper reference.
Moli is an open-source headless browser built in Rust for automation. It runs your app’s JavaScript in V8 and computes real CSS, but skips layout and painting, so it starts fast and stays small. Visibility checks such as seeElement and waitForVisible work.
Limitations:
- No screenshots:
saveScreenshot, failure screenshots and thescreencastplugin do not work. clickXYdoes not work.attachFileuploads files without a MIME type; the server receivesapplication/octet-stream.- Links have no default color:
acomputescolor: rgb(0, 0, 0).
Install Moli following the official instructions and put moli on PATH. Then enable the helper:
export const config = { helpers: { Moli: { url: 'http://localhost:3000', }, },}If the binary is not on PATH, set binaryPath in the config or the MOLI_PATH environment variable.
npx codeceptjs runThe helper starts moli serve on a free port before the first test and stops it after the last one. Each worker gets its own instance:
npx codeceptjs run-workers 8To connect to a Moli you started yourself, set endpoint; the helper then never starts or stops it:
moli serve --host 127.0.0.1 --port 9222Moli: { url: 'http://localhost:3000', endpoint: 'http://127.0.0.1:9222',}All options: Moli helper reference.
Kitesurf
Section titled “Kitesurf”Kitesurf is Cloudflare’s browser running on Cloudflare Workers, with a real layout and rendering pipeline. Sessions start in about a second and nothing runs on your machine, so the number of parallel browsers is limited only by how far your suite splits.
Limitations:
- Cloud only, currently a free beta.
- The browser cannot reach
localhost: test a deployed environment or expose your app with a tunnel such ascloudflared tunnel --url http://localhost:3000.
Enable Cloudflare Browser Run and create an API token with the Browser Rendering → Edit permission. Export the credentials:
export CF_ACCOUNT_ID=your-account-idexport CF_API_TOKEN=your-api-tokenThen enable the helper:
export const config = { helpers: { Kitesurf: { url: 'https://staging.myapp.com', }, },}Every worker opens its own cloud session:
npx codeceptjs run-workers 16All options: Kitesurf helper reference.