Ctrl K
ComunidadGuías…

EchoUITests/TerminalUITests.swift

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
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()
    }
}