Shuffle/e2e/README.md
cschlaefke cd96d91eae
All checks were successful
CI / flutter (pull_request) Successful in 1m29s
CI / web-build (pull_request) Successful in 1m1s
CI / supabase (pull_request) Successful in 8s
CI / supabase-tests (pull_request) Successful in 33s
CI / e2e (pull_request) Successful in 3m33s
test(catalog): Datensaetze trennen, Assertions und Latenzmessung schaerfen
Jede Suche enthaelt das Kunstwort des eigenen Datensets (Kollision web/api
behoben); Kachelzaehlung ohne first(), konkrete Trefferzahlen; screenText
wartet auf die Live-Region statt sie zu entfernen; Latenzmessung ueberspringt
bereits sichtbare Treffer, Filtersuchen ergaenzt; Ladeskripte mit Exit-Code
und TCP-Schutz; Doku aktualisiert.

Refs #3

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-04 21:32:29 +01:00

83 lines
7.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# E2E-Tests (Playwright)
Auth-Tests für KTO-01 (Spec `docs/specs/1-auth-registrierung-anmeldung.md` § 7, Issue #38) und Tests der
Katalogsuche KAT-01 (Spec `docs/specs/3-katalog-suche.md` § 7, Issue #3). Jeder Auth-Test
nutzt zufällige E-Mail-Adressen und filtert Mails je Adresse (Mailpit wird nie global geleert),
die Tests laufen deshalb parallel.
## Projekte
| Projekt | Ziel | Voraussetzung | Tests |
|---|---|---|---|
| `api` | GoTrue und `search_catalog_games` über Kong (`:54321`) + Mailpit (`:54324`) + Postgres (`:54322`) | `supabase start` | 77 |
| `web` | gebaute Flutter-Web-App auf `http://localhost:3000` | zusätzlich `flutter build web` | 45 |
| `throttle` | Extra-GoTrue-Container mit `GOTRUE_RATE_LIMIT_HEADER` (AUTH-CFG-13) | `THROTTLE_GOTRUE_URL` | 4 |
| `spike` | GoTrue mit unerreichbarem SMTP (Issue #37), nicht blockierend | `SPIKE_GOTRUE_URL` | 3 |
| `perf` | Latenzmessung der Katalogsuche (KAT-01 Krit. 7), nur lesend, nie in der CI | `PERF_WEB_URL`, `PERF_ANON_KEY` | 1 |
`throttle`, `spike` und `perf` werden nur registriert, wenn die jeweilige Variable gesetzt ist.
## Lokal ausführen
```bash
supabase start -x studio,imgproxy,vector,logflare,edge-runtime,postgres-meta,realtime,storage-api
supabase db reset
# Web-Build gegen die lokale CLI (echten Anon-Key aus `supabase status -o env` eintragen)
cd app && flutter build web --dart-define-from-file=env/ci.example.json # SUPABASE_URL/ANON_KEY anpassen
cd ../e2e && npm ci && npx playwright install chromium
npx playwright test --project=api
npx playwright test --project=web # startet `serve -s ../app/build/web -l 3000` selbst
# Drosselung (Krit. 7) und SMTP-Spike
./support/start-throttle-gotrue.sh start throttle # :9998
./support/start-throttle-gotrue.sh start smtp-down # :9997
THROTTLE_GOTRUE_URL=http://127.0.0.1:9998 SPIKE_GOTRUE_URL=http://127.0.0.1:9997 npx playwright test
./support/start-throttle-gotrue.sh stop throttle; ./support/start-throttle-gotrue.sh stop smtp-down
```
Umgebungsvariablen (Standard = lokale CLI-Demo-Werte, keine Secrets): `SUPABASE_URL`,
`SUPABASE_ANON_KEY`, `SUPABASE_SERVICE_ROLE_KEY`, `MAILPIT_URL`, `E2E_DB_URL`, `WEB_URL`,
`TERMS_VERSION`, `E2E_ALLOWED_HOSTS` (zusätzlich erlaubte Hosts für SUPABASE_URL/MAILPIT_URL/E2E_DB_URL, kommagetrennt; Standard nur 127.0.0.1, localhost, [::1]).
## Katalogsuche (KAT-01)
- `tests/web/kat01-suche.spec.ts` (Suche per Schaltfläche „Search games“, Relevanz, alternative Titel, Verlage, Filter, Nachladen, leere Zustände, URL/Neuladen/Zurück, Offline) und `tests/api/kat01-suche.spec.ts` (`search_catalog_games` als `anon` über Kong, Fehlerfälle). Testnamen tragen „KAT-01 Kriterium n“.
- **Testdaten:** `support/catalog.ts` legt je Spec-Datei ein eigenes Datenset an (eigener UUID-Präfix, eigenes Kunstwort: `zqvk`/`e2ec0001-` für web, `wlpd`/`e2ec0002-` für api), im `beforeAll`, aufgeräumt im `afterAll` (idempotent: `seed` löscht zuerst). Die Dateien laufen intern seriell, untereinander parallel. Jede Suche muss das Kunstwort des eigenen Datensets enthalten (z. B. `zqvk dunkelforst`); die Unterscheidungswörter sind in beiden Sets gleich, nur mit Kunstwort treffen Suchen weder das andere Set noch Startbestand noch die pgTAP-Fixtures (`qxz`). Nur lokal/CI (`support/db.ts`).
- **Bekannte Eigenheiten der Flutter-Semantics (beim Schreiben weiterer Tests beachten):** Die Trefferkacheln sind Textknoten (`span`) unter *einem* Listen-Container, nicht einzelne Elemente mit Rolle; die Liste ist virtualisiert. Während einer neuen Suche bleiben die alten Treffer sichtbar: nie nur auf „irgendeine Kachel“ warten, sondern auf Trefferzahl und erwartete Kachel. Hinweistexte stehen zusätzlich in der Live-Region `flt-announcement-polite`; Texte mit `locator('span', { hasText })` suchen. Das Semantics-Eingabefeld zeigt seinen Wert nur, solange es Fokus hat (nach Auswahlmenü oder Neuladen ist es leer); den Suchbegriff über die URL prüfen. Ein direkt geladenes `/catalog` nimmt über den Semantics-Baum getippten Text nicht verlässlich an (Autofokus des Suchfelds ist beim Einschalten der Semantics schon gesetzt); ohne Semantics, mit Mausklick und Tastatur, funktioniert es (Probe: 3 von 3). Es ist ein Testwerkzeug-Effekt, kein Produktfehler. Deshalb die Suche in Tests über die Startseite öffnen (`openCatalog` im Spec).
### Latenzmessung (Projekt `perf`, KAT-01 Krit. 7, vorläufig)
Vorläufige Messung (Option A der Spec, `docs/specs/3-katalog-suche.md` Spec-F4): kein hartes Gate gegen Staging. Ergebnis und Aussagegrenzen: `docs/specs/3-katalog-suche-umsetzung.md`, Abschnitt „PR 3c“.
```bash
# 1. Synthetisches Volumen laden (10 000 Spiele, nur lokal, wird COMMITTET; danach wieder entfernen)
docker exec -i supabase_db_shuffle psql -U postgres -d postgres -X -v confirm_local=yes -v n_games=10000 \
< supabase/perf/catalog_search_perf_load.sql
# 2. Web-Build (gegen dieselbe Supabase-URL) bereitstellen, z. B. `npx serve -s ../app/build/web -l 3000`, und messen
cd e2e
PERF_WEB_URL=http://localhost:3000 PERF_SUPABASE_URL=http://127.0.0.1:54321 PERF_ANON_KEY=<anon> \
npm run test:perf # setzt PERF_ONLY=1: nur Projekt perf, kein lokaler Web-Server
# 3. Aufräumen
docker exec -i supabase_db_shuffle psql -U postgres -d postgres -X -v confirm_local=yes \
< supabase/perf/catalog_search_perf_unload.sql
```
Der Test drosselt Chrome per CDP (`Network.emulateNetworkConditions`: 100 ms Latenz, 10 Mbit/s), baut aus dem Katalog eine feste Liste von mindestens 100 Suchen (Titel, Titelanfang, Wort, Wortkombination, Verlag, Großbuchstaben, alternative Titel, 5 ohne Treffer), fragt den erwarteten ersten Treffer je Suche ungedrosselt bei der RPC ab und misst **im Browser** die Zeit vom letzten Tastendruck (inklusive 300 ms Entprellung) bis zur ersten passenden Kachel. Ausgabe p50/p95/Maximum, Anhang `kat01-latenz.json`, bestanden bei p95 ≤ 2000 ms. `PERF_SEARCHES` (Standard 110) setzt die Anzahl, `PERF_LATENCY_MS` (Standard 100) dient nur der Gegenprobe des Gates. Das Projekt greift weder auf `support/db.ts` noch auf `support/auth-config.ts` zu; es läuft nie in `e2e-run.sh`/CI.
## Aufbau
- `support/auth-config.ts` – Konstanten mit `AUTH-CFG-nn`-Bezug; `tests/api/config.spec.ts` prüft sie gegen `supabase/config.toml` und `docs/auth-konfiguration.md`.
- `support/gotrue.ts`, `support/mailpit.ts` – REST-Client und Mailfänger-Helfer.
- `support/db.ts` – direkter Postgres-Zugriff, **nur lokal/CI** (bricht bei anderem Host ab); setzt `recovery_sent_at`/`confirmation_sent_at` für Ablauftests.
- `support/web.ts` – Flutter-Web-Helfer für Auth (Registrierung, Anmeldung, Uhr verschieben); die allgemeinen Helfer (Semantics einschalten, Felder füllen) liegen in `support/flutter.ts` (ohne Auth-Konstanten, auch für `perf`).
- `support/catalog.ts` – Testdaten der Katalogsuche (Datenset je Spec-Datei, Aufräumen über den UUID-Präfix).
- `support/start-throttle-gotrue.sh` – zweiter GoTrue-Container (Profile `throttle`, `smtp-down`).
## Hinweise zum Web-Projekt
- Flutter zeichnet auf Canvas. Der Semantics-Baum wird über `flt-semantics-placeholder` eingeschaltet (`enableSemantics`).
- Eingabefelder werden mit `click` + `pressSequentially` gefüllt; `fill` allein geht gelegentlich verloren.
- Immer `localhost` (nicht `127.0.0.1`): Die Mail-Links nutzen die Site-URL (AUTH-CFG-01), sonst liegt die Sitzung in einem anderen `localStorage`.
- Gegen die gemeinsame CLI-Instanz werden nie `X-Forwarded-For`-Header gesendet (R13).