Skip to content

Add Lightpanda as an alternative headless browser for E2E tests#171

Draft
krichprollsch wants to merge 7 commits intoPackmindHub:mainfrom
krichprollsch:lightpanda
Draft

Add Lightpanda as an alternative headless browser for E2E tests#171
krichprollsch wants to merge 7 commits intoPackmindHub:mainfrom
krichprollsch:lightpanda

Conversation

@krichprollsch
Copy link

Explanation

Lightpanda is an open-source headless browser written in Zig. It exposes a CDP (Chrome DevTools Protocol) endpoint and is designed to be significantly faster and lighter than Chromium. This PR wires it up as an opt-in alternative to the existing Chromium E2E runner.

Type of Change

  • Bug fix
  • New feature
  • Improvement/Enhancement
  • Refactoring
  • Documentation
  • Breaking change

Affected Components

Docker Compose (docker-compose.yml)

  • lightpanda service — lightpanda/browser:nightly image, under the e2e-lightpanda profile. Healthcheck uses bash -c </dev/tcp/127.0.0.1/9222 (the image ships no wget/curl).
  • run-e2e-tests-lightpanda service — mirrors run-e2e-tests but sets LIGHTPANDA_WS_ENDPOINT and depends on lightpanda being healthy first.

Playwright config (playwright.lightpanda.config.ts)

  • video: 'off', screenshot: 'off' — Lightpanda has no rendering engine.
  • locale: '' — Playwright's built-in locale fixture defaults to "en-US", which makes crPage.js call mulation.setUserAgentOverride during page initialisation. Lightpanda does not implement that CDP command and returns UnknownMethod. An empty string is falsy so the conditional is skipped.
  • Single lightpanda project (no device preset needed for a CDP connection).

Fixture (src/fixtures/packmindTest.ts)

  • Worker-scoped browser fixture override: when LIGHTPANDA_WS_ENDPOINT is set, chromium.connectOverCDP() is used instead of chromium.launch(). All downstream fixtures (testWithUserSignedUp, testWithApi) inherit this automatically.
  • Browser.disconnect() does not exist on CDP-connected browsers in playwright-core 1.56 — the IPC connection closes naturally when the worker exits.

npm script (apps/e2e-tests/package.json)

  • "e2e:lightpanda": "playwright test --config=playwright.lightpanda.config.ts"

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing completed
  • Test coverage maintained or improved

Test Details:

Start Lightpanda + full dev stack

docker compose --profile e2e-lightpanda up

Or run tests manually once the stack is up

LIGHTPANDA_WS_ENDPOINT=ws://localhost:9222 npm run e2e:lightpanda

TODO List

  • CHANGELOG Updated
  • Documentation Updated

Reviewer Notes

The CDP integration is fully wired up and Playwright successfully connects to Lightpanda. Tests navigate to the frontend, but the frontend JS bundle throws ReferenceError: TextEncoderStream is not defined — Lightpanda's nightly build does not yet implement TextEncoderStream (part of the Web Streams Encoding API). This causes Lightpanda to crash on the first page load.

The fix belongs in Lightpanda, not in our test suite. Once Lightpanda implements TextEncoderStream (and likely TextDecoderStream), the tests should run without further changes on our side.

krichprollsch and others added 7 commits March 1, 2026 16:12
Add `lightpanda` service (nightly image, CDP on :9222, healthcheck) and
`run-e2e-tests-lightpanda` service under the `e2e-lightpanda` profile so
the full Lightpanda-backed E2E stack can be launched with a single
`docker compose --profile e2e-lightpanda up`.

Co-Authored-By: Claude <claude@anthropic.com>
Add playwright.lightpanda.config.ts with video and screenshot disabled
since Lightpanda has no rendering engine. Uses a single 'lightpanda'
project and preserves trace on first retry.

Co-Authored-By: Claude <claude@anthropic.com>
When LIGHTPANDA_WS_ENDPOINT is set, connect to the Lightpanda browser
over CDP using chromium.connectOverCDP() instead of launching a local
Chromium instance. All downstream fixtures (testWithUserSignedUp,
testWithApi) inherit this automatically via the fixture chain.

Co-Authored-By: Claude <claude@anthropic.com>
Add a dedicated script that runs Playwright with the Lightpanda-specific
config (no video/screenshot, CDP-connected browser).

Co-Authored-By: Claude <claude@anthropic.com>
The Lightpanda image does not ship wget or curl. Replace the healthcheck
with a bash built-in TCP connection test which has no external dependencies.

Co-Authored-By: Claude <claude@anthropic.com>
Playwright's built-in locale fixture defaults to "en-US", which causes
crPage.js to call Emulation.setUserAgentOverride during page init.
Lightpanda does not implement that CDP command and returns UnknownMethod.
An empty string is falsy, so the conditional (if options.locale) is skipped.

Co-Authored-By: Claude <claude@anthropic.com>
Playwright requires the first fixture argument to use object destructuring
({}) not a plain parameter; _fixtures caused a runtime error.
Browser.disconnect() does not exist on CDP-connected browsers in
playwright-core 1.56 — the connection closes naturally on worker exit.

Co-Authored-By: Claude <claude@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant