Playwright drives a production build served by Vite preview on :4175 against a throwaway
Continuwuity homeserver started per run. The suite
covers functional flows (login, sync, navigation, timeline) and captures
screenshots for layout regression.
- Docker running (a Continuwuity container is started via testcontainers).
pnpm test:e2e # functional tests on the host (screenshots skipped)
pnpm test:e2e:docker # full suite, browser in the pinned container
pnpm test:e2e:docker:update # regenerate screenshot baselines
pnpm test:e2e:ui # interactive UI mode
pnpm test:e2e:report # open the last HTML reportScreenshot baselines are rendered in mcr.microsoft.com/playwright:<version>-noble,
because font rendering differs between hosts. Regenerate them with
test:e2e:docker:update, never on the host. Visual tests skip unless
PW_TEST_CONNECT_WS_ENDPOINT is set.
global.setup.ts:
- Starts a Continuwuity container with open registration.
- Registers a bootstrap user and seeds deterministic rooms/messages over the client-server API.
- Gives each Playwright worker its own identically seeded user and
storageState, isolating sync and crypto state while specs run in parallel. - Saves the container id for
global.teardown.ts. - Injects the session into the app's
localStorage(matrixSessions+matrixActiveSession), so specs start already logged in without driving the login UI.
global.teardown.ts removes the container after the dependent projects finish.
Specs live in tests/e2e/*.spec.ts and run against both a desktop and a mobile
viewport. The touch project runs touch interactions and permalink navigation;
the narrow mobile project covers the rest of the responsive flows. Assert
behaviour with locators; add toHaveScreenshot where a layout baseline is
useful. Screenshot baselines live in tests/e2e/__screenshots__.
Notes when adding screenshots:
- Mask dynamic content (
timeelements, the room-intro creation line). - The message timeline is virtualised, so its item positions shift between runs; snapshot the surrounding layout rather than the timeline itself.
foldsrendersTextasp, sogetByRole('heading')will not match titles.