Repository navigation
test(console): wait for the settings page's registration release before the shell leaves after a save - #26212
Merged
objectstack-fleet[bot] merged 2 commits intoOct 26, 2026
Conversation
…re the shell leaves after a save
The after-save case of SettingsView.shellLeave-13231 waited only for the
unsaved bar to go. The bar goes in the save's commit; the page's
unsaved-edits registration is released a step later, in a passive effect
React runs as its own task because the save settles outside act. On a
loaded worker the bar-wait returned in between, the Profile click met a
still-registered page, the stubbed confirm answered Cancel, and the route
never changed, so findByText('Profile page') timed out at the 1000 ms
default (queue builds 40316529606 and 40337868008). A longer timeout
cannot help: the navigation never happens.
Wait on the registration itself, as the sibling leaveGuard-13163 save case
already does: a cancelable beforeunload that is no longer prevented means
nothing is registered. Assertions unchanged.
Claude-Session: https://claude.ai/code/session_01SMps7wq7rBTk53e8KTSEup
Co-authored-by: Claude <noreply@anthropic.com>
…ttings-shell-leave-wait
Contributor
Author
席位核对ACCEPT ·
|
objectstack-fleet
Bot
deleted the
claude/issue-26096-settings-shell-leave-wait
branch
October 26, 2026 16:58
This was referenced Oct 26, 2026
Closed
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.
Fixes #26096
Clause-②: no
Metadata-protocol: none
What was wrong
Both queue ejections on this anchor (builds 40316529606 and 40337868008, at 1066 ms and 1064 ms) are the same case:
CONTROLS … › after a successful save: the shell leaves at once, atfindByText('Profile page'). It looked like a slow navigation that ran out of the 1000 ms default. It is not one. The click is swallowed, and the navigation never happens at all:act, so React commits it as an ordinary Scheduler task. The unsaved bar goes in that commit.useRegisterUnsavedEdits, throughuseUnsavedLeaveGuard) is released in that commit's passive effect. React runs that effect as a task of its own, after the commit.confirmUnsavedLeavewhile the page is still registered. It askswindow.confirm, the stub answers Cancel (false), and the route stays on/settings/localization.'Profile page'never renders, so a longer timeout cannot help.This is the same race the sibling harness
SettingsView.leaveGuard-13163fixed in its own save case (objectui#13317). That fix waits on the guard itself, through a cancelablebeforeunloadthat is no longer prevented, and this PR applies it here.The change
One file, test-only, +16 / -0:
ui/apps/console/src/pages/settings/__tests__/SettingsView.shellLeave-13231.test.tsx. In the after-save case, after the existing barwaitFor, the test now waits until a cancelablebeforeunloaddispatched onwindowis no longerdefaultPrevented. The seam installs that listener only while some page is registered, so the wait ends exactly when nothing is registered any more. The assertions are unchanged: Profile page appears, andconfirmis never called. There is no timeout change, no sleep, no retry, no skip and no product change.Evidence
All runs were under
scripts/pm/os-verify-lock.shon a shared box,pnpm exec vitest run --project @object-ui/console --maxWorkers=2.ProfileronRenderhook logged each commit. The save's commit runs withIS_REACT_ACT_ENVIRONMENT=false, and at that commit the bar is already gone while the registration is still held (held=true bar=false). The registration is released only later.registrationHeld=trueat the click,confirmCalls=1, path still/settings/localization, andNOT FOUND after 1006 ms. That is the CI signature. Without the emulation the same probe passed.main: not reproduced. Plain runs of the file onmainare green. I did not run a CPU hog on the shared container. The red above comes from the emulation only, and nothing else is claimed.Tests 6 passed (6),VERDICT command-exit 0.@object-ui/consoleproject at f7b810d:Test Files 247 passed (247),Tests 2488 passed (2488),VERDICT command-exit 0.origin/main(head 9c7d1a0), deps rebuilt: this file plusSettingsView.leaveGuard-13163,Test Files 2 passed (2),Tests 18 passed (18),VERDICT command-exit 0.dispatch-gates --commandsderived 23 commands, and all 23 exit 0.--ranreconciliation: 23 derived, 23 run, 0 NOT-MEASURED, 0 UNRUN.pnpm --filter @object-ui/console run type-checkexits 0, but that program does not list this test file (--listFilescount 0), so it does not cover the change.Acceptance notes
findByText('Profile page')sites (:162 and :184) are left as they are, on purpose. A probe showed'Profile page'is already in the DOM synchronously after the click there (sync=true, found in 2–7 ms). Neither case has a commit outsideactbefore the click. The OK case navigates whatever the registration state is, and the clean-page case never registers. Neither has ever ejected a PR.findBywaits to a route-load budget. That would not have fixed this, because the navigation never happens. It would also breakui/AGENTS.md"测试纪律", which forbids fixing a flake by raising a timeout. The triage wording "await the save's settled state before querying" is what was done: the settled state that matters is the released registration.@object-ui/console'sfiles[](dist,plugin.*,README.md) ships none of it, so the PR carriesskip-changeset.Generated by Claude Code