Timeline UI Tests (#380)

* Add signalling between UI tests and the app.

* Fix navigationStack on roomLayout screens and update screenshots

Co-authored-by: Stefan Ceriu <stefanc@matrix.org>
This commit is contained in:
Doug
2023-01-05 16:35:20 +00:00
committed by GitHub
parent 530ae336ab
commit 51e300642c
63 changed files with 597 additions and 79 deletions
+22 -2
View File
@@ -41,13 +41,21 @@ extension XCUIApplication {
/// Assert screenshot for a screen with the given identifier. Does not fail if a screenshot is newly created.
/// - Parameter identifier: Identifier of the UI test screen
func assertScreenshot(_ identifier: UITestScreenIdentifier, step: Int? = nil) {
/// - Parameter step: An optional integer that can be used to take multiple snapshots per test identifier.
/// - Parameter insets: Optional insets with which to crop the image by.
func assertScreenshot(_ identifier: UITestScreenIdentifier, step: Int? = nil, insets: UIEdgeInsets? = nil) {
var snapshotName = identifier.rawValue
if let step {
snapshotName += "-\(step)"
}
var snapshot = XCUIScreen.main.screenshot().image
if let insets {
snapshot = snapshot.inset(by: insets)
}
let failure = verifySnapshot(matching: XCUIScreen.main.screenshot().image,
let failure = verifySnapshot(matching: snapshot,
as: .image(precision: 0.99, perceptualPrecision: 0.98, scale: nil),
named: snapshotName,
testName: testName)
@@ -79,3 +87,15 @@ extension XCUIApplication {
UIDevice.current.systemVersion.replacingOccurrences(of: ".", with: "-")
}
}
private extension UIImage {
/// Adjusts the image by cropping it with the given edge insets.
func inset(by insets: UIEdgeInsets) -> UIImage {
let insetRect = CGRect(origin: .zero, size: size).inset(by: insets)
let renderer = UIGraphicsImageRenderer(size: insetRect.size)
return renderer.image { _ in
draw(at: CGPoint(x: -insets.left, y: -insets.top))
}
}
}
+115 -7
View File
@@ -47,19 +47,127 @@ class RoomScreenUITests: XCTestCase {
app.assertScreenshot(.roomSmallTimeline)
}
func testSmallTimelineWithIncomingAndPagination() {
func testSmallTimelineWithIncomingAndPagination() async throws {
let server = try UITestsSignalling.Server()
let app = Application.launch()
app.goToScreenWithIdentifier(.roomSmallTimelineIncomingAndSmallPagination)
// Wait for both the incoming message and the pagination chunk.
XCTAssert(app.staticTexts["Bob"].waitForExistence(timeout: 2))
XCTAssert(app.staticTexts["Helena"].waitForExistence(timeout: 2))
try await server.connect()
defer { server.disconnect() }
// When a back pagination occurs and an incoming message arrives.
try await performOperation(.incomingMessage, using: server)
try await performOperation(.paginate, using: server)
// The messages should still be bottom aligned after the new items are added.
// Then the 4 visible messages should stay aligned to the bottom.
app.assertScreenshot(.roomSmallTimelineIncomingAndSmallPagination)
}
func testSmallTimelineWithLargePagination() {
// To be implemented
func testSmallTimelineWithLargePagination() async throws {
let server = try UITestsSignalling.Server()
let app = Application.launch()
app.goToScreenWithIdentifier(.roomSmallTimelineLargePagination)
try await server.connect()
defer { server.disconnect() }
// When a large back pagination occurs.
try await performOperation(.paginate, using: server)
// The bottom of the timeline should remain visible with more items added above.
app.assertScreenshot(.roomSmallTimelineLargePagination)
}
func testTimelineLayoutInMiddle() async throws {
let server = try UITestsSignalling.Server()
let app = Application.launch()
app.goToScreenWithIdentifier(.roomLayoutMiddle)
try await server.connect()
defer { server.disconnect() }
// Given a timeline that is neither at the top nor the bottom.
app.tables.element.swipeDown()
try await Task.sleep(for: .milliseconds(500)) // Allow the table to settle
app.assertScreenshot(.roomLayoutMiddle, step: 0) // Assert initial state for comparison.
// When a back pagination occurs.
try await performOperation(.paginate, using: server)
// Then the UI should remain unchanged.
app.assertScreenshot(.roomLayoutMiddle, step: 0)
// When an incoming message arrives
try await performOperation(.incomingMessage, using: server)
// Then the UI should still remain unchanged.
app.assertScreenshot(.roomLayoutMiddle, step: 0)
// When the keyboard appears for the message composer.
try await tapMessageComposer(in: app)
// Then the timeline scroll offset should remain unchanged.
app.assertScreenshot(.roomLayoutMiddle, step: 1)
}
func testTimelineLayoutAtTop() async throws {
let server = try UITestsSignalling.Server()
let app = Application.launch()
app.goToScreenWithIdentifier(.roomLayoutTop)
try await server.connect()
defer { server.disconnect() }
// Given a timeline that is scrolled to the top.
while !app.staticTexts["Bacon ipsum dolor amet commodo incididunt ribeye dolore cupidatat short ribs."].isHittable {
app.tables.element.swipeDown()
}
let cropped = UIEdgeInsets(top: 150, left: 0, bottom: 0, right: 0) // Ignore the navigation bar and pagination indicator as these change.
app.assertScreenshot(.roomLayoutTop, insets: cropped) // Assert initial state for comparison.
// When a back pagination occurs.
try await performOperation(.paginate, using: server)
// Then the bottom of the timeline should remain unchanged (with new items having been added above).
app.assertScreenshot(.roomLayoutTop, insets: cropped)
}
func testTimelineLayoutAtBottom() async throws {
let server = try UITestsSignalling.Server()
let app = Application.launch()
app.goToScreenWithIdentifier(.roomLayoutBottom)
try await server.connect()
defer { server.disconnect() }
// When an incoming message arrives.
try await performOperation(.incomingMessage, using: server)
// Then the timeline should scroll down to reveal the message.
app.assertScreenshot(.roomLayoutBottom, step: 0)
// When the keyboard appears for the message composer.
try await tapMessageComposer(in: app)
// Then the timeline should still show the last message.
app.assertScreenshot(.roomLayoutBottom, step: 1)
}
// MARK: - Helper Methods
private func performOperation(_ operation: UITestsSignal, using server: UITestsSignalling.Server) async throws {
try await server.send(operation)
guard try await server.receive() == .success else { throw UITestsSignalError.unexpected }
try await Task.sleep(for: .milliseconds(500)) // Allow the timeline to update
}
private func tapMessageComposer(in app: XCUIApplication) async throws {
app.textViews.element.tap()
try await Task.sleep(for: .milliseconds(500)) // Allow the animations to complete
}
}
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9902bf55f027c729fd31b790d875699bf4a2e0f2852b9ceb2178c84bc8aca226
size 211684
oid sha256:32e747c2a8b7b7cd5aeee2f8e50f26ef2af0bf03d2fd4a89e25fad0104687fcf
size 211496
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3cb8e1d07e418e7a3fecd9b0699158b8fef40609771fef9666428015d056738c
size 305317
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:410e331dca5dbd99356ed345216f83288e231b808d4c3cbc05276a38dc5fba1f
size 304826
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6018b19cf7b412b3a74080a4b3b4bf35ce86a4ef187f9b4945f68b9744760dd6
size 314107
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5d507e3246043e67cc67873a83f9cb2a82e200f6debecfbf2cc4dd2e1fab86e9
size 321969
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6aef1da13173322dbd51e933df69733a48c02b89cfdf564c41ac1933c7a4f9b8
size 303249
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1fbf57e59072a7e06026a69a0858ed9f65a72e0bfa4fabdf4de6a28e1bc4b364
size 211052
oid sha256:85656b18c4ef17cf3a36aaef699fffdd34c43089749b5496b09f18fd3a520e60
size 210875
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:089f14916f6e386fb8ea620df10e74f8f24c703ccfba65b2c46c5f5888c79f3d
size 311767
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dd603c2e38d5281190788cfa06425a512587fbb49a32d5d895361533ab48419a
size 373824
oid sha256:9ba4ef4f768e1c44c0e058db23dc97e8a50516af2a2001fc5f433abf16aeac1a
size 366658
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8943c20d22d19e720eb949a47dce8ab304da3cdb6ae292dc007d38c62ee435a8
size 330436
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4312ba6002da73071187b871f6532f122bb6c4c3fdf3c9e7a93e9baffd27edfd
size 323699
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ff71a79bf353a284c2c8afa92ce2562a45c25c64486fb132d795a07bf0c4b6f0
size 335617
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a466639c4f320f4d684fe485255fd217d960665d8d9ea6cd1dd0e1f425b8cac0
size 335663
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:01a5fa9431bdfa0dffc6ed4ec5816db6eb923b8048f3af3124eb8701dad59ba1
size 283965
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:066c66947a2d47092dde8db56d885cd62127f24a817a06198e2ab0d29fa61857
size 371508
oid sha256:54301aeca9fdaea001bbabf7bd9d4624c820c6cca08bd75eaa3a66a3b88e271a
size 365082
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3295b6e8348a37998c95f72285ae0bfc5651ec3166a376c327f482a0baa1e93d
size 114678
oid sha256:94c4a7bb1f6ecf74120324ab118ab314f07663d0b01889581804afc6826a70d0
size 115882
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3f7192b4cffb7a9079b4a90a4dcb03d663cde46c0835eeb2481deead9d069d30
size 333980
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0a34acc9936b4fbff9aad17617ee77dd8c89356d652b2a7132f5bb7d20c4f715
size 210981
oid sha256:874b7aafe67bc385648ffdfce0d6fa8b75899dcd923de24a97b2d9a5246d4e9e
size 210847
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e293cc224e3c71f5339ca59f10db4450d96e025738c9117b18d41b57fe49a4d5
size 305117
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4580e0f596f44aece15bf7b8deb28b996e4c3f2132babd243d8896cdc67319f9
size 307638
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f5bf2982f09c57a980df0dc3d3dba3d3bafa67269704aa342a2dd5d169e9971b
size 313966
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d9ae251abae3f358ac0c2aae41ff55ff9eb209696d2dff43154679cfb2ba30ea
size 319312
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3e2192501b67459b5d4f85353976e7d3a7b5cf55d5b1f712b41c736579a919be
size 303063
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ec8c0bdbf78d2bd1019cd8319aed419fd729be3d8be566b729d171cc21adec8b
size 210340
oid sha256:e181e9ded4026b2ecfb48c7a2f9d3f4b5045c4d08608dbca45ad26cca831c160
size 210222
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c7482b45bcde59ec93b1a3f211d2f3187357b5326be5a70dce4a309c8204b6a2
size 311570
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f7322585bdb968fa0ad5244e5ca05401e7b32e3c27a0e3b1abb4f74f2cc736f9
size 372873
oid sha256:aa7c6d90c7f8021a1131a5c5db0f15aaf282548642cd97aeecac8574969771d3
size 366679
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ba8df321653a203447b6a48facc32c1b99a3167ed3f1c44019d06aa53b07db9b
size 330472
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:611e841427673aee43571e8b3079f9f84f9624b05efcc678f687ec496c9d66af
size 323568
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e17cbe7c08f8feddfeaec82d64d4c7ba001c91ef3ee5a38efd4e9eafe73e9d9b
size 335662
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:90f0175794dfebcc609105207e345e34c8d272cbd896f4bff0786ee4ecbf9c0c
size 335528
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e9b41ae6543ffcc994c2468f48641149d1932065600f94af29379d0fbb5d1297
size 283690
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:bf8edaf502cb0a8ea89699280a31ef2a8505b2107fb67d81975b9a63813bdd2e
size 370584
oid sha256:92e93f947f47be4f87e3c997f1e9103064771a78a95836dc38b24ed92431d581
size 365103
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a365ef80c8bce284dfddd840433afe9fa6b3d7eee8521da98e065777a6819530
size 114689
oid sha256:9b780d9c6cdd369717d2e0981bcbcc641a5091b3835d4b7ac6315d3486098c1b
size 115915
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0d6d8a1147d9d7292a3ef66658d6bece8dca96434ae7951f4400db0a081e4337
size 334023
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:aa4dc34fbb2b7412232fb048d1ddde465f949784bc4e9af0374d7cae490a5dd3
size 211181
oid sha256:64679be3305dcfd54950f6d00ea6de2d2156a9e91c09f1c2635f222f65cd21ac
size 211035
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e293cc224e3c71f5339ca59f10db4450d96e025738c9117b18d41b57fe49a4d5
size 305117
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6656cd40298881511962f8a3fd292b990b1c029f0cf4fc8f7050e5a4fba662aa
size 305022
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a8b8dfcebe6730d4e584bf757cf0e9599130d1d9b981e77bba9a25d2cb28bc5b
size 313911
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5d436eaaeb195d07a600fd8ae093b85bf616ca6f03bffbdf17d0f7284f2ed2c1
size 319464
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3e2192501b67459b5d4f85353976e7d3a7b5cf55d5b1f712b41c736579a919be
size 303063
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ca335bfdc0d02a56eb7584e9f18004361abcb0365c30733861bbd20b7a385b3b
size 210546
oid sha256:91060605f5e1166dc33eb3481845e60ac8c49da257395b37c513bf8477b3304d
size 210405
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c7482b45bcde59ec93b1a3f211d2f3187357b5326be5a70dce4a309c8204b6a2
size 311570
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:794a4b78bd5e5cda370bfac8168d19951ef5005c5d9267d372b9b55c9accfa4b
size 373232
oid sha256:aa7c6d90c7f8021a1131a5c5db0f15aaf282548642cd97aeecac8574969771d3
size 366679
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ba8df321653a203447b6a48facc32c1b99a3167ed3f1c44019d06aa53b07db9b
size 330472
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:611e841427673aee43571e8b3079f9f84f9624b05efcc678f687ec496c9d66af
size 323568
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e17cbe7c08f8feddfeaec82d64d4c7ba001c91ef3ee5a38efd4e9eafe73e9d9b
size 335662
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:90f0175794dfebcc609105207e345e34c8d272cbd896f4bff0786ee4ecbf9c0c
size 335528
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e9b41ae6543ffcc994c2468f48641149d1932065600f94af29379d0fbb5d1297
size 283690
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:39a5f3d31a13112058a4b4c3d0b83066ff1e3a546b65e82234970b76748812ed
size 370940
oid sha256:92e93f947f47be4f87e3c997f1e9103064771a78a95836dc38b24ed92431d581
size 365103
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:180aae2e7f67beb59cfee31788efaf7f0a6b4fef910956ba1db1ed22edbfdc7f
size 114685
oid sha256:9b780d9c6cdd369717d2e0981bcbcc641a5091b3835d4b7ac6315d3486098c1b
size 115915
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0d6d8a1147d9d7292a3ef66658d6bece8dca96434ae7951f4400db0a081e4337
size 334023