From 76c5693a592d2e68eb70c51e5e3893179947302f Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Fri, 25 Aug 2023 11:49:00 +0300 Subject: [PATCH] Split up the tests into performance tests that are measured, and user flow tests that access more screens and aren't --- ElementX.xcodeproj/project.pbxproj | 16 +- IntegrationTests/Sources/Common.swift | 135 ++++++++++++ IntegrationTests/Sources/LoginTests.swift | 200 ------------------ .../Sources/PerformanceTests.swift | 55 +++++ IntegrationTests/Sources/UserFlowTests.swift | 77 +++++++ 5 files changed, 279 insertions(+), 204 deletions(-) create mode 100644 IntegrationTests/Sources/Common.swift delete mode 100644 IntegrationTests/Sources/LoginTests.swift create mode 100644 IntegrationTests/Sources/PerformanceTests.swift create mode 100644 IntegrationTests/Sources/UserFlowTests.swift diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index ed3a5b2e1..daa9984e0 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -26,7 +26,7 @@ 06B55882911B4BF5B14E9851 /* URL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 227AC5D71A4CE43512062243 /* URL.swift */; }; 06D3942496E9E0E655F14D21 /* NotificationManagerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A057F2FDC14866C3026A89A4 /* NotificationManagerProtocol.swift */; }; 071A017E415AD378F2961B11 /* URL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 227AC5D71A4CE43512062243 /* URL.swift */; }; - 07240B7159A3990C4C2E8FFC /* LoginTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D256FEE2F1AF1E51D39B622 /* LoginTests.swift */; }; + 07240B7159A3990C4C2E8FFC /* PerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D256FEE2F1AF1E51D39B622 /* PerformanceTests.swift */; }; 07756D532EFE33DD1FA258E5 /* GeoURITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A7ED2EF5BDBAD2A7DBC4636 /* GeoURITests.swift */; }; 095C0ACFC234E0550A6404C5 /* AppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FC803282F9268D49F4ABF14 /* AppCoordinator.swift */; }; 095D3906CF2F940C2D2D17CC /* RoomFlowCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FCB2126C091EEF2454B4D56 /* RoomFlowCoordinatorTests.swift */; }; @@ -72,6 +72,8 @@ 1772AFA97DDA51CF1B293A78 /* RoomAttachmentPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E6A9B9DFEE964962C179DE3 /* RoomAttachmentPicker.swift */; }; 17780569FB41E9BAC60D4710 /* UNUserNotificationCenter+Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E685274772980BDEFF6691E /* UNUserNotificationCenter+Settings.swift */; }; 1830E5431DB426E2F3660D58 /* NotificationSettingsEditScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46F52419AEEDA2C006CB7181 /* NotificationSettingsEditScreenUITests.swift */; }; + 185218222A989A9A00E16DD4 /* UserFlowTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 185218212A989A9A00E16DD4 /* UserFlowTests.swift */; }; + 185218242A989B0E00E16DD4 /* Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 185218232A989B0E00E16DD4 /* Common.swift */; }; 18867F4F1C8991EEC56EA932 /* UTType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 897DF5E9A70CE05A632FC8AF /* UTType.swift */; }; 1950A80CD198BED283DFC2CE /* ClientProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2958E6D247AE2516BEEE8 /* ClientProxy.swift */; }; 19FE025AE9BA2959B6589B0D /* RoomMemberDetailsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CC575D1895FA62591451A93 /* RoomMemberDetailsScreen.swift */; }; @@ -904,6 +906,8 @@ 1734A445A58ED855B977A0A8 /* TracingConfigurationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TracingConfigurationTests.swift; sourceTree = ""; }; 1756F24C1913F809A0039FD0 /* MessageComposerTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageComposerTextField.swift; sourceTree = ""; }; 184CF8C196BE143AE226628D /* DecorationTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecorationTimelineItemProtocol.swift; sourceTree = ""; }; + 185218212A989A9A00E16DD4 /* UserFlowTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserFlowTests.swift; sourceTree = ""; }; + 185218232A989B0E00E16DD4 /* Common.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Common.swift; sourceTree = ""; }; 1877038D1AD3D5A029F8AE2C /* TimelineReadReceiptsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineReadReceiptsView.swift; sourceTree = ""; }; 18F2958E6D247AE2516BEEE8 /* ClientProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientProxy.swift; sourceTree = ""; }; 18FE0CDF1FFA92EA7EE17B0B /* RoomTimelineControllerFactoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineControllerFactoryProtocol.swift; sourceTree = ""; }; @@ -963,7 +967,7 @@ 2CA028DCD4157F9A1F999827 /* BackgroundTaskProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskProtocol.swift; sourceTree = ""; }; 2CEBCB9676FCD1D0F13188DD /* StringTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringTests.swift; sourceTree = ""; }; 2D0946F77B696176E062D037 /* RoomMembersListScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersListScreenModels.swift; sourceTree = ""; }; - 2D256FEE2F1AF1E51D39B622 /* LoginTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginTests.swift; sourceTree = ""; }; + 2D256FEE2F1AF1E51D39B622 /* PerformanceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PerformanceTests.swift; sourceTree = ""; }; 2D505843AB66822EB91F0DF0 /* TimelineItemProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemProxy.swift; sourceTree = ""; }; 2EFE1922F39398ABFB36DF3F /* RoomDetailsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsViewModelTests.swift; sourceTree = ""; }; 2F36C5D9B37E50915ECBD3EE /* RoomMemberProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberProxy.swift; sourceTree = ""; }; @@ -2281,7 +2285,9 @@ isa = PBXGroup; children = ( D33116993D54FADC0C721C1F /* Application.swift */, - 2D256FEE2F1AF1E51D39B622 /* LoginTests.swift */, + 2D256FEE2F1AF1E51D39B622 /* PerformanceTests.swift */, + 185218212A989A9A00E16DD4 /* UserFlowTests.swift */, + 185218232A989B0E00E16DD4 /* Common.swift */, 9C4048041C1A6B20CB97FD18 /* TestMeasurementParser.swift */, ); path = Sources; @@ -4913,9 +4919,11 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 185218222A989A9A00E16DD4 /* UserFlowTests.swift in Sources */, DC08ADC41E792086A340A8B3 /* AccessibilityIdentifiers.swift in Sources */, 1702981A8085BE4FB0EC001B /* Application.swift in Sources */, - 07240B7159A3990C4C2E8FFC /* LoginTests.swift in Sources */, + 07240B7159A3990C4C2E8FFC /* PerformanceTests.swift in Sources */, + 185218242A989B0E00E16DD4 /* Common.swift in Sources */, A439B456D0761D6541745CC3 /* NSRegularExpresion.swift in Sources */, 88356DE7F2AD243AB10C7B7A /* Signposter.swift in Sources */, 290FDB0FFDC2F1DDF660343E /* TestMeasurementParser.swift in Sources */, diff --git a/IntegrationTests/Sources/Common.swift b/IntegrationTests/Sources/Common.swift new file mode 100644 index 000000000..8f7ad1769 --- /dev/null +++ b/IntegrationTests/Sources/Common.swift @@ -0,0 +1,135 @@ +// +// Copyright 2023 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import XCTest + +extension XCUIApplication { + func login(currentTestCase: XCTestCase) { + let getStartedButton = buttons[A11yIdentifiers.onboardingScreen.signIn] + + XCTAssertTrue(getStartedButton.waitForExistence(timeout: 10.0)) + getStartedButton.tap() + + let changeHomeserverButton = buttons[A11yIdentifiers.serverConfirmationScreen.changeServer] + XCTAssertTrue(changeHomeserverButton.waitForExistence(timeout: 10.0)) + changeHomeserverButton.tap() + + let homeserverTextField = textFields[A11yIdentifiers.changeServerScreen.server] + XCTAssertTrue(homeserverTextField.waitForExistence(timeout: 10.0)) + + homeserverTextField.clearAndTypeText(homeserver) + + let confirmButton = buttons[A11yIdentifiers.changeServerScreen.continue] + XCTAssertTrue(confirmButton.waitForExistence(timeout: 10.0)) + confirmButton.tap() + + let continueButton = buttons[A11yIdentifiers.serverConfirmationScreen.continue] + XCTAssertTrue(continueButton.waitForExistence(timeout: 10.0)) + continueButton.tap() + + let usernameTextField = textFields[A11yIdentifiers.loginScreen.emailUsername] + XCTAssertTrue(usernameTextField.waitForExistence(timeout: 10.0)) + + usernameTextField.clearAndTypeText(username) + + let passwordTextField = secureTextFields[A11yIdentifiers.loginScreen.password] + XCTAssertTrue(passwordTextField.waitForExistence(timeout: 10.0)) + + passwordTextField.clearAndTypeText(password) + + let nextButton = buttons[A11yIdentifiers.loginScreen.continue] + XCTAssertTrue(nextButton.waitForExistence(timeout: 10.0)) + XCTAssertTrue(nextButton.isEnabled) + + nextButton.tap() + + sleep(10) + + // Handle analytics prompt screen + if staticTexts[A11yIdentifiers.analyticsPromptScreen.title].waitForExistence(timeout: 1.0) { + // Wait for login and then handle save password sheet + let savePasswordButton = buttons["Save Password"] + if savePasswordButton.waitForExistence(timeout: 10.0) { + savePasswordButton.tap() + } + + let enableButton = buttons[A11yIdentifiers.analyticsPromptScreen.enable] + XCTAssertTrue(enableButton.waitForExistence(timeout: 10.0)) + enableButton.tap() + } + + // This might come in a different order, wait for both. + let savePasswordButton = buttons["Save Password"] + if savePasswordButton.waitForExistence(timeout: 10.0) { + savePasswordButton.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: 10.0) { + alertAllowButton.tap() + } + + // Migration screen may be shown as an overlay. + // if that pops up soon enough, we just let that happen and wait + 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) + } + + // Welcome screen may be shown as an overlay. + if buttons[A11yIdentifiers.welcomeScreen.letsGo].waitForExistence(timeout: 1.0) { + let goButton = buttons[A11yIdentifiers.welcomeScreen.letsGo] + XCTAssertTrue(goButton.waitForExistence(timeout: 1.0)) + goButton.tap() + } + + // Wait for the home screen to become visible. + let profileButton = buttons[A11yIdentifiers.homeScreen.userAvatar] + // Timeouts are huge because we're waiting for the server. + XCTAssertTrue(profileButton.waitForExistence(timeout: 300.0)) + } + + func logout() { + let profileButton = buttons[A11yIdentifiers.homeScreen.userAvatar] + + // `Failed to scroll to visible (by AX action) Button` https://stackoverflow.com/a/33534187/730924 + profileButton.forceTap() + + // Open the settings + let settingsButton = buttons["Settings"] + XCTAssertTrue(settingsButton.waitForExistence(timeout: 10.0)) + settingsButton.tap() + + // Logout + let logoutButton = buttons[A11yIdentifiers.settingsScreen.logout] + XCTAssertTrue(logoutButton.waitForExistence(timeout: 10.0)) + logoutButton.tap() + + // Confirm logout + let alertLogoutButton = alerts.firstMatch.buttons["Sign out"] + XCTAssertTrue(alertLogoutButton.waitForExistence(timeout: 10.0)) + alertLogoutButton.tap() + + // Check that we're back on the login screen + let getStartedButton = buttons[A11yIdentifiers.onboardingScreen.signIn] + XCTAssertTrue(getStartedButton.waitForExistence(timeout: 10.0)) + } +} diff --git a/IntegrationTests/Sources/LoginTests.swift b/IntegrationTests/Sources/LoginTests.swift deleted file mode 100644 index 6c66c577b..000000000 --- a/IntegrationTests/Sources/LoginTests.swift +++ /dev/null @@ -1,200 +0,0 @@ -// -// Copyright 2022 New Vector Ltd -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import XCTest - -class LoginTests: XCTestCase { - func testLoginFlow() throws { - let parser = TestMeasurementParser() - parser.capture(testCase: self) { - let metrics: [XCTMetric] = [ - XCTApplicationLaunchMetric(), - XCTClockMetric(), - XCTOSSignpostMetric(subsystem: Signposter.subsystem, category: Signposter.category, name: "\(Signposter.Name.login)"), - XCTOSSignpostMetric(subsystem: Signposter.subsystem, category: Signposter.category, name: "\(Signposter.Name.firstSync)"), - XCTOSSignpostMetric(subsystem: Signposter.subsystem, category: Signposter.category, name: "\(Signposter.Name.firstRooms)"), - XCTOSSignpostMetric(subsystem: Signposter.subsystem, category: Signposter.category, name: "\(Signposter.Name.roomFlow)") - ] - - self.measure(metrics: metrics) { - self.runLoginLogoutFlow() - } - } - } - - private func runLoginLogoutFlow() { - let app = Application.launch() - - let getStartedButton = app.buttons[A11yIdentifiers.onboardingScreen.signIn] - - XCTAssertTrue(getStartedButton.waitForExistence(timeout: 10.0)) - getStartedButton.tap() - - let changeHomeserverButton = app.buttons[A11yIdentifiers.serverConfirmationScreen.changeServer] - XCTAssertTrue(changeHomeserverButton.waitForExistence(timeout: 10.0)) - changeHomeserverButton.tap() - - let homeserverTextField = app.textFields[A11yIdentifiers.changeServerScreen.server] - XCTAssertTrue(homeserverTextField.waitForExistence(timeout: 10.0)) - - homeserverTextField.clearAndTypeText(app.homeserver) - - let confirmButton = app.buttons[A11yIdentifiers.changeServerScreen.continue] - XCTAssertTrue(confirmButton.waitForExistence(timeout: 10.0)) - confirmButton.tap() - - let continueButton = app.buttons[A11yIdentifiers.serverConfirmationScreen.continue] - XCTAssertTrue(continueButton.waitForExistence(timeout: 10.0)) - continueButton.tap() - - let usernameTextField = app.textFields[A11yIdentifiers.loginScreen.emailUsername] - XCTAssertTrue(usernameTextField.waitForExistence(timeout: 10.0)) - - usernameTextField.clearAndTypeText(app.username) - - let passwordTextField = app.secureTextFields[A11yIdentifiers.loginScreen.password] - XCTAssertTrue(passwordTextField.waitForExistence(timeout: 10.0)) - - passwordTextField.clearAndTypeText(app.password) - - let nextButton = app.buttons[A11yIdentifiers.loginScreen.continue] - XCTAssertTrue(nextButton.waitForExistence(timeout: 10.0)) - XCTAssertTrue(nextButton.isEnabled) - - nextButton.tap() - - sleep(10) - - // Handle analytics prompt screen - if app.staticTexts[A11yIdentifiers.analyticsPromptScreen.title].waitForExistence(timeout: 1.0) { - // Wait for login and then handle save password sheet - let savePasswordButton = app.buttons["Save Password"] - if savePasswordButton.waitForExistence(timeout: 10.0) { - savePasswordButton.tap() - } - - let enableButton = app.buttons[A11yIdentifiers.analyticsPromptScreen.enable] - XCTAssertTrue(enableButton.waitForExistence(timeout: 10.0)) - enableButton.tap() - } - - // This might come in a different order, wait for both. - let savePasswordButton = app.buttons["Save Password"] - if savePasswordButton.waitForExistence(timeout: 10.0) { - savePasswordButton.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: 10.0) { - alertAllowButton.tap() - } - - // Migration screen may be shown as an overlay. - // if that pops up soon enough, we just let that happen and wait - let message = app.staticTexts[A11yIdentifiers.migrationScreen.message] - - if message.waitForExistence(timeout: 10.0) { - let doesNotExistPredicate = NSPredicate(format: "exists == 0") - expectation(for: doesNotExistPredicate, evaluatedWith: message) - waitForExpectations(timeout: 300.0) - } - - // Welcome screen may be shown as an overlay. - if app.buttons[A11yIdentifiers.welcomeScreen.letsGo].waitForExistence(timeout: 1.0) { - let goButton = app.buttons[A11yIdentifiers.welcomeScreen.letsGo] - XCTAssertTrue(goButton.waitForExistence(timeout: 1.0)) - goButton.tap() - } - - // Wait for the home screen to become visible. - let profileButton = app.buttons[A11yIdentifiers.homeScreen.userAvatar] - // Timeouts are huge because we're waiting for the server. - XCTAssertTrue(profileButton.waitForExistence(timeout: 300.0)) - - // Open the first room in the list. - let firstRoom = app.buttons.matching(NSPredicate(format: "identifier BEGINSWITH %@", A11yIdentifiers.homeScreen.roomNamePrefix)).firstMatch - XCTAssertTrue(firstRoom.waitForExistence(timeout: 10.0)) - firstRoom.tap() - - // Long press on the last message - let lastMessage = app.cells.firstMatch - XCTAssertTrue(lastMessage.waitForExistence(timeout: 10.0)) - lastMessage.press(forDuration: 2.0) - - // Hide the bottom sheet - let timelineItemActionMenu = app.otherElements[A11yIdentifiers.roomScreen.timelineItemActionMenu].firstMatch - XCTAssertTrue(timelineItemActionMenu.waitForExistence(timeout: 10.0)) - timelineItemActionMenu.swipeDown(velocity: .fast) - - // Open the room details - let roomHeader = app.staticTexts["room-name"] - XCTAssertTrue(roomHeader.waitForExistence(timeout: 10.0)) - roomHeader.tap() - - // Open the room member details - let roomMembers = app.buttons["room_details-people"] - XCTAssertTrue(roomMembers.waitForExistence(timeout: 10.0)) - roomMembers.tap() - - // Open the first member's details - let firstRoomMember = app.scrollViews.buttons.firstMatch - XCTAssertTrue(firstRoomMember.waitForExistence(timeout: 10.0)) - firstRoomMember.tap() - - // Go back to the room member details - var backButton = app.buttons["People"] - XCTAssertTrue(backButton.waitForExistence(timeout: 10.0)) - backButton.tap() - - // Go back to the room details - backButton = app.buttons["Back"] - XCTAssertTrue(backButton.waitForExistence(timeout: 10.0)) - backButton.tap() - - // Go back to the room - backButton = app.buttons["Back"] - XCTAssertTrue(backButton.waitForExistence(timeout: 10.0)) - backButton.tap() - - // Go back to the room list - backButton = app.navigationBars.firstMatch.buttons["All Chats"] - XCTAssertTrue(backButton.waitForExistence(timeout: 10.0)) - backButton.tap() - - // `Failed to scroll to visible (by AX action) Button` https://stackoverflow.com/a/33534187/730924 - profileButton.forceTap() - - // Open the settings - let settingsButton = app.buttons["Settings"] - XCTAssertTrue(settingsButton.waitForExistence(timeout: 10.0)) - settingsButton.tap() - - // Logout - let logoutButton = app.buttons[A11yIdentifiers.settingsScreen.logout] - XCTAssertTrue(logoutButton.waitForExistence(timeout: 10.0)) - logoutButton.tap() - - // Confirm logout - let alertLogoutButton = app.alerts.firstMatch.buttons["Sign out"] - XCTAssertTrue(alertLogoutButton.waitForExistence(timeout: 10.0)) - alertLogoutButton.tap() - - // Check that we're back on the login screen - XCTAssertTrue(getStartedButton.waitForExistence(timeout: 10.0)) - } -} diff --git a/IntegrationTests/Sources/PerformanceTests.swift b/IntegrationTests/Sources/PerformanceTests.swift new file mode 100644 index 000000000..a57f55ad3 --- /dev/null +++ b/IntegrationTests/Sources/PerformanceTests.swift @@ -0,0 +1,55 @@ +// +// Copyright 2022 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import XCTest + +class PerformanceTests: XCTestCase { + func testLoginFlow() throws { + let parser = TestMeasurementParser() + parser.capture(testCase: self) { + let metrics: [XCTMetric] = [ + XCTApplicationLaunchMetric(), + XCTClockMetric(), + XCTOSSignpostMetric(subsystem: Signposter.subsystem, category: Signposter.category, name: "\(Signposter.Name.login)"), + XCTOSSignpostMetric(subsystem: Signposter.subsystem, category: Signposter.category, name: "\(Signposter.Name.firstSync)"), + XCTOSSignpostMetric(subsystem: Signposter.subsystem, category: Signposter.category, name: "\(Signposter.Name.firstRooms)"), + XCTOSSignpostMetric(subsystem: Signposter.subsystem, category: Signposter.category, name: "\(Signposter.Name.roomFlow)") + ] + + self.measure(metrics: metrics) { + self.runLoginLogoutFlow() + } + } + } + + private func runLoginLogoutFlow() { + let app = Application.launch() + + app.login(currentTestCase: self) + + // Open the first room in the list. + let firstRoom = app.buttons.matching(NSPredicate(format: "identifier BEGINSWITH %@", A11yIdentifiers.homeScreen.roomNamePrefix)).firstMatch + XCTAssertTrue(firstRoom.waitForExistence(timeout: 10.0)) + firstRoom.tap() + + // Go back to the room list + let backButton = app.navigationBars.firstMatch.buttons["All Chats"] + XCTAssertTrue(backButton.waitForExistence(timeout: 10.0)) + backButton.tap() + + app.logout() + } +} diff --git a/IntegrationTests/Sources/UserFlowTests.swift b/IntegrationTests/Sources/UserFlowTests.swift new file mode 100644 index 000000000..dbcaa11bc --- /dev/null +++ b/IntegrationTests/Sources/UserFlowTests.swift @@ -0,0 +1,77 @@ +// +// Copyright 2023 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import XCTest + +class UserFlowTests: XCTestCase { + func testUserFlow() { + let app = Application.launch() + + app.login(currentTestCase: self) + + // Open the first room in the list. + let firstRoom = app.buttons.matching(NSPredicate(format: "identifier BEGINSWITH %@", A11yIdentifiers.homeScreen.roomNamePrefix)).firstMatch + XCTAssertTrue(firstRoom.waitForExistence(timeout: 10.0)) + firstRoom.tap() + + // Long press on the last message + let lastMessage = app.cells.firstMatch + XCTAssertTrue(lastMessage.waitForExistence(timeout: 10.0)) + lastMessage.press(forDuration: 2.0) + + // Hide the bottom sheet + let timelineItemActionMenu = app.otherElements[A11yIdentifiers.roomScreen.timelineItemActionMenu].firstMatch + XCTAssertTrue(timelineItemActionMenu.waitForExistence(timeout: 10.0)) + timelineItemActionMenu.swipeDown(velocity: .fast) + + // Open the room details + let roomHeader = app.staticTexts["room-name"] + XCTAssertTrue(roomHeader.waitForExistence(timeout: 10.0)) + roomHeader.tap() + + // Open the room member details + let roomMembers = app.buttons["room_details-people"] + XCTAssertTrue(roomMembers.waitForExistence(timeout: 10.0)) + roomMembers.tap() + + // Open the first member's details + let firstRoomMember = app.scrollViews.buttons.firstMatch + XCTAssertTrue(firstRoomMember.waitForExistence(timeout: 10.0)) + firstRoomMember.tap() + + // Go back to the room member details + var backButton = app.buttons["People"] + XCTAssertTrue(backButton.waitForExistence(timeout: 10.0)) + backButton.tap() + + // Go back to the room details + backButton = app.buttons["Back"] + XCTAssertTrue(backButton.waitForExistence(timeout: 10.0)) + backButton.tap() + + // Go back to the room + backButton = app.buttons["Back"] + XCTAssertTrue(backButton.waitForExistence(timeout: 10.0)) + backButton.tap() + + // Go back to the room list + backButton = app.navigationBars.firstMatch.buttons["All Chats"] + XCTAssertTrue(backButton.waitForExistence(timeout: 10.0)) + backButton.tap() + + app.logout() + } +}