diff options
| author | Bug Magnet <marco.nikic@mullvad.net> | 2024-01-16 12:42:54 +0100 |
|---|---|---|
| committer | Bug Magnet <marco.nikic@mullvad.net> | 2024-01-16 12:42:54 +0100 |
| commit | b700b79d16c4980ee2028b4b5fb67caa785fbcfd (patch) | |
| tree | 8601bb208284433651ae2f63a931c0f8663c6747 | |
| parent | ee9597c4628773fcc6cc93306bab5e01ce2401f1 (diff) | |
| parent | d26686cef766ac0248883e79c71ba5ba6481340f (diff) | |
| download | mullvadvpn-b700b79d16c4980ee2028b4b5fb67caa785fbcfd.tar.xz mullvadvpn-b700b79d16c4980ee2028b4b5fb67caa785fbcfd.zip | |
Merge branch 'test-app-login-ios-428'
17 files changed, 517 insertions, 1 deletions
diff --git a/ios/Configurations/UITests.xcconfig.template b/ios/Configurations/UITests.xcconfig.template new file mode 100644 index 0000000000..c8727dd3e1 --- /dev/null +++ b/ios/Configurations/UITests.xcconfig.template @@ -0,0 +1,13 @@ +// +// MullvadVPNUITests.xcconfig +// MullvadVPN +// +// Created by Niklas Berglund on 2024-01-10. +// Copyright © 2024 Mullvad VPN AB. All rights reserved. +// + +// Mullvad accounts used by UI tests +MULLVAD_NO_TIME_ACCOUNT_NUMBER = +MULLVAD_HAS_TIME_ACCOUNT_NUMBER = +MULLVAD_FIVE_WIREGUARD_KEYS_ACCOUNT_NUMBER = + diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj index 60a74fa1b5..dde9de3805 100644 --- a/ios/MullvadVPN.xcodeproj/project.pbxproj +++ b/ios/MullvadVPN.xcodeproj/project.pbxproj @@ -566,6 +566,13 @@ 7AF9BE902A39F26000DBFEDB /* Collection+Sorting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF9BE8F2A39F26000DBFEDB /* Collection+Sorting.swift */; }; 7AF9BE952A40461100DBFEDB /* RelayFilterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF9BE942A40461100DBFEDB /* RelayFilterView.swift */; }; 7AF9BE972A41C71F00DBFEDB /* RelayFilterChipView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF9BE962A41C71F00DBFEDB /* RelayFilterChipView.swift */; }; + 850201E12B51389500EF8C96 /* BaseUITestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 850201E02B51389500EF8C96 /* BaseUITestCase.swift */; }; + 852969282B4D9C1F007EAD4C /* AccountTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 852969272B4D9C1F007EAD4C /* AccountTests.swift */; }; + 852969332B4E9232007EAD4C /* Page.swift in Sources */ = {isa = PBXBuildFile; fileRef = 852969322B4E9232007EAD4C /* Page.swift */; }; + 852969352B4E9270007EAD4C /* LoginPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 852969342B4E9270007EAD4C /* LoginPage.swift */; }; + 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 */; }; A900E9B82ACC5C2B00C95F67 /* AccountsProxy+Stubs.swift in Sources */ = {isa = PBXBuildFile; fileRef = A900E9B72ACC5C2B00C95F67 /* AccountsProxy+Stubs.swift */; }; A900E9BA2ACC5D0600C95F67 /* RESTRequestExecutor+Stubs.swift in Sources */ = {isa = PBXBuildFile; fileRef = A900E9B92ACC5D0600C95F67 /* RESTRequestExecutor+Stubs.swift */; }; A900E9BC2ACC609200C95F67 /* DevicesProxy+Stubs.swift in Sources */ = {isa = PBXBuildFile; fileRef = A900E9BB2ACC609200C95F67 /* DevicesProxy+Stubs.swift */; }; @@ -1031,6 +1038,13 @@ remoteGlobalIDString = 7A88DCCD2A8FABBE00D2FF0E; remoteInfo = Routing; }; + 8529692B2B4D9C1F007EAD4C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 58CE5E58224146200008646E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 58CE5E5F224146200008646E; + remoteInfo = MullvadVPN; + }; A91614D22B108F4D00F416EB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 58CE5E58224146200008646E /* Project object */; @@ -1697,6 +1711,16 @@ 7AF9BE8F2A39F26000DBFEDB /* Collection+Sorting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+Sorting.swift"; sourceTree = "<group>"; }; 7AF9BE942A40461100DBFEDB /* RelayFilterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayFilterView.swift; sourceTree = "<group>"; }; 7AF9BE962A41C71F00DBFEDB /* RelayFilterChipView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayFilterChipView.swift; sourceTree = "<group>"; }; + 850201E02B51389500EF8C96 /* BaseUITestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseUITestCase.swift; sourceTree = "<group>"; }; + 852969252B4D9C1F007EAD4C /* MullvadVPNUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MullvadVPNUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 852969272B4D9C1F007EAD4C /* AccountTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTests.swift; sourceTree = "<group>"; }; + 852969302B4D9E70007EAD4C /* MullvadVPNUITests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = MullvadVPNUITests.xctestplan; sourceTree = "<group>"; }; + 852969322B4E9232007EAD4C /* Page.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Page.swift; sourceTree = "<group>"; }; + 852969342B4E9270007EAD4C /* LoginPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginPage.swift; sourceTree = "<group>"; }; + 852969372B4ED20E007EAD4C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; }; + 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>"; }; 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>"; }; A900E9BB2ACC609200C95F67 /* DevicesProxy+Stubs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DevicesProxy+Stubs.swift"; sourceTree = "<group>"; }; @@ -1975,6 +1999,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 852969222B4D9C1F007EAD4C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -2905,6 +2936,7 @@ 58C7A4432A863F490060C66F /* PacketTunnelCoreTests */, 7A88DCCF2A8FABBE00D2FF0E /* Routing */, 7A88DCDD2A8FABBE00D2FF0E /* RoutingTests */, + 852969262B4D9C1F007EAD4C /* MullvadVPNUITests */, 58CE5E61224146200008646E /* Products */, 584F991F2902CBDD001F858D /* Frameworks */, ); @@ -2930,6 +2962,7 @@ 7A88DCCE2A8FABBE00D2FF0E /* Routing.framework */, 7A88DCD72A8FABBE00D2FF0E /* RoutingTests.xctest */, 58B2FDD32AA71D2A003EB5C6 /* MullvadSettings.framework */, + 852969252B4D9C1F007EAD4C /* MullvadVPNUITests.xctest */, ); name = Products; sourceTree = "<group>"; @@ -3143,6 +3176,7 @@ 5808273B284888BC006B77A4 /* App.xcconfig */, 5808273C284888E5006B77A4 /* PacketTunnel.xcconfig */, 58ECD29123F178FD004298B6 /* Screenshots.xcconfig */, + 852969382B4ED818007EAD4C /* UITests.xcconfig */, ); path = Configurations; sourceTree = "<group>"; @@ -3221,6 +3255,7 @@ 7A83C3FC2A55B39500DFB83A /* TestPlans */ = { isa = PBXGroup; children = ( + 852969302B4D9E70007EAD4C /* MullvadVPNUITests.xctestplan */, 7A83C3FE2A55B72E00DFB83A /* MullvadVPNApp.xctestplan */, 7A83C4002A55B81A00DFB83A /* MullvadVPNCI.xctestplan */, 7A02D4EA2A9CEC7A00C19E31 /* MullvadVPNScreenshots.xctestplan */, @@ -3262,6 +3297,28 @@ path = RelayFilter; sourceTree = "<group>"; }; + 852969262B4D9C1F007EAD4C /* MullvadVPNUITests */ = { + isa = PBXGroup; + children = ( + 852969372B4ED20E007EAD4C /* Info.plist */, + 852969312B4E9220007EAD4C /* Pages */, + 852969272B4D9C1F007EAD4C /* AccountTests.swift */, + 850201E02B51389500EF8C96 /* BaseUITestCase.swift */, + ); + path = MullvadVPNUITests; + sourceTree = "<group>"; + }; + 852969312B4E9220007EAD4C /* Pages */ = { + isa = PBXGroup; + children = ( + 852969322B4E9232007EAD4C /* Page.swift */, + 852969342B4E9270007EAD4C /* LoginPage.swift */, + 852969392B4F0238007EAD4C /* TermsOfServicePage.swift */, + 8529693B2B4F0257007EAD4C /* Alert.swift */, + ); + path = Pages; + sourceTree = "<group>"; + }; A907639F2B2857D50045ADF0 /* Socks5 */ = { isa = PBXGroup; children = ( @@ -3913,6 +3970,24 @@ productReference = 7A88DCD72A8FABBE00D2FF0E /* RoutingTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 852969242B4D9C1F007EAD4C /* MullvadVPNUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8529692F2B4D9C1F007EAD4C /* Build configuration list for PBXNativeTarget "MullvadVPNUITests" */; + buildPhases = ( + 852969212B4D9C1F007EAD4C /* Sources */, + 852969222B4D9C1F007EAD4C /* Frameworks */, + 852969232B4D9C1F007EAD4C /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 8529692C2B4D9C1F007EAD4C /* PBXTargetDependency */, + ); + name = MullvadVPNUITests; + productName = MullvadVPNUITests; + productReference = 852969252B4D9C1F007EAD4C /* MullvadVPNUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -3920,7 +3995,7 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = YES; - LastSwiftUpdateCheck = 1430; + LastSwiftUpdateCheck = 1510; LastUpgradeCheck = 1430; ORGANIZATIONNAME = "Mullvad VPN AB"; TargetAttributes = { @@ -3995,6 +4070,10 @@ 7A88DCD62A8FABBE00D2FF0E = { CreatedOnToolsVersion = 14.3.1; }; + 852969242B4D9C1F007EAD4C = { + CreatedOnToolsVersion = 15.1; + TestTargetID = 58CE5E5F224146200008646E; + }; }; }; buildConfigurationList = 58CE5E5B224146200008646E /* Build configuration list for PBXProject "MullvadVPN" */; @@ -4019,6 +4098,7 @@ 58CE5E78224146470008646E /* PacketTunnel */, 58B0A29F238EE67E00BC001D /* MullvadVPNTests */, 58D0C79223F1CE7000FE9BA7 /* MullvadVPNScreenshots */, + 852969242B4D9C1F007EAD4C /* MullvadVPNUITests */, 58D223A4294C8A480029F5F8 /* Operations */, 589A455128E094B300565204 /* OperationsTests */, 06799ABB28F98E1D00ACD94E /* MullvadREST */, @@ -4151,6 +4231,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 852969232B4D9C1F007EAD4C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -5070,6 +5157,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 852969212B4D9C1F007EAD4C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8529693C2B4F0257007EAD4C /* Alert.swift in Sources */, + 852969362B4E9724007EAD4C /* AccessbilityIdentifier.swift in Sources */, + 852969352B4E9270007EAD4C /* LoginPage.swift in Sources */, + 850201E12B51389500EF8C96 /* BaseUITestCase.swift in Sources */, + 852969282B4D9C1F007EAD4C /* AccountTests.swift in Sources */, + 8529693A2B4F0238007EAD4C /* TermsOfServicePage.swift in Sources */, + 852969332B4E9232007EAD4C /* Page.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -5255,6 +5356,11 @@ target = 7A88DCCD2A8FABBE00D2FF0E /* Routing */; targetProxy = 7ABCA5B52A9349F20044A708 /* PBXContainerItemProxy */; }; + 8529692C2B4D9C1F007EAD4C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 58CE5E5F224146200008646E /* MullvadVPN */; + targetProxy = 8529692B2B4D9C1F007EAD4C /* PBXContainerItemProxy */; + }; A91614D32B108F4D00F416EB /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 58D223D4294C8E5E0029F5F8 /* MullvadTypes */; @@ -6398,6 +6504,67 @@ }; name = Release; }; + 8529692D2B4D9C1F007EAD4C /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 852969382B4ED818007EAD4C /* UITests.xcconfig */; + buildSettings = { + APPLICATION_IDENTIFIER = net.mullvad.MullvadVPN; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = CKG9MXH72F; + "DEVELOPMENT_TEAM[sdk=macosx*]" = CKG9MXH72F; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MullvadVPNUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.2; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "$(APPLICATION_IDENTIFIER).MullvadVPNUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + 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_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = MullvadVPN; + }; + name = Debug; + }; + 8529692E2B4D9C1F007EAD4C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_IDENTIFIER = net.mullvad.MullvadVPN; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = CKG9MXH72F; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MullvadVPNUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.2; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "$(APPLICATION_IDENTIFIER).MullvadVPNUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SECURITY_GROUP_IDENTIFIER = group.net.mullvad.MullvadVPN; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = MullvadVPN; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -6572,6 +6739,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 8529692F2B4D9C1F007EAD4C /* Build configuration list for PBXNativeTarget "MullvadVPNUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8529692D2B4D9C1F007EAD4C /* Debug */, + 8529692E2B4D9C1F007EAD4C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ diff --git a/ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/MullvadVPNUITests.xcscheme b/ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/MullvadVPNUITests.xcscheme new file mode 100644 index 0000000000..45ec07ec85 --- /dev/null +++ b/ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/MullvadVPNUITests.xcscheme @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Scheme + LastUpgradeVersion = "1510" + version = "1.7"> + <BuildAction + parallelizeBuildables = "YES" + buildImplicitDependencies = "YES"> + </BuildAction> + <TestAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + shouldUseLaunchSchemeArgsEnv = "YES"> + <TestPlans> + <TestPlanReference + reference = "container:TestPlans/MullvadVPNUITests.xctestplan" + default = "YES"> + </TestPlanReference> + </TestPlans> + <Testables> + <TestableReference + skipped = "NO"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "852969242B4D9C1F007EAD4C" + BuildableName = "MullvadVPNUITests.xctest" + BlueprintName = "MullvadVPNUITests" + ReferencedContainer = "container:MullvadVPN.xcodeproj"> + </BuildableReference> + </TestableReference> + </Testables> + </TestAction> + <LaunchAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + launchStyle = "0" + useCustomWorkingDirectory = "NO" + ignoresPersistentStateOnLaunch = "NO" + debugDocumentVersioning = "YES" + debugServiceExtension = "internal" + allowLocationSimulation = "YES"> + <MacroExpansion> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "58CE5E5F224146200008646E" + BuildableName = "MullvadVPN.app" + BlueprintName = "MullvadVPN" + ReferencedContainer = "container:MullvadVPN.xcodeproj"> + </BuildableReference> + </MacroExpansion> + </LaunchAction> + <ProfileAction + buildConfiguration = "Release" + shouldUseLaunchSchemeArgsEnv = "YES" + savedToolIdentifier = "" + useCustomWorkingDirectory = "NO" + debugDocumentVersioning = "YES"> + </ProfileAction> + <AnalyzeAction + buildConfiguration = "Debug"> + </AnalyzeAction> + <ArchiveAction + buildConfiguration = "Release" + revealArchiveInOrganizer = "YES"> + </ArchiveAction> +</Scheme> diff --git a/ios/MullvadVPN/Classes/AccessbilityIdentifier.swift b/ios/MullvadVPN/Classes/AccessbilityIdentifier.swift index 340762d787..a69c70c32d 100644 --- a/ios/MullvadVPN/Classes/AccessbilityIdentifier.swift +++ b/ios/MullvadVPN/Classes/AccessbilityIdentifier.swift @@ -21,6 +21,7 @@ public enum AccessibilityIdentifier: String { case infoButton case learnAboutPrivacyButton case loginBarButton + case loginTextFieldButton case logoutButton case purchaseButton case redeemVoucherButton @@ -37,6 +38,15 @@ public enum AccessibilityIdentifier: String { case relayFilterOwnershipCell case relayFilterProviderCell + // Labels + case headerDeviceNameLabel + + // Views + case alertContainerView + case alertTitle + case loginView + case termsOfServiceView + // Other UI elements case loginTextField diff --git a/ios/MullvadVPN/Containers/Root/HeaderBarView.swift b/ios/MullvadVPN/Containers/Root/HeaderBarView.swift index 6b551cb276..1f701cbede 100644 --- a/ios/MullvadVPN/Containers/Root/HeaderBarView.swift +++ b/ios/MullvadVPN/Containers/Root/HeaderBarView.swift @@ -33,6 +33,7 @@ class HeaderBarView: UIView { label.font = UIFont.systemFont(ofSize: 14) label.textColor = UIColor(white: 1.0, alpha: 0.8) label.setContentHuggingPriority(.defaultHigh, for: .horizontal) + label.accessibilityIdentifier = .headerDeviceNameLabel return label }() diff --git a/ios/MullvadVPN/View controllers/Alert/AlertViewController.swift b/ios/MullvadVPN/View controllers/Alert/AlertViewController.swift index 1cc23b2943..3d0e0a29ed 100644 --- a/ios/MullvadVPN/View controllers/Alert/AlertViewController.swift +++ b/ios/MullvadVPN/View controllers/Alert/AlertViewController.swift @@ -53,6 +53,8 @@ class AlertViewController: UIViewController { view.backgroundColor = .secondaryColor view.layer.cornerRadius = 11 + view.accessibilityIdentifier = .alertContainerView + return view }() @@ -198,6 +200,7 @@ class AlertViewController: UIViewController { header.adjustsFontForContentSizeCategory = true header.textAlignment = .center header.numberOfLines = 0 + header.accessibilityIdentifier = .alertTitle contentView.addArrangedSubview(header) contentView.setCustomSpacing(16, after: header) diff --git a/ios/MullvadVPN/View controllers/Login/AccountInputGroupView.swift b/ios/MullvadVPN/View controllers/Login/AccountInputGroupView.swift index e5eb0ddb77..c021286c0d 100644 --- a/ios/MullvadVPN/View controllers/Login/AccountInputGroupView.swift +++ b/ios/MullvadVPN/View controllers/Login/AccountInputGroupView.swift @@ -24,6 +24,7 @@ final class AccountInputGroupView: UIView { button.translatesAutoresizingMaskIntoConstraints = false button.setImage(UIImage(named: "IconArrow"), for: .normal) button.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal) + button.accessibilityIdentifier = .loginTextFieldButton button.accessibilityLabel = NSLocalizedString( "ACCOUNT_INPUT_LOGIN_BUTTON_ACCESSIBILITY_LABEL", tableName: "AccountInput", diff --git a/ios/MullvadVPN/View controllers/Login/LoginContentView.swift b/ios/MullvadVPN/View controllers/Login/LoginContentView.swift index 940317347c..c994286d51 100644 --- a/ios/MullvadVPN/View controllers/Login/LoginContentView.swift +++ b/ios/MullvadVPN/View controllers/Login/LoginContentView.swift @@ -102,6 +102,7 @@ class LoginContentView: UIView { backgroundColor = .primaryColor directionalLayoutMargins = UIMetrics.contentLayoutMargins + accessibilityIdentifier = .loginView accountInputGroup.textField.accessibilityIdentifier = .loginTextField diff --git a/ios/MullvadVPN/View controllers/TermsOfService/TermsOfServiceContentView.swift b/ios/MullvadVPN/View controllers/TermsOfService/TermsOfServiceContentView.swift index e4292d2a80..945b2bccc5 100644 --- a/ios/MullvadVPN/View controllers/TermsOfService/TermsOfServiceContentView.swift +++ b/ios/MullvadVPN/View controllers/TermsOfService/TermsOfServiceContentView.swift @@ -100,6 +100,8 @@ class TermsOfServiceContentView: UIView { override init(frame: CGRect) { super.init(frame: frame) + self.accessibilityIdentifier = .termsOfServiceView + addSubviews() } diff --git a/ios/MullvadVPNUITests/AccountTests.swift b/ios/MullvadVPNUITests/AccountTests.swift new file mode 100644 index 0000000000..bb719c91a9 --- /dev/null +++ b/ios/MullvadVPNUITests/AccountTests.swift @@ -0,0 +1,53 @@ +// +// MullvadVPNUITests.swift +// MullvadVPNUITests +// +// Created by Niklas Berglund on 2024-01-09. +// Copyright © 2024 Mullvad VPN AB. All rights reserved. +// + +import XCTest + +class AccountTests: BaseUITestCase { + override func setUpWithError() throws { + continueAfterFailure = false + } + + override func tearDownWithError() throws {} + + func testLogin() throws { + let app = XCUIApplication() + app.launch() + + TermsOfServicePage(app) + .tapAgreeButton() + + Alert(app) + .tapOkay() + + LoginPage(app) + .tapAccountNumberTextField() + .enterText(self.noTimeAccountNumber) + .tapAccountNumberSubmitButton() + .verifySuccessIconShown() + .verifyDeviceLabelShown() + } + + func testLoginWithIncorrectAccountNumber() throws { + let app = XCUIApplication() + app.launch() + + TermsOfServicePage(app) + .tapAgreeButton() + + Alert(app) + .tapOkay() + + LoginPage(app) + .tapAccountNumberTextField() + .enterText("0000000000000000") + .tapAccountNumberSubmitButton() + .verifyFailIconShown() + .waitForPageToBeShown() // Verify still on login page + } +} diff --git a/ios/MullvadVPNUITests/BaseUITestCase.swift b/ios/MullvadVPNUITests/BaseUITestCase.swift new file mode 100644 index 0000000000..7ca4356e03 --- /dev/null +++ b/ios/MullvadVPNUITests/BaseUITestCase.swift @@ -0,0 +1,19 @@ +// +// BaseTestCase.swift +// MullvadVPNUITests +// +// Created by Niklas Berglund on 2024-01-12. +// Copyright © 2024 Mullvad VPN AB. All rights reserved. +// + +import Foundation +import XCTest + +class BaseUITestCase: XCTestCase { + // swiftlint:disable force_cast + let noTimeAccountNumber = Bundle(for: AccountTests.self).infoDictionary?["MullvadNoTimeAccountNumber"] as! String + let hasTimeAccountNumber = Bundle(for: AccountTests.self).infoDictionary?["MullvadHasTimeAccountNumber"] as! String + let fiveWireGuardKeysAccountNumber = Bundle(for: AccountTests.self) + .infoDictionary?["MullvadFiveWireGuardKeysAccountNumber"] as! String + // swiftlint:enable force_cast +} diff --git a/ios/MullvadVPNUITests/Info.plist b/ios/MullvadVPNUITests/Info.plist new file mode 100644 index 0000000000..f0e3228b4b --- /dev/null +++ b/ios/MullvadVPNUITests/Info.plist @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>MullvadFiveWireGuardKeysAccountNumber</key> + <string>$(MULLVAD_FIVE_WIREGUARD_KEYS_ACCOUNT_NUMBER)</string> + <key>MullvadHasTimeAccountNumber</key> + <string>$(MULLVAD_HAS_TIME_ACCOUNT_NUMBER)</string> + <key>MullvadNoTimeAccountNumber</key> + <string>$(MULLVAD_NO_TIME_ACCOUNT_NUMBER)</string> +</dict> +</plist> diff --git a/ios/MullvadVPNUITests/Pages/Alert.swift b/ios/MullvadVPNUITests/Pages/Alert.swift new file mode 100644 index 0000000000..7ecfb59e25 --- /dev/null +++ b/ios/MullvadVPNUITests/Pages/Alert.swift @@ -0,0 +1,25 @@ +// +// Alert.swift +// MullvadVPNUITests +// +// Created by Niklas Berglund on 2024-01-10. +// Copyright © 2024 Mullvad VPN AB. All rights reserved. +// + +import Foundation +import XCTest + +/// Generic alert "page" +class Alert: Page { + @discardableResult override init(_ app: XCUIApplication) { + super.init(app) + + self.pageAccessibilityIdentifier = .alertContainerView + waitForPageToBeShown() + } + + @discardableResult func tapOkay() -> Self { + app.buttons[AccessibilityIdentifier.alertOkButton.rawValue].tap() + return self + } +} diff --git a/ios/MullvadVPNUITests/Pages/LoginPage.swift b/ios/MullvadVPNUITests/Pages/LoginPage.swift new file mode 100644 index 0000000000..7d13d88088 --- /dev/null +++ b/ios/MullvadVPNUITests/Pages/LoginPage.swift @@ -0,0 +1,48 @@ +// +// LoginPage.swift +// MullvadVPNUITests +// +// Created by Niklas Berglund on 2024-01-10. +// Copyright © 2024 Mullvad VPN AB. All rights reserved. +// + +import Foundation +import XCTest + +class LoginPage: Page { + @discardableResult override init(_ app: XCUIApplication) { + super.init(app) + + self.pageAccessibilityIdentifier = .loginView + waitForPageToBeShown() + } + + @discardableResult public func tapAccountNumberTextField() -> Self { + app.textFields[AccessibilityIdentifier.loginTextField.rawValue].tap() + return self + } + + @discardableResult public func tapAccountNumberSubmitButton() -> Self { + app.buttons[AccessibilityIdentifier.loginTextFieldButton.rawValue].tap() + return self + } + + @discardableResult public func verifyDeviceLabelShown() -> Self { + XCTAssertTrue( + app.staticTexts[AccessibilityIdentifier.headerDeviceNameLabel.rawValue] + .waitForExistence(timeout: defaultTimeout) + ) + + return self + } + + @discardableResult public func verifySuccessIconShown() -> Self { + app.images.element(matching: .image, identifier: "IconSuccess") + return self + } + + @discardableResult public func verifyFailIconShown() -> Self { + app.images.element(matching: .image, identifier: "IconFail") + return self + } +} diff --git a/ios/MullvadVPNUITests/Pages/Page.swift b/ios/MullvadVPNUITests/Pages/Page.swift new file mode 100644 index 0000000000..775edf0beb --- /dev/null +++ b/ios/MullvadVPNUITests/Pages/Page.swift @@ -0,0 +1,34 @@ +// +// Page.swift +// MullvadVPNUITests +// +// Created by Niklas Berglund on 2024-01-10. +// Copyright © 2024 Mullvad VPN AB. All rights reserved. +// + +import Foundation +import XCTest + +class Page { + let app: XCUIApplication + var pageAccessibilityIdentifier: AccessibilityIdentifier? + let defaultTimeout = 10.0 + + init(_ app: XCUIApplication) { + self.app = app + } + + public func enterText(_ text: String) -> Self { + app.typeText(text) + return self + } + + public func waitForPageToBeShown() { + if let pageAccessibilityIdentifier = self.pageAccessibilityIdentifier { + XCTAssert( + self.app.otherElements[pageAccessibilityIdentifier.rawValue] + .waitForExistence(timeout: defaultTimeout) + ) + } + } +} diff --git a/ios/MullvadVPNUITests/Pages/TermsOfServicePage.swift b/ios/MullvadVPNUITests/Pages/TermsOfServicePage.swift new file mode 100644 index 0000000000..fb64b3237d --- /dev/null +++ b/ios/MullvadVPNUITests/Pages/TermsOfServicePage.swift @@ -0,0 +1,23 @@ +// +// TermsOfServicePage.swift +// MullvadVPNUITests +// +// Created by Niklas Berglund on 2024-01-10. +// Copyright © 2024 Mullvad VPN AB. All rights reserved. +// + +import Foundation +import XCTest + +class TermsOfServicePage: Page { + @discardableResult override init(_ app: XCUIApplication) { + super.init(app) + + self.pageAccessibilityIdentifier = .termsOfServiceView + } + + @discardableResult func tapAgreeButton() -> Self { + app.buttons[AccessibilityIdentifier.agreeButton.rawValue].tap() + return self + } +} diff --git a/ios/TestPlans/MullvadVPNUITests.xctestplan b/ios/TestPlans/MullvadVPNUITests.xctestplan new file mode 100644 index 0000000000..dd5cb5a09e --- /dev/null +++ b/ios/TestPlans/MullvadVPNUITests.xctestplan @@ -0,0 +1,28 @@ +{ + "configurations" : [ + { + "id" : "97A9D9C1-040F-4F36-8CFE-B600F97AB953", + "name" : "Test Scheme Action", + "options" : { + + } + } + ], + "defaultOptions" : { + "targetForVariableExpansion" : { + "containerPath" : "container:MullvadVPN.xcodeproj", + "identifier" : "58CE5E5F224146200008646E", + "name" : "MullvadVPN" + } + }, + "testTargets" : [ + { + "target" : { + "containerPath" : "container:MullvadVPN.xcodeproj", + "identifier" : "852969242B4D9C1F007EAD4C", + "name" : "MullvadVPNUITests" + } + } + ], + "version" : 1 +} |
