Ctrl K
ComunidadGuías…

EchoUITests/TranscriptJumpUITests.swift

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

Archivo original ↗Preguntar a KiBot
import XCTest

/// "Jump to latest" has to bring back the newest message after fast flings. XCUITest waits
/// for the list to settle before each tap, so a tap during momentum can't be simulated here;
/// these cover what broke it: the button vanishing mid-fling and long jumps landing short.
@MainActor
final class TranscriptJumpUITests: XCTestCase {
    private func launchLongDemo() -> XCUIApplication {
        continueAfterFailure = false
        let app = XCUIApplication()
        // Launch arguments land in UserDefaults' argument domain: skip setup, stay on the transcript.
        app.launchArguments = ["-echo.demoLong"] + XCUIApplication.chatsSection + XCUIApplication.straightToChat
        app.launch()
        XCTAssertTrue(app.staticTexts["End of the long demo."].waitForExistence(timeout: 15), "The long demo didn't open at its end")
        return app
    }

    /// Opened from a reply's notification: at the reply's first line, not its end (GitHub #63),
    /// with Jump to latest for the rest.
    func testOpenedFromAReplyStartsAtItsTop() {
        continueAfterFailure = false
        let app = XCUIApplication()
        app.launchArguments = ["-echo.demoHeavy", "3", "-echo.fromReply"] + XCUIApplication.chatsSection + XCUIApplication.straightToChat
        app.launch()
        let jump = app.buttons["Jump to the newest message"]
        XCTAssertTrue(jump.waitForExistence(timeout: 15), "It opened at the end of the reply")
        let asked = app.staticTexts.matching(NSPredicate(format: "label BEGINSWITH 'Turn 3'")).firstMatch
        XCTAssertTrue(asked.exists && asked.frame.maxY < app.frame.midY, "The question the reply answers isn't just above it")
    }

    func testJumpToLatestReachesTheEndAtRest() {
        let app = launchLongDemo()
        let end = app.staticTexts["End of the long demo."]
        let transcript = app.scrollViews.firstMatch
        transcript.swipeDown(velocity: .fast)
        transcript.swipeDown(velocity: .fast)
        let jump = app.buttons["Jump to the newest message"]
        XCTAssertTrue(jump.waitForExistence(timeout: 5), "No Jump to latest after scrolling up")
        jump.tap()
        XCTAssertTrue(end.waitForExistence(timeout: 5), "The arrow didn't bring back the newest message")
        XCTAssertTrue(end.isHittable, "The newest message exists but isn't on screen")
    }

    func testJumpToLatestReachesTheEndAfterLongFlings() {
        let app = launchLongDemo()
        let end = app.staticTexts["End of the long demo."]
        let transcript = app.scrollViews.firstMatch

        // Read back up the transcript so the arrow appears.
        transcript.swipeDown(velocity: .fast)
        transcript.swipeDown(velocity: .fast)
        let jump = app.buttons["Jump to the newest message"]
        XCTAssertTrue(jump.waitForExistence(timeout: 5), "No Jump to latest after scrolling up")
        // A screen point captured earlier, so the tap goes where the arrow was even if it vanished.
        let frame = jump.frame
        let target = app.coordinate(withNormalizedOffset: .zero).withOffset(CGVector(dx: frame.midX, dy: frame.midY))

        // Fling far up the transcript, then hit the arrow.
        transcript.swipeDown(velocity: 3000)
        target.tap()

        XCTAssertTrue(end.waitForExistence(timeout: 5), "The arrow didn't bring back the newest message")
        XCTAssertTrue(end.isHittable, "The newest message exists but isn't on screen")
    }

    /// Scrolled back to the end by hand, the pill has nothing left to offer and goes.
    func testJumpToLatestGoesOnceTheEndIsReachedByHand() {
        let app = launchLongDemo()
        let end = app.staticTexts["End of the long demo."]
        let transcript = app.scrollViews.firstMatch
        transcript.swipeDown(velocity: .fast)
        let jump = app.buttons["Jump to the newest message"]
        XCTAssertTrue(jump.waitForExistence(timeout: 5), "No Jump to latest after scrolling up")

        for _ in 0 ..< 6 where !end.isHittable { transcript.swipeUp(velocity: .fast) }
        XCTAssertTrue(end.isHittable, "Swiping didn't reach the end")
        XCTAssertTrue(jump.waitForNonExistence(timeout: 3), "Jump to latest is still there at the end")

        // A touch on the transcript at its end doesn't bring it back.
        transcript.swipeUp(velocity: .slow)
        XCTAssertFalse(jump.exists, "A swipe at the end brought Jump to latest back")
    }
}