# Sprint 12 Test Plan: "Golden Test Standard" **Datum:** 18.06.2026 **Autor:** Patrick Plate / Lumen (Planner) **Status:** v1 **Basis:** cannamanage-sprint12-plan.md --- ## Testübersicht | ID | Beschreibung | Typ | Seite | Status | |----|-------------|-----|-------|--------| | T-01 | Document upload end-to-end | E2E | documents | ⬜ | | T-02 | Document download triggers file save | E2E | documents | ⬜ | | T-03 | Document delete with confirmation | E2E | documents | ⬜ | | T-04 | Document upload validation (missing fields) | E2E | documents | ⬜ | | T-05 | Document category badges have distinct colors | Visual | documents | ⬜ | | T-06 | Document table column widths don't stretch | Visual | documents | ⬜ | | T-07 | Board: create position via dialog | E2E | board | ⬜ | | T-08 | Board: elect member via dialog | E2E | board | ⬜ | | T-09 | Board: remove member with confirmation | E2E | board | ⬜ | | T-10 | All pages: no buttons without onClick handlers | Automated | all | ⬜ | | T-11 | Documents page loads from API (React Query) | Integration | documents | ⬜ | | T-12 | Board page loads from API (React Query) | Integration | board | ⬜ | Status: ⬜ Offen | ✅ Bestanden | ❌ Fehlgeschlagen | ⏭️ Übersprungen --- ## Testfälle ### T-01: Document upload end-to-end **Typ:** E2E (Playwright) **Datei:** `e2e/sprint12-documents.spec.ts` **Vorbedingungen:** - Mock-Backend läuft oder Frontend-Mock-API aktiv - Nutzer ist eingeloggt als Admin **Szenarien:** | # | Eingabe | Erwartetes Ergebnis | |---|---------|-------------------| | a | Upload-Button klicken → Dialog öffnet sich | Dialog mit Titel, Kategorie, Datei-Upload sichtbar | | b | Alle Felder ausfüllen + Datei wählen → "Hochladen" klicken | Loading-Spinner erscheint, dann Success-Toast, Dialog schließt | | c | Nach Upload: Dokumentenliste wird refresht | Neues Dokument erscheint in der Liste | **Nachbedingungen:** - Upload-Mutation wurde mit korrekten Parametern aufgerufen - QueryClient hat `["documents"]` invalidiert --- ### T-02: Document download triggers file save **Typ:** E2E (Playwright) **Datei:** `e2e/sprint12-documents.spec.ts` **Vorbedingungen:** - Mindestens 1 Dokument in der Liste sichtbar **Szenarien:** | # | Eingabe | Erwartetes Ergebnis | |---|---------|-------------------| | a | Download-Icon-Button für ein Dokument klicken | Datei-Download wird ausgelöst (Playwright download event) | | b | Backend nicht erreichbar → Download klicken | Error-Toast "Download fehlgeschlagen" | **Nachbedingungen:** - `downloadDocument(id)` wurde aufgerufen - Blob wurde zu download-link konvertiert --- ### T-03: Document delete with confirmation **Typ:** E2E (Playwright) **Datei:** `e2e/sprint12-documents.spec.ts` **Vorbedingungen:** - Mindestens 1 Dokument in der Liste **Szenarien:** | # | Eingabe | Erwartetes Ergebnis | |---|---------|-------------------| | a | Delete-Icon klicken | Bestätigungs-Dialog erscheint ("Dokument wirklich löschen?") | | b | "Abbrechen" im Dialog | Dialog schließt, Dokument bleibt | | c | "Löschen" im Dialog bestätigen | Loading-State, dann Success-Toast, Dokument verschwindet aus Liste | **Nachbedingungen:** - `deleteDocument(id, clubId)` wurde aufgerufen - Liste wurde refresht (query invalidation) --- ### T-04: Document upload validation (missing fields) **Typ:** E2E (Playwright) **Datei:** `e2e/sprint12-documents.spec.ts` **Szenarien:** | # | Eingabe | Erwartetes Ergebnis | |---|---------|-------------------| | a | Upload-Dialog öffnen → sofort "Hochladen" klicken (kein Titel, keine Datei) | Error-Toast "Bitte alle Pflichtfelder ausfüllen", kein API-Call | | b | Titel eingeben aber keine Datei → "Hochladen" | Fehler-Hinweis | | c | Datei wählen aber kein Titel → "Hochladen" | Fehler-Hinweis | --- ### T-05: Document category badges have distinct colors **Typ:** Visual (Screenshot-Vergleich oder manuell) **Datei:** `e2e/sprint12-documents.spec.ts` (Screenshot) **Szenarien:** | # | Kategorie | Erwartete Farbe | Icon vorhanden | |---|-----------|----------------|----------------| | a | SATZUNG | Blau (bg-blue-*) | ✅ BookOpen | | b | PROTOKOLL | Lila (bg-purple-*) | ✅ FileText | | c | VERTRAG | Amber (bg-amber-*) | ✅ FileSignature | | d | VERSICHERUNG | Cyan (bg-cyan-*) | ✅ Shield | | e | GENEHMIGUNG | Grün (bg-green-*) | ✅ CheckCircle | | f | SONSTIGES | Grau (bg-gray-*) | ✅ File | **Prüfmethode:** Screenshot machen, visuell prüfen dass alle 6 Kategorien klar unterscheidbar sind. --- ### T-06: Document table column widths don't stretch **Typ:** Visual **Datei:** `e2e/sprint12-documents.spec.ts` (Screenshot) **Szenarien:** | # | Viewport | Erwartetes Verhalten | |---|----------|---------------------| | a | Desktop (1280px) | Name-Spalte max 40% breit, truncated bei langen Titeln | | b | Tablet (768px) | Table responsive, keine horizontale Scrollbar | | c | Mobile (375px) | Graceful wrapping oder collapsed view | --- ### T-07: Board — create position via dialog **Typ:** E2E (Playwright) **Datei:** `e2e/sprint12-board.spec.ts` **Szenarien:** | # | Eingabe | Erwartetes Ergebnis | |---|---------|-------------------| | a | "Position hinzufügen" → Dialog öffnet | Formular mit Titel, Beschreibung, Reihenfolge | | b | Titel "Beisitzer" + Beschreibung + Reihenfolge 6 → Speichern | Success-Toast, Dialog schließt, Position erscheint in Liste | | c | Leerer Titel → Speichern | Kein API-Call, Validierung greift | --- ### T-08: Board — elect member via dialog **Typ:** E2E (Playwright) **Datei:** `e2e/sprint12-board.spec.ts` **Szenarien:** | # | Eingabe | Erwartetes Ergebnis | |---|---------|-------------------| | a | "Mitglied wählen" → Dialog öffnet | Formular mit Position-Select, Member-Select, Datum-Felder | | b | Position + Mitglied + Wahldatum + Amtsbeginn ausfüllen → Bestätigen | Success-Toast, Dialog schließt, neues Board-Member in Karten | | c | Keine Position gewählt → Bestätigen | Kein API-Call, Validierung | --- ### T-09: Board — remove member with confirmation **Typ:** E2E (Playwright) **Datei:** `e2e/sprint12-board.spec.ts` **Szenarien:** | # | Eingabe | Erwartetes Ergebnis | |---|---------|-------------------| | a | UserMinus-Icon auf Board-Member-Card klicken | Bestätigungs-Dialog "Wirklich absetzen?" | | b | Bestätigen | Success-Toast, Member-Card verschwindet | | c | Abbrechen | Dialog schließt, keine Änderung | --- ### T-10: All pages — no buttons without onClick handlers **Typ:** Automated (Static analysis / Playwright audit) **Datei:** `e2e/sprint12-button-audit.spec.ts` **Ansatz:** Playwright-Test der jede Dashboard-Seite navigiert und prüft: ```typescript const buttons = await page.locator('button').all() for (const btn of buttons) { // Verify button is either: // 1. Inside a (navigation button) // 2. Has an onClick or is type="submit" in a form // 3. Is a dialog trigger (data-state attribute) const isDisabled = await btn.getAttribute('disabled') if (isDisabled) continue // disabled buttons are OK // Click and verify something happens (no silent no-op) } ``` **Seiten zu prüfen:** - /documents - /board - /members - /distributions - /stock - /grow - /reports - /calendar - /forum - /info-board - /finance - /assemblies - /compliance - /audit-log - /settings/staff --- ### T-11: Documents page loads from API (React Query) **Typ:** Integration **Datei:** `e2e/sprint12-documents.spec.ts` **Szenarien:** | # | Bedingung | Erwartetes Ergebnis | |---|-----------|-------------------| | a | Backend erreichbar, Dokumente vorhanden | Dokumente aus API angezeigt (nicht Mock) | | b | Backend nicht erreichbar | Mock-Fallback-Daten angezeigt (keine Fehlerseite) | | c | Kategorie-Filter gewählt | Query-Key enthält Kategorie, neue Daten geladen | --- ### T-12: Board page loads from API (React Query) **Typ:** Integration **Datei:** `e2e/sprint12-board.spec.ts` **Szenarien:** | # | Bedingung | Erwartetes Ergebnis | |---|-----------|-------------------| | a | Backend erreichbar | Board-Mitglieder + Positionen aus API | | b | Backend nicht erreichbar | Mock-Fallback angezeigt | --- ## Testdaten ### Documents - Mock-Dokumente sind bereits in `documents/page.tsx` definiert (5 Dokumente, verschiedene Kategorien) - Für Upload-Test: beliebige PDF-Datei < 5MB - Für Download-Test: Mock-Backend muss Blob zurückgeben ### Board - Mock-Board-Mitglieder sind bereits in `board/page.tsx` definiert (5 Positionen, 5 Mitglieder) - Für Election-Test: Member-IDs aus Mock-Daten verwenden --- ## Testabdeckung | Komponente | E2E | Integration | Visual | Gesamt | |-----------|-----|-------------|--------|--------| | Documents (upload) | 2 | 1 | 0 | 3 | | Documents (download) | 1 | 0 | 0 | 1 | | Documents (delete) | 1 | 0 | 0 | 1 | | Documents (UX) | 0 | 0 | 2 | 2 | | Board (create pos) | 1 | 1 | 0 | 2 | | Board (elect) | 1 | 0 | 0 | 1 | | Board (remove) | 1 | 0 | 0 | 1 | | All pages audit | 1 | 0 | 0 | 1 | | **Summe** | **8** | **2** | **2** | **12** | --- ## Playwright Test File Structure ``` e2e/ ├── sprint12-documents.spec.ts # T-01 through T-06, T-11 ├── sprint12-board.spec.ts # T-07 through T-09, T-12 └── sprint12-button-audit.spec.ts # T-10 ``` ## Ausführung ```bash cd cannamanage-frontend npx playwright test e2e/sprint12-*.spec.ts ```