Fix UI test helper closure captures
This commit is contained in:
parent
60aab29e39
commit
b0d994c99f
4 changed files with 41 additions and 39 deletions
|
|
@ -98,7 +98,7 @@ final class BrowserOmnibarSuggestionsUITests: XCTestCase {
|
|||
// Note: example.com may redirect to example.org in some environments.
|
||||
XCTAssertTrue(
|
||||
waitForCondition(timeout: 8.0) {
|
||||
containsExampleDomain((omnibar.value as? String) ?? "")
|
||||
self.containsExampleDomain((omnibar.value as? String) ?? "")
|
||||
},
|
||||
"Expected omnibar to navigate to example.com after keyboard nav + Enter. value=\(String(describing: omnibar.value))"
|
||||
)
|
||||
|
|
@ -134,7 +134,7 @@ final class BrowserOmnibarSuggestionsUITests: XCTestCase {
|
|||
// Note: example.com may redirect to example.org in some environments.
|
||||
XCTAssertTrue(
|
||||
waitForCondition(timeout: 8.0) {
|
||||
containsExampleDomain((omnibar.value as? String) ?? "")
|
||||
self.containsExampleDomain((omnibar.value as? String) ?? "")
|
||||
},
|
||||
"Expected committed omnibar value to contain example.com or example.org. value=\(String(describing: omnibar.value))"
|
||||
)
|
||||
|
|
@ -328,7 +328,7 @@ final class BrowserOmnibarSuggestionsUITests: XCTestCase {
|
|||
|
||||
let loaded = waitForCondition(timeout: 8.0) {
|
||||
let value = ((omnibar.value as? String) ?? "").lowercased()
|
||||
return containsExampleDomain(value)
|
||||
return self.containsExampleDomain(value)
|
||||
}
|
||||
XCTAssertTrue(loaded, "Expected baseline navigation to load before Cmd+L fast-typing check.")
|
||||
|
||||
|
|
@ -642,7 +642,7 @@ final class BrowserOmnibarSuggestionsUITests: XCTestCase {
|
|||
|
||||
private func waitForSuggestionRowToBeSelected(_ row: XCUIElement, timeout: TimeInterval) -> Bool {
|
||||
waitForCondition(timeout: timeout) {
|
||||
isSuggestionRowSelected(row)
|
||||
self.isSuggestionRowSelected(row)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -973,14 +973,14 @@ final class BrowserPaneNavigationKeybindUITests: XCTestCase {
|
|||
|
||||
private func waitForData(keys: [String], timeout: TimeInterval) -> Bool {
|
||||
waitForCondition(timeout: timeout) {
|
||||
guard let data = loadData() else { return false }
|
||||
guard let data = self.loadData() else { return false }
|
||||
return keys.allSatisfy { data[$0] != nil }
|
||||
}
|
||||
}
|
||||
|
||||
private func waitForDataMatch(timeout: TimeInterval, predicate: ([String: String]) -> Bool) -> Bool {
|
||||
private func waitForDataMatch(timeout: TimeInterval, predicate: @escaping ([String: String]) -> Bool) -> Bool {
|
||||
waitForCondition(timeout: timeout) {
|
||||
guard let data = loadData() else { return false }
|
||||
guard let data = self.loadData() else { return false }
|
||||
return predicate(data)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,16 @@ import CoreGraphics
|
|||
import ImageIO
|
||||
import Darwin
|
||||
|
||||
private extension XCTestCase {
|
||||
func waitForCondition(timeout: TimeInterval, predicate: @escaping () -> Bool) -> Bool {
|
||||
let expectation = XCTNSPredicateExpectation(
|
||||
predicate: NSPredicate { _, _ in predicate() },
|
||||
object: nil
|
||||
)
|
||||
return XCTWaiter().wait(for: [expectation], timeout: timeout) == .completed
|
||||
}
|
||||
}
|
||||
|
||||
final class MenuKeyEquivalentRoutingUITests: XCTestCase {
|
||||
private var gotoSplitPath = ""
|
||||
private var keyequivPath = ""
|
||||
|
|
@ -127,21 +137,21 @@ final class MenuKeyEquivalentRoutingUITests: XCTestCase {
|
|||
|
||||
private func waitForGotoSplit(keys: [String], timeout: TimeInterval) -> Bool {
|
||||
waitForCondition(timeout: timeout) {
|
||||
guard let data = loadGotoSplit() else { return false }
|
||||
guard let data = self.loadGotoSplit() else { return false }
|
||||
return keys.allSatisfy { data[$0] != nil }
|
||||
}
|
||||
}
|
||||
|
||||
private func waitForGotoSplitMatch(timeout: TimeInterval, predicate: ([String: String]) -> Bool) -> Bool {
|
||||
private func waitForGotoSplitMatch(timeout: TimeInterval, predicate: @escaping ([String: String]) -> Bool) -> Bool {
|
||||
waitForCondition(timeout: timeout) {
|
||||
guard let data = loadGotoSplit() else { return false }
|
||||
guard let data = self.loadGotoSplit() else { return false }
|
||||
return predicate(data)
|
||||
}
|
||||
}
|
||||
|
||||
private func waitForKeyequivInt(key: String, toBeAtLeast expected: Int, timeout: TimeInterval) -> Bool {
|
||||
waitForCondition(timeout: timeout) {
|
||||
let value = loadKeyequiv()[key].flatMap(Int.init) ?? 0
|
||||
let value = self.loadKeyequiv()[key].flatMap(Int.init) ?? 0
|
||||
return value >= expected
|
||||
}
|
||||
}
|
||||
|
|
@ -798,14 +808,14 @@ final class SplitCloseRightBlankRegressionUITests: XCTestCase {
|
|||
|
||||
private func waitForData(keys: [String], timeout: TimeInterval) -> Bool {
|
||||
waitForCondition(timeout: timeout) {
|
||||
guard let data = loadData() else { return false }
|
||||
guard let data = self.loadData() else { return false }
|
||||
return keys.allSatisfy { data[$0] != nil }
|
||||
}
|
||||
}
|
||||
|
||||
private func waitForAnyData(timeout: TimeInterval) -> Bool {
|
||||
waitForCondition(timeout: timeout) {
|
||||
loadData() != nil
|
||||
self.loadData() != nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -813,7 +823,7 @@ final class SplitCloseRightBlankRegressionUITests: XCTestCase {
|
|||
var last: [String: String]?
|
||||
|
||||
_ = waitForCondition(timeout: timeout) {
|
||||
guard let data = loadData() else { return false }
|
||||
guard let data = self.loadData() else { return false }
|
||||
last = data
|
||||
|
||||
if let setupError = data["setupError"], !setupError.isEmpty {
|
||||
|
|
@ -866,24 +876,16 @@ final class SplitCloseRightBlankRegressionUITests: XCTestCase {
|
|||
|
||||
private func waitForSocketPong(timeout: TimeInterval) -> Bool {
|
||||
waitForCondition(timeout: timeout) {
|
||||
socketCommand("ping") == "PONG"
|
||||
self.socketCommand("ping") == "PONG"
|
||||
}
|
||||
}
|
||||
|
||||
private func waitForVisualDone(timeout: TimeInterval) -> Bool {
|
||||
waitForCondition(timeout: timeout) {
|
||||
loadData()?["visualDone"] == "1"
|
||||
self.loadData()?["visualDone"] == "1"
|
||||
}
|
||||
}
|
||||
|
||||
private func waitForCondition(timeout: TimeInterval, predicate: @escaping () -> Bool) -> Bool {
|
||||
let expectation = XCTNSPredicateExpectation(
|
||||
predicate: NSPredicate { _, _ in predicate() },
|
||||
object: nil
|
||||
)
|
||||
return XCTWaiter().wait(for: [expectation], timeout: timeout) == .completed
|
||||
}
|
||||
|
||||
private func socketCommand(_ cmd: String) -> String? {
|
||||
if socketClient == nil {
|
||||
socketClient = ControlSocketClient(path: socketPath)
|
||||
|
|
|
|||
|
|
@ -423,7 +423,7 @@ final class MultiWindowNotificationsUITests: XCTestCase {
|
|||
|
||||
private func waitForFocusChange(from token: String?, timeout: TimeInterval) -> Bool {
|
||||
waitForCondition(timeout: timeout) {
|
||||
guard let data = loadData(),
|
||||
guard let data = self.loadData(),
|
||||
let current = data["focusToken"],
|
||||
!current.isEmpty else {
|
||||
return false
|
||||
|
|
@ -434,14 +434,14 @@ final class MultiWindowNotificationsUITests: XCTestCase {
|
|||
|
||||
private func waitForData(keys: [String], timeout: TimeInterval) -> Bool {
|
||||
waitForCondition(timeout: timeout) {
|
||||
guard let data = loadData() else { return false }
|
||||
guard let data = self.loadData() else { return false }
|
||||
return keys.allSatisfy { (data[$0] ?? "").isEmpty == false }
|
||||
}
|
||||
}
|
||||
|
||||
private func waitForDataMatch(timeout: TimeInterval, predicate: ([String: String]) -> Bool) -> Bool {
|
||||
private func waitForDataMatch(timeout: TimeInterval, predicate: @escaping ([String: String]) -> Bool) -> Bool {
|
||||
waitForCondition(timeout: timeout) {
|
||||
guard let data = loadData() else { return false }
|
||||
guard let data = self.loadData() else { return false }
|
||||
return predicate(data)
|
||||
}
|
||||
}
|
||||
|
|
@ -449,7 +449,7 @@ final class MultiWindowNotificationsUITests: XCTestCase {
|
|||
private func waitForSocketPong(timeout: TimeInterval) -> String? {
|
||||
var lastResponse: String?
|
||||
_ = waitForCondition(timeout: timeout) {
|
||||
lastResponse = socketCommand("ping")
|
||||
lastResponse = self.socketCommand("ping")
|
||||
return lastResponse == "PONG"
|
||||
}
|
||||
return lastResponse == "PONG" ? "PONG" : (socketCommand("ping") ?? lastResponse)
|
||||
|
|
@ -457,7 +457,7 @@ final class MultiWindowNotificationsUITests: XCTestCase {
|
|||
|
||||
private func waitForTerminalFocus(surfaceId: String, timeout: TimeInterval) -> Bool {
|
||||
waitForCondition(timeout: timeout) {
|
||||
socketCommand("is_terminal_focused \(surfaceId)") == "true"
|
||||
self.socketCommand("is_terminal_focused \(surfaceId)") == "true"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -465,8 +465,8 @@ final class MultiWindowNotificationsUITests: XCTestCase {
|
|||
var lastStdout: String?
|
||||
var lastStderr: String?
|
||||
let didSucceed = waitForCondition(timeout: timeout) {
|
||||
let result = runCmuxCommand(
|
||||
socketPath: socketPath,
|
||||
let result = self.runCmuxCommand(
|
||||
socketPath: self.socketPath,
|
||||
arguments: ["ping"],
|
||||
responseTimeoutSeconds: 2.0
|
||||
)
|
||||
|
|
@ -481,8 +481,8 @@ final class MultiWindowNotificationsUITests: XCTestCase {
|
|||
if result.terminationStatus == 0, stdout == "PONG" {
|
||||
return true
|
||||
}
|
||||
if isSocketPermissionFailure(stderr),
|
||||
waitForSocketPong(timeout: 0.5) == "PONG" {
|
||||
if self.isSocketPermissionFailure(stderr),
|
||||
self.waitForSocketPong(timeout: 0.5) == "PONG" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -553,7 +553,7 @@ final class MultiWindowNotificationsUITests: XCTestCase {
|
|||
private func waitForSurfaceId(forWorkspaceId workspaceId: String, timeout: TimeInterval) -> String? {
|
||||
var surfaceId: String?
|
||||
_ = waitForCondition(timeout: timeout) {
|
||||
surfaceId = firstSurfaceId(forWorkspaceId: workspaceId)
|
||||
surfaceId = self.firstSurfaceId(forWorkspaceId: workspaceId)
|
||||
return surfaceId != nil
|
||||
}
|
||||
return surfaceId ?? firstSurfaceId(forWorkspaceId: workspaceId)
|
||||
|
|
@ -562,7 +562,7 @@ final class MultiWindowNotificationsUITests: XCTestCase {
|
|||
private func waitForSurfaceIdViaCLI(forWorkspaceId workspaceId: String, timeout: TimeInterval) -> String? {
|
||||
var surfaceId: String?
|
||||
_ = waitForCondition(timeout: timeout) {
|
||||
surfaceId = firstSurfaceIdViaCLI(forWorkspaceId: workspaceId)
|
||||
surfaceId = self.firstSurfaceIdViaCLI(forWorkspaceId: workspaceId)
|
||||
return surfaceId != nil
|
||||
}
|
||||
return surfaceId ?? firstSurfaceIdViaCLI(forWorkspaceId: workspaceId)
|
||||
|
|
@ -899,15 +899,15 @@ final class MultiWindowNotificationsUITests: XCTestCase {
|
|||
guard FileManager.default.fileExists(atPath: candidate) else { continue }
|
||||
// Primary candidate is the explicitly requested CMUX_SOCKET_PATH. If it responds,
|
||||
// prefer it even before workspace contents are fully initialized.
|
||||
if socketRespondsToPing(at: candidate) {
|
||||
if self.socketRespondsToPing(at: candidate) {
|
||||
resolvedPath = candidate
|
||||
return true
|
||||
}
|
||||
}
|
||||
for candidate in fallbackCandidates {
|
||||
guard FileManager.default.fileExists(atPath: candidate) else { continue }
|
||||
if socketRespondsToPing(at: candidate),
|
||||
socketMatchesRequiredWorkspace(candidate, workspaceId: requiredWorkspaceId) {
|
||||
if self.socketRespondsToPing(at: candidate),
|
||||
self.socketMatchesRequiredWorkspace(candidate, workspaceId: requiredWorkspaceId) {
|
||||
resolvedPath = candidate
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue