Remove two sources of nightly CI failure (auto-update modal, urlPrefix mock ordering) - #8138
Merged
Conversation
On a fresh CI runner Settings.Default.AutoUpdateDialogShown is 0, so WorkspaceView opened the "Auto Update" ReactDialog modally as a startup action. With nobody to dismiss it, it sat on the UI thread in its own nested message loop for the entire run: the 2026-08-03 nightly's hang dumps show all three captures, eight minutes apart, with the main thread parked in Form.ShowDialog under ShowAutoUpdateDialogIfNeeded. Program.RunningE2eTests already exists to suppress exactly this -- its own comment describes "a dialog nobody can dismiss and hanging the whole run" -- and covers modal error dialogs and Debug.Assert boxes. This nag dialog was simply never included, so honor the same flag here. This was NOT the cause of that night's visual-regression failure (that is BL-16612, and the step passed on other nights with this dialog up), just an independent hazard found while reading the dumps. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
talkingBookSpec's "showTool(checksum=missing, audio=missing, scenario=PreTextBox) => UPDATE" failed every nightly since 2026-07-29, comparing http://localhost:3000/... against the expected http://localhost:63315/..., while passing locally both in isolation and under a full-suite run with the same worker count. 63315 is not a real port, it is a literal inside a mock of AudioRecording.urlPrefix, which setupForAudioRecordingTests installed on theOneAudioRecorder AFTER awaiting initializeTalkingBookToolAsync. Two things made that ordering fragile: - theOneAudioRecorder does not exist until that call creates it (it is an `export let` populated by getAudioRecorder), so the mock could not have been installed on the instance any earlier. - The call itself already sets the player's src, so that first src was built by the REAL urlPrefix: a relative URL, which jsdom resolves against its own http://localhost:3000/ base. setCurrentAudioId only refreshes the player when the audio id CHANGES, so a test whose id was already current never overwrote that stale pre-mock value and compared :3000 against the mocked :63315. Whether an id was already current depended on what earlier work happened to leave behind, which is why the machine mattered. Mock the PROTOTYPE, before initializing, so even the init-time write goes through the mock and no stale value exists to inherit. Verified: full front-end suite still 578 passed / 5 skipped, unchanged from before. Since the failure never reproduced locally, confirming the CI-side fix needs a nightly (or workflow_dispatch) run. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
andrew-polk
commented
Aug 3, 2026
Contributor
Author
|
(Claude Opus 5) Consulted Devin on 2026-08-03 (during preflight) up to commit Result: 0 bugs, 1 Investigate flag, 2 Informational items.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two independent fixes for things making the nightly red, found while evaluating the 2026-08-03 nightly. Neither one touches the actual visual-regression hang — that is BL-16612, whose fix is on
BL-16612-page-checks-hang(#8110). These just remove the noise around it.1. Don't show the auto-update dialog in automated runs
On a fresh CI runner
Settings.Default.AutoUpdateDialogShownis 0, soWorkspaceViewopened the "Auto Update"ReactDialogmodally as a startup action. With nobody to dismiss it, it sat on the UI thread in its own nested message loop for the whole run — all three stack captures from the 08-03 nightly show the main thread parked inForm.ShowDialogunderShowAutoUpdateDialogIfNeeded.Program.RunningE2eTestsalready exists to suppress exactly this (its own comment: "a dialog nobody can dismiss and hanging the whole run") and covers modal error dialogs andDebug.Assertboxes. This nag dialog was simply never included.This was not the cause of that night's hang — the visual-regression step passed on other nights with this dialog up — just an independent hazard.
2. Install the talking-book
urlPrefixmock before the recorder existstalkingBookSpec > showTool(checksum=missing, audio=missing, scenario=PreTextBox) => UPDATEfailed every nightly since 2026-07-29, comparinghttp://localhost:3000/...against the expectedhttp://localhost:63315/..., while passing locally both in isolation and under a full-suite run with the same worker count.63315is not a real port; it is a literal inside a mock ofAudioRecording.urlPrefixthatsetupForAudioRecordingTestsinstalled ontheOneAudioRecorderafter awaitinginitializeTalkingBookToolAsync. Two things made that fragile:theOneAudioRecorderdoes not exist until that call creates it (it is anexport letpopulated bygetAudioRecorder), so the mock could not have gone on the instance any earlier.src, so that firstsrccame from the realurlPrefix— a relative URL, which jsdom resolves against its ownhttp://localhost:3000/base.setCurrentAudioIdonly refreshes the player when the audio id changes, so a test whose id was already current never overwrote that stale pre-mock value, and compared:3000against the mocked:63315. Which ids were already current depended on what earlier work happened to leave behind — hence local pass, CI fail.Fix: mock the prototype, before initializing, so even the init-time write goes through the mock and no stale value exists to inherit.
One deliberate consequence: the mock now applies to every
AudioRecordinginstance rather than only the singleton. That matches the mock's intent ("in tests,urlPrefixreturns this absolute URL") and the suite confirms it.Verification
pnpm typecheck— passedpnpm lint— 0 errors (774 pre-existing repo-wide warnings; none in the changed files)build/agent-dotnet.sh build BloomExe— 0 errorsThe full-suite numbers being unchanged is the honest reading: it confirms no regression, not that the CI failure is fixed. That test never reproduced locally, so fix 2 is justified by mechanism, and confirming it needs a nightly (or
workflow_dispatch) run on this branch. Fix 1 likewise can only be observed in CI.No tracker card — this branch carries no
BL-id (small CI cleanups). Related context: BL-16612.Devin review
This change is