From cdab4e1c0c24ff568246bd0624f569821afdaba3 Mon Sep 17 00:00:00 2001 From: "pulse-triage[bot]" <249995291+pulse-triage[bot]@users.noreply.github.com> Date: Mon, 7 Sep 2026 10:02:25 +0100 Subject: [PATCH] test(web): preserve toast announcement and focus semantics Recovery feedback must remain available without stealing keyboard focus. Cover existing error/warning and success/info live-region distinctions, atomic contextual text and retained focus through the public toast entry point. This protects accessibility behaviour without adding product scope; DOM assertions do not establish screen-reader acceptance. Change-source: pulse-maintainer --- .../components/Toast/__tests__/Toast.test.tsx | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/frontend-modern/src/components/Toast/__tests__/Toast.test.tsx b/frontend-modern/src/components/Toast/__tests__/Toast.test.tsx index 047da5a10..632474b35 100644 --- a/frontend-modern/src/components/Toast/__tests__/Toast.test.tsx +++ b/frontend-modern/src/components/Toast/__tests__/Toast.test.tsx @@ -11,6 +11,27 @@ describe('Toast', () => { vi.useRealTimers(); }); + it.each([ + ['error', 'alert', 'assertive'], + ['warning', 'alert', 'assertive'], + ['success', 'status', 'polite'], + ['info', 'status', 'polite'], + ] as const)('preserves %s announcement semantics without moving focus', (type, role, live) => { + render(() => <>); + const action = screen.getByRole('button', { name: 'Recovery action' }); + action.focus(); + + window.showToast(type, 'Recovery result', 'Action context'); + + const announcement = screen.getByRole(role); + expect(announcement).toHaveAttribute('aria-live', live); + expect(announcement).toHaveAttribute('aria-atomic', 'true'); + expect(announcement).toHaveTextContent('Recovery result'); + expect(announcement).toHaveTextContent('Action context'); + expect(action).toHaveFocus(); + expect(screen.queryByRole(role === 'alert' ? 'status' : 'alert')).not.toBeInTheDocument(); + }); + it('keeps all toasts created within a batch', () => { render(() => );