cmux-next tests: batch B suites close the windows they open (1 of 2), popups close their panels

Merged
TE
7d ago
+129-38

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:

  • Teardowns that only order a window out. defer { window.orderOut(nil) } hides a window, but it stays open in NSApp.windows. Affected: AgentInteropAccessibility (2), FullScreenTitlebarPageMode (2), the Home suites' shell windows, HibernationWakeCover, HostPressureBannerToast and others. Fixed with close().
  • Product popups that keep their panel between opens and only order it out. Page Info and the Extensions bubble (NativePopupHost) stayed open after their page closed: BrowserToolbarPressTarget 8, AgentPageStaysInWindow 2, DaemonClosedBrowserPage 2. The fix is the new NativePopupHost.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.
  • Panels the code under test opens that the test never closed. These are the palette (BrowserProfileNewTabMenu, DebugPaletteCapture) and Home's Chief Settings popover (HomeOpenFocusesComposer; Home makes it up front and only ever hides it). The tests now close them through the product's own API in teardown.

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.

metricbeforeafterdeltaharness
windows left open at exit, 19 suites351-34 (-97%)package-test-lane.sh suite, steps wleak-before-1/3/5 / ef4421a6
BrowserToolbarPressTargetTests80-8same
HomeOpenFocusesComposerTests21-1same (that run was cut short; see below)

Known, not ours

  • BackgroundAccessoryPolicyTests.aWindowClosedBeforeTheRestoreFinishesStaysClosed fails 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 of openingAConversationFromTheList… (the run-loop stop its own doc comment describes). The harness window is then still open because its defer never 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

  • Teardowns that only ordered a window out hid it but left it in NSApp.windows; they now call close().
  • Page Info, the Extensions bubble and the host pressure popover kept their panels between opens and only ordered them out; the new 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).
  • Panels the tests themselves opened, the palette and Home's Chief Settings popover, are now closed in teardown through the product's own APIs.

Every suite carries @Suite(.closesItsWindows), so a new leak fails that suite by name. No test is skipped and no assertion changes.