This repository has been archived on 2026-10-04. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
hope-voice-ios/UITests/VoiceUITests.swift
T

114 lines
5.6 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import XCTest
/// Real UI interactions with isolated preferences. These cover the client,
/// including offline recovery; they do not claim to verify the live backend.
final class VoiceUITests: XCTestCase {
private var app: XCUIApplication!
override func setUpWithError() throws {
continueAfterFailure = false
app = XCUIApplication()
app.launchArguments = ["--ui-testing", "--reset-ui-testing"]
}
func testWelcomeNavigationAndOfflineRecovery() {
app.launch()
XCTAssertTrue(app.buttons["Let’s talk"].waitForExistence(timeout: 10))
XCTAssertTrue(app.staticTexts["Your microphone turns on when you connect."].exists)
app.buttons["Type"].tap()
XCTAssertTrue(app.buttons["Start chatting"].exists)
XCTAssertTrue(app.staticTexts["Your microphone stays off."].exists)
app.buttons["Start chatting"].tap()
XCTAssertTrue(app.buttons["Try again"].waitForExistence(timeout: 20))
XCTAssertTrue(app.staticTexts["Couldn’t connect to Hope"].exists)
app.buttons["Check connection settings"].tap()
XCTAssertTrue(app.textFields["Server URL"].waitForExistence(timeout: 5))
capture("Offline recovery")
}
func testVoiceSelectionPersistsAndURLValidation() {
app.launch()
app.buttons["Settings"].tap()
app.buttons.matching(NSPredicate(format: "label CONTAINS 'Speaking voice'")).firstMatch.tap()
let voice = app.buttons.matching(NSPredicate(format: "label CONTAINS 'Jenny'")).firstMatch
XCTAssertTrue(voice.waitForExistence(timeout: 5))
voice.tap()
XCTAssertTrue(app.buttons.matching(NSPredicate(format: "label CONTAINS 'Speaking voice' AND label CONTAINS 'Jenny'")).firstMatch.exists)
let server = app.textFields["Server URL"]
server.tap()
let old = server.value as? String ?? ""
server.typeText(String(repeating: XCUIKeyboardKey.delete.rawValue, count: old.count) + "http://example.com")
app.buttons["Save server address"].tap()
XCTAssertTrue(app.staticTexts.matching(NSPredicate(format: "label CONTAINS 'must use https'")).firstMatch.waitForExistence(timeout: 5))
app.terminate()
app.launchArguments = ["--ui-testing"]
app.launch()
app.buttons["Settings"].tap()
XCTAssertTrue(app.buttons.matching(NSPredicate(format: "label CONTAINS 'Speaking voice' AND label CONTAINS 'Jenny'")).firstMatch.waitForExistence(timeout: 5))
XCTAssertEqual(app.textFields["Server URL"].value as? String, "https://127.0.0.1:1")
}
func testMusicSearchAndStationValidation() {
app.launch()
app.tabBars.buttons["Music"].tap()
XCTAssertTrue(app.buttons["Add radio station"].waitForExistence(timeout: 5))
XCTAssertTrue(app.staticTexts["Music server unavailable"].waitForExistence(timeout: 10))
app.segmentedControls.buttons["Search"].tap()
let query = app.textFields["Song, artist, lyrics…"]
query.tap()
query.typeText("Piano")
app.buttons["music.search"].tap()
XCTAssertTrue(app.staticTexts.matching(NSPredicate(format: "label CONTAINS 'connect to the server'")).firstMatch.waitForExistence(timeout: 15))
app.buttons["Add radio station"].tap()
let url = app.textFields["Audio stream URL"]
XCTAssertTrue(url.waitForExistence(timeout: 5))
url.tap()
url.typeText("not-a-url")
app.buttons["Add station"].tap()
XCTAssertTrue(app.staticTexts["Enter a complete http:// or https:// audio stream address."].exists)
app.buttons["Cancel"].tap()
XCTAssertTrue(app.buttons["Add radio station"].exists)
capture("Music search")
}
func testTranscriptClearConfirmationAndActivityDetails() {
app.launchArguments.append("--ui-fixtures")
app.launch()
XCTAssertTrue(app.staticTexts["Help me plan a quiet weekend."].waitForExistence(timeout: 10))
app.buttons["Conversation options"].tap()
app.buttons["Clear conversation"].tap()
app.buttons["Cancel"].tap()
XCTAssertTrue(app.staticTexts["Help me plan a quiet weekend."].exists)
app.buttons["Conversation options"].tap()
app.buttons["Clear conversation"].tap()
app.buttons["Clear conversation"].tap()
XCTAssertTrue(app.buttons["Let’s talk"].exists)
XCTAssertFalse(app.staticTexts["Help me plan a quiet weekend."].exists)
app.tabBars.buttons["Activity"].tap()
XCTAssertTrue(app.staticTexts["Needs attention"].waitForExistence(timeout: 5))
XCTAssertTrue(app.staticTexts["Search backend timed out after 30s"].exists)
app.buttons["1 progress updates"].tap()
XCTAssertTrue(app.staticTexts["Fetching benchmark articles…"].exists)
capture("Activity details")
}
func testLargeTypeNavigation() {
app.launchArguments += ["-UIPreferredContentSizeCategoryName", "UICTContentSizeCategoryAccessibilityXXXL"]
app.launch()
XCTAssertTrue(app.buttons["Let’s talk"].waitForExistence(timeout: 10))
XCTAssertTrue(app.buttons["Let’s talk"].isHittable)
app.tabBars.buttons["Activity"].tap()
XCTAssertTrue(app.staticTexts["A little help, in the background"].waitForExistence(timeout: 5))
app.buttons["Settings"].tap()
XCTAssertTrue(app.navigationBars["Settings"].exists)
capture("Accessibility text size")
}
private func capture(_ name: String) {
let attachment = XCTAttachment(screenshot: app.screenshot())
attachment.name = name
attachment.lifetime = .keepAlways
add(attachment)
}
}