lsa-planer
LSA-Planer Professional – Planungssoftware für Lichtsignalanlagen nach RiLSA 2015 und § 45 StVO. EUPL-1.2.
/ tests ui meldungsstapelAnsageumfang.test.ts
| 1 | import { afterEach, describe, expect, it } from 'vitest'; |
| 2 | import { notify, setzeMeldungsdauer } from '@/ui/feedback'; |
| 3 | |
| 4 | /** |
| 5 | * Befund 46 zur Fassung 5.9.0 (WCAG 4.1.3 Statusmeldungen). |
| 6 | * |
| 7 | * WAS DER ANWENDER SONST ERLEBT |
| 8 | * |
| 9 | * Er traegt in der Signalgruppentabelle nacheinander drei unzulaessige Zahlen |
| 10 | * ein. Jede erzeugt ueber `melde()` in src/ui/inputs.ts eine Warnung, und |
| 11 | * Warnungen laufen mit Absicht nie ab. Sie stapeln sich also im selben |
| 12 | * Behaelter. `role="alert"` und `role="status"` tragen nach ARIA implizit |
| 13 | * `aria-atomic="true"`: Die Sprachausgabe liest bei jeder Aenderung den GANZEN |
| 14 | * Bereich vor, nicht die hinzugekommene Meldung. Bei der dritten Eingabe |
| 15 | * bekommt er alle drei Saetze zu hoeren, bevor der Satz kommt, auf den es |
| 16 | * ankommt. |
| 17 | * |
| 18 | * Denselben Weg nimmt der hoefliche Bereich, sobald die Anzeigedauer auf |
| 19 | * "stehen lassen, bis ich sie schließe" steht (`setzeMeldungsdauer(0)`) - dann |
| 20 | * laeuft fuer KEINE Meldung mehr eine Uhr, und ausgerechnet die Vorkehrung fuer |
| 21 | * WCAG 2.2.1 erzeugt das schlechteste Ansageverhalten. |
| 22 | * |
| 23 | * Geprueft wird das Merkmal und nicht die Ansage selbst: Was eine |
| 24 | * Sprachausgabe daraus macht, laesst sich in jsdom nicht messen; welchen |
| 25 | * Umfang sie dabei zugrunde legt, steht im Baum. |
| 26 | */ |
| 27 | |
| 28 | afterEach(() => { |
| 29 | setzeMeldungsdauer(5); |
| 30 | document.body.replaceChildren(); |
| 31 | }); |
| 32 | |
| 33 | function bereiche(): HTMLElement[] { |
| 34 | return [...document.querySelectorAll<HTMLElement>('.meldungen .meldungen-gruppe')]; |
| 35 | } |
| 36 | |
| 37 | describe('Meldungsstapel sagt nur die neue Meldung an, nicht den ganzen Stapel', () => { |
| 38 | it('setzt an beiden Bereichen ausdruecklich aria-atomic="false"', () => { |
| 39 | notify('Gespeichert.', 'erfolg'); |
| 40 | notify('"200" liegt außerhalb von 10 bis 100.', 'warnung'); |
| 41 | |
| 42 | const gefunden = bereiche(); |
| 43 | expect(gefunden, 'Es gibt nicht die beiden Meldungsbereiche').toHaveLength(2); |
| 44 | expect(gefunden.map((b) => b.getAttribute('role'))).toEqual(['status', 'alert']); |
| 45 | for (const bereich of gefunden) { |
| 46 | expect( |
| 47 | bereich.getAttribute('aria-atomic'), |
| 48 | `Der Bereich "${bereich.getAttribute('role') ?? ''}" laesst den ganzen Stapel ansagen`, |
| 49 | ).toBe('false'); |
| 50 | } |
| 51 | }); |
| 52 | |
| 53 | it('behaelt das Merkmal, wenn sich Warnungen stapeln', () => { |
| 54 | notify('Erste abgelehnte Zahl.', 'warnung'); |
| 55 | notify('Zweite abgelehnte Zahl.', 'warnung'); |
| 56 | notify('Dritte abgelehnte Zahl.', 'warnung'); |
| 57 | |
| 58 | const bestimmt = bereiche()[1]; |
| 59 | expect(bestimmt, 'Kein bestimmter Meldungsbereich').toBeDefined(); |
| 60 | // Alle drei stehen noch: Warnungen laufen nicht ab. |
| 61 | expect(bestimmt?.querySelectorAll('.meldung')).toHaveLength(3); |
| 62 | expect(bestimmt?.getAttribute('aria-atomic')).toBe('false'); |
| 63 | }); |
| 64 | |
| 65 | it('gilt auch fuer den hoeflichen Bereich bei "stehen lassen"', () => { |
| 66 | setzeMeldungsdauer(0); |
| 67 | notify('Projekt gespeichert.', 'erfolg'); |
| 68 | notify('Phase hinzugefügt.', 'info'); |
| 69 | |
| 70 | const hoeflich = bereiche()[0]; |
| 71 | expect(hoeflich?.querySelectorAll('.meldung')).toHaveLength(2); |
| 72 | expect(hoeflich?.getAttribute('aria-atomic')).toBe('false'); |
| 73 | }); |
| 74 | }); |