Skip to content

Commit 71b0cf0

Browse files
committed
Stabilize UI test launch foreground activation
1 parent 811cf13 commit 71b0cf0

1 file changed

Lines changed: 42 additions & 7 deletions

File tree

Sources/AppDelegate.swift

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2078,6 +2078,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
20782078
private var didSetupMultiWindowNotificationsUITest = false
20792079
private var didSetupDisplayResolutionUITestDiagnostics = false
20802080
private var displayResolutionUITestObservers: [NSObjectProtocol] = []
2081+
private var didRequestFallbackUITestWindow = false
20812082
private struct UITestRenderDiagnosticsSnapshot {
20822083
let panelId: UUID
20832084
let drawCount: Int
@@ -2384,13 +2385,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
23842385
)
23852386
}
23862387
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { [weak self] in
2387-
guard let self else { return }
2388-
if NSApp.windows.isEmpty {
2389-
self.openNewMainWindow(nil)
2390-
}
2391-
self.moveUITestWindowToTargetDisplayIfNeeded()
2392-
NSRunningApplication.current.activate(options: [.activateAllWindows, .activateIgnoringOtherApps])
2393-
self.writeUITestDiagnosticsIfNeeded(stage: "afterForceWindow")
2388+
self?.stabilizeUITestLaunchWindowAndForeground()
23942389
}
23952390
if env["CMUX_UI_TEST_BROWSER_IMPORT_HINT_OPEN_BLANK_BROWSER"] == "1" {
23962391
DispatchQueue.main.asyncAfter(deadline: .now() + 0.45) { [weak self] in
@@ -2416,6 +2411,46 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
24162411
}
24172412

24182413
#if DEBUG
2414+
// Retry launch stabilization until a delayed WindowGroup materialization produces
2415+
// a visible key window that XCUITest can bring to the foreground on the shared VM.
2416+
private func stabilizeUITestLaunchWindowAndForeground(attempt: Int = 0) {
2417+
let env = ProcessInfo.processInfo.environment
2418+
guard isRunningUnderXCTest(env) else { return }
2419+
2420+
if NSApp.windows.isEmpty, !didRequestFallbackUITestWindow {
2421+
didRequestFallbackUITestWindow = true
2422+
openNewMainWindow(nil)
2423+
}
2424+
2425+
moveUITestWindowToTargetDisplayIfNeeded()
2426+
activateUITestAppIfNeeded()
2427+
2428+
let hasWindow = !NSApp.windows.isEmpty
2429+
let hasVisibleWindow = NSApp.windows.contains { $0.isVisible }
2430+
let hasKeyWindow = NSApp.keyWindow != nil
2431+
let stage = attempt == 0 ? "afterForceWindow" : "afterForceWindow.retry\(attempt)"
2432+
writeUITestDiagnosticsIfNeeded(stage: stage)
2433+
2434+
guard attempt < 20 else { return }
2435+
if !hasWindow || !hasVisibleWindow || !hasKeyWindow || !NSRunningApplication.current.isActive {
2436+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { [weak self] in
2437+
self?.stabilizeUITestLaunchWindowAndForeground(attempt: attempt + 1)
2438+
}
2439+
}
2440+
}
2441+
2442+
private func activateUITestAppIfNeeded() {
2443+
if let window = NSApp.windows.first {
2444+
window.makeKeyAndOrderFront(nil)
2445+
window.orderFrontRegardless()
2446+
}
2447+
if #available(macOS 14.0, *) {
2448+
NSRunningApplication.current.activate(options: [.activateAllWindows])
2449+
} else {
2450+
NSRunningApplication.current.activate(options: [.activateAllWindows, .activateIgnoringOtherApps])
2451+
}
2452+
}
2453+
24192454
private func writeUITestDiagnosticsIfNeeded(stage: String) {
24202455
let env = ProcessInfo.processInfo.environment
24212456
guard let path = env["CMUX_UI_TEST_DIAGNOSTICS_PATH"], !path.isEmpty else { return }

0 commit comments

Comments
 (0)