I use special server to substitute real url server responses (like Swifter). I send bunch of url path and new substitution url to launchEnvironment before app launching:
func launchNewApp(serverManager: ServerManagerProtocol) -> XCUIApplication {
let app = XCUIApplication()
app.launchArguments += ["UI-TESTING"]
serverManager.routeInfo.forEach {
app.launchEnvironment[$0.key] = $0.value
}
app.launch()
return app
}
My test launch the app, into my app I substitute urls and my app get mocked server response:
extension URLRequest {
private var isUITestingLaunching: Bool {
ProcessInfo.processInfo.arguments.contains("UI-TESTING")
}
mutating func tryReplaceUITestRequest() {
#if DEBUG
if isUITestingLaunching,
let path = url?.path,
let substitutionuUrlString = ProcessInfo.processInfo.environment[path],
let substitutionuUrl = URL(string: substitutionuUrlString) {
url = substitutionuUrl
}
#endif
}
}
Now I desire to substitute mocked url in test runtime:
I set launchEnvironment and launch app
I analyze UI recieved from the data from mock response
I change may url in launchEnvironment
I do pull to refresh in app
I see new UI (because in new mock url response receive new data)
func testExample() throws {
// 1 launch app
let app = XCUIApplication()
app.launchArguments += ["UI-TESTING"]
app.launchEnvironment["HomeSceneStructureUrlPath"] = "http://localhost:9000/SomeUrlPath"
app.launch()
// 2 test UI
...
XCTAssertFalse(someElement.waitForExistence(timeout: 100))
// 3 change launchEnvironment
app.launchEnvironment["HomeSceneStructureUrlPath"] = "http://localhost:9000/OtherUrlPath"
// 4 do PULL TO REFRESH
let firstCell = app.tables["someTable"].cells.firstMatch
let start = firstCell.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 0))
let finish = firstCell.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 10))
start.press(forDuration: 0, thenDragTo: finish)
// 5 test updating UI
...
XCTAssertTrue(settingsButton.waitForExistence(timeout: 100))
}
But my step 3 doesn't work, I can't change launchEnvironment in test runtime. Do you have any ideas how this can be done? Or maybe there is another way to send the mock url from the Test target to the Project target? I will be grateful you for an answers.