test: Zusagen pruefbar machen, die nur von Hand hielten (#038, #037)
Prüfung / pruefung (push) Canceled after 0s
Prüfung / e2e (push) Canceled after 0s

#038: Die E2E-Ablaeufe laufen ab jetzt vor jedem Merge nach main, nicht vor
jedem Commit. Gemessen: Bau 14 s, Start 7 s, Ablaeufe 256 s — zu den vier
Minuten des bestehenden Tores. Neun Minuten vor jedem Commit ist ein Tor, das
umgangen wird. Vor jedem Merge waeren es in Phase 2 acht Laeufe gewesen, und
jeder der vier Befunde aus #027 waere am Tag seiner Entstehung aufgefallen.

Geprueft wurde jeder der 16 Ablaeufe gegen die Frage, ob es ein
Vitest-Gegenstueck gibt. Neun Zusagen haengen ausschliesslich dort, und keine
laesst sich holen: alle brauchen einen echten Browser. Die Liste steht in
CLAUDE.md.

Der eigentliche Fund dabei war keine Testluecke, sondern eine Konvention ohne
Pruefer: "jede Seite prueft selbst" steht seit #007 in CLAUDE.md, und geprueft
hat es bis hierher nur ein Mensch, der nachsieht. Der Review von Phase 2 hat
alle 27 Seiten durchgesehen — ein Ergebnis, das fuer genau einen Tag gilt.
tests/zugang.test.ts liest sie jetzt, samt jedem Route Handler; die Ausnahmen
(Auth, Healthcheck) stehen namentlich mit Begruendung, und ein Test prueft auch
die Gegenrichtung.

#037: Das Lesemodell der Anhaenge liegt in queries/ und engt selbst ein — vorher
hing das daran, dass beide Aufrufer den Lauf vorher pruefen. /meine-geraete wird
bei 390 px gemessen, mit einem echten MITARBEITER-Konto aus dem E2E-Vorlauf,
dazu ein Test, dass dort kein Link in die Verwaltung angeboten wird.

Dabei selbst einen Fehler gemacht, der die neue Regel begruendet: fuer das
zweite Konto brauchte `anmelden` eine Variante, die nicht auf / wartet, und ich
habe das Warten fuer alle gelockert. Das machte zwei unverwandte Ablaeufe
unzuverlaessig — sichtbar nur im vollen Durchgang, einzeln waren beide gruen.
Ein gemeinsamer Helfer in einer Testsuite ist geteilter Zustand. Ohne vollen
Durchgang haette ich zwei rote Ablaeufe gemergt.

1457 Vitest-Tests (vorher 1454), 115 E2E-Ablaeufe (vorher 113). Offen bleibt nur
noch #024, und das verlangt einen echten Proxmox-Host.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Florian Wilde
2026-10-11 06:05:29 +02:00
co-authored by Claude Opus 5
parent 80d97467da
commit 75c335df23
16 changed files with 639 additions and 80 deletions
+50 -12
View File
@@ -1,10 +1,10 @@
# #038 Die E2E-Abläufe laufen in keinem Tor und waren monatelang rot
**Status:** offen
**Status:** erledigt
**Im Tracker:** –
**Meilenstein:** v0.3.0
**Meilenstein:** v0.2.0
**Labels:** phase-2, test, infra
**Geschätzt:** 3 h **Tatsächlich:** –
**Geschätzt:** 3 h **Tatsächlich:** 1 h 35 min
## Ziel
@@ -27,28 +27,66 @@ eine Notiz und keine Prüfung.
## Zu entscheiden
- [ ] **`pnpm test:e2e` ins Tor vor dem Commit?** Dagegen: es verlangt einen **gebauten,
- [x] **`pnpm test:e2e` ins Tor vor dem Commit?** → **Nein.** Dagegen: es verlangt einen **gebauten,
laufenden** Stand (`pnpm build && pnpm start`), dauert über vier Minuten und braucht eine
Datenbank mit Seed-Bestand. Vier Minuten vor jedem Commit ist ein Tor, das umgangen wird.
- [ ] **Oder eine kleinere, verbindliche Regel:** E2E läuft vor jedem Merge nach `main` — das wären
- [x] **Gewählt: eine kleinere, verbindliche Regel.** E2E läuft vor jedem Merge nach `main` — das wären
acht Läufe in Phase 2 gewesen und hätte jeden der vier Befunde am Tag seiner Entstehung
gezeigt. Das ist die Empfehlung.
- [ ] **Oder im CI** (`.gitea/workflows/ci.yml`). Dort ist kein Runner registriert; das zu ändern
- [x] **Nicht im CI** (`.gitea/workflows/ci.yml`). Dort ist kein Runner registriert; das zu ändern
ist eine eigene Entscheidung und gehört nicht in dieses Issue.
## Aufgaben
- [ ] Die gewählte Regel in `CLAUDE.md` aufschreiben, mit **gemessener** Dauer und der Begründung,
- [x] Die gewählte Regel in `CLAUDE.md` aufschreiben, mit **gemessener** Dauer und der Begründung,
warum sie nicht im Commit-Tor steht
- [ ] Die Voraussetzungen, die `tests/e2e/global-setup.ts` prüft, in derselben Reihenfolge
- [x] Die Voraussetzungen, die `tests/e2e/global-setup.ts` prüft, in derselben Reihenfolge
dokumentieren — der Vorlauf ist inzwischen die ehrlichste Beschreibung dessen, was E2E braucht
- [ ] Prüfen, welche Zusagen **ausschließlich** in E2E stehen, und für jede entscheiden: gehört sie
- [x] Prüfen, welche Zusagen **ausschließlich** in E2E stehen, und für jede entscheiden: gehört sie
zusätzlich in einen Vitest-Test, der den Handler direkt fährt? (Das Muster steht in
`tests/scim.test.ts`, `tests/anhang-route.test.ts` und `tests/lauf-ereignisse.test.ts`.)
- [ ] Mindestens die Rechteprüfung der beiden Phase-2-Handler ist damit schon abgedeckt — bleiben
- [x] Mindestens die Rechteprüfung der beiden Phase-2-Handler ist damit schon abgedeckt — bleiben
Rückfall auf Polling, Herzschlag am echten Browser und 390 px
## Akzeptanzkriterien
- [ ] In `CLAUDE.md` steht, wann E2E läuft, und die Angabe ist gemessen, nicht geschätzt
- [ ] Eine Liste der Zusagen, die nur in E2E stehen — und zu jeder eine Entscheidung
- [x] In `CLAUDE.md` steht, wann E2E läuft, und die Angabe ist gemessen, nicht geschätzt
- [x] Eine Liste der Zusagen, die nur in E2E stehen — und zu jeder eine Entscheidung
## Die Entscheidung, und was sie gekostet hat
**Nicht im Commit-Tor.** Gemessen am 2026-10-11: Bau 14 s, Start 7 s, Abläufe **256 s** — zusammen
4 min 37 s, zu den vier Minuten des bestehenden Tores. Neun Minuten vor jedem Commit ist ein Tor,
das umgangen wird, und ein umgangenes Tor prüft nichts.
**Vor jedem Merge nach `main`.** In Phase 2 wären das acht Läufe gewesen, und jeder der vier
Befunde aus #027 wäre am Tag seiner Entstehung aufgefallen. Die Regel steht in `CLAUDE.md` mit den
gemessenen Zahlen und der Begründung; `docs/architektur.md` §5b trägt sie mit.
**Nicht im CI**, weil dort kein Runner registriert ist. Das zu ändern ist eine eigene Entscheidung
und gehört nicht in dieses Issue.
## Die Liste der Zusagen — und was sich davon holen ließ
Geprüft wurde jeder der 16 Abläufe gegen die Frage „gibt es dafür ein Vitest-Gegenstück?“. Das
Ergebnis steht als Tabelle in `CLAUDE.md`. Die Kurzfassung:
**Nichts davon lässt sich nach Vitest holen** — alle brauchen einen echten Browser: Layout bei
390 px, `BarcodeDetector`, Touch-Ereignisse, zwei Browser-Kontexte gleichzeitig, Zwischenablage,
Print-CSS, gerendertes DOM, und überhaupt die Hydrierung. Die Antwort auf #038 ist deshalb nicht
„verlagern“, sondern „regelmäßig laufen lassen“.
**Was sich holen ließ, ist geholt** — und das war mehr als erwartet:
- Die **Rechteprüfung der Route Handler** steht seit [#036](036-reviewbefunde-phase-2.md) in
`tests/anhang-route.test.ts`, `tests/lauf-ereignisse.test.ts` und `tests/scim.test.ts`: die
Handler werden mit echten `Request`-Objekten gefahren, nicht über die Oberfläche.
- Neu in diesem Issue: `tests/zugang.test.ts` prüft **strukturell**, dass jede `page.tsx` unter
`(app)` und jeder `route.ts` sein Recht selbst prüft. Die Ausnahmen (Auth, Healthcheck) stehen
dort namentlich samt Begründung, und ein Test prüft auch die **Gegenrichtung**: eine Ausnahme für
einen Handler, den es nicht mehr gibt, verdeckt beim nächsten Mal einen echten Befund.
Dass das nötig war, ist der eigentliche Fund: die Zusage „jede Seite prüft selbst“ steht seit #007
in `CLAUDE.md`, und sie hielt bis hierher **nur durch Nachsehen von Hand**. Der Review von Phase 2
hat alle 27 Seiten durchgesehen — das gilt für den Tag, an dem es lief. Beide Gegenproben (eine
Seite, ein Handler ohne Prüfung) werden jetzt rot.