From d44c6282defa855bc85909eeeaa6037899bba6b8 Mon Sep 17 00:00:00 2001 From: "pulse-triage[bot]" <249995291+pulse-triage[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2026 01:52:20 +0100 Subject: [PATCH] test(web): guard bootstrap timer cleanup across attempts Slow-start recovery is advertised to preview users. Pin cleanup when the loading fallback unmounts and ensure a later attempt does not inherit the previous warning deadline. This guards existing UX without changing product behaviour; 34 focused bootstrap, connection badge and runtime tests pass. Change-source: pulse-maintainer --- .../__tests__/AppBootstrapStatus.test.tsx | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/frontend-modern/src/components/__tests__/AppBootstrapStatus.test.tsx b/frontend-modern/src/components/__tests__/AppBootstrapStatus.test.tsx index 128ad1b91..8e536f2af 100644 --- a/frontend-modern/src/components/__tests__/AppBootstrapStatus.test.tsx +++ b/frontend-modern/src/components/__tests__/AppBootstrapStatus.test.tsx @@ -34,4 +34,24 @@ describe('AppBootstrapStatus', () => { fireEvent.click(retry); expect(onRetry).toHaveBeenCalledOnce(); }); + + it('cancels a completed bootstrap timer and gives a fresh attempt its full waiting period', async () => { + vi.useFakeTimers(); + const first = render(() => ); + await vi.advanceTimersByTimeAsync(APP_BOOTSTRAP_SLOW_DELAY_MS - 1); + expect(screen.queryByRole('button', { name: 'Retry connection' })).toBeNull(); + + first.unmount(); + expect(vi.getTimerCount()).toBe(0); + + render(() => ); + await vi.advanceTimersByTimeAsync(1); + expect(screen.getByRole('status')).toHaveTextContent( + 'Checking your session and preparing the workspace.', + ); + expect(screen.queryByRole('button', { name: 'Retry connection' })).toBeNull(); + + await vi.advanceTimersByTimeAsync(APP_BOOTSTRAP_SLOW_DELAY_MS - 1); + expect(screen.getByRole('button', { name: 'Retry connection' })).toBeVisible(); + }); });