EchoUITests/TerminalUITests.swift
Rama main · réplica de lectura del repositorio original.
import XCTest
/// The terminal with the real app and a real OpenSSH server (`scripts/terminal-lab/lab.sh up`,
/// run with TEST_RUNNER_REDDE_TERMINAL_LAB and TEST_RUNNER_REDDE_TERMINAL_USER): Settings ›
/// Terminal takes the account, shows this iPhone's key (which the test puts in the lab's
/// authorized_keys, as a person would on their server), opens the terminal, asks to trust the
/// server, and a command typed runs. Skips without the lab.
@MainActor
final class TerminalUITests: XCTestCase {
private func keep(_ screenshot: XCUIScreenshot, as name: String) {
let attachment = XCTAttachment(screenshot: screenshot)
attachment.name = name
attachment.lifetime = .keepAlways
add(attachment)
}
/// Empties a field the way a person does: long-press, Select All, delete. (A run of delete
/// keys left a character behind in the numbers-only port field.)
private func clear(_ field: XCUIElement, in app: XCUIApplication) {
field.tap()
guard let old = field.value as? String, !old.isEmpty, old != field.placeholderValue else { return }
field.press(forDuration: 1.0)
let selectAll = app.menuItems["Select All"]
if selectAll.waitForExistence(timeout: 3) {
selectAll.tap()
field.typeText(XCUIKeyboardKey.delete.rawValue)
} else {
field.typeText(String(repeating: XCUIKeyboardKey.delete.rawValue, count: old.count + 30))
}
}
private func replace(_ field: XCUIElement, with text: String, in app: XCUIApplication) {
clear(field, in: app)
field.typeText(text)
XCTAssertEqual(field.value as? String, text, "the field didn't take what was typed")
}
func testSettingsKeyTrustAndACommand() throws {
continueAfterFailure = false
let env = ProcessInfo.processInfo.environment
guard let lab = env["REDDE_TERMINAL_LAB"], env["REDDE_TERMINAL_USER"] != nil else {
throw XCTSkip("No terminal lab (scripts/terminal-lab/lab.sh up, and TEST_RUNNER_REDDE_TERMINAL_LAB / _USER)")
}
let app = XCUIApplication()
app.launchArguments = XCUIApplication.straightToChat + ["-echo.screen", "settings"]
app.launch()
let row = app.buttons["Terminal"]
for _ in 0 ..< 10 where !(row.exists && row.isHittable) { app.swipeUp() }
XCTAssertTrue(row.waitForExistence(timeout: 10), "no Terminal row in Settings")
row.tap()
replace(app.textFields["hermes.example.ts.net"], with: "127.0.0.1", in: app)
replace(app.textFields["22"], with: "2222", in: app)
// With the user empty (an earlier run may have saved one), the form says so, and Open
// Terminal goes to the field instead of opening.
let user = app.textFields["required, such as hermes"]
clear(user, in: app)
sleep(1)
keep(app.screenshot(), as: "terminal-user-missing")
XCTAssertTrue(app.descendants(matching: .any).matching(NSPredicate(format: "label CONTAINS 'fill in the user'")).firstMatch
.waitForExistence(timeout: 5), "nothing says the user is missing")
app.buttons["Open Terminal"].tap()
XCTAssertFalse(app.alerts["Trust this server?"].waitForExistence(timeout: 3), "it tried to connect without a user")
XCTAssertFalse(app.buttons["Close"].exists, "the terminal opened without a user")
replace(user, with: env["REDDE_TERMINAL_USER"]!, in: app)
let key = app.staticTexts.containing(NSPredicate(format: "label BEGINSWITH 'ssh-ed25519 '")).firstMatch
XCTAssertTrue(key.waitForExistence(timeout: 10), "this iPhone's key isn't shown")
try (key.label + "\n").write(toFile: lab + "/authorized_keys", atomically: true, encoding: .utf8)
defer { try? "".write(toFile: lab + "/authorized_keys", atomically: true, encoding: .utf8) }
keep(app.screenshot(), as: "terminal-settings")
// A fresh trust each run: forget any key an earlier run trusted.
let forget = app.buttons["Forget This Server's Key"]
if forget.exists { forget.tap() }
app.buttons["Open Terminal"].tap()
let trust = app.alerts["Trust this server?"]
XCTAssertTrue(trust.waitForExistence(timeout: 20), "a new server wasn't asked about")
keep(app.screenshot(), as: "terminal-trust")
trust.buttons["Trust"].tap()
// The shell is up when the keyboard is (the terminal takes it); then a command.
sleep(4)
keep(app.screenshot(), as: "terminal-after-trust")
if !app.keyboards.firstMatch.waitForExistence(timeout: 6) {
app.scrollViews["Terminal"].firstMatch.tap()
}
XCTAssertTrue(app.keyboards.firstMatch.waitForExistence(timeout: 10), "the terminal didn't take the keyboard")
sleep(1)
app.typeText("echo redde-$((6*7)); stty size\n")
sleep(2)
keep(app.screenshot(), as: "terminal-command")
app.buttons["Close"].tap()
}
}