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();
+ });
});