Ctrl K
ComunidadGuías…

EchoUITests/PhotoViewerUITests.swift

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

Archivo original ↗Preguntar a KiBot
import XCTest

/// Pictures in the conversation: several are set out together, a tap opens the one tapped full
/// screen, a swipe goes to the next, and a pinch or a double tap zooms. Needs no server.
@MainActor
final class PhotoViewerUITests: XCTestCase {
    private func shot(_ name: String) {
        let attachment = XCTAttachment(screenshot: XCUIScreen.main.screenshot())
        attachment.name = name
        attachment.lifetime = .keepAlways
        add(attachment)
    }

    private func launch() -> XCUIApplication {
        continueAfterFailure = false
        let app = XCUIApplication()
        app.launchArguments = ["-echo.demoPhotos"] + XCUIApplication.straightToChat
        app.launch()
        XCTAssertTrue(app.staticTexts["Here are the 5 most recent photos from your library."].waitForExistence(timeout: 20), "The photo demo didn't open")
        return app
    }

    /// The viewer's "Photo 2 of 5", by what it says (it is found by name as "photo-count").
    private func says(_ words: String, in app: XCUIApplication) -> XCUIElement {
        app.staticTexts.matching(NSPredicate(format: "label == %@", words)).firstMatch
    }

    /// The picture on screen in the viewer. Its neighbors are kept ready beside it.
    private func picture(in app: XCUIApplication) -> XCUIElement {
        let all = app.descendants(matching: .any).matching(identifier: "photo")
        for index in 0 ..< all.count where all.element(boundBy: index).isHittable { return all.element(boundBy: index) }
        return all.firstMatch
    }

    func testSeveralPicturesOpenOnTheOneTappedAndSwipeToTheNext() {
        let app = launch()
        shot("pictures in the conversation")
        // The reply's five pictures are the last collage; the two that were sent come first.
        let second = app.descendants(matching: .any).matching(identifier: "photo-tile-2")
        XCTAssertEqual(second.count, 2, "Two messages have a second picture")
        let tile = second.element(boundBy: 1)
        XCTAssertEqual(tile.label, "Photo 2 of 5")
        tile.tap()

        let count = app.staticTexts["photo-count"]
        XCTAssertTrue(count.waitForExistence(timeout: 5), "The viewer didn't open")
        XCTAssertEqual(count.label, "Photo 2 of 5")
        // And it is the second picture that is on the screen, not only the count that says so.
        XCTAssertEqual(picture(in: app).label, "photo-2.jpg", "The viewer opened on another picture than the one tapped")
        shot("viewer, second of five")

        picture(in: app).swipeLeft()
        XCTAssertTrue(says("Photo 3 of 5", in: app).waitForExistence(timeout: 3),
                      "A swipe didn't go to the next picture: the viewer says “\(count.exists ? count.label : "nothing, it is gone")”")
        XCTAssertEqual(picture(in: app).label, "photo-3.jpg")
        picture(in: app).swipeRight()
        XCTAssertTrue(says("Photo 2 of 5", in: app).waitForExistence(timeout: 3),
                      "A swipe back didn't go to the picture before: the viewer says “\(count.exists ? count.label : "nothing, it is gone")”")
        picture(in: app).swipeRight()
        XCTAssertTrue(says("Photo 1 of 5", in: app).waitForExistence(timeout: 3),
                      "Swiping back didn't reach the first: the viewer says “\(count.exists ? count.label : "nothing, it is gone")”")
        XCTAssertEqual(picture(in: app).label, "photo-1.jpg")

        app.buttons["Close"].tap()
        XCTAssertTrue(count.waitForNonExistence(timeout: 5), "The viewer didn't close")

        // The fourth tile stands for the fifth picture too: it opens on the fourth, and the
        // fifth is a swipe on.
        let last = app.descendants(matching: .any).matching(identifier: "photo-tile-4").firstMatch
        XCTAssertEqual(last.label, "Photo 4 of 5, and 1 more")
        last.tap()
        XCTAssertTrue(says("Photo 4 of 5", in: app).waitForExistence(timeout: 5))
        picture(in: app).swipeLeft()
        XCTAssertTrue(says("Photo 5 of 5", in: app).waitForExistence(timeout: 3), "The picture without a tile isn't in the viewer")
        app.buttons["Close"].tap()
    }

    func testAPinchZoomsAndADoubleTapGoesBack() {
        let app = launch()
        app.descendants(matching: .any).matching(identifier: "photo-tile-1").element(boundBy: 1).tap()
        XCTAssertTrue(says("Photo 1 of 5", in: app).waitForExistence(timeout: 5), "The viewer didn't open")
        let shown = picture(in: app)
        XCTAssertEqual(shown.value as? String ?? "", "", "The picture opens whole")

        shown.pinch(withScale: 2.5, velocity: 2)
        let zoomed = NSPredicate(format: "value BEGINSWITH 'Zoomed in'")
        expectation(for: zoomed, evaluatedWith: picture(in: app))
        waitForExpectations(timeout: 5)
        XCTAssertTrue(says("Photo 1 of 5", in: app).exists, "The pinch closed the viewer or turned the page")
        shot("zoomed in")

        // Zoomed in, a drag moves about the picture and not on to the next one.
        picture(in: app).swipeLeft(velocity: .slow)
        XCTAssertTrue(says("Photo 1 of 5", in: app).exists, "A drag on a zoomed picture turned the page")

        picture(in: app).doubleTap()
        let whole = NSPredicate(format: "value == ''")
        expectation(for: whole, evaluatedWith: picture(in: app))
        waitForExpectations(timeout: 5)

        picture(in: app).doubleTap()
        expectation(for: zoomed, evaluatedWith: picture(in: app))
        waitForExpectations(timeout: 5)
        app.buttons["Close"].tap()
        XCTAssertTrue(says("Photo 1 of 5", in: app).waitForNonExistence(timeout: 5))
    }

    /// One picture on its own opens the same way, with nothing to count.
    func testASinglePictureZoomsToo() {
        let app = launch()
        let single = app.images["again-2.jpg"]
        XCTAssertTrue(single.waitForExistence(timeout: 5), "The reply's one picture isn't there")
        single.tap()
        let shown = picture(in: app)
        XCTAssertTrue(shown.waitForExistence(timeout: 5), "The viewer didn't open")
        XCTAssertFalse(app.staticTexts["photo-count"].exists)
        shown.pinch(withScale: 3, velocity: 2)
        expectation(for: NSPredicate(format: "value BEGINSWITH 'Zoomed in'"), evaluatedWith: picture(in: app))
        waitForExpectations(timeout: 5)
        app.buttons["Close"].tap()
    }
}