Skip to content

ci: boot the runner image and run playwright against it - #79

Merged
matthew-demidoff merged 1 commit into
masterfrom
phase2/runner-e2e
Sep 5, 2026
Merged

ci: boot the runner image and run playwright against it#79
matthew-demidoff merged 1 commit into
masterfrom
phase2/runner-e2e

Conversation

@matthew-demidoff

Copy link
Copy Markdown
Member

Third of the CI stack; based on #78 (phase2/authz-matrix). Needs the Redis
service from #77 because /api/health/ready requires both stores. Rebase onto
master after #78 merges.

CI built the production runner image on every push and then threw it away,
running the Playwright scenarios against the dev server instead. Nonce CSP,
HSTS, the standalone server and migrate-on-boot exist only in the image, so
the artifact that ships was the one thing the end-to-end suite never touched.

  • security.yml: tag the runner build, boot it with --network host against
    the Postgres and Redis services and the five secrets validateConfig()
    requires (Cloudflare's documented always-pass Turnstile keypair, so
    login/register submissions can be exercised in a later spec), wait on
    /api/health/ready with a bounded loop that dumps container logs on
    timeout, run Playwright with PLAYWRIGHT_BASE_URL, dump logs on failure,
    always remove the container. Playwright's browser install overlaps the
    image boot. The dev-server e2e run is dropped from CI: one pass, against
    the artifact that ships.
  • playwright.config.ts: baseURL from PLAYWRIGHT_BASE_URL, webServer only
    when it is unset. Local flow unchanged.
  • README: CI paragraph and the PLAYWRIGHT_BASE_URL knob.

Rehearsed locally against scratch Postgres/Redis: the image was ready in
about 4s, served the production CSP and HSTS headers, and all 14 e2e
scenarios passed against it; the dev-server path still passes with the
variable unset.

CI built the production runner image on every push and then threw it away,
running the Playwright scenarios against the dev server instead. Nonce CSP,
HSTS, the standalone server and migrate-on-boot exist only in the image, so
the artifact that ships was the one thing the end-to-end suite never touched.

Tag the runner build, boot it on the host network against the Postgres and
Redis services with the five secrets validateConfig() requires (Cloudflare's
always-pass Turnstile keypair, so form submissions can be exercised later),
wait on /api/health/ready, and point Playwright at it via PLAYWRIGHT_BASE_URL.
Container logs are dumped on failure and the container is always removed.

Locally nothing changes: without PLAYWRIGHT_BASE_URL the config still starts
the dev server on 3100.
@matthew-demidoff
matthew-demidoff changed the base branch from phase2/authz-matrix to master September 5, 2026 19:56
@matthew-demidoff
matthew-demidoff merged commit 340fa37 into master Sep 5, 2026
4 checks passed
@matthew-demidoff
matthew-demidoff deleted the phase2/runner-e2e branch September 5, 2026 19:59
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