The Playwright suite had no linter and no formatter — only tsc. Add flat-config ESLint
(typescript-eslint, type-aware) and Prettier (2-space, matching the suite's style).
Rules keep the ones that catch real TEST bugs and drop the noise:
- no-floating-promises KEPT — an un-awaited request/assertion can let a test end before it runs,
passing vacuously. It caught one: the SSE reader loop in sse-listener is now explicitly `void`.
- no-unused-vars KEPT — caught three dead bindings (an unused adminToken fixture arg, an unused
`api` arg, an unused JPEG_MAGIC import), all removed.
- no-explicit-any OFF — all test code; `any` is the honest type for an untyped res.json() body or
a page.evaluate() return.
- no-empty-pattern OFF — Playwright's dependency-free fixtures are `async ({}, use) => {}`.
Refactor: `const BASE = process.env.E2E_FRONTEND_URL ?? '...'` was redeclared verbatim in 23
files — extracted to helpers/env.ts and imported, so a port/scheme change is one edit not a sweep.
Then `prettier --write`. Verified: eslint clean, tsc clean, prettier clean, desktop suite 210
passed / 1 skipped. (One mobile spec flaked once under retries:0 — a pre-existing cross-test
reflow-timing vector from the flakiness audit, not this change: the each-key edit is stable across
16 isolated runs and a clean full mobile re-run.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
78 lines
2.2 KiB
YAML
78 lines
2.2 KiB
YAML
# Isolated EventSnap test stack. Mirrors production layout (Caddy → frontend +
|
|
# backend) but on its own ports, its own volumes, with rate-limits disabled and
|
|
# `EVENTSNAP_TEST_MODE=1` so the `/admin/__truncate` reset endpoint is live.
|
|
#
|
|
# Bring it up once before running the suite:
|
|
# npm run stack:up
|
|
# Tear it down (and wipe all volumes) after:
|
|
# npm run stack:down
|
|
#
|
|
# Port 3101 is the only externally exposed port: Caddy fronts everything.
|
|
|
|
services:
|
|
db:
|
|
image: postgres:16-alpine
|
|
environment:
|
|
POSTGRES_USER: eventsnap_test
|
|
POSTGRES_PASSWORD: eventsnap_test
|
|
POSTGRES_DB: eventsnap_test
|
|
healthcheck:
|
|
test: ['CMD-SHELL', 'pg_isready -U eventsnap_test -d eventsnap_test']
|
|
interval: 3s
|
|
timeout: 3s
|
|
retries: 30
|
|
ports:
|
|
- '55432:5432' # exposed so the e2e harness can connect via pg for fixture setup
|
|
|
|
app:
|
|
build:
|
|
context: ../backend
|
|
dockerfile: Dockerfile
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
environment:
|
|
DATABASE_URL: postgres://eventsnap_test:eventsnap_test@db:5432/eventsnap_test
|
|
JWT_SECRET: 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff
|
|
# bcrypt hash for the literal string "admin-test-pw" (cost 4 — fast for tests).
|
|
# Generated once and committed. Verified with `bcrypt.compareSync`.
|
|
# The $ characters are doubled to escape compose interpolation.
|
|
ADMIN_PASSWORD_HASH: $$2b$$04$$XKJJkNX6BOi6y3S42DA5JOWwk4oxc8DHPL6.MrPfJI2vpnccZjP32
|
|
EVENT_SLUG: e2e-test-event
|
|
EVENT_NAME: E2E Test Event
|
|
APP_PORT: '3000'
|
|
MEDIA_PATH: /media
|
|
SESSION_EXPIRY_DAYS: '30'
|
|
EVENTSNAP_TEST_MODE: '1' # ENABLES /admin/__truncate — never set in prod
|
|
RUST_LOG: eventsnap_backend=info,tower_http=warn
|
|
volumes:
|
|
- media_data:/media
|
|
expose:
|
|
- '3000'
|
|
|
|
frontend:
|
|
build:
|
|
context: ../frontend
|
|
dockerfile: Dockerfile
|
|
depends_on:
|
|
- app
|
|
environment:
|
|
PORT: '3001'
|
|
HOST: '0.0.0.0'
|
|
ORIGIN: 'http://localhost:3101'
|
|
expose:
|
|
- '3001'
|
|
|
|
caddy:
|
|
image: caddy:2-alpine
|
|
depends_on:
|
|
- app
|
|
- frontend
|
|
volumes:
|
|
- ./Caddyfile.test:/etc/caddy/Caddyfile:ro
|
|
ports:
|
|
- '3101:3101'
|
|
|
|
volumes:
|
|
media_data:
|