Fix display resolution UI test foreground activation on CI

XCUIApplication.launch() fails to activate the app on headless CI
runners, reporting "Failed to activate application (current state:
Running Background)". With continueAfterFailure=false, this kills the
test before ensureForegroundAfterLaunch can retry.

Fix by temporarily setting continueAfterFailure=true around launch(),
then retrying activation via app.activate(). Also add a retry loop in
the CI workflow since foreground activation is inherently flaky on
headless runners.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
austinpower1258 2026-03-23 02:19:12 -07:00
parent 10fd323bb0
commit 75375ab7af
2 changed files with 41 additions and 6 deletions

View file

@ -495,12 +495,24 @@ jobs:
{"helperBinaryPath":"$HELPER_PATH"}
EOF
xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -configuration Debug \
# Retry once — foreground activation on headless CI runners is flaky
for attempt in 1 2; do
if xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -configuration Debug \
-clonedSourcePackagesDirPath "$SOURCE_PACKAGES_DIR" \
-disableAutomaticPackageResolution \
-destination "platform=macOS" \
-only-testing:cmuxUITests/DisplayResolutionRegressionUITests \
test
test; then
exit 0
fi
if [ "$attempt" -eq 2 ]; then
echo "Display resolution UI regression failed after 2 attempts" >&2
exit 1
fi
echo "Attempt $attempt failed, retrying..."
pkill -x "cmux DEV" 2>/dev/null || true
sleep 3
done
- name: Run browser find focus UI regression
run: |

View file

@ -244,9 +244,21 @@ final class DisplayResolutionRegressionUITests: XCTestCase {
for (key, value) in launchEnvironment(targetDisplayID: targetDisplayID) {
app.launchEnvironment[key] = value
}
// On headless CI runners, XCUIApplication.launch() may fail to activate
// the app (reporting "Failed to activate application" as a test error).
// Temporarily allow continuation so we can retry activation manually.
continueAfterFailure = true
app.launch()
continueAfterFailure = false
launchedApp = app
guard ensureForegroundAfterLaunch(app, timeout: 15.0) else {
throw NSError(domain: "DisplayResolutionRegressionUITests", code: 2, userInfo: [
NSLocalizedDescriptionKey: "App failed to reach foreground. state=\(app.state.rawValue) diagnostics=\(loadDiagnostics() ?? [:])"
])
}
if !waitForAppLaunchDiagnostics(timeout: 12.0) {
throw NSError(domain: "DisplayResolutionRegressionUITests", code: 2, userInfo: [
NSLocalizedDescriptionKey: "App failed to write launch diagnostics. state=\(app.state.rawValue) diagnostics=\(loadDiagnostics() ?? [:])"
@ -254,6 +266,17 @@ final class DisplayResolutionRegressionUITests: XCTestCase {
}
}
private func ensureForegroundAfterLaunch(_ app: XCUIApplication, timeout: TimeInterval) -> Bool {
if app.wait(for: .runningForeground, timeout: timeout) {
return true
}
if app.state == .runningBackground {
app.activate()
return app.wait(for: .runningForeground, timeout: 6.0)
}
return false
}
private func launchEnvironment(targetDisplayID: String) -> [String: String] {
[
"CMUX_UI_TEST_MODE": "1",