import { afterEach, describe, expect, it } from 'vitest'; import { notify, setzeMeldungsdauer } from '@/ui/feedback'; /** * Befund 46 zur Fassung 5.9.0 (WCAG 4.1.3 Statusmeldungen). * * WAS DER ANWENDER SONST ERLEBT * * Er traegt in der Signalgruppentabelle nacheinander drei unzulaessige Zahlen * ein. Jede erzeugt ueber `melde()` in src/ui/inputs.ts eine Warnung, und * Warnungen laufen mit Absicht nie ab. Sie stapeln sich also im selben * Behaelter. `role="alert"` und `role="status"` tragen nach ARIA implizit * `aria-atomic="true"`: Die Sprachausgabe liest bei jeder Aenderung den GANZEN * Bereich vor, nicht die hinzugekommene Meldung. Bei der dritten Eingabe * bekommt er alle drei Saetze zu hoeren, bevor der Satz kommt, auf den es * ankommt. * * Denselben Weg nimmt der hoefliche Bereich, sobald die Anzeigedauer auf * "stehen lassen, bis ich sie schließe" steht (`setzeMeldungsdauer(0)`) - dann * laeuft fuer KEINE Meldung mehr eine Uhr, und ausgerechnet die Vorkehrung fuer * WCAG 2.2.1 erzeugt das schlechteste Ansageverhalten. * * Geprueft wird das Merkmal und nicht die Ansage selbst: Was eine * Sprachausgabe daraus macht, laesst sich in jsdom nicht messen; welchen * Umfang sie dabei zugrunde legt, steht im Baum. */ afterEach(() => { setzeMeldungsdauer(5); document.body.replaceChildren(); }); function bereiche(): HTMLElement[] { return [...document.querySelectorAll('.meldungen .meldungen-gruppe')]; } describe('Meldungsstapel sagt nur die neue Meldung an, nicht den ganzen Stapel', () => { it('setzt an beiden Bereichen ausdruecklich aria-atomic="false"', () => { notify('Gespeichert.', 'erfolg'); notify('"200" liegt außerhalb von 10 bis 100.', 'warnung'); const gefunden = bereiche(); expect(gefunden, 'Es gibt nicht die beiden Meldungsbereiche').toHaveLength(2); expect(gefunden.map((b) => b.getAttribute('role'))).toEqual(['status', 'alert']); for (const bereich of gefunden) { expect( bereich.getAttribute('aria-atomic'), `Der Bereich "${bereich.getAttribute('role') ?? ''}" laesst den ganzen Stapel ansagen`, ).toBe('false'); } }); it('behaelt das Merkmal, wenn sich Warnungen stapeln', () => { notify('Erste abgelehnte Zahl.', 'warnung'); notify('Zweite abgelehnte Zahl.', 'warnung'); notify('Dritte abgelehnte Zahl.', 'warnung'); const bestimmt = bereiche()[1]; expect(bestimmt, 'Kein bestimmter Meldungsbereich').toBeDefined(); // Alle drei stehen noch: Warnungen laufen nicht ab. expect(bestimmt?.querySelectorAll('.meldung')).toHaveLength(3); expect(bestimmt?.getAttribute('aria-atomic')).toBe('false'); }); it('gilt auch fuer den hoeflichen Bereich bei "stehen lassen"', () => { setzeMeldungsdauer(0); notify('Projekt gespeichert.', 'erfolg'); notify('Phase hinzugefügt.', 'info'); const hoeflich = bereiche()[0]; expect(hoeflich?.querySelectorAll('.meldung')).toHaveLength(2); expect(hoeflich?.getAttribute('aria-atomic')).toBe('false'); }); });