Skip to content

test: fix flaky UpdateTab reconcile flow (Restarting-button race) (#2065)#2067

Merged
atomantic merged 2 commits into
mainfrom
claim/issue-2065
Jul 2, 2026
Merged

test: fix flaky UpdateTab reconcile flow (Restarting-button race) (#2065)#2067
atomantic merged 2 commits into
mainfrom
claim/issue-2065

Conversation

@atomantic

Copy link
Copy Markdown
Owner

Closes #2065

Root cause

The UpdateTab reconcile flow tests intermittently failed CI with:

TestingLibraryElementError: Unable to find role="button" and name "Restarting..."

The component mirrors the updating state into updatingRef via a separate passive effect (useEffect(() => { updatingRef.current = updating }, [updating])), and handleDisconnect's guard reads that ref synchronously:

const handleDisconnect = () => {
  if (!updatingRef.current) return;   // <-- reads ref synchronously
  setTimeout(async () => { ... arm restart polling ... }, 1500);
};

Because runUpdate() calls setUpdating(true) outside any act (after two awaits), the "Reconciling..." button — driven directly by the updating state in JSX — can commit to the DOM and satisfy the test's waitFor(...'Reconciling...') a scheduler tick before the ref-sync passive effect runs. In that window updatingRef.current is still false, so firing disconnect hits the early-return, the 1.5s confirmation timer is never armed, and the button never becomes "Restarting...". This is a pure test-timing race — in production the ref-sync effect flushes long before any socket disconnect, so product behavior is correct.

Fix (test-only)

Flush pending passive effects (await act(async () => {})) before firing disconnect in the shared fireDisconnectAndConfirm helper (used by both failing cases, including the StrictMode one) and in the unmount case's inline block. This syncs updatingRef to the state production always reaches over real network time. No product code changed; all original assertions (restart-polling fallback arming, { silent: true } health check, StrictMode mountedRef survival) are preserved.

Test plan

Ran the file 25x green after the fix (had reproduced the flake ~1 in 8 on clean pre-fix code):

cd client && for i in $(seq 1 25); do npm test -- UpdateTab; done
# 25/25: Tests  5 passed (5)

https://claude.ai/code/session_01TSuyZ5XG9JiijEibeJjL6T

@atomantic atomantic merged commit cc9ca28 into main Jul 2, 2026
2 checks passed
@atomantic atomantic deleted the claim/issue-2065 branch July 2, 2026 17:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Flaky test: UpdateTab.test.jsx reconcile flow intermittently fails ('Restarting...' button not found)

1 participant