75 lines
2.8 KiB
Swift
75 lines
2.8 KiB
Swift
import Foundation
|
|
import XCTest
|
|
|
|
@MainActor
|
|
extension XCUIApplication {
|
|
|
|
/// Launch with a freshly-fetched pairing URL so the test starts from a
|
|
/// known paired state. Hits `/pair-qr` on the sidecar to obtain a
|
|
/// one-time-use token, then passes it to the app via launch args.
|
|
/// Fails the current test if the sidecar is unreachable.
|
|
func launchPaired(file: StaticString = #file, line: UInt = #line) {
|
|
guard let url = TestSidecar.freshPairURL() else {
|
|
XCTFail("Could not fetch fresh pair URL from sidecar — is it running?",
|
|
file: file, line: line)
|
|
return
|
|
}
|
|
launchArguments = ["--uitest", "--reset-state", "--pair-with-url", url]
|
|
launch()
|
|
}
|
|
|
|
/// Launch with state reset so the PairingFlowView is shown.
|
|
func launchUnpaired() {
|
|
launchArguments = ["--uitest", "--reset-state"]
|
|
launch()
|
|
}
|
|
|
|
/// Launch with a specific pairing URL (for the explicit deep-link test).
|
|
func launchWithPairing(url: String) {
|
|
launchArguments = ["--uitest", "--reset-state", "--pair-with-url", url]
|
|
launch()
|
|
}
|
|
|
|
/// Launch directly into the lock screen (faceid enabled + forced lock).
|
|
/// Resets state first so the test isn't polluted by previous runs.
|
|
func launchLocked() {
|
|
launchArguments = ["--uitest", "--reset-state", "--enable-faceid", "--force-lock"]
|
|
launch()
|
|
}
|
|
}
|
|
|
|
// MARK: - Sidecar helpers
|
|
|
|
enum TestSidecar {
|
|
static let baseURL = "http://10.13.37.2:17373"
|
|
static let bearer = "GeoZytsPPGwItCHRNu8EwoZGlHH5iUAx"
|
|
|
|
/// Synchronously fetch a fresh pairing URL from the sidecar.
|
|
static func freshPairURL() -> String? {
|
|
let url = URL(string: "\(baseURL)/pair-qr?token=\(bearer)&format=url")!
|
|
var result: String?
|
|
let sem = DispatchSemaphore(value: 0)
|
|
URLSession.shared.dataTask(with: url) { data, _, _ in
|
|
defer { sem.signal() }
|
|
guard let data = data,
|
|
let text = String(data: data, encoding: .utf8) else { return }
|
|
if let match = text.range(of: #"pi-remote://[^\s]+"#,
|
|
options: .regularExpression) {
|
|
result = String(text[match])
|
|
}
|
|
}.resume()
|
|
_ = sem.wait(timeout: .now() + 5)
|
|
return result
|
|
}
|
|
|
|
/// Delete a session via the sidecar REST API (best-effort, for cleanup).
|
|
static func deleteSession(_ id: String) {
|
|
var req = URLRequest(url: URL(string: "\(baseURL)/sessions/\(id)")!)
|
|
req.httpMethod = "DELETE"
|
|
req.setValue("Bearer \(bearer)", forHTTPHeaderField: "Authorization")
|
|
let sem = DispatchSemaphore(value: 0)
|
|
URLSession.shared.dataTask(with: req) { _, _, _ in sem.signal() }.resume()
|
|
_ = sem.wait(timeout: .now() + 5)
|
|
}
|
|
}
|