From 0ed69d564991ca338e95cb3a781c8c876b794fed Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Thu, 20 Apr 2023 15:54:41 +0300 Subject: [PATCH] Add integration tests support for password saving, notifications and the analytics screen --- .../Other/AccessibilityIdentifiers.swift | 29 ++++++---- .../Other/Extensions/XCUIElement.swift | 9 ++++ .../View/AnalyticsPrompt.swift | 3 ++ IntegrationTests/Sources/LoginTests.swift | 53 ++++++++++++++----- 4 files changed, 70 insertions(+), 24 deletions(-) diff --git a/ElementX/Sources/Other/AccessibilityIdentifiers.swift b/ElementX/Sources/Other/AccessibilityIdentifiers.swift index 32e25fd44..cffe931f0 100644 --- a/ElementX/Sources/Other/AccessibilityIdentifiers.swift +++ b/ElementX/Sources/Other/AccessibilityIdentifiers.swift @@ -17,6 +17,7 @@ import Foundation struct A11yIdentifiers { + static let analyticsPromptScreen = AnalyticsPromptScreen() static let bugReportScreen = BugReportScreen() static let changeServerScreen = ChangeServer() static let homeScreen = HomeScreen() @@ -30,6 +31,12 @@ struct A11yIdentifiers { static let startChatScreen = StartChatScreen() static let roomMemberDetailsScreen = RoomMemberDetailsScreen() static let invitesScreen = InvitesScreen() + + struct AnalyticsPromptScreen { + let title = "analytics_prompt-title" + let enable = "analytics_prompt-enable" + let notNow = "analytics_prompt-not_now" + } struct BugReportScreen { let report = "bug_report-report" @@ -54,6 +61,12 @@ struct A11yIdentifiers { "home_screen-room_name:\(name)" } } + + struct InvitesScreen { + let noInvites = "invites-no_invites" + let accept = "invites-accept" + let decline = "invites-decline" + } struct LoginScreen { let emailUsername = "login-email_username" @@ -84,6 +97,11 @@ struct A11yIdentifiers { let people = "room_details-people" } + struct RoomMemberDetailsScreen { + let ignore = "room_member_details-ignore" + let unignore = "room_member_details-unignore" + } + struct SessionVerificationScreen { let requestVerification = "session_verification-request_verification" let startSasVerification = "session_verification-start_sas_verification" @@ -110,15 +128,4 @@ struct A11yIdentifiers { let inviteFriends = "start_chat-invite_friends" let searchNoResults = "start_chat-search_no_results" } - - struct RoomMemberDetailsScreen { - let ignore = "room_member_details-ignore" - let unignore = "room_member_details-unignore" - } - - struct InvitesScreen { - let noInvites = "invites-no_invites" - let accept = "invites-accept" - let decline = "invites-decline" - } } diff --git a/ElementX/Sources/Other/Extensions/XCUIElement.swift b/ElementX/Sources/Other/Extensions/XCUIElement.swift index 41a9f769f..347b7528b 100644 --- a/ElementX/Sources/Other/Extensions/XCUIElement.swift +++ b/ElementX/Sources/Other/Extensions/XCUIElement.swift @@ -32,4 +32,13 @@ extension XCUIElement { typeText(String(character)) } } + + func forceTap() { + if isHittable { + tap() + } else { + let coordinate: XCUICoordinate = coordinate(withNormalizedOffset: .init(dx: 0.0, dy: 0.0)) + coordinate.tap() + } + } } diff --git a/ElementX/Sources/Screens/AnalyticsPrompt/View/AnalyticsPrompt.swift b/ElementX/Sources/Screens/AnalyticsPrompt/View/AnalyticsPrompt.swift index 0079bbcb7..40b879511 100644 --- a/ElementX/Sources/Screens/AnalyticsPrompt/View/AnalyticsPrompt.swift +++ b/ElementX/Sources/Screens/AnalyticsPrompt/View/AnalyticsPrompt.swift @@ -64,6 +64,7 @@ struct AnalyticsPrompt: View { .multilineTextAlignment(.center) .foregroundColor(.element.primaryContent) .padding(.bottom, 2) + .accessibilityIdentifier(A11yIdentifiers.analyticsPromptScreen.title) Text(context.viewState.strings.optInContent) .font(.element.body) @@ -100,12 +101,14 @@ struct AnalyticsPrompt: View { .font(.element.bodyBold) } .buttonStyle(.elementAction(.xLarge)) + .accessibilityIdentifier(A11yIdentifiers.analyticsPromptScreen.enable) Button { context.send(viewAction: .disable) } label: { Text(L10n.actionNotNow) .font(.element.bodyBold) .padding(12) } + .accessibilityIdentifier(A11yIdentifiers.analyticsPromptScreen.notNow) } } } diff --git a/IntegrationTests/Sources/LoginTests.swift b/IntegrationTests/Sources/LoginTests.swift index 47b1103e1..4003af445 100644 --- a/IntegrationTests/Sources/LoginTests.swift +++ b/IntegrationTests/Sources/LoginTests.swift @@ -37,53 +37,80 @@ class LoginTests: XCTestCase { private func runLoginLogoutFlow() { let app = Application.launch() - + let getStartedButton = app.buttons[A11yIdentifiers.onboardingScreen.signIn] - XCTAssertTrue(getStartedButton.waitForExistence(timeout: 5.0)) + XCTAssertTrue(getStartedButton.waitForExistence(timeout: 1.0)) getStartedButton.tap() let editHomeserverButton = app.buttons[A11yIdentifiers.loginScreen.changeServer] - XCTAssertTrue(editHomeserverButton.waitForExistence(timeout: 5.0)) + XCTAssertTrue(editHomeserverButton.waitForExistence(timeout: 1.0)) editHomeserverButton.tap() let homeserverTextField = app.textFields[A11yIdentifiers.changeServerScreen.server] - XCTAssertTrue(homeserverTextField.waitForExistence(timeout: 5.0)) + XCTAssertTrue(homeserverTextField.waitForExistence(timeout: 1.0)) homeserverTextField.clearAndTypeText(app.homeserver) let confirmButton = app.buttons[A11yIdentifiers.changeServerScreen.continue] - XCTAssertTrue(confirmButton.waitForExistence(timeout: 5.0)) + XCTAssertTrue(confirmButton.waitForExistence(timeout: 1.0)) confirmButton.tap() let usernameTextField = app.textFields[A11yIdentifiers.loginScreen.emailUsername] - XCTAssertTrue(usernameTextField.waitForExistence(timeout: 5.0)) + XCTAssertTrue(usernameTextField.waitForExistence(timeout: 1.0)) usernameTextField.clearAndTypeText(app.username) let passwordTextField = app.secureTextFields[A11yIdentifiers.loginScreen.password] - XCTAssertTrue(passwordTextField.waitForExistence(timeout: 5.0)) + XCTAssertTrue(passwordTextField.waitForExistence(timeout: 1.0)) passwordTextField.clearAndTypeText(app.password) let nextButton = app.buttons[A11yIdentifiers.loginScreen.continue] - XCTAssertTrue(nextButton.waitForExistence(timeout: 5.0)) + XCTAssertTrue(nextButton.waitForExistence(timeout: 1.0)) XCTAssertTrue(nextButton.isEnabled) nextButton.tap() + // Wait for login to finish + let doesNotExistPredicate = NSPredicate(format: "exists == 0") + expectation(for: doesNotExistPredicate, evaluatedWith: nextButton) + waitForExpectations(timeout: expectedDuration) + + // Handle save password sheet + let savePasswordButton = app.buttons["Save Password"] + if savePasswordButton.waitForExistence(timeout: 1.0) { + savePasswordButton.tap() + } + + // Handle analytics prompt screen + if app.staticTexts[A11yIdentifiers.analyticsPromptScreen.title].waitForExistence(timeout: 1.0) { + let enableButton = app.buttons[A11yIdentifiers.analyticsPromptScreen.enable] + XCTAssertTrue(enableButton.waitForExistence(timeout: 1.0)) + enableButton.tap() + } + + // Handle the notifications permission alert https://stackoverflow.com/a/58171074/730924 + let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard") + let alertAllowButton = springboard.buttons.element(boundBy: 1) + if alertAllowButton.waitForExistence(timeout: 1.0) { + alertAllowButton.tap() + } + let profileButton = app.buttons[A11yIdentifiers.homeScreen.userAvatar] - XCTAssertTrue(profileButton.waitForExistence(timeout: expectedDuration)) - profileButton.tap() + XCTAssertTrue(profileButton.waitForExistence(timeout: 1.0)) + + // `Failed to scroll to visible (by AX action) Button` https://stackoverflow.com/a/33534187/730924 + profileButton.forceTap() let menuLogoutButton = app.buttons["Sign out"] - XCTAssertTrue(menuLogoutButton.waitForExistence(timeout: 5.0)) + XCTAssertTrue(menuLogoutButton.waitForExistence(timeout: 1.0)) menuLogoutButton.tap() let alertLogoutButton = app.buttons["Sign out"] - XCTAssertTrue(alertLogoutButton.waitForExistence(timeout: 5.0)) + XCTAssertTrue(alertLogoutButton.waitForExistence(timeout: 1.0)) alertLogoutButton.tap() - XCTAssertTrue(getStartedButton.waitForExistence(timeout: 5.0)) + XCTAssertTrue(getStartedButton.waitForExistence(timeout: 1.0)) } }