From dfc065b727b7754e01ed9e682a0e8e6710735bba Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 9 Jun 2026 16:47:04 +0200 Subject: [PATCH] test(journey-editor): verify liveAnnounce region clears after 500ms A persistent non-empty aria-live region can cause stale re-announcements on adjacent DOM mutations. This test confirms the region is empty after the 500ms clear timeout fires following a move operation. Co-Authored-By: Claude Sonnet 4.6 --- .../geschichte/JourneyEditor.svelte.spec.ts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/frontend/src/lib/geschichte/JourneyEditor.svelte.spec.ts b/frontend/src/lib/geschichte/JourneyEditor.svelte.spec.ts index 4eed135c..32f2c048 100644 --- a/frontend/src/lib/geschichte/JourneyEditor.svelte.spec.ts +++ b/frontend/src/lib/geschichte/JourneyEditor.svelte.spec.ts @@ -280,6 +280,36 @@ describe('JourneyEditor — reorder via move buttons', () => { }); }); +describe('JourneyEditor — live announce region', () => { + it('clears the live announce region 500ms after a move operation', async () => { + const items = [ + { id: 'i1', position: 0, document: docSummary('d1', 'Brief A') }, + { id: 'i2', position: 1, document: docSummary('d2', 'Brief B') } + ]; + vi.stubGlobal( + 'fetch', + vi.fn().mockResolvedValue({ + ok: true, + json: vi.fn().mockResolvedValue([ + { id: 'i2', position: 0, document: docSummary('d2', 'Brief B') }, + { id: 'i1', position: 1, document: docSummary('d1', 'Brief A') } + ]) + }) + ); + + render(JourneyEditor, defaultProps({ geschichte: makeGeschichte({ items }) })); + + await userEvent.click(page.getByRole('button', { name: /Brief B.*nach oben verschieben/ })); + await new Promise((r) => setTimeout(r, 50)); // wait for csrfFetch + + const liveRegion = document.querySelector('[aria-live="polite"]'); + expect((liveRegion?.textContent ?? '').trim().length).toBeGreaterThan(0); + + await new Promise((r) => setTimeout(r, 650)); // 500ms clear timeout + buffer + expect((liveRegion?.textContent ?? '').trim()).toBe(''); + }); +}); + describe('JourneyEditor — duplicate document aria-disabled', () => { it('already-added document appears as aria-disabled in picker', async () => { const items = [{ id: 'i1', position: 0, document: docSummary('d1', 'Brief von Karl') }];