Neun Kapitel unter docs/anleitung/ fuer Technik und Verwaltung, mit 35 Bildern aus `pnpm docs:screenshots` und einem Fehlerbehebungskapitel aus echten Meldungen. `pnpm docs:pdf` macht daraus 72 Seiten A4 — hell gedruckt, mit Deckblatt, Inhaltsverzeichnis und Seitenzahlen, ohne neue Abhaengigkeit. Die Ablaeufe pruefen ihre Voraussetzungen, bevor der erste startet: antwortet ein gebauter Stand, steht der Seed-Bestand, und liest der Server dieselbe Datenbank wie der Testprozess. Jeder Ablauf legt an, was er braucht, und raeumt es weg. Vier neue kommen dazu: Hauptablauf, Onboarding mit Vergleich der Zwischenablage, Rollen und 390 px auf achtzehn Seiten. Drei Fehler kamen dabei heraus. Das Projekt „handy" pruefte 412 px statt der verlangten 390. Ein angemeldeter Benutzer ohne Recht erfuhr nie, warum er abgewiesen wurde — die Meldung stand auf einer Seite, die ihn sofort weiterleitet; jetzt gibt es /kein-zugriff. Und der Verzeichnis-Ablauf schrieb die Attributzuordnung der ersten vorhandenen Quelle um, in einer echten Installation also der produktiven. 101 Ablaeufe in INTERN und 97 in DIENSTLEISTUNG, beide ohne Fehlschlag. Closes #18 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
86 lines
7.7 KiB
Markdown
86 lines
7.7 KiB
Markdown
# #018 M13 – E2E-Tests, Anleitung, PDF
|
||
|
||
**Status:** erledigt
|
||
**Meilenstein:** v0.1.0
|
||
**Labels:** phase-1, test, docs
|
||
**Geschätzt:** 14 h **Tatsächlich:** 2 h 15 min
|
||
|
||
## Ziel
|
||
|
||
Nachweis, dass die Abläufe wirklich durchlaufen, und eine Anleitung, mit der ein Techniker ohne Einweisung arbeiten kann.
|
||
|
||
## Aufgaben
|
||
|
||
- [x] Playwright-Hauptablauf: anmelden → „PC Neuinstallation“ für `PC-001` starten → Schritte abhaken → Wert eintragen → einen Schritt „nicht zutreffend“ mit Notiz → abschließen → archivieren → im Archiv finden → Schreibschutz greift
|
||
- [x] Derselbe Hauptablauf mit `SEED_MODE=SERVICE` gegen `MUS-PC-001`, mit Kundenwahl im Start-Dialog
|
||
- [x] Playwright-QR-Ablauf: `/t/LZ-7K3F9Q` ohne Anmeldung → Login → Geräteseite → „Vorlage zuweisen“ → Lauf erscheint unter „Zugewiesen“ → „Starten“ setzt `IN_ARBEIT`; dazu unregistrierter Tag → Registrierformular → Geräteseite; unbekannter Tag → Hinweis
|
||
- [x] Playwright-Onboarding-Ablauf: Vorlage starten → Vorname und Nachname eingeben → UPN, `sam` und Mail werden vorgeschlagen → Abteilung „Buchhaltung“ wählen → im Schritt „Konto anlegen“ steht der fertige `New-ADUser`-Befehl → Kopieren liefert exakt diesen Text (Clipboard auslesen)
|
||
- [x] Playwright-Mobilprüfung: auf allen Hauptseiten bei 390 × 844 ist `scrollWidth <= clientWidth`
|
||
- [x] Playwright-Rollenprüfung: `LESER` sieht keine Schreib-Knöpfe und wird serverseitig abgewiesen
|
||
- [x] Die Abläufe suchen ihre Vorlage **am Namen**, nicht über `select ... { index: 1 }`. Aufgefallen in #017: gegen eine frisch geseedete Datenbank steht an erster Stelle „Mitarbeiter-Offboarding“ mit Pflichtvariablen, die der Helfer nicht füllt — sechs Abläufe liefen je 30 s in den Zeitablauf. Ein Ablauf, der von der Sortierung der Vorlagenliste abhängt, prüft nicht, was er zu prüfen vorgibt
|
||
- [x] Die Voraussetzungen eines E2E-Laufs stehen an einer Stelle und werden geprüft, statt im Kopfkommentar zu stehen (`pnpm beispiel:vorlage`, `pnpm beispiel:stammdaten`, `pnpm beispiel:lauf`) — besser noch: die Abläufe legen an, was sie brauchen. Die drei Skripte tragen auch die Screenshots; was davon bleibt und was in die Abläufe wandert, wird hier entschieden. In den Seed gehört es **nicht**: eine frische Installation soll keine Demo-Läufe und keine offenen Entwürfe mitbringen (in #017 geprüft und so entschieden)
|
||
- [x] Kein Ablauf setzt voraus, dass die Datenbank schon Läufe enthält. `uebersicht-druck.spec.ts` sucht sich mit `lauf.findFirstOrThrow()` irgendeinen Lauf und „Zuletzt bearbeitet" muss gefüllt sein — gegen eine frisch eingerichtete Installation scheitert beides mit „No record was found", und das sagt nichts über die Ursache (gesehen in #017)
|
||
- [x] `pnpm beispiel:stammdaten` und `pnpm beispiel:lauf` laufen nur im Modus `INTERN`: sie rufen die Dienste ohne Kunden und scheitern im Modus `DIENSTLEISTUNG` an `MandantFehler: Im Modus Dienstleistung muss ein Kunde gewählt werden`. Das ist richtiges Verhalten der App und eine Lücke der Skripte — wer den Hauptablauf in beiden Modi fahren will, braucht sie in beiden
|
||
- [x] Der E2E-Lauf prüft beim Start, dass er **dieselbe** Datenbank benutzt wie der Server unter Test. Die Abläufe legen ihre Daten über `prisma` aus `.env` an, die Adresse des Servers steht in `E2E_APP_URL` — zeigen beide auf verschiedene Datenbanken, schreibt der Test in die eine und sucht in der anderen. Die Meldung heißt dann „0 Treffer“ und sagt nichts über die Ursache (gesehen in #017)
|
||
- [x] `pnpm docs:screenshots`: Playwright-Skript, Desktop 1440 × 900 und Handy 390 × 844, Seed-Daten, dunkles Design, mit Markierungen (Rahmen, Nummern) für die beschriebenen Stellen; Ablage `docs/anleitung/bilder/`
|
||
- [x] `pnpm docs:pdf`: Anleitung als PDF über Chromium (`page.pdf`, A4, `printBackground`), Ablage `docs/anleitung/laufzettel-anleitung.pdf`
|
||
- [x] `docs/anleitung/` auf Deutsch, getrennt für Techniker und Admins: Erste Schritte · Vorlagen bauen · Läufe abarbeiten (Desktop und Handy) · QR-Tags drucken und registrieren · Mitarbeiter und Abteilungen · Betriebsmodus · Admin: Verzeichnis, Benutzer, Einstellungen · Fehlerbehebung
|
||
- [x] `README.md` vollständig: Setup, alle Umgebungsvariablen, Betrieb mit Docker Compose, authentik-Anbindung inkl. Gruppen für Rollen, Seed, Sicherungshinweis für die Datenbank
|
||
|
||
## Akzeptanzkriterien
|
||
|
||
- [x] Alle Playwright-Abläufe grün, in `INTERN` und in `DIENSTLEISTUNG`
|
||
- [x] Der Kopier-Knopf liefert exakt den erwarteten Befehlstext, zeichengenau geprüft
|
||
- [x] Keine Hauptseite scrollt bei 390 px horizontal
|
||
- [x] `pnpm docs:screenshots` erzeugt alle in der Anleitung verlinkten Bilder reproduzierbar neu
|
||
- [x] `pnpm pruefe:doku` meldet kein fehlendes Bild
|
||
- [x] Das PDF enthält alle Kapitel mit Bildern, Umlaute korrekt, keine abgeschnittenen Seiten
|
||
- [x] Die README beschreibt authentik so, dass ein Dritter die Anbindung ohne Rückfrage hinbekommt
|
||
|
||
## Ergebnis
|
||
|
||
Erledigt am 2026-09-26. **101 Ende-zu-Ende-Abläufe** im Modus `INTERN` und **97** im Modus
|
||
`DIENSTLEISTUNG`, beide ohne Fehlschlag; Vitest unverändert bei 1130. Die Anleitung steht unter
|
||
`docs/anleitung/` mit 35 Bildern, das PDF hat 72 Seiten.
|
||
|
||
### Was die Abläufe jetzt anders machen
|
||
|
||
- **Die Voraussetzungen werden geprüft, nicht behauptet.** `tests/e2e/global-setup.ts` fragt vor dem
|
||
ersten Ablauf: antwortet ein gebauter Stand, steht der Seed-Bestand, und liest der Server
|
||
**dieselbe** Datenbank wie der Testprozess? Die dritte Frage hat in #017 einen halben Abend
|
||
gekostet, weil ihre Antwort „0 Treffer" hieß.
|
||
- **Jeder Ablauf legt an, was er braucht, und räumt es weg.** Keine Vorlage über `index: 1`, keine
|
||
Annahme „die Datenbank enthält schon Läufe", kein `test.skip` bei fehlenden Daten.
|
||
- **Zehn Kopien von `anmelden()`** sind zu einer geworden.
|
||
|
||
### Drei Fehler, die dabei herauskamen
|
||
|
||
1. **Das Projekt „handy" prüfte 412 px statt 390.** `devices["Pixel 7"]` ist 412 breit; CLAUDE.md und
|
||
das Abnahmekriterium nennen 390. Jeder „trägt am Handy ohne horizontales Scrollen"-Test lief
|
||
gegen eine Breite, die niemand verlangt hatte. Nach der Korrektur blieb alles grün — die Zusage
|
||
hielt, sie war nur nie geprüft.
|
||
2. **Eine Auskunft, die niemand je gesehen hat.** Ein angemeldeter Benutzer ohne Recht wurde auf
|
||
`/anmelden?fehler=keinrecht` geschickt, und die Anmeldeseite leitet einen Angemeldeten sofort
|
||
weiter. Die Meldung war unerreichbar, der Kommentar im Code versprach sie. Jetzt gibt es
|
||
`/kein-zugriff` mit der eigenen Rolle darin.
|
||
3. **Zwei Tests, die Schaden anrichteten:** der Verzeichnis-Ablauf schrieb die Attributzuordnung der
|
||
**ersten vorhandenen** Quelle um — in einer echten Installation die produktive; und ein Nachlauf
|
||
setzte die Namensregeln auf leer, statt den vorherigen Wert zurückzustellen.
|
||
|
||
### Der zweite Betriebsmodus
|
||
|
||
Der erste Durchgang im Modus `DIENSTLEISTUNG` hatte **28 rote Abläufe**, sechs Ursachen, alle
|
||
dieselbe blinde Stelle: die Kundenebene. Dort hat jedes Anlege-Formular ein Pflichtfeld mehr, und
|
||
dahinter steht eine Regel, die nicht verhandelbar ist — ein Lauf kann **strukturell** kein Gerät und
|
||
keine Abteilung eines fremden Kunden wählen, dafür sorgen zusammengesetzte Fremdschlüssel. „Irgendein
|
||
Kunde" ist dort nicht ungenau, sondern rot. Beim Onboarding war es sogar eine Reihenfolge: die
|
||
Kundenwahl stand hinter dem Namensvorschlag, und ohne Kunden greifen die Namensregeln nicht.
|
||
|
||
Ohne dieses Abnahmekriterium wäre der zweite Betriebsmodus ungeprüft ins Release gegangen.
|
||
|
||
### Beim Schreiben der Anleitung aufgefallen
|
||
|
||
Zwei Stellen, an denen die App etwas kann, das niemand bedienen kann — beide als Issue festgehalten,
|
||
nicht weggeschwiegen: [#022](022-schnellstart-pflegen.md) (Schnellstart je Gerätetyp setzt nur der
|
||
Seed) und [#023](023-protokoll-ansicht.md) (das Protokoll wird geschrieben, aber nie angezeigt).
|