Repository navigation
cmux-next tests: batch B suites close the windows they open (1 of 2), popups close their panels - #27239
Conversation
Leo (2026-10-28), on Swift suites that leave windows open for the suites after them: "But why do you guys not just clean up after yourselves, or at least do your best to?" Each suite in this batch now closes every window its tests open, in the test's own teardown, and carries `.closesItsWindows` so a new leak fails by name: - teardowns that only ordered a window out close it; - tests that make browser pages release them (or close the chrome's popup panels), and tests that open the palette close its panel; - background mode's menu bar item goes when the launch test shuts down. Product code never closed three kinds of panel, only ordered them out, so they stayed in the app's window list while anything held their owner: - a window's overlay host panel, when the window closed (WindowOverlayHost); - a browser page's Page Info and Extensions panels, when its tab closed (BrowserEntry.close now calls BrowserChromeView.closePopupPanels); - the Mac screen approval prompt's panel, whose content holds the prompt (now closed and dropped when the prompt hides; the next request makes one). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-85ca59f74f02d81734c3
…heir panels Leo (2026-10-28): "But why do you guys not just clean up after yourselves, or at least do your best to?" - WindowOverlayHost keeps a closed window's torn-down host registered, so a late `host(for:)` for that window returns it instead of making a fresh panel nothing closes; a window shown again gets a new host, and `existingHost` still answers nil once torn down. - NativePopupHost.closePanel closes a popup's panel for good; Page Info, the Extensions bubble and the host pressure popover (when its indicator leaves its window) use it. - DebugPaletteCaptureTests and HomeOpenFocusesComposerTests drop the trait for now: the first leaves only AppKit's own TUINSWindow, the second the Chief Settings popover's panel, which its owner never closes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-85ca59f74f02d81734c3
…pKit-only suites keep the trait Leo: "But why do you guys not just clean up after yourselves, or at least do your best to?" Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-85ca59f74f02d81734c3
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
red: cmux-next checks (god files, concurrency, crash safety, l10n); no finished base run on e219b3a to compare; do not merge until green; see lane-rules |
|
Owned by an agent session · session |
|
Found 8 test failures on Blacksmith runners: Failures
|
|
Review (codex gpt-6-astra, high): SHIP at 2a4ec40 Independent Codex review of the full diff at this head, including the moved popup close in BrowserPageRetirement.close(). The reviewer found no blockers. BackgroundAccessoryPolicyTests.aWindowClosedBeforeTheRestoreFinishesStaysClosed fails the same way at base on the same worker. |
|
Bead |
|
This PR conflicts with feat-cmux-next. Please resolve it with a normal merge commit (no force push) and get a fresh review at the new head. The window-leak series is the fix for the cmux-next swift test hang, where leaked windows starve the main thread and runs get cut short at 1500 s. Four UI PRs are blocked on it: #24073, #24295, #25978 and #26558. #27462 has merged, so a cut-short run now names its unfinished tests. |
|
For awareness, from an audit against the aiforui course's popover rules (a popover inside another layer closes only itself; overflow fades at the edge, never a hard clip). This PR touches the same popup hosts, so these are yours to take or reject:
The audit is leaving both files alone while this PR is open, to avoid conflicts. 🤖 Generated with Claude Code |
Resolve BrowserToolbarPressTargetTests: keep base's NSApplication.shared init and the PR's .closesItsWindows trait. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-0cf32b32a03b27dcdf4d
|
Review (codex gpt-6-astra high, next-review): SHIP at 7d6bea5 No blocking findings. |
Base now has #27239 squashed. Conflicts keep this branch's cleanup: PageInfoController.closePanel retires and closes its windows, BackgroundAccessoryPolicyTests stops through AppTestDaemonOwner, DaemonClosedBrowserPageTests releases both tabs, and BrowserProfileNewTabMenuTests / DebugPaletteCaptureTests keep their own panel close (base's second close is dropped). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-0cf32b32a03b27dcdf4d
|
Shipped in:
|
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Leo: "But why do you guys not just clean up after yourselves, or at least do your best to?" (on Swift suites that leave windows open for the suites after them)
This is the second of three. It follows #27172 (overlay host panels close with their window).
What leaked and why
The #27003 census at its head (fleet steps wleak-before-1/3/5) named 19 suites in this batch. Together they left 35 windows open at process exit. There were three causes:
defer { window.orderOut(nil) }hides a window, but it stays open inNSApp.windows. Affected: AgentInteropAccessibility (2), FullScreenTitlebarPageMode (2), the Home suites' shell windows, HibernationWakeCover, HostPressureBannerToast and others. Fixed withclose().NativePopupHost) stayed open after their page closed: BrowserToolbarPressTarget 8, AgentPageStaysInWindow 2, DaemonClosedBrowserPage 2. The fix is the newNativePopupHost.closePanel().BrowserPageRetirement(the page close path) now closes both bubbles for good. The host pressure popover closes its panel when its indicator leaves its window. The Mac screen approval prompt closes and drops its panel on hide. That panel held the prompt, so it stayed for good, and the next request makes a fresh one.Each suite now carries
@Suite(.closesItsWindows), so a new leak fails that suite by name. No test is skipped and no assertion is changed.No capture: no visible change. The popups look and open the same; only their hidden panels now close when their owner goes away.
Performance
Windows these 19 suites left open at process exit, from the fleet test census. Before is the #27003 head (steps wleak-before-1/3/5); after is step ef4421a6 at this tree, same filters.
package-test-lane.sh suite, steps wleak-before-1/3/5 / ef4421a6Known, not ours
BackgroundAccessoryPolicyTests.aWindowClosedBeforeTheRestoreFinishesStaysClosedfails on the slower perf minis with the same two expectations and messages at base. The base runs that show it are steps fd82dc62 and 0d61f186, both pinned to the same worker; the test passes on faster workers at both base and head. It also leaves no window open now.HomeOpenFocusesComposerTests: the test process sometimes ends in the middle ofopeningAConversationFromTheList…(the run-loop stop its own doc comment describes). The harness window is then still open because itsdefernever ran. This happens at base too (wleak-before-1 and the batch base run). Runs that finish pass and leave 0 windows.Risk
The product changes are small and only on close paths: a page's popup panels close when the page retires; the host pressure popover's panel closes when it leaves its window; the approval prompt's panel closes on hide. Each popup reopens with a fresh or reopened panel on its next show.
Agent session: agent session
🤖 Generated with Claude Code
Summary by cubic
Closes the windows these 19 cmux-next test suites leave open at process exit (35 open at exit down to 1), and makes the popup panels that caused most of the leak close for good when their owner goes away.
What leaked and why
NSApp.windows; they now callclose().NativePopupHost.closePanel()now closes them when their page retires, when the indicator leaves its window, and when the Mac screen approval prompt hides (the prompt also drops its panel).Every suite carries
@Suite(.closesItsWindows), so a new leak fails that suite by name. No test is skipped and no assertion changes.Written for commit 7d6bea5. Summary will update on new commits.