From 2abc5ed909d6a91f235e55cb373cd1c91bdf4492 Mon Sep 17 00:00:00 2001 From: Niklas Berglund <niklas.berglund@gmail.com> Date: Mon, 26 Feb 2024 15:17:11 +0100 Subject: [PATCH] Add problem report test --- ios/Configurations/UITests.xcconfig.template | 6 ++- ios/MullvadVPN.xcodeproj/project.pbxproj | 33 ++++++++++++++- .../Classes/AccessbilityIdentifier.swift | 1 + .../ProblemReportSubmissionOverlayView.swift | 2 + ...mReportViewController+ViewManagement.swift | 1 + ios/MullvadVPNUITests/AccountTests.swift | 6 --- .../Pages/ProblemReportPage.swift | 2 +- .../Pages/ProblemReportSubmittedPage.swift | 19 +++++++++ ios/MullvadVPNUITests/SettingsTests.swift | 41 +++++++++++++++++++ .../Test base classes/BaseUITestCase.swift | 1 + 10 files changed, 102 insertions(+), 10 deletions(-) create mode 100644 ios/MullvadVPNUITests/Pages/ProblemReportSubmittedPage.swift create mode 100644 ios/MullvadVPNUITests/SettingsTests.swift diff --git a/ios/Configurations/UITests.xcconfig.template b/ios/Configurations/UITests.xcconfig.template index 0584179b3d37..b55222dac280 100644 --- a/ios/Configurations/UITests.xcconfig.template +++ b/ios/Configurations/UITests.xcconfig.template @@ -7,8 +7,10 @@ IOS_DEVICE_PIN_CODE = TEST_DEVICE_IDENTIFIER_UUID = // Mullvad accounts used by UI tests -NO_TIME_ACCOUNT_NUMBER = -HAS_TIME_ACCOUNT_NUMBER = +NO_TIME_ACCOUNT_NUMBER[config=Debug] = +NO_TIME_ACCOUNT_NUMBER[config=Staging] = +HAS_TIME_ACCOUNT_NUMBER[config=Debug] = +HAS_TIME_ACCOUNT_NUMBER[config=Staging] = FIVE_WIREGUARD_KEYS_ACCOUNT_NUMBER = // Ad serving domain used when testing ad blocking. Note that we are assuming there's an HTTP server running on the host. diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj index a0943f1f1ab6..b26f3c30971d 100644 --- a/ios/MullvadVPN.xcodeproj/project.pbxproj +++ b/ios/MullvadVPN.xcodeproj/project.pbxproj @@ -602,6 +602,7 @@ 852969362B4E9724007EAD4C /* AccessbilityIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A0B311D2B303A0D004B12E0 /* AccessbilityIdentifier.swift */; }; 8529693A2B4F0238007EAD4C /* TermsOfServicePage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 852969392B4F0238007EAD4C /* TermsOfServicePage.swift */; }; 8529693C2B4F0257007EAD4C /* Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8529693B2B4F0257007EAD4C /* Alert.swift */; }; + 8532E6872B8CCED600ACECD1 /* ProblemReportSubmittedPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8532E6862B8CCED600ACECD1 /* ProblemReportSubmittedPage.swift */; }; 85557B0E2B591B2600795FE1 /* FirewallAPIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85557B0D2B591B2600795FE1 /* FirewallAPIClient.swift */; }; 85557B102B59215F00795FE1 /* FirewallRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85557B0F2B59215F00795FE1 /* FirewallRule.swift */; }; 85557B122B594FC900795FE1 /* ConnectivityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85557B112B594FC900795FE1 /* ConnectivityTests.swift */; }; @@ -612,6 +613,7 @@ 855D9F5B2B63E56B00D7C64D /* ProblemReportPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 855D9F5A2B63E56B00D7C64D /* ProblemReportPage.swift */; }; 8590896C2B61763B003AF5F5 /* LoggedInWithoutTimeUITestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 859089682B61763B003AF5F5 /* LoggedInWithoutTimeUITestCase.swift */; }; 8590896F2B61763B003AF5F5 /* LoggedOutUITestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8590896B2B61763B003AF5F5 /* LoggedOutUITestCase.swift */; }; + 85C7A2E92B89024B00035D5A /* SettingsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85C7A2E82B89024B00035D5A /* SettingsTests.swift */; }; 85D2B0B12B6BD32400DF9DA7 /* BaseUITestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8590896A2B61763B003AF5F5 /* BaseUITestCase.swift */; }; 85E3BDE52B70E18C00FA71FD /* Networking.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85E3BDE42B70E18C00FA71FD /* Networking.swift */; }; A900E9B82ACC5C2B00C95F67 /* AccountsProxy+Stubs.swift in Sources */ = {isa = PBXBuildFile; fileRef = A900E9B72ACC5C2B00C95F67 /* AccountsProxy+Stubs.swift */; }; @@ -1825,6 +1827,7 @@ 852969382B4ED818007EAD4C /* UITests.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = UITests.xcconfig; sourceTree = "<group>"; }; 852969392B4F0238007EAD4C /* TermsOfServicePage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TermsOfServicePage.swift; sourceTree = "<group>"; }; 8529693B2B4F0257007EAD4C /* Alert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Alert.swift; sourceTree = "<group>"; }; + 8532E6862B8CCED600ACECD1 /* ProblemReportSubmittedPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProblemReportSubmittedPage.swift; sourceTree = "<group>"; }; 85557B0D2B591B2600795FE1 /* FirewallAPIClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirewallAPIClient.swift; sourceTree = "<group>"; }; 85557B0F2B59215F00795FE1 /* FirewallRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirewallRule.swift; sourceTree = "<group>"; }; 85557B112B594FC900795FE1 /* ConnectivityTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectivityTests.swift; sourceTree = "<group>"; }; @@ -1837,6 +1840,7 @@ 859089692B61763B003AF5F5 /* LoggedInWithTimeUITestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoggedInWithTimeUITestCase.swift; sourceTree = "<group>"; }; 8590896A2B61763B003AF5F5 /* BaseUITestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseUITestCase.swift; sourceTree = "<group>"; }; 8590896B2B61763B003AF5F5 /* LoggedOutUITestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoggedOutUITestCase.swift; sourceTree = "<group>"; }; + 85C7A2E82B89024B00035D5A /* SettingsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTests.swift; sourceTree = "<group>"; }; 85E3BDE42B70E18C00FA71FD /* Networking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Networking.swift; sourceTree = "<group>"; }; A900E9B72ACC5C2B00C95F67 /* AccountsProxy+Stubs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AccountsProxy+Stubs.swift"; sourceTree = "<group>"; }; A900E9B92ACC5D0600C95F67 /* RESTRequestExecutor+Stubs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RESTRequestExecutor+Stubs.swift"; sourceTree = "<group>"; }; @@ -3513,6 +3517,7 @@ 850201DA2B503D7700EF8C96 /* RelayTests.swift */, 8518F6392B601910009EB113 /* Test base classes */, 85557B152B5ABBBE00795FE1 /* XCUIElementQuery+Extensions.swift */, + 85C7A2E82B89024B00035D5A /* SettingsTests.swift */, ); path = MullvadVPNUITests; sourceTree = "<group>"; @@ -3526,6 +3531,7 @@ 852969342B4E9270007EAD4C /* LoginPage.swift */, 852969322B4E9232007EAD4C /* Page.swift */, 855D9F5A2B63E56B00D7C64D /* ProblemReportPage.swift */, + 8532E6862B8CCED600ACECD1 /* ProblemReportSubmittedPage.swift */, 850201DC2B503D8C00EF8C96 /* SelectLocationPage.swift */, 850201E22B51A93C00EF8C96 /* SettingsPage.swift */, 852969392B4F0238007EAD4C /* TermsOfServicePage.swift */, @@ -5480,6 +5486,7 @@ 85557B142B5983CF00795FE1 /* MullvadAPIWrapper.swift in Sources */, 852969362B4E9724007EAD4C /* AccessbilityIdentifier.swift in Sources */, 85E3BDE52B70E18C00FA71FD /* Networking.swift in Sources */, + 85C7A2E92B89024B00035D5A /* SettingsTests.swift in Sources */, 8590896C2B61763B003AF5F5 /* LoggedInWithoutTimeUITestCase.swift in Sources */, 8590896F2B61763B003AF5F5 /* LoggedOutUITestCase.swift in Sources */, 85557B202B5FBBD700795FE1 /* AccountPage.swift in Sources */, @@ -5491,6 +5498,7 @@ 85557B162B5ABBBE00795FE1 /* XCUIElementQuery+Extensions.swift in Sources */, 855D9F5B2B63E56B00D7C64D /* ProblemReportPage.swift in Sources */, 8529693A2B4F0238007EAD4C /* TermsOfServicePage.swift in Sources */, + 8532E6872B8CCED600ACECD1 /* ProblemReportSubmittedPage.swift in Sources */, 850201DF2B5040A500EF8C96 /* TunnelControlPage.swift in Sources */, 85557B1E2B5FB8C700795FE1 /* HeaderBar.swift in Sources */, 85557B122B594FC900795FE1 /* ConnectivityTests.swift in Sources */, @@ -6861,7 +6869,7 @@ PROVISIONING_PROFILE_SPECIFIER = ""; "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "MullvadVPN app integration tests"; SECURITY_GROUP_IDENTIFIER = group.net.mullvad.MullvadVPN; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG MULLVAD_ENVIRONMENT_PRODUCTION $(inherited)"; SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/MullvadVPNUITests/BridgingHeader.h"; SWIFT_VERSION = 5.0; @@ -6872,9 +6880,12 @@ }; 8529692E2B4D9C1F007EAD4C /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 852969382B4ED818007EAD4C /* UITests.xcconfig */; buildSettings = { APPLICATION_IDENTIFIER = net.mullvad.MullvadVPN; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = CKG9MXH72F; ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu17; GENERATE_INFOPLIST_FILE = YES; @@ -6888,6 +6899,7 @@ MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = "$(APPLICATION_IDENTIFIER).MullvadVPNUITests"; PRODUCT_NAME = "$(TARGET_NAME)"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "MullvadVPN app integration tests"; SECURITY_GROUP_IDENTIFIER = group.net.mullvad.MullvadVPN; SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/MullvadVPNUITests/BridgingHeader.h"; @@ -7472,25 +7484,44 @@ }; A93A1D062B59145C00F7796C /* Staging */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 852969382B4ED818007EAD4C /* UITests.xcconfig */; buildSettings = { + APPLICATION_IDENTIFIER = net.mullvad.MullvadVPN; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = CKG9MXH72F; + "DEVELOPMENT_TEAM[sdk=macosx*]" = CKG9MXH72F; + GENERATE_INFOPLIST_FILE = YES; HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/../mullvad-api/include"; + INFOPLIST_FILE = MullvadVPNUITests/Info.plist; "LIBRARY_SEARCH_PATHS[sdk=iphoneos*][arch=arm64]" = "$(PROJECT_DIR)/../target/aarch64-apple-ios/debug"; "LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*][arch=arm64]" = "$(PROJECT_DIR)/../target/aarch64-apple-ios-sim/debug"; "LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*][arch=x86_64]" = "$(PROJECT_DIR)/../target/x86_64-apple-ios/debug"; + PRODUCT_BUNDLE_IDENTIFIER = "$(APPLICATION_IDENTIFIER).MullvadVPNUITests"; PRODUCT_NAME = MullvadVPNUITests; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "MullvadVPN app integration tests"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG MULLVAD_ENVIRONMENT_STAGING"; SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/MullvadVPNUITests/BridgingHeader.h"; + SWIFT_VERSION = 5.0; + TEST_TARGET_NAME = MullvadVPN; }; name = Staging; }; A93A1D072B59145C00F7796C /* MockRelease */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 852969382B4ED818007EAD4C /* UITests.xcconfig */; buildSettings = { + APPLICATION_IDENTIFIER = net.mullvad.MullvadVPN; HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/../mullvad-api/include"; + INFOPLIST_FILE = MullvadVPNUITests/Info.plist; "LIBRARY_SEARCH_PATHS[sdk=iphoneos*][arch=arm64]" = "$(PROJECT_DIR)/../target/aarch64-apple-ios/release"; "LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*][arch=arm64]" = "$(PROJECT_DIR)/../target/aarch64-apple-ios-sim/release"; "LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*][arch=x86_64]" = "$(PROJECT_DIR)/../target/x86_64-apple-ios/release"; PRODUCT_NAME = MullvadVPNUITests; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = MULLVAD_ENVIRONMENT_PRODUCTION; SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/MullvadVPNUITests/BridgingHeader.h"; + SWIFT_VERSION = 5.0; + TEST_TARGET_NAME = MullvadVPN; }; name = MockRelease; }; diff --git a/ios/MullvadVPN/Classes/AccessbilityIdentifier.swift b/ios/MullvadVPN/Classes/AccessbilityIdentifier.swift index 855ea3c7483f..a5dc7f26a5fa 100644 --- a/ios/MullvadVPN/Classes/AccessbilityIdentifier.swift +++ b/ios/MullvadVPN/Classes/AccessbilityIdentifier.swift @@ -60,6 +60,7 @@ public enum AccessibilityIdentifier: String { case settingsTableView case tunnelControlView case problemReportView + case problemReportSubmittedView // Other UI elements case connectionPanelInAddressRow diff --git a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportSubmissionOverlayView.swift b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportSubmissionOverlayView.swift index 7cba3d1ec9a1..a6af41be565e 100644 --- a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportSubmissionOverlayView.swift +++ b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportSubmissionOverlayView.swift @@ -174,6 +174,8 @@ class ProblemReportSubmissionOverlayView: UIView { override init(frame: CGRect) { super.init(frame: frame) + accessibilityIdentifier = AccessibilityIdentifier.problemReportSubmittedView + addSubviews() transitionToState(state) diff --git a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportViewController+ViewManagement.swift b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportViewController+ViewManagement.swift index 30a5e7d2e276..488c48370fec 100644 --- a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportViewController+ViewManagement.swift +++ b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportViewController+ViewManagement.swift @@ -96,6 +96,7 @@ extension ProblemReportViewController { func makeSendButton() -> AppButton { let button = AppButton(style: .success) + button.accessibilityIdentifier = AccessibilityIdentifier.problemReportSendButton button.translatesAutoresizingMaskIntoConstraints = false button.setTitle(Self.persistentViewModel.sendLogsButtonTitle, for: .normal) button.addTarget(self, action: #selector(handleSendButtonTap), for: .touchUpInside) diff --git a/ios/MullvadVPNUITests/AccountTests.swift b/ios/MullvadVPNUITests/AccountTests.swift index 319ce2350973..f15195b69d57 100644 --- a/ios/MullvadVPNUITests/AccountTests.swift +++ b/ios/MullvadVPNUITests/AccountTests.swift @@ -9,12 +9,6 @@ import XCTest class AccountTests: LoggedOutUITestCase { - override func setUpWithError() throws { - continueAfterFailure = false - - try super.setUpWithError() - } - func testLogin() throws { LoginPage(app) .tapAccountNumberTextField() diff --git a/ios/MullvadVPNUITests/Pages/ProblemReportPage.swift b/ios/MullvadVPNUITests/Pages/ProblemReportPage.swift index 4bb2407cecf5..d02a0ec9917e 100644 --- a/ios/MullvadVPNUITests/Pages/ProblemReportPage.swift +++ b/ios/MullvadVPNUITests/Pages/ProblemReportPage.swift @@ -40,7 +40,7 @@ class ProblemReportPage: Page { } @discardableResult func tapSendButton() -> Self { - app.otherElements[AccessibilityIdentifier.problemReportSendButton] + app.buttons[AccessibilityIdentifier.problemReportSendButton] .tap() return self diff --git a/ios/MullvadVPNUITests/Pages/ProblemReportSubmittedPage.swift b/ios/MullvadVPNUITests/Pages/ProblemReportSubmittedPage.swift new file mode 100644 index 000000000000..a90c93b3ff77 --- /dev/null +++ b/ios/MullvadVPNUITests/Pages/ProblemReportSubmittedPage.swift @@ -0,0 +1,19 @@ +// +// ProblemReportSubmittedPage.swift +// MullvadVPNUITests +// +// Created by Niklas Berglund on 2024-02-26. +// Copyright © 2024 Mullvad VPN AB. All rights reserved. +// + +import Foundation +import XCTest + +class ProblemReportSubmittedPage: Page { + @discardableResult override init(_ app: XCUIApplication) { + super.init(app) + + pageAccessibilityIdentifier = .problemReportSubmittedView + waitForPageToBeShown() + } +} diff --git a/ios/MullvadVPNUITests/SettingsTests.swift b/ios/MullvadVPNUITests/SettingsTests.swift new file mode 100644 index 000000000000..c41c7ef957e9 --- /dev/null +++ b/ios/MullvadVPNUITests/SettingsTests.swift @@ -0,0 +1,41 @@ +// +// SettingsTests.swift +// MullvadVPNUITests +// +// Created by Niklas Berglund on 2024-02-23. +// Copyright © 2024 Mullvad VPN AB. All rights reserved. +// + +import Foundation +import XCTest + +class SettingsTests: LoggedOutUITestCase { + func testSendProblemReport() throws { + #if MULLVAD_ENVIRONMENT_STAGING + let shouldSkipTest = false + #else + let shouldSkipTest = true + #endif + + try XCTSkipIf(shouldSkipTest, "This test should only run in the staging environment") + + HeaderBar(app) + .tapSettingsButton() + + SettingsPage(app) + .tapReportAProblemCell() + + ProblemReportPage(app) + .tapEmailTextField() + .enterText("cookie@mullvad.net") + .tapMessageTextView() + .enterText(""" + Dear support + This is a problem report from an iOS app test. + """) + .tapKeyboardDoneButton() + .tapSendButton() + + ProblemReportSubmittedPage(app) + } +} diff --git a/ios/MullvadVPNUITests/Test base classes/BaseUITestCase.swift b/ios/MullvadVPNUITests/Test base classes/BaseUITestCase.swift index 00a73cd36c1c..c99f25463ec1 100644 --- a/ios/MullvadVPNUITests/Test base classes/BaseUITestCase.swift +++ b/ios/MullvadVPNUITests/Test base classes/BaseUITestCase.swift @@ -50,6 +50,7 @@ class BaseUITestCase: XCTestCase { /// Test level setup override func setUp() { + continueAfterFailure = false app.launch() }