Skip to content

test(cypress): Suite auf staging-Stand aktualisieren — Reparaturen + neue Feature-Tests - #237

Merged
Gree44 merged 22 commits into
stagingfrom
integrationstests-staging-update
Jul 25, 2026
Merged

test(cypress): Suite auf staging-Stand aktualisieren — Reparaturen + neue Feature-Tests#237
Gree44 merged 22 commits into
stagingfrom
integrationstests-staging-update

Conversation

@Gree44

@Gree44 Gree44 commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Was & Warum

Bringt die Cypress-Integrationstest-Suite auf den aktuellen staging-Stand. Seit der ursprünglichen Suite (d1af1a7) sind ~7.800 src/-Zeilen dazugekommen (Student-Self-Service, Admin-Rework, Redeploy, Kurs-Filter u.a.) — mehrere Tests waren dadurch veraltet und große neue Bereiche ungetestet.

Ergebnis

  • 46/46 Tests grün über 30 Specs
  • TypeScript (tsc --noEmit -p cypress/tsconfig.json): 0 Fehler
  • ESLint: 0 Fehler (40 pre-existing Warnings)
  • Build (vite build): success
  • 0 Produktivcode-Änderungen, 0 neue data-testid

Reparaturen (6)

Test Ursache Fix
auth-admin-bypasses-setup-gate /admin in /admin/projects|templates|lecturers gesplittet Ziel → /admin/projects
admin-approve-template-version Queue nach /admin/templates verschoben Route angepasst
detail-delete-confirmation-flow Owner-Only-Gate (#126) deaktivierte Button owner_id in Fixture
auth-non-admin-cannot-access-admin-route war skip (Befund); via ProtectedRoute behoben neu geschrieben (Redirect-Assertion) + reaktiviert
detail-issue-207-ungrouped-members Card-Titel off-screen scrollIntoView()
visual-capture Mobile: Match auf versteckten Sidebar-Link; falscher Reference-Pfad cy.contains("h1", …) + Pfad-Fix

Neue Feature-Tests (11)

Student-Self-Service: student-dashboard-lists-deployments (P0), student-role-routing-guard (P0), student-deployment-details-credentials (P1)
Admin: lecturer-management-lists (P1), lecturer-delete-cascade-poll (P1), admin-project-overview-renders (P1), admin-reject-template-with-reason (P1)
Deployment/Courses: redeploy-deployment-config-override (P1), course-filters-toggle-chip (P1), course-filters-admin-crud (P1)
Wizard/Dashboard: wizard-36-months-runtime (P2), dashboard-expiry-color-tiers (P2)

Sicherheits-Verbesserung bestätigt

Der zuvor in cypress/SECURITY-FINDINGS.md dokumentierte Privilege-Escalation-Befund (/admin ohne Frontend-Rollen-Gate) ist auf staging behobenProtectedRoute requireAdmin leitet Nicht-Admins auf /dashboard um. Der geskippte Test ist reaktiviert und sichert den Guard; das Finding steht jetzt auf RESOLVED.

Konventionen

  • Alle API-Calls via cy.intercept + Fixtures gemockt; Keycloak komplett gestubbt (window-Hook)
  • Keine festen Wartezeiten (cy.wait(<number>)) — nur Alias-/Assertion-Timeouts
  • Stabile Selektoren (role/text/id/aria); ein Sub-Agent pro Test, ein Commit pro Test

Hinweise

  • CI: npm run test:e2e ist noch nicht in der Pipeline verdrahtet — sollte als PR-Schritt ergänzt werden (via start-server-and-test).
  • Details, verbliebene Risiken und 10 Kandidaten für Folge-Tests: cypress/REPORT-STAGING-UPDATE.md + cypress/TEST-MATRIX-DELTA.md.

Gree44 added 22 commits July 25, 2026 16:24
…ute split

Abgedeckte Funktion:
- App.tsx Admin-Short-Circuit + neue admin-Route-Struktur mit ProtectedRoute

Getesteter Nutzerfluss:
- Admin ohne OpenStack-Projekt besucht /dashboard → Dashboard rendert
- Admin besucht /admin/projects → AdminProjectOverview rendert (ProtectedRoute requireAdmin lässt durch)

Getestete Fachlogik:
- Non-Lecturer-Branch überspringt listOpenstackProjects() (0 Calls)
- needsSetup bleibt false → kein /setup-Redirect

Geprüfte Fehlerfälle:
- (n/a)

Geprüfte Edge Cases:
- Auch bei explizit leerer Projektliste kein Setup-Zwang

Betroffene Komponenten:
- src/App.tsx, src/components/ProtectedRoute.tsx, src/pages/AdminProjectOverview.tsx

Warum dieser Test wichtig ist:
- Nach dem Admin-Rework (Split von /admin in /admin/projects|templates|lecturers)
  sichert der Test, dass Admins weiterhin ohne Projekt in den Adminbereich kommen.

Aktualisierung: alte /admin-Route + AdminMonitoring-Heading existieren nicht mehr;
Test zielt jetzt auf /admin/projects + Projektübersicht.
…ute split

Abgedeckte Funktion:
- AdminTemplateApprovals Approval-Queue (aus AdminMonitoring herausgelöst)

Getesteter Nutzerfluss:
- Admin → /admin/templates → Queue mit zwei pending Versions → Schnell genehmigen → Row verschwindet

Getestete Fachlogik:
- getTemplateVersionsQueue() lädt Queue
- approveTemplateVersion() POSTet /template-versions/<id>/approve
- Row-Removal via lokalem State (kein Refetch)

Geprüfte Fehlerfälle:
- (n/a — happy path)

Geprüfte Edge Cases:
- Korrekte Row wird approved, andere bleibt sichtbar

Betroffene Komponenten:
- src/pages/AdminTemplateApprovals.tsx, src/api/github.ts

Warum dieser Test wichtig ist:
- Approval ist der einzige Weg, public Templates in den AppStore-Katalog zu bringen.

Aktualisierung: Route /admin → /admin/templates nach dem Admin-Rework;
Selektoren/Endpunkte/Fixture unverändert gültig.
… gating

Abgedeckte Funktion:
- DeploymentDetails Delete-Flow unter neuem Owner-Only-Gate (fix/126)

Getesteter Nutzerfluss:
- Owner-Lecturer öffnet /deployment/<id> → Löschen → Bestätigen → DELETE → /dashboard

Getestete Fachlogik:
- canManageDeployment = deployment.ownerId === currentUser.userId
- Delete-Button ist nur für den Owner (oder Admin) aktiv

Geprüfte Fehlerfälle:
- (n/a — happy path)

Geprüfte Edge Cases:
- owner_id der Fixture == sub der lecturer-Fixture (user-lec-1) aktiviert die Aktion

Betroffene Komponenten:
- src/pages/DeploymentDetails.tsx, src/pages/DeploymentDetailsPage.tsx, cypress/fixtures/deployments/detail-running.json

Warum dieser Test wichtig ist:
- Nach Einführung des Owner-Gates würde der Delete-Button ohne passendes
  owner_id in der Fixture deaktiviert bleiben; der Test würde falsch-negativ
  fehlschlagen. Fixture spiegelt jetzt einen Owner-Zugriff wider.

Hinweis: detail-running.json wird von mehreren Detail-Specs geteilt; owner_id
aktiviert nur owner-gebundene Aktionen und lässt Rendering-Assertions unberührt
(mit dashboard-row-click, detail-renders-status-and-phases gegengeprüft).
…e (gate fixed)

Abgedeckte Funktion:
- ProtectedRoute requireAdmin-Guard auf admin-Routen

Getesteter Nutzerfluss:
- Lecturer ruft /admin/templates direkt auf → Redirect zu /dashboard, kein Admin-Content

Getestete Fachlogik:
- ProtectedRoute: requireAdmin && !isAdmin → Navigate /dashboard replace
- AdminTemplateApprovals mountet nicht → loadQueue()-Effect feuert nicht
- Template-Freigaben-Heading nicht im DOM

Geprüfte Fehlerfälle:
- (n/a — permission gate)

Geprüfte Edge Cases:
- Defense-in-Depth: echter Redirect statt CSS-Hide; queue-Fetch = 0 Calls

Betroffene Komponenten:
- src/components/ProtectedRoute.tsx, src/App.tsx, src/pages/AdminTemplateApprovals.tsx

Warum dieser Test wichtig ist:
- Der zuvor dokumentierte Privilege-Escalation-Befund (SECURITY-FINDINGS.md #1)
  ist durch den Admin-Rework behoben. Der zuvor geskippte Test ist jetzt aktiv
  und sichert den Guard gegen Regression ab.

SECURITY-FINDINGS.md #1 auf RESOLVED aktualisiert.
Erfasst die Reparaturen bestehender Tests nach dem großen staging-Update
und die geplanten neuen Feature-Tests (Student-Self-Service, Lecturer-
Verwaltung, Admin-Rework, Redeploy, Kurs-Filter, 36-Monate, Expiry-Tiers,
Mobile-Nav). Grundlage für die folgende Test-Implementierung.
Bereitet die Student-Self-Service-Tests vor: cy.loginAs("student", url)
nutzt die vorhandene keycloak/student.json-Fixture (roles=["student"]).
Reine Test-Infrastruktur, kein Produktivcode.
…ent CourseGroupsCard

Abgedeckte Funktion:
- CourseGroupsCard "Ohne Gruppe"-Sektion + nachträgliche Gruppenzuweisung (Feat #207)

Getesteter Nutzerfluss:
- Owner-Lecturer öffnet Deployment-Detail → Karte "Gruppen & Mitglieder" aufklappen → gruppenloses Mitglied in "Ohne Gruppe" → Gruppe wählen → Hinzufügen → POST addGroupMembers

Getestete Fachlogik:
- Kurs course-alpha hat 3 aktive Mitglieder; cm-1 in grp-1, cm-2 in grp-2, cm-3 (u3-neu) in keiner Gruppe → cm-3 erscheint korrekt in der amber "Ohne Gruppe"-Sektion
- Hinweistext "Der Student erhält erst Zugriff…" wird angezeigt
- "Hinzufügen"-Button ist ohne Gruppenauswahl disabled, nach Auswahl von "Gruppe A" aktiv
- POST addGroupMembers sendet exakt { member_ids: ["cm-3"] }

Geprüfte Fehlerfälle:
- keine

Geprüfte Edge Cases:
- Gruppenloses Mitglied (cm-3) erscheint separat und verschwindet nach Zuweisung

Betroffene Komponenten:
- src/pages/DeploymentDetails.tsx (CourseGroupsCard), cypress/e2e/detail/detail-issue-207-ungrouped-members.cy.ts

Warum dieser Test wichtig ist:
- Sichert das #207-Feature: gruppenlose Studierende bekommen sonst nie Zugriff.

Reparatur: Der Karten-Titel <h4> lag unterhalb des Falzes in einem Scroll-Container mit overflow und war zwar im DOM, aber nicht sichtbar. scrollIntoView vor der Visibility-Assertion (und vor dem Klick auf "Anzeigen") ergänzt; keine Produktionsänderung, keine Fixture-Änderung nötig.
Abgedeckte Funktion:
- Student-Self-Service Dashboard (StudentDashboard) + Rollen-Routing

Getesteter Nutzerfluss:
- Pure Student besucht / → Redirect /student/dashboard → GET /api/v1/student/deployments → Deployment-Karten sichtbar

Getestete Fachlogik:
- App.tsx pure-student Routing (student && !lecturer && !admin)
- getStudentDeployments() lädt die zugewiesenen Deployments
- StatusBadge-Mapping (running→Läuft etc.)
- Sidebar zeigt nur "Meine Deployments" + Rolle "Student"

Geprüfte Fehlerfälle:
- (n/a — success path)

Geprüfte Edge Cases:
- Mehrere Deployments mit unterschiedlichem Status

Betroffene Komponenten:
- src/pages/StudentDashboard.tsx, src/pages/StudentDashboardPage.tsx, src/api/student.ts, src/layouts/Sidebar.tsx, src/App.tsx

Warum dieser Test wichtig ist:
- Sichert den Kernpfad des neuen Student-Bereichs. Bricht das Routing oder der
  Fetch, sehen Studierende ihre zugewiesenen Umgebungen nicht.
Abgedeckte Funktion:
- App.tsx pure-student Routing-Guard

Getesteter Nutzerfluss:
- Pure Student ruft /dashboard und /appstore auf → beide Male Redirect zu /student/dashboard

Getestete Fachlogik:
- student && !lecturer && !admin bekommt nur die Student-Routes + Catch-all
- Lecturer/Admin-Endpoints (deployments, templates) feuern NICHT für den Studenten

Geprüfte Fehlerfälle:
- (n/a — permission gate)

Geprüfte Edge Cases:
- Direktes Aufrufen einer Nicht-Student-Route landet über Catch-all wieder im Student-Dashboard

Betroffene Komponenten:
- src/App.tsx, src/pages/StudentDashboard.tsx

Warum dieser Test wichtig ist:
- Verhindert, dass Studierende Lecturer-/Admin-Oberflächen sehen. Bricht das
  Routing, könnten Studenten in nicht für sie gedachte Bereiche gelangen.
Abgedeckte Funktion:
- Student-Deployment-Detailseite + CredentialInstanceCard (mode=student)

Getesteter Nutzerfluss:
- Student öffnet /student/deployment/:id → Liste wird gefiltert → Credentials geladen → VMs + Zugangsdaten sichtbar

Getestete Fachlogik:
- getStudentDeployments() + client-seitige Filterung nach id
- getStudentDeploymentCredentials() lädt Instanzen + Accesses
- CredentialInstanceCard rendert Zugangsdaten (mode=student)

Geprüfte Fehlerfälle:
- (n/a — success path; 403/404 in eigenem potenziellen Folgetest)

Geprüfte Edge Cases:
- Mehrere Access-Typen (ssh + web_url) in einer Instanz

Betroffene Komponenten:
- src/pages/StudentDeploymentDetails.tsx, src/pages/StudentDeploymentDetailsPage.tsx, src/components/credentials/CredentialInstanceCard.tsx, src/api/student.ts

Warum dieser Test wichtig ist:
- Ohne funktionierende Credentials-Anzeige können Studierende nicht auf ihre
  zugewiesenen VMs zugreifen — der Kernnutzen des Student-Bereichs.
Abgedeckte Funktion:
- Admin Lecturer-Verwaltung (Liste + Detail-Dialog)

Getesteter Nutzerfluss:
- Admin → /admin/lecturers → Tabelle geladen → Zeile klicken → Detail-Dialog mit Ressourcen-Sektionen

Getestete Fachlogik:
- listLecturers() GET /api/v1/lecturers?skip&limit
- getLecturer(id) GET /api/v1/lecturers/{id} beim Öffnen des Dialogs
- Tabellen-Header + Detail-Sektionen (Templates/Deployments/OpenStack-Projekte)

Geprüfte Fehlerfälle:
- (n/a — success path)

Geprüfte Edge Cases:
- Mehrere Lecturer in der Liste; korrekte Detail-Zuordnung per id

Betroffene Komponenten:
- src/pages/LecturerManagement.tsx, src/components/LecturerDetailDialog.tsx, src/api/lecturers.ts

Warum dieser Test wichtig ist:
- Die Lecturer-Verwaltung ist der Admin-Kanal für Nutzer-Übersicht und
  Cascade-Delete. Bricht Liste oder Detail-Fetch, ist Admin blind.
Abgedeckte Funktion:
- Lecturer Cascade-Delete: Type-to-confirm + 202 + Poll bis 404

Getesteter Nutzerfluss:
- Admin → Lecturer-Detail → Account löschen → Namen tippen → Endgültig löschen → DELETE 202 → Poll → 404 → Erfolgstoast

Getestete Fachlogik:
- DeleteLecturerConfirmDialog Type-to-confirm (exakter Name aktiviert Button)
- deleteLecturer() DELETE /api/v1/lecturers/{id} → 202 enqueue
- LecturerDetailDialog Poll GET /{id} alle 2s; 404 = Erfolg → Toast + Refetch + Close

Geprüfte Fehlerfälle:
- (n/a — happy path)

Geprüfte Edge Cases:
- Button erst bei exakt passendem Bestätigungsnamen aktiv
- Poll-Übergang 200→404 löst Erfolg aus

Betroffene Komponenten:
- src/components/DeleteLecturerConfirmDialog.tsx, src/components/LecturerDetailDialog.tsx, src/api/lecturers.ts

Warum dieser Test wichtig ist:
- Cascade-Delete ist destruktiv + asynchron. Bricht der Poll oder das
  Confirm-Gate, löscht der Admin evtl. versehentlich oder bekommt kein Feedback.
Abgedeckte Funktion:
- AdminProjectOverview globale Deployment-Übersicht (Admin-Rework)

Getesteter Nutzerfluss:
- Admin → /admin/projects → Stat-Cards + Gruppierungs-Ansicht geladen aus getAllDeployments(null)

Getestete Fachlogik:
- getAllDeployments(null) ohne openstack_project_id (Admin sieht alles)
- Stat-Cards Gesamt/Aktiv/Inaktiv
- View-Selector Nach Dozent/Kurs/Datum; Teacher-Extraktion aus deployment_parameters

Geprüfte Fehlerfälle:
- (n/a — success path)

Geprüfte Edge Cases:
- Deployments mit unterschiedlichem Status (aktiv/inaktiv) fließen in die Zählung

Betroffene Komponenten:
- src/pages/AdminProjectOverview.tsx, src/api/deployments.ts

Warum dieser Test wichtig ist:
- Die Projektübersicht ist das zentrale Admin-Monitoring nach dem Rework.
  Bricht der globale Fetch oder die Gruppierung, verliert der Admin den Überblick.
Abgedeckte Funktion:
- AdminTemplateApprovals Reject-Flow mit Begründung

Getesteter Nutzerfluss:
- Admin → /admin/templates → Ablehnen → Begründung eingeben → absenden → POST /reject mit reason → Row verschwindet

Getestete Fachlogik:
- rejectTemplateVersion(id, reason) POSTet /template-versions/<id>/reject mit {reason}
- Row-Removal via lokalem State nach Erfolg

Geprüfte Fehlerfälle:
- (n/a — happy path)

Geprüfte Edge Cases:
- Begründungstext landet exakt im Request-Body
- Korrekte Row wird abgelehnt, andere bleibt sichtbar

Betroffene Komponenten:
- src/pages/AdminTemplateApprovals.tsx, src/api/github.ts

Warum dieser Test wichtig ist:
- Ohne funktionierendes Reject-mit-Begründung bekommen Template-Autoren kein
  Feedback, warum ihre Version abgelehnt wurde.
Abgedeckte Funktion:
- RedeployDialog Config-Override für ein laufendes Deployment

Getesteter Nutzerfluss:
- Owner öffnet running Deployment → Neu deployen → Parameter ändern → absenden → POST /redeploy

Getestete Fachlogik:
- canManageDeployment (owner) schaltet "Neu deployen" frei
- RedeployDialog rendert Felder aus deployment_parameters.parameters
- Nur geänderte Keys landen in deployment_parameter_overrides
- preserve_credentials default true; POST /deployments/<id>/redeploy?openstack_project_id

Geprüfte Fehlerfälle:
- (n/a — happy path; Fehler/Permission separat)

Geprüfte Edge Cases:
- Nur der geänderte Parameter wird als Override gesendet (Diff-Logik)

Betroffene Komponenten:
- src/pages/DeploymentDetails.tsx, src/components/deployments/RedeployDialog.tsx, src/api/deployments.ts

Warum dieser Test wichtig ist:
- Redeploy mit Config-Override ist ein neues Kernfeature (#192). Bricht die
  Diff-Logik oder der POST, deployen Dozenten mit falschen Parametern neu.
Abgedeckte Funktion:
- Courses Kurs-Filter-Chips (client-seitige Filterung)

Getesteter Nutzerfluss:
- Lecturer → /courses → Filter-Chip klicken → Kursliste verengt sich → Alle anzeigen setzt zurück

Getestete Fachlogik:
- listCourseFilters() lädt die Chips
- Client-seitige OR-Filterung, case-insensitive Substring auf Kurs-/Gruppenname
- aria-pressed spiegelt aktiven Filter; "Alle anzeigen" leert den Filter-Set

Geprüfte Fehlerfälle:
- (n/a — state/UI)

Geprüfte Edge Cases:
- Nur Kurse mit Deployments werden überhaupt angezeigt
- Toggle an/aus verändert die sichtbare Liste konsistent

Betroffene Komponenten:
- src/pages/Courses.tsx, src/api/courseFilters.ts, src/api/courses.ts

Warum dieser Test wichtig ist:
- Bei vielen Kursen ist die Chip-Filterung die zentrale Navigationshilfe;
  bricht sie, wird die Kursliste unbrauchbar.
Abgedeckte Funktion:
- Courses Kurs-Filter-Verwaltung (Admin: Anlegen + Löschen)

Getesteter Nutzerfluss:
- Admin → /courses → Filter "Docker" anlegen (POST) → erscheint; Filter "Web" löschen (DELETE) → verschwindet

Getestete Fachlogik:
- Admin-gated Controls sichtbar (isAdmin)
- createCourseFilter POST {name}; deleteCourseFilter DELETE /{id}
- loadFilters() Refetch nach Mutation aktualisiert die Chip-Leiste

Geprüfte Fehlerfälle:
- (n/a — happy path; 409/422/403 optional künftig)

Geprüfte Edge Cases:
- POST-Body enthält exakt {name}; DELETE trifft die richtige Filter-id

Betroffene Komponenten:
- src/pages/Courses.tsx, src/api/courseFilters.ts

Warum dieser Test wichtig ist:
- Nur Admins verwalten die Filter-Taxonomie; bricht CRUD, kann die Chip-Leiste
  nicht mehr gepflegt werden und die Kursnavigation verwahrlost.
Abgedeckte Funktion:
- DeploymentWizard 36-Monate-Laufzeit ("3 Jahre", Feat #179)

Getesteter Nutzerfluss:
- Lecturer durchläuft Wizard, wählt Laufzeit "3 Jahre" → Anwendung deployen → POST mit runtime_months: 36

Getestete Fachlogik:
- Runtime-Select bietet Wert 36 ("3 Jahre")
- Submit serialisiert runtime_months: parseInt(runtime) = 36

Geprüfte Fehlerfälle:
- (n/a — success/edge)

Geprüfte Edge Cases:
- Nicht-Default-Laufzeit (36) statt Default 4 landet korrekt im Payload

Betroffene Komponenten:
- src/pages/DeploymentWizard.tsx, src/api/deployments.ts

Warum dieser Test wichtig ist:
- Die 36-Monate-Option ist neu; ohne Test könnte ein Regressions-Bug die
  Laufzeit stillschweigend auf den Default zurücksetzen.
Abgedeckte Funktion:
- Dashboard Ablauf-Farbstufen (getExpiryState, Feat #180)

Getesteter Nutzerfluss:
- Lecturer → /dashboard → Deployment-Zeilen zeigen je nach Restlaufzeit warning/critical/expired-Indikator

Getestete Fachlogik:
- getExpiryState Schwellen: expired (vorbei), critical ≤42d, warning ≤90d, sonst ok
- Dashboard rendert Ablauf-Icon nur bei warning/critical/expired
- Kein Indikator bei weit entfernter Ablaufzeit

Geprüfte Fehlerfälle:
- (n/a — state/UI)

Geprüfte Edge Cases:
- Vier Stufen (ok/warning/critical/expired) korrekt unterschieden anhand relativer Daten

Betroffene Komponenten:
- src/pages/Dashboard.tsx, src/utils/deployment.ts

Warum dieser Test wichtig ist:
- Die Ablaufwarnung verhindert, dass Dozenten Deployments unbemerkt auslaufen
  lassen; falsche Schwellen/Farbstufen kosten Daten.
Abgedeckte Funktion:
- Visual-Regression-Screenshot-Harness über alle Hauptseiten (desktop + mobile)

Getesteter Nutzerfluss:
- Jede Seite in beiden Viewports laden bis Ready-Heading sichtbar, Screenshot

Getestete Fachlogik:
- Seiten rendern ihre Headings unter der aktuellen Rollen-/Routing-Struktur

Geprüfte Fehlerfälle:
- (n/a — Screenshot-Capture)

Geprüfte Edge Cases:
- Mobile-Drawer öffnet über Hamburger

Betroffene Komponenten:
- cypress/e2e/visual/visual-capture.cy.ts

Warum dieser Test wichtig ist:
- Fängt visuelle Regressionen über alle Kernseiten in zwei Viewports ab.

Reparatur:
- Reference-Path korrigiert: ../support/index.d.ts -> ../../support/index.d.ts
- Ready-Assertion auf <h1> eingegrenzt (cy.contains(ready) -> cy.contains("h1", ready)):
  die Ready-Strings (Dashboard, App Store, Kurse, Projektübersicht, Template-Freigaben,
  Meine Deployments) matchten sonst die auf Mobile versteckten Sidebar-Nav-Links.
- Mobile-Drawer-Test: "Dashboard" auf <h1> eingegrenzt; "Kurse" auf den offenen
  Sheet-Dialog eingegrenzt ([role="dialog"] .contains("Kurse")), da die Desktop-Sidebar
  (hidden md:flex) denselben Link versteckt im DOM hält.
- Keine Ready-Strings inhaltlich geändert (alle Headings stimmen), keine Intercepts nötig.
Die PageSpec.overrides-Deklaration war {fixture?; body?; statusCode?} und
damit nicht auf mockApi's InterceptOverride-Union zuweisbar (tsc TS2345).
Alle tatsächlichen Verwendungen sind {fixture}, daher den Typ darauf
verengt. Kein Verhaltensänderung, Suite bleibt 17/17 grün.
tsc --noEmit -p cypress/tsconfig.json jetzt fehlerfrei.
@RamonaKT
RamonaKT self-requested a review July 25, 2026 17:27
@Gree44
Gree44 merged commit 9c2654d into staging Jul 25, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants