Add native dev stack and Playwright e2e/API tests

- src/dev/devenv.sh: run backend, Vite and Mailpit without Docker
- CONFIG_PATH env override for the backend config; optional Vite /api proxy
- src/e2e: Playwright API + UI tests (real email sign-in via Mailpit) and
  shoot.mjs screenshot CLI
- Document the workflow in CLAUDE.md

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
simandClaude Sonnet 5.5 committed 2026-11-05 21:56:03 +00:00
1 parent c4aa7f00c2
commit b7eb2bb6d0
17 files changed
+717 -9

No files matched your search

+20 -6
View File
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Overview
Lunchtime is a self-hosted group lunch ordering app: FastAPI + SQLite backend (Python 3.12), React 18 + TypeScript + Vite + Ant Design frontend, nginx in front. All app code lives under `src/`. There are no tests and no linter configured.
Lunchtime is a self-hosted group lunch ordering app: FastAPI + SQLite backend (Python 3.12), React 18 + TypeScript + Vite + Ant Design frontend, nginx in front. All app code lives under `src/`. No linter is configured; end-to-end/API tests live in `src/e2e/` (Playwright, see below).
## Workflow
@@ -18,15 +18,29 @@ Full dev stack (backend with `--reload`, Vite HMR, nginx, Mailpit); also what th
cd src && docker compose up -d # app at http://localhost:8020, Mailpit at http://localhost:8025
```
Without Docker:
Without Docker (native stack: uvicorn `--reload` on :5000, Vite HMR on **:8020** proxying `/api` to the backend, Mailpit on :8025 / SMTP :1025):
```bash
cd src/backend && pip install -r requirements.txt && DB_PATH=./.data uvicorn app.main:app --reload --port 5000
cd src/frontend && npm install && npm run dev # Vite on :3000
cd src/frontend && npm run build # tsc is not run by build; use `npx tsc --noEmit` for type checking
src/dev/devenv.sh setup # backend venv (src/backend/.venv), npm ci for frontend + e2e, Mailpit binary into src/.devenv/bin
src/dev/devenv.sh start # idempotent; waits until everything answers. Also: stop | restart | status | logs [service] | reset (wipes DB + uploads)
cd src/frontend && npx tsc --noEmit # type checking (vite build does not run tsc)
```
`nginx.conf` (repo root) expects `backend:5000` and `frontend:8000`, so running outside Compose needs your own proxy for `/api`.
The native stack uses `src/dev/config.yaml` (via the `CONFIG_PATH` env var) instead of the root `config.yaml`, stores data in `src/backend/data/`, sets `ADMIN_EMAILS=admin@example.com`, and keeps pids/logs in `src/.devenv/`. `API_PROXY_TARGET` turns on Vite's `/api` proxy; it's unset under Compose, where nginx does the routing.
### Testing (requires a running stack; both Compose and native serve the app on :8020)
```bash
cd src/e2e
npx playwright test # everything; --project=api or --project=ui to narrow down
node shoot.mjs / /create "{order}" "{admin}" /stats [--as=user|admin|anon] [--dark] [--mobile] [--full]
```
- Logging in uses the real flow: `lib.mjs` `signIn(email?)` registers (or migrates, for an existing email), reads the confirmation mail from Mailpit's API and confirms it, giving back a user ID. In the browser, a user is "logged in" by setting localStorage `lunchtime_token` before load (`loginAs` in `fixtures.ts`). Fixtures: `user` (fresh per test), `admin` (the ADMIN_EMAILS account), `userPage`.
- `lib.mjs` also has `api()` (fetch with `X-User-Id`), `createOrder()` (with `SAMPLE_MENU`) and `submit()`. Use them to seed data instead of clicking through the UI.
- `shoot.mjs` prints PNG paths (default dir `src/e2e/screenshots/`, gitignored) plus console errors and failed requests. `{order}`/`{admin}` seed an order that has a menu and two submissions. Use it to view the UI after visual changes.
- Ant Design Select: its `role=option` nodes are hidden a11y helpers, so click `.ant-select-item-option` instead.
- Playwright is pinned to 1.65.0 to match the Chromium build in `PLAYWRIGHT_BROWSERS_PATH`. If they diverge, `npx playwright install chromium`.
CI (`.gitea/workflows/build-and-push-images.yaml`) builds and pushes backend/frontend images with Kaniko on changes to `src/**`.