EchoUITests/PhotoViewerUITests.swift
Rama main · réplica de lectura del repositorio original.
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()
}
}