test(512): flush LibrariesScreen scan-poll chain deterministically instead of waitFor timeouts #558

Merged
timothy merged 1 commits from issue-512-deterministic-libraries-test into main 2026-07-22 18:02:25 +02:00
1 Commits
Author SHA1 Message Date
timothyandClaude Opus 4.8 b5596f55f3 test(512): flush LibrariesScreen scan-poll chain deterministically instead of waitFor timeouts
PR Gates / Docs update reminder (pull_request) Successful in 18s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 18s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 13s
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 8s
PR Gates / decisions lifecycle (pull_request) Successful in 19s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 5m57s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 20m49s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 6m9s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
The "stops scan polling and refreshes sources once when scans complete" test
fired the poll tick via runPollTick but discarded the promise loadScanStatuses
returns, so the progress-clear state update and the fire-and-forget
loadSources() refetch it triggers landed on real microtasks AFTER act() had
resolved. The test out-waited that race with two waitFor({ timeout: 5000 })
calls, which were marginal on a starved CI VM (timed out on PR #509/run 918);
prior timeout bumps (#447) were diminishing whack-a-mole.

Drive the chain to completion deterministically instead of out-waiting it:
runPollTick now awaits the promise the handler returns (settling the
progress-clear) and then yields to a single macrotask (setTimeout 0) to drain
the microtask queue — including the fire-and-forget loadSources() refetch —
all INSIDE act(async () => ...). The mock fetches resolve synchronously on
microtasks and setInterval is the only mocked timer, so one macrotask turn
completes both chains with no wall-clock delay. The two waitFor calls are
replaced by synchronous assertions (progress label gone; exactly one extra
/api/v1/media-sources fetch), and the 20s test-level budget is dropped.

Verified: LibrariesScreen suite green 15/15 consecutive runs; npm run lint and
npm run build clean. No production code changed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Fixes #512
2026-07-22 17:02:14 +02:00