pediatric-ai-scribe-v3/docker-compose.e2e.yml
Daniel 79c329ceda
Some checks failed
Forgejo Android APK / Root app tests (push) Successful in 55s
Forgejo Docker Build / Root app tests (push) Successful in 48s
Forgejo Android APK / Build signed APK (push) Successful in 2m0s
Forgejo Docker Build / Build Docker image (push) Successful in 16s
Forgejo Docker Build / Deploy to the host (push) Failing after 0s
test(e2e): seed an admin account, and fix the sign-in that broke the browser suite
Adds the admin fixture the Search Sources screen needed, and repairs the reason
no browser-driving e2e test could log in at all.

The sign-in failure first. The suite drove the app over http on a container
hostname, which is not a secure context, so the browser provides no
crypto.randomUUID. AccountBoundary calls it to mint a session generation on
every sign-in; the call threw, the boot handler's catch swallowed it, and every
test landed on the login screen holding a perfectly valid session. Measured:
isSecureContext false and randomUUID undefined on
http://pediatric-ai-scribe-e2e:3000, both true on http://127.0.0.1:3553, where
boundary.enter() returns true and the app enters.

Chrome's --unsafely-treat-insecure-origin-as-secure was tried first and does not
work: Playwright rejects the --user-data-dir it must be paired with, and the
flag alone leaves isSecureContext false. Loopback needs no flags, so the runner
now uses the host network and the published port.

The seed is new. The e2e user was a registration someone did by hand once that
the shared Postgres happened to keep — enough to log in and no more. There was
no admin account, so nothing under /api/admin could be tested through a real
request, which is how the Search Sources card came to be verified by reading its
markup. e2e/seed.js creates both accounts and reconciles an existing one, so a
leftover with the wrong role cannot fail the suite for a reason unrelated to the
code. It resets passwords and grants admin, so it refuses any address outside
@ped-ai.test. The runner seeds before it tests.

The new spec covers what markup-reading could not: that an ordinary account is
refused the settings and never offered the Admin menu item, that no API key
comes back readable, that the Test button reports each source separately, and
that every control the save handler reads exists in a real render. Each account
gets its own browser context, because AccountBoundary allows one owner per
document and freezing the page on a second is the behaviour, not a bug.

10/10 pass on both projects. Two unit tests pin the loopback requirement and the
seed's domain guard so neither can be undone quietly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU
2026-09-11 17:24:32 +02:00

69 lines
2.7 KiB
YAML

# E2E test environment — runs a second instance of the app on port 3553 with
# Turnstile disabled so Playwright can log in without the bot challenge.
# Shares the postgres + pgdata volume with production so seeded e2e test users
# (email pattern *@ped-ai.test) persist across test runs.
#
# Bring up with:
# docker compose -f docker-compose.yml -f docker-compose.e2e.yml up -d pediatric-scribe-e2e
#
# Tear down with:
# docker compose -f docker-compose.yml -f docker-compose.e2e.yml down pediatric-scribe-e2e
services:
pediatric-scribe-e2e:
build:
context: .
args:
GIT_REVISION: ${GIT_REVISION:-unknown}
image: ped-ai-local:latest
ports:
- "127.0.0.1:3553:3000"
networks:
# Its own project network, plus the converter so PDF export is exercised
# here too. Without this the e2e stack could only reach Postgres and
# Redis, and a PDF download failed in a way production would not.
- default
- danvics_convert
env_file:
- .env
environment:
# Disable Turnstile entirely — both server-side verification AND the
# client-side widget. Without clearing the SITE_KEY the frontend tries
# to initialise the Turnstile iframe against the prod domain and
# throws error 110200, which Playwright's pageerror guard correctly
# flags as an uncaught exception.
TURNSTILE_SECRET_KEY: ""
TURNSTILE_SITE_KEY: ""
# Disable SMTP so register auto-verifies the user and returns a session
SMTP_HOST: ""
# Raise the login rate-limit so Playwright multi-worker runs don't
# trip the production 10/15min cap. Only affects this e2e container.
LOGIN_RATE_LIMIT_MAX: "500"
# Also raise the global /api/ limit so multi-spec Playwright runs
# that make hundreds of API calls don't burn through the 200/min cap.
API_RATE_LIMIT_MAX: "5000"
# Allow fetches from the two origins Playwright serves tests from —
# the in-network hostname and the host-port loopback. Without this
# the CORS middleware (scoped to /api) rejects any non-GET request
# because .env's APP_URL points at the production domain.
CORS_ORIGINS: "http://pediatric-ai-scribe-e2e:3000,http://host.docker.internal:3553,http://localhost:3553,http://127.0.0.1:3553"
volumes:
- scribe-logs-e2e:/app/data/logs
depends_on:
postgres:
condition: service_healthy
container_name: pediatric-ai-scribe-e2e
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/api/health"]
interval: 30s
timeout: 10s
retries: 5
start_period: 20s
volumes:
scribe-logs-e2e:
networks:
danvics_convert:
external: true