Publish socket health into notify focus UI test
This commit is contained in:
parent
69cfce9596
commit
ee899042ca
2 changed files with 94 additions and 5 deletions
|
|
@ -5725,10 +5725,60 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
|
|||
"expectedLatestWindowId": window1.windowId.uuidString,
|
||||
"expectedLatestTabId": tabId1.uuidString,
|
||||
], at: path)
|
||||
self.publishMultiWindowNotificationSocketStateIfNeeded(at: path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func publishMultiWindowNotificationSocketStateIfNeeded(at path: String) {
|
||||
let env = ProcessInfo.processInfo.environment
|
||||
guard env["CMUX_UI_TEST_SOCKET_SANITY"] == "1" else { return }
|
||||
|
||||
guard let config = socketListenerConfigurationIfEnabled() else {
|
||||
writeMultiWindowNotificationTestData([
|
||||
"socketExpectedPath": env["CMUX_SOCKET_PATH"] ?? "",
|
||||
"socketMode": "off",
|
||||
"socketReady": "0",
|
||||
"socketIsRunning": "0",
|
||||
"socketAcceptLoopAlive": "0",
|
||||
"socketPathMatches": "0",
|
||||
"socketPathExists": "0",
|
||||
"socketFailureSignals": "socket_disabled",
|
||||
], at: path)
|
||||
return
|
||||
}
|
||||
|
||||
writeMultiWindowNotificationTestData([
|
||||
"socketExpectedPath": config.path,
|
||||
"socketMode": config.mode.rawValue,
|
||||
"socketReady": "pending",
|
||||
], at: path)
|
||||
|
||||
restartSocketListenerIfEnabled(source: "uiTest.multiWindowNotifications.setup")
|
||||
|
||||
let deadline = Date().addingTimeInterval(12.0)
|
||||
func publish() {
|
||||
let health = TerminalController.shared.socketListenerHealth(expectedSocketPath: config.path)
|
||||
let isTimedOut = Date() >= deadline
|
||||
writeMultiWindowNotificationTestData([
|
||||
"socketExpectedPath": config.path,
|
||||
"socketMode": config.mode.rawValue,
|
||||
"socketReady": health.isHealthy ? "1" : (isTimedOut ? "0" : "pending"),
|
||||
"socketIsRunning": health.isRunning ? "1" : "0",
|
||||
"socketAcceptLoopAlive": health.acceptLoopAlive ? "1" : "0",
|
||||
"socketPathMatches": health.socketPathMatches ? "1" : "0",
|
||||
"socketPathExists": health.socketPathExists ? "1" : "0",
|
||||
"socketFailureSignals": health.failureSignals.joined(separator: ","),
|
||||
], at: path)
|
||||
guard !health.isHealthy, !isTimedOut else { return }
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
|
||||
publish()
|
||||
}
|
||||
}
|
||||
|
||||
publish()
|
||||
}
|
||||
|
||||
private func writeMultiWindowNotificationTestData(_ updates: [String: String], at path: String) {
|
||||
var payload = loadMultiWindowNotificationTestData(at: path)
|
||||
for (key, value) in updates {
|
||||
|
|
|
|||
|
|
@ -207,19 +207,44 @@ final class MultiWindowNotificationsUITests: XCTestCase {
|
|||
"Expected app to launch for notify focus regression test. state=\(app.state.rawValue)"
|
||||
)
|
||||
XCTAssertTrue(
|
||||
waitForData(keys: ["tabId2"], timeout: 15.0),
|
||||
"Expected multi-window notification setup data"
|
||||
waitForDataMatch(timeout: 20.0) { data in
|
||||
let tabId2 = data["tabId2"] ?? ""
|
||||
let socketReady = data["socketReady"] ?? ""
|
||||
return !tabId2.isEmpty && !socketReady.isEmpty && socketReady != "pending"
|
||||
},
|
||||
"Expected multi-window notification setup data and socket readiness"
|
||||
)
|
||||
|
||||
guard let tabId2 = loadData()?["tabId2"], !tabId2.isEmpty else {
|
||||
guard let setup = loadData() else {
|
||||
XCTFail("Missing setup data")
|
||||
return
|
||||
}
|
||||
guard let tabId2 = setup["tabId2"], !tabId2.isEmpty else {
|
||||
XCTFail("Missing setup workspace id")
|
||||
return
|
||||
}
|
||||
if let expectedSocketPath = setup["socketExpectedPath"], !expectedSocketPath.isEmpty {
|
||||
socketPath = expectedSocketPath
|
||||
}
|
||||
if setup["socketReady"] != "1" {
|
||||
XCTFail(
|
||||
"Control socket unavailable in this test environment. expected=\(socketPath) " +
|
||||
"mode=\(setup["socketMode"] ?? "") running=\(setup["socketIsRunning"] ?? "") " +
|
||||
"acceptLoopAlive=\(setup["socketAcceptLoopAlive"] ?? "") pathMatches=\(setup["socketPathMatches"] ?? "") " +
|
||||
"pathExists=\(setup["socketPathExists"] ?? "") signals=\(setup["socketFailureSignals"] ?? "")"
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
XCTAssertTrue(waitForWindowCount(atLeast: 2, app: app, timeout: 6.0))
|
||||
|
||||
guard let resolvedPath = resolveSocketPath(timeout: 20.0, requiredWorkspaceId: tabId2) else {
|
||||
XCTFail("Control socket unavailable in this test environment. requested=\(socketPath)")
|
||||
guard let resolvedPath = resolveSocketPath(timeout: 5.0, requiredWorkspaceId: tabId2) else {
|
||||
XCTFail(
|
||||
"Control socket unavailable in this test environment. requested=\(socketPath) " +
|
||||
"mode=\(setup["socketMode"] ?? "") running=\(setup["socketIsRunning"] ?? "") " +
|
||||
"acceptLoopAlive=\(setup["socketAcceptLoopAlive"] ?? "") pathMatches=\(setup["socketPathMatches"] ?? "") " +
|
||||
"pathExists=\(setup["socketPathExists"] ?? "") signals=\(setup["socketFailureSignals"] ?? "")"
|
||||
)
|
||||
return
|
||||
}
|
||||
socketPath = resolvedPath
|
||||
|
|
@ -342,6 +367,20 @@ final class MultiWindowNotificationsUITests: XCTestCase {
|
|||
return false
|
||||
}
|
||||
|
||||
private func waitForDataMatch(timeout: TimeInterval, predicate: ([String: String]) -> Bool) -> Bool {
|
||||
let deadline = Date().addingTimeInterval(timeout)
|
||||
while Date() < deadline {
|
||||
if let data = loadData(), predicate(data) {
|
||||
return true
|
||||
}
|
||||
RunLoop.current.run(until: Date().addingTimeInterval(0.05))
|
||||
}
|
||||
if let data = loadData(), predicate(data) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private func waitForSocketPong(timeout: TimeInterval) -> String? {
|
||||
let deadline = Date().addingTimeInterval(timeout)
|
||||
var lastResponse: String?
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue