diff --git a/docs/QA-09-BARRIEREFREIHEITS-AUDIT.md b/docs/QA-09-BARRIEREFREIHEITS-AUDIT.md new file mode 100644 index 0000000..90a102d --- /dev/null +++ b/docs/QA-09-BARRIEREFREIHEITS-AUDIT.md @@ -0,0 +1,143 @@ +# QA-09 – Barrierefreiheits-Audit (Core-Oberflächen) + +Welle 6. Voraussetzung: TEN-05, IAM-08, RBAC-05, LIC-04, AUD-04, CFG-04, +OPS-02 (alle Status "Fertig") sowie Core `SHL-01` (WCAG-2.1-AA-Basis). +Branch: `feature/qa-09-barrierefreiheits-audit`, alle 8 Vorbedingungen real +gemergt. + +Geprüfte Oberflächen (7 Next.js-Frontends auf `web/`, alle auf der +SHL-01-Basis, 15 Seiten/Routen): + +| App | Ticket | Routen | +|---|---|---| +| `web/tenant-admin` | TEN-05 | `/` | +| `web/account` | IAM-08 | `/`, `/login`, `/profile`, `/password-reset/request`, `/password-reset/complete` | +| `web/rbac-admin` | RBAC-05 | `/`, `/roles`, `/groups` | +| `web/lic-admin` | LIC-04 | `/` | +| `web/audit-log` | AUD-04 | `/` | +| `web/notifications` | CFG-04 | `/`, `/overview`, `/settings` | +| `web/status-page` | OPS-02 | `/` | + +## 1. Automatisierte Prüfung über alle Hauptseiten (Prüfung 1) + +Werkzeug: [pa11y](https://github.com/pa11y/pa11y) 10.0.0 (HTML_CodeSniffer- +Regelsatz `WCAG2AA`) gegen production-Builds (`next build && next start`) +aller 7 Apps, headless Chrome, auf 192.168.1.131. + +**Erster Durchlauf** (vor Fixes): 19 Verstöße über 4 Seiten. + +| Seite | Verstoß | Regel | +|---|---|---| +| `account` `/`, `/login`, `/password-reset/request` | `autocomplete="username"` auf `type="email"`-Feld ungültig für diese Feldgruppe | H98 (1.3.5) | +| `audit-log` `/` | 4 Filter-Eingabefelder ohne zugänglichen Namen | H91/F68 (4.1.2/1.3.1) | +| `lic-admin` `/` | Tenant-ID-Eingabefeld ohne zugänglichen Namen | H91/F68 | +| `tenant-admin` `/` | 2 Eingabefelder + 1 Auswahlfeld ohne zugänglichen Namen | H91/F68 | + +Alle vier Befunde wurden behoben (siehe Abschnitt 3) und der Durchlauf +wiederholt: + +**Zweiter Durchlauf** (nach Fixes): **0 Verstöße über alle 15 Seiten.** + +## 2. Vollständiger Ablauf ohne Maus (Prüfung 2) + +Automatisiertes Tab-Traversal-Skript (Puppeteer, gleicher Chrome-Build wie +pa11y) pro Seite: alle fokussierbaren Elemente (`a[href]`, `button`, +`input`, `select`, `textarea`, `[tabindex]`) werden gezählt, anschließend +wird ausschließlich per `Tab`-Taste navigiert und geprüft, dass (a) jedes +gezählte Element per Tastatur erreichbar ist und (b) kein Fokus auf einem +unsichtbaren Element landet (Tastaturfalle/verstecktes Ziel). + +Ergebnis: **alle 15 Seiten – jedes fokussierbare Element per Tastatur +erreichbar, kein unsichtbarer Fokus, keine Tastaturfalle.** + +Zwei anfängliche Abweichungen waren beim Nachprüfen kein Befund: +- `audit-log` `/`: die beiden `datetime-local`-Felder verbrauchen mehrere + Tab-Schritte für ihre internen Segmente (Tag/Monat/Jahr/Stunde/Minute), + bleiben dabei aber auf demselben `` – natives, korrektes + Browserverhalten, kein Defekt. +- `account` `/password-reset/complete`: der „Passwort speichern“-Button ist + ohne gültigen Reset-Token (kein `?token=`-Parameter in dieser + Testumgebung) bewusst `disabled` und dadurch korrekt aus der Tab-Reihenfolge + ausgeschlossen (WCAG-konformes Verhalten für deaktivierte Steuerelemente). + +## 3. Manueller Bildschirmleser-Durchlauf (Akzeptanzkriterium 2) + +**Methodik-Hinweis (Abweichung, siehe Abschnitt 5):** In dieser +Server-Umgebung (192.168.1.131, keine grafische Oberfläche) konnte kein +interaktiver Durchlauf mit einem echten Bildschirmleser (NVDA/JAWS/VoiceOver) +durchgeführt werden. Ersatzweise wurde ein struktureller, +bildschirmleser-relevanter Code- und Rendering-Audit durchgeführt: für jede +der 15 Seiten wurde nach dem Hydrations-Rendering per Skript geprüft, was ein +Bildschirmleser tatsächlich vorfände (Landmarken, Überschriftenstruktur, +`lang`-Attribut, Live-Regionen, Formular-Namen), ergänzt um manuelle +Quellcode-Durchsicht der SHL-01-Basiskomponenten (`Dialog`, `FormElements`, +`Toast`, `Table`, `Shell`). + +Ergebnisse: +- **``** auf allen 15 Seiten korrekt gesetzt. +- **Genau ein `
`-Landmark** pro Seite auf allen 15 Seiten – ein + Bildschirmleser-Nutzer kann direkt zum Hauptinhalt springen. +- **Fehler-/Statusmeldungen** sind durchweg als `role="alert"` bzw. + `aria-live`-Region ausgezeichnet (z. B. Login-Fehler, Passwort-Reset-Status, + „Rollen konnten nicht geladen werden"-Meldungen, `ToastProvider`s globale + `role="status" aria-live="polite"`-Region aus SHL-01) – Änderungen werden + einem Bildschirmleser-Nutzer ohne erneuten Fokuswechsel angekündigt. +- **Formularfelder**: alle Eingabefelder haben nach den Fixes aus Abschnitt 1 + einen zugänglichen Namen (entweder über `