From e7ab176b40d936653ea4311d3a79ee954ff2ba5b Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Thu, 11 Jan 2024 16:35:03 +0200 Subject: [PATCH] More integration test tweaks (#2321) * Improve integration test timings and alert handing * Add missing `receive(on: DispatchQueue.main` on the invites screen * Wait for photo library to load * Disable the preferForLoop swiftformat rule and fix a couple of new warnings * Delay invites screen snapshotting after dispatch main queue addition --- .swiftformat | 1 + .../Navigation/NavigationCoordinators.swift | 2 +- .../InvitesScreenViewModel.swift | 1 + .../InvitesScreen/View/InvitesScreen.swift | 1 + .../Services/Emojis/EmojiCategory.swift | 1 + IntegrationTests/Sources/Common.swift | 11 ++-- IntegrationTests/Sources/UserFlowTests.swift | 57 +++++++++++++++---- 7 files changed, 58 insertions(+), 16 deletions(-) diff --git a/.swiftformat b/.swiftformat index 2ad2ac657..4251bb1fe 100644 --- a/.swiftformat +++ b/.swiftformat @@ -4,6 +4,7 @@ --disable wrapMultiLineStatementBraces --disable hoistPatternLet +--disable preferForLoop --commas inline --ifdef no-indent diff --git a/ElementX/Sources/Application/Navigation/NavigationCoordinators.swift b/ElementX/Sources/Application/Navigation/NavigationCoordinators.swift index cc61371c7..5e5db1b73 100644 --- a/ElementX/Sources/Application/Navigation/NavigationCoordinators.swift +++ b/ElementX/Sources/Application/Navigation/NavigationCoordinators.swift @@ -176,7 +176,7 @@ class NavigationSplitCoordinator: CoordinatorProtocol, ObservableObject, CustomS case .insert: break case .remove(_, let module, _): - self.processCompactLayoutStackModuleRemoval(module) + processCompactLayoutStackModuleRemoval(module) } } } diff --git a/ElementX/Sources/Screens/InvitesScreen/InvitesScreenViewModel.swift b/ElementX/Sources/Screens/InvitesScreen/InvitesScreenViewModel.swift index c1ba7b246..cf33b2e7a 100644 --- a/ElementX/Sources/Screens/InvitesScreen/InvitesScreenViewModel.swift +++ b/ElementX/Sources/Screens/InvitesScreen/InvitesScreenViewModel.swift @@ -80,6 +80,7 @@ class InvitesScreenViewModel: InvitesScreenViewModelType, InvitesScreenViewModel inviteSummaryProvider.roomListPublisher .removeDuplicates() + .receive(on: DispatchQueue.main) .sink { [weak self] roomSummaries in guard let self else { return } diff --git a/ElementX/Sources/Screens/InvitesScreen/View/InvitesScreen.swift b/ElementX/Sources/Screens/InvitesScreen/View/InvitesScreen.swift index e9c799428..5808db50a 100644 --- a/ElementX/Sources/Screens/InvitesScreen/View/InvitesScreen.swift +++ b/ElementX/Sources/Screens/InvitesScreen/View/InvitesScreen.swift @@ -73,6 +73,7 @@ struct InvitesScreen_Previews: PreviewProvider, TestablePreview { NavigationView { InvitesScreen(context: InvitesScreenViewModel.someInvite.context) } + .snapshot(delay: 1.0) .previewDisplayName("Some Invite") } } diff --git a/ElementX/Sources/Services/Emojis/EmojiCategory.swift b/ElementX/Sources/Services/Emojis/EmojiCategory.swift index fe74184ae..6ae94eed0 100644 --- a/ElementX/Sources/Services/Emojis/EmojiCategory.swift +++ b/ElementX/Sources/Services/Emojis/EmojiCategory.swift @@ -15,6 +15,7 @@ // import Foundation + struct EmojiCategory: Equatable, Identifiable { let id: String let emojis: [EmojiItem] diff --git a/IntegrationTests/Sources/Common.swift b/IntegrationTests/Sources/Common.swift index 2b1a0821e..9c1bea4fc 100644 --- a/IntegrationTests/Sources/Common.swift +++ b/IntegrationTests/Sources/Common.swift @@ -23,8 +23,9 @@ extension XCUIApplication { XCTAssertTrue(getStartedButton.waitForExistence(timeout: 10.0)) getStartedButton.tap() + // Get started is network bound, wait for the change homeserver button for longer let changeHomeserverButton = buttons[A11yIdentifiers.serverConfirmationScreen.changeServer] - XCTAssertTrue(changeHomeserverButton.waitForExistence(timeout: 10.0)) + XCTAssertTrue(changeHomeserverButton.waitForExistence(timeout: 30.0)) changeHomeserverButton.tap() let homeserverTextField = textFields[A11yIdentifiers.changeServerScreen.server] @@ -36,7 +37,11 @@ extension XCUIApplication { XCTAssertTrue(confirmButton.waitForExistence(timeout: 10.0)) confirmButton.tap() - // Server cofirmation is network bound and might take a while + // Wait for server confirmation to finish + let doesNotExistPredicate = NSPredicate(format: "exists == 0") + currentTestCase.expectation(for: doesNotExistPredicate, evaluatedWith: confirmButton) + currentTestCase.waitForExpectations(timeout: 300.0) + let continueButton = buttons[A11yIdentifiers.serverConfirmationScreen.continue] XCTAssertTrue(continueButton.waitForExistence(timeout: 30.0)) continueButton.tap() @@ -58,7 +63,6 @@ extension XCUIApplication { nextButton.tap() // Wait for login to finish - let doesNotExistPredicate = NSPredicate(format: "exists == 0") currentTestCase.expectation(for: doesNotExistPredicate, evaluatedWith: usernameTextField) currentTestCase.waitForExpectations(timeout: 300.0) @@ -93,7 +97,6 @@ extension XCUIApplication { let message = staticTexts[A11yIdentifiers.migrationScreen.message] if message.waitForExistence(timeout: 10.0) { - let doesNotExistPredicate = NSPredicate(format: "exists == 0") currentTestCase.expectation(for: doesNotExistPredicate, evaluatedWith: message) currentTestCase.waitForExpectations(timeout: 300.0) } diff --git a/IntegrationTests/Sources/UserFlowTests.swift b/IntegrationTests/Sources/UserFlowTests.swift index 6e447ca5d..a268f2de6 100644 --- a/IntegrationTests/Sources/UserFlowTests.swift +++ b/IntegrationTests/Sources/UserFlowTests.swift @@ -36,7 +36,11 @@ class UserFlowTests: XCTestCase { XCTAssertTrue(firstRoom.waitForExistence(timeout: 10.0)) firstRoom.tap() - checkAttachmentsPicker() + checkPhotoSharing() + + checkDocumentSharing() + + checkLocationSharing() checkTimelineItemActionMenu() @@ -55,15 +59,7 @@ class UserFlowTests: XCTestCase { tapOnBackButton("All Chats") } - private func checkAttachmentsPicker() { - for identifier in [A11yIdentifiers.roomScreen.attachmentPickerPhotoLibrary, - A11yIdentifiers.roomScreen.attachmentPickerDocuments, - A11yIdentifiers.roomScreen.attachmentPickerLocation] { - tapOnMenu(A11yIdentifiers.roomScreen.composerToolbar.openComposeOptions) - tapOnButton(identifier) - tapOnButton("Cancel") - } - + private func checkPhotoSharing() { // Open attachments picker tapOnMenu(A11yIdentifiers.roomScreen.composerToolbar.openComposeOptions) @@ -71,7 +67,9 @@ class UserFlowTests: XCTestCase { tapOnButton(A11yIdentifiers.roomScreen.attachmentPickerPhotoLibrary) // Tap on the second image. First one is always broken on simulators. - app.scrollViews.images.element(boundBy: 1).tap() + let secondImage = app.scrollViews.images.element(boundBy: 1) + XCTAssertTrue(secondImage.waitForExistence(timeout: 10.0)) // Photo library takes a bit to load + secondImage.tap() // Cancel the upload flow tapOnButton("Cancel") @@ -79,6 +77,43 @@ class UserFlowTests: XCTestCase { sleep(2) // Wait for dismissal } + private func checkDocumentSharing() { + tapOnMenu(A11yIdentifiers.roomScreen.composerToolbar.openComposeOptions) + tapOnButton(A11yIdentifiers.roomScreen.attachmentPickerDocuments) + tapOnButton("Cancel") + + sleep(2) // Wait for dismissal + } + + private func checkLocationSharing() { + tapOnMenu(A11yIdentifiers.roomScreen.composerToolbar.openComposeOptions) + tapOnButton(A11yIdentifiers.roomScreen.attachmentPickerLocation) + + // The order of the alerts is a bit of a mistery so try twice + + allowLocationPermissionOnce() + + // Handle map loading errors (missing credentials) + let alertOkButton = app.alerts.firstMatch.buttons["OK"].firstMatch + if alertOkButton.waitForExistence(timeout: 10.0) { + alertOkButton.tap() + } + + allowLocationPermissionOnce() + + tapOnButton("Cancel") + + sleep(2) // Wait for dismissal + } + + private func allowLocationPermissionOnce() { + let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard") + let notificationAlertAllowButton = springboard.buttons["Allow Once"].firstMatch + if notificationAlertAllowButton.waitForExistence(timeout: 10.0) { + notificationAlertAllowButton.tap() + } + } + private func checkRoomCreation() { tapOnButton(A11yIdentifiers.homeScreen.startChat)