From 800663fdf3364e86663475fc90c838eb358b1368 Mon Sep 17 00:00:00 2001 From: "pulse-triage[bot]" <249995291+pulse-triage[bot]@users.noreply.github.com> Date: Mon, 7 Sep 2026 18:06:54 +0100 Subject: [PATCH] test(web): preserve editing focus during recovery feedback Existing coverage checks focus after Clear but not when asynchronous failure feedback arrives. Guard input focus, unfinished text and mounted live-region identity without changing the interface or claiming screen-reader acceptance. Change-source: pulse-maintainer --- .../alerts/AlertDeliveryHealthCard.test.tsx | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/frontend-modern/src/features/alerts/AlertDeliveryHealthCard.test.tsx b/frontend-modern/src/features/alerts/AlertDeliveryHealthCard.test.tsx index 3c2fdd021..82170c438 100644 --- a/frontend-modern/src/features/alerts/AlertDeliveryHealthCard.test.tsx +++ b/frontend-modern/src/features/alerts/AlertDeliveryHealthCard.test.tsx @@ -219,6 +219,29 @@ describe('AlertDeliveryHealthCard', () => { describe('recovery feedback beside delivery health', () => { afterEach(() => cleanup()); + it('preserves editing focus and live-region identity when failure feedback changes', () => { + const [message, setMessage] = createSignal(null); + render(() => <> + + setMessage(null)} /> + ); + const input = screen.getByRole('textbox', { name: 'Destination name' }); + const status = screen.getByRole('status'); + expect(status).toHaveAttribute('aria-live', 'polite'); + expect(status).toHaveAttribute('aria-atomic', 'true'); + input.focus(); + fireEvent.input(input, { target: { value: 'Unfinished edit' } }); + for (const failure of [ + 'Unable to retry retained notification deliveries.', + 'Unable to dismiss retained notification failures.', + ]) { + setMessage(failure); + expect(screen.getByRole('status')).toBe(status); + expect(status).toHaveTextContent(failure); + expect(input).toHaveFocus(); + expect(input).toHaveValue('Unfinished edit'); + } + }); it('keeps a mounted live region and returns focus to it when deliberately cleared', () => { const [message, setMessage] = createSignal(null); render(() => setMessage(null)} />);