diff options
| author | Bug Magnet <marco.nikic@mullvad.net> | 2023-12-20 14:55:53 +0100 |
|---|---|---|
| committer | Bug Magnet <marco.nikic@mullvad.net> | 2023-12-20 14:55:53 +0100 |
| commit | ce7f4f73f82295275631ef05dbe12ba17843ec2d (patch) | |
| tree | 59ab16766342775ff0efbd9e49d0fc6d1e15dd2d | |
| parent | 0f6214ded9a2915b13187fa224d2cee449b823da (diff) | |
| parent | 3fe502fb14343f645b4c8432c94d57d4bc607aff (diff) | |
| download | mullvadvpn-ce7f4f73f82295275631ef05dbe12ba17843ec2d.tar.xz mullvadvpn-ce7f4f73f82295275631ef05dbe12ba17843ec2d.zip | |
Merge branch 'export-identifiers-for-accessibility-elements-ios-127'
29 files changed, 221 insertions, 128 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj index 811b045d47..b0a92a69fc 100644 --- a/ios/MullvadVPN.xcodeproj/project.pbxproj +++ b/ios/MullvadVPN.xcodeproj/project.pbxproj @@ -485,6 +485,8 @@ 58FF9FF42B07C61B00E4C97D /* AccessMethodValidationError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FF9FF32B07C61B00E4C97D /* AccessMethodValidationError.swift */; }; 7A02D4EB2A9CEC7A00C19E31 /* MullvadVPNScreenshots.xctestplan in Resources */ = {isa = PBXBuildFile; fileRef = 7A02D4EA2A9CEC7A00C19E31 /* MullvadVPNScreenshots.xctestplan */; }; 7A09C98129D99215000C2CAC /* String+FuzzyMatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A09C98029D99215000C2CAC /* String+FuzzyMatch.swift */; }; + 7A0B311E2B303A0D004B12E0 /* AccessbilityIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A0B311D2B303A0D004B12E0 /* AccessbilityIdentifier.swift */; }; + 7A0B311F2B303A11004B12E0 /* AccessbilityIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A0B311D2B303A0D004B12E0 /* AccessbilityIdentifier.swift */; }; 7A0C0F632A979C4A0058EFCE /* Coordinator+Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A0C0F622A979C4A0058EFCE /* Coordinator+Router.swift */; }; 7A11DD0B2A9495D400098CD8 /* AppRoutes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5802EBC42A8E44AC00E5CE4C /* AppRoutes.swift */; }; 7A12D0762B062D5C00E9602D /* URLSessionProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A12D0752B062D5C00E9602D /* URLSessionProtocol.swift */; }; @@ -1630,6 +1632,8 @@ 58FF9FF32B07C61B00E4C97D /* AccessMethodValidationError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessMethodValidationError.swift; sourceTree = "<group>"; }; 7A02D4EA2A9CEC7A00C19E31 /* MullvadVPNScreenshots.xctestplan */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MullvadVPNScreenshots.xctestplan; sourceTree = "<group>"; }; 7A09C98029D99215000C2CAC /* String+FuzzyMatch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+FuzzyMatch.swift"; sourceTree = "<group>"; }; + 7A0B31152B2B4BE7004B12E0 /* AccessbilityIdentifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccessbilityIdentifier.swift; sourceTree = "<group>"; }; + 7A0B311D2B303A0D004B12E0 /* AccessbilityIdentifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccessbilityIdentifier.swift; sourceTree = "<group>"; }; 7A0C0F622A979C4A0058EFCE /* Coordinator+Router.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Coordinator+Router.swift"; sourceTree = "<group>"; }; 7A12D0752B062D5C00E9602D /* URLSessionProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLSessionProtocol.swift; sourceTree = "<group>"; }; 7A1A26422A2612AE00B978AA /* PaymentAlertPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentAlertPresenter.swift; sourceTree = "<group>"; }; @@ -2019,15 +2023,16 @@ 581943F228F8014500B0CB5E /* MullvadTypes */ = { isa = PBXGroup; children = ( + 7A0B31152B2B4BE7004B12E0 /* AccessbilityIdentifier.swift */, 584D26BE270C550B004EA533 /* AnyIPAddress.swift */, 586A951329013235007BAF2B /* AnyIPEndpoint.swift */, 06AC113628F83FD70037AF9A /* Cancellable.swift */, - A9A8A8EA2A262AB30086D569 /* FileCache.swift */, 58E511E328DDDE8900B0BCDE /* CustomErrorDescriptionProtocol.swift */, 586168682976F6BD00EF8598 /* DisplayError.swift */, 7A307AD82A8CD8DA0017618B /* Duration.swift */, 7A307ADA2A8F56DF0017618B /* Duration+Extensions.swift */, 58E511EA28DDE18400B0BCDE /* Error+Chain.swift */, + A9A8A8EA2A262AB30086D569 /* FileCache.swift */, 58900D0228BBDCC70094E4F0 /* FixedWidthInteger+Arithmetics.swift */, 06AC115628F848D00037AF9A /* IPAddress+Codable.swift */, 58561C98239A5D1500BD6B5E /* IPv4Endpoint.swift */, @@ -2044,8 +2049,8 @@ 5898D2AF2902A67C00EB5EBA /* RelayLocation.swift */, 581DA2722A1E227D0046ED47 /* RESTTypes.swift */, 58F1311427E0B2AB007AC5BC /* Result+Extensions.swift */, - 58E511E028DDB7F100B0BCDE /* WrappingError.swift */, A91614D02B108D1B00F416EB /* TransportLayer.swift */, + 58E511E028DDB7F100B0BCDE /* WrappingError.swift */, ); path = MullvadTypes; sourceTree = "<group>"; @@ -2428,6 +2433,7 @@ 583FE02829C1B079006E85F9 /* Classes */ = { isa = PBXGroup; children = ( + 7A0B311D2B303A0D004B12E0 /* AccessbilityIdentifier.swift */, 587988C628A2A01F00E3DF54 /* AccountDataThrottling.swift */, F04FBE602A8379EE009278D7 /* AppPreferences.swift */, 5802EBC42A8E44AC00E5CE4C /* AppRoutes.swift */, @@ -4661,6 +4667,7 @@ 7A9CCCB82A96302800DD6A34 /* SetupAccountCompletedCoordinator.swift in Sources */, 58435AC229CB2A350099C71B /* LocationCellFactory.swift in Sources */, 58BFA5C622A7C97F00A6173D /* RelayCacheTracker.swift in Sources */, + 7A0B311E2B303A0D004B12E0 /* AccessbilityIdentifier.swift in Sources */, E158B360285381C60002F069 /* String+AccountFormatting.swift in Sources */, 7AC8A3AE2ABC6FBB00DC4939 /* SettingsHeaderView.swift in Sources */, 588D7EDC2AF3A55E005DF40A /* ListAccessMethodInteractorProtocol.swift in Sources */, @@ -4958,6 +4965,7 @@ buildActionMask = 2147483647; files = ( 58D0C7A223F1CECF00FE9BA7 /* MullvadVPNScreenshots.swift in Sources */, + 7A0B311F2B303A11004B12E0 /* AccessbilityIdentifier.swift in Sources */, 58D0C79E23F1CEBA00FE9BA7 /* SnapshotHelper.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/ios/MullvadVPN/AppDelegate.swift b/ios/MullvadVPN/AppDelegate.swift index 2a7e869888..64f642cd89 100644 --- a/ios/MullvadVPN/AppDelegate.swift +++ b/ios/MullvadVPN/AppDelegate.swift @@ -48,6 +48,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { + if ProcessInfo().arguments.contains("DisableAnimations") { + UIView.setAnimationsEnabled(false) + } + let containerURL = ApplicationConfiguration.containerURL configureLogging() diff --git a/ios/MullvadVPN/Classes/AccessbilityIdentifier.swift b/ios/MullvadVPN/Classes/AccessbilityIdentifier.swift new file mode 100644 index 0000000000..340762d787 --- /dev/null +++ b/ios/MullvadVPN/Classes/AccessbilityIdentifier.swift @@ -0,0 +1,77 @@ +// +// RelayFilter.swift +// MullvadVPN +// +// Created by Jon Petersson on 2023-12-20. +// Copyright © 2023 Mullvad VPN AB. All rights reserved. +// + +import UIKit + +public enum AccessibilityIdentifier: String { + // Buttons + case accountButton + case agreeButton + case alertOkButton + case applyButton + case cancelButton + case collapseButton + case deleteButton + case disconnectButton + case infoButton + case learnAboutPrivacyButton + case loginBarButton + case logoutButton + case purchaseButton + case redeemVoucherButton + case selectLocationButton + case settingsButton + case startUsingTheAppButton + + // Cells + case preferencesCell + case versionCell + case problemReportCell + case faqCell + case apiAccessCell + case relayFilterOwnershipCell + case relayFilterProviderCell + + // Other UI elements + case loginTextField + + // DNS settings + case dnsSettings + case wireGuardCustomPort + case wireGuardObfuscationAutomatic + case wireGuardObfuscationOff + case wireGuardObfuscationOn + case wireGuardPort + + // Custom DNS + case blockAdvertising + case blockTracking + case blockMalware + case blockGambling + case blockAdultContent + case blockSocialMedia + case useCustomDNS + case addDNSServer + case dnsServer + case dnsServerInfo + + // Error + case unknown +} + +extension UIAccessibilityIdentification { + var accessibilityIdentifier: AccessibilityIdentifier? { + get { + guard let accessibilityIdentifier else { return nil } + return AccessibilityIdentifier(rawValue: accessibilityIdentifier) + } + set { + accessibilityIdentifier = newValue?.rawValue + } + } +} diff --git a/ios/MullvadVPN/Containers/Root/HeaderBarView.swift b/ios/MullvadVPN/Containers/Root/HeaderBarView.swift index ef7e37688a..6b551cb276 100644 --- a/ios/MullvadVPN/Containers/Root/HeaderBarView.swift +++ b/ios/MullvadVPN/Containers/Root/HeaderBarView.swift @@ -6,7 +6,6 @@ // Copyright © 2020 Mullvad VPN AB. All rights reserved. // -import Foundation import UIKit class HeaderBarView: UIView { @@ -58,7 +57,7 @@ class HeaderBarView: UIView { let accountButton: UIButton = { let button = makeHeaderBarButton(with: UIImage(named: "IconAccount")) - button.accessibilityIdentifier = "AccountButton" + button.accessibilityIdentifier = .accountButton button.accessibilityLabel = NSLocalizedString( "HEADER_BAR_ACCOUNT_BUTTON_ACCESSIBILITY_LABEL", tableName: "HeaderBar", @@ -72,7 +71,7 @@ class HeaderBarView: UIView { let settingsButton: UIButton = { let button = makeHeaderBarButton(with: UIImage(named: "IconSettings")) - button.accessibilityIdentifier = "SettingsButton" + button.accessibilityIdentifier = .settingsButton button.accessibilityLabel = NSLocalizedString( "HEADER_BAR_SETTINGS_BUTTON_ACCESSIBILITY_LABEL", tableName: "HeaderBar", diff --git a/ios/MullvadVPN/Coordinators/ChangeLogCoordinator.swift b/ios/MullvadVPN/Coordinators/ChangeLogCoordinator.swift index 915502fd43..c3e53cc9f4 100644 --- a/ios/MullvadVPN/Coordinators/ChangeLogCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/ChangeLogCoordinator.swift @@ -38,6 +38,7 @@ final class ChangeLogCoordinator: Coordinator, Presentable { comment: "" ), style: .default, + accessibilityId: .alertOkButton, handler: { [weak self] in guard let self else { return } didFinish?(self) diff --git a/ios/MullvadVPN/Coordinators/WelcomeCoordinator.swift b/ios/MullvadVPN/Coordinators/WelcomeCoordinator.swift index 512d31df00..eefe8ce9d1 100644 --- a/ios/MullvadVPN/Coordinators/WelcomeCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/WelcomeCoordinator.swift @@ -6,7 +6,6 @@ // Copyright © 2023 Mullvad VPN AB. All rights reserved. // -import Foundation import MullvadREST import Routing import StoreKit diff --git a/ios/MullvadVPN/View controllers/Account/AccountContentView.swift b/ios/MullvadVPN/View controllers/Account/AccountContentView.swift index 563b9e8505..55cb501096 100644 --- a/ios/MullvadVPN/View controllers/Account/AccountContentView.swift +++ b/ios/MullvadVPN/View controllers/Account/AccountContentView.swift @@ -12,7 +12,7 @@ class AccountContentView: UIView { let purchaseButton: InAppPurchaseButton = { let button = InAppPurchaseButton() button.translatesAutoresizingMaskIntoConstraints = false - button.accessibilityIdentifier = "PurchaseButton" + button.accessibilityIdentifier = .purchaseButton return button }() @@ -31,7 +31,7 @@ class AccountContentView: UIView { let redeemVoucherButton: AppButton = { let button = AppButton(style: .success) button.translatesAutoresizingMaskIntoConstraints = false - button.accessibilityIdentifier = "redeemVoucherButton" + button.accessibilityIdentifier = .redeemVoucherButton button.setTitle(NSLocalizedString( "REDEEM_VOUCHER_BUTTON_TITLE", tableName: "Account", @@ -44,7 +44,7 @@ class AccountContentView: UIView { let logoutButton: AppButton = { let button = AppButton(style: .danger) button.translatesAutoresizingMaskIntoConstraints = false - button.accessibilityIdentifier = "LogoutButton" + button.accessibilityIdentifier = .logoutButton button.setTitle(NSLocalizedString( "LOGOUT_BUTTON_TITLE", tableName: "Account", @@ -57,7 +57,7 @@ class AccountContentView: UIView { let deleteButton: AppButton = { let button = AppButton(style: .danger) button.translatesAutoresizingMaskIntoConstraints = false - button.accessibilityIdentifier = "DeleteButton" + button.accessibilityIdentifier = .deleteButton button.setTitle(NSLocalizedString( "DELETE_BUTTON_TITLE", tableName: "Account", diff --git a/ios/MullvadVPN/View controllers/Account/AccountDeviceRow.swift b/ios/MullvadVPN/View controllers/Account/AccountDeviceRow.swift index ae7ac01991..5a38dd908a 100644 --- a/ios/MullvadVPN/View controllers/Account/AccountDeviceRow.swift +++ b/ios/MullvadVPN/View controllers/Account/AccountDeviceRow.swift @@ -6,7 +6,6 @@ // Copyright © 2023 Mullvad VPN AB. All rights reserved. // -import Foundation import UIKit class AccountDeviceRow: UIView { @@ -41,7 +40,7 @@ class AccountDeviceRow: UIView { private let infoButton: UIButton = { let button = IncreasedHitButton(type: .system) - button.accessibilityIdentifier = "InfoButton" + button.accessibilityIdentifier = .infoButton button.tintColor = .white button.setImage(UIImage(named: "IconInfo"), for: .normal) return button diff --git a/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionContentView.swift b/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionContentView.swift index 05ef64925a..f0200849ae 100644 --- a/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionContentView.swift +++ b/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionContentView.swift @@ -21,10 +21,6 @@ class AccountDeletionContentView: UIView { case failure(Error) } - private enum Action: String { - case delete, cancel - } - private let scrollView: UIScrollView = { let scrollView = UIScrollView() return scrollView @@ -103,7 +99,7 @@ class AccountDeletionContentView: UIView { private let deleteButton: AppButton = { let button = AppButton(style: .danger) - button.accessibilityIdentifier = Action.delete.rawValue + button.accessibilityIdentifier = .deleteButton button.setTitle(NSLocalizedString( "OK_BUTTON_TITLE", tableName: "Account", @@ -115,7 +111,7 @@ class AccountDeletionContentView: UIView { private let cancelButton: AppButton = { let button = AppButton(style: .default) - button.accessibilityIdentifier = Action.cancel.rawValue + button.accessibilityIdentifier = .cancelButton button.setTitle(NSLocalizedString( "CANCEL_BUTTON_TITLE", tableName: "Account", @@ -376,10 +372,10 @@ class AccountDeletionContentView: UIView { } @objc private func didPress(button: AppButton) { - switch Action(rawValue: button.accessibilityIdentifier ?? "") { - case .delete: + switch AccessibilityIdentifier(rawValue: button.accessibilityIdentifier ?? "") { + case .deleteButton: delegate?.didTapDeleteButton(contentView: self, button: button) - case .cancel: + case .cancelButton: delegate?.didTapCancelButton(contentView: self, button: button) default: return } diff --git a/ios/MullvadVPN/View controllers/Alert/AlertPresentation.swift b/ios/MullvadVPN/View controllers/Alert/AlertPresentation.swift index 38f60a8981..b0056b7ea9 100644 --- a/ios/MullvadVPN/View controllers/Alert/AlertPresentation.swift +++ b/ios/MullvadVPN/View controllers/Alert/AlertPresentation.swift @@ -17,7 +17,7 @@ struct AlertMetadata { struct AlertAction { let title: String let style: AlertActionStyle - var accessibilityID: String? + var accessibilityId: AccessibilityIdentifier? var handler: (() -> Void)? } diff --git a/ios/MullvadVPN/View controllers/Alert/AlertViewController.swift b/ios/MullvadVPN/View controllers/Alert/AlertViewController.swift index 96142fa502..1cc23b2943 100644 --- a/ios/MullvadVPN/View controllers/Alert/AlertViewController.swift +++ b/ios/MullvadVPN/View controllers/Alert/AlertViewController.swift @@ -126,6 +126,7 @@ class AlertViewController: UIViewController { addAction( title: action.title, style: action.style, + accessibilityId: action.accessibilityId, handler: action.handler ) } @@ -251,10 +252,16 @@ class AlertViewController: UIViewController { contentView.addArrangedSubview(iconView) } - private func addAction(title: String, style: AlertActionStyle, handler: (() -> Void)? = nil) { + private func addAction( + title: String, + style: AlertActionStyle, + accessibilityId: AccessibilityIdentifier?, + handler: (() -> Void)? = nil + ) { let button = AppButton(style: style.buttonStyle) button.setTitle(title, for: .normal) + button.accessibilityIdentifier = accessibilityId button.addTarget(self, action: #selector(didTapButton), for: .touchUpInside) buttonView.addArrangedSubview(button) diff --git a/ios/MullvadVPN/View controllers/CreationAccount/Completed/SetupAccountCompletedContentView.swift b/ios/MullvadVPN/View controllers/CreationAccount/Completed/SetupAccountCompletedContentView.swift index 5b83cfffb4..6ea08e3914 100644 --- a/ios/MullvadVPN/View controllers/CreationAccount/Completed/SetupAccountCompletedContentView.swift +++ b/ios/MullvadVPN/View controllers/CreationAccount/Completed/SetupAccountCompletedContentView.swift @@ -14,10 +14,6 @@ protocol SetupAccountCompletedContentViewDelegate: AnyObject { } class SetupAccountCompletedContentView: UIView { - private enum Action: String { - case learnAboutPrivacy, startUsingTheApp - } - private let titleLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .largeTitle, weight: .bold) @@ -57,7 +53,7 @@ class SetupAccountCompletedContentView: UIView { private let privacyButton: AppButton = { let button = AppButton(style: .success) - button.accessibilityIdentifier = Action.learnAboutPrivacy.rawValue + button.accessibilityIdentifier = .learnAboutPrivacyButton let localizedString = NSLocalizedString( "LEARN_ABOUT_PRIVACY_BUTTON", tableName: "CreatedAccountConfirmation", @@ -71,7 +67,7 @@ class SetupAccountCompletedContentView: UIView { private let startButton: AppButton = { let button = AppButton(style: .success) - button.accessibilityIdentifier = Action.startUsingTheApp.rawValue + button.accessibilityIdentifier = .startUsingTheAppButton button.setTitle(NSLocalizedString( "START_USING_THE_APP_BUTTON", tableName: "CreatedAccountConfirmation", @@ -142,10 +138,10 @@ class SetupAccountCompletedContentView: UIView { } @objc private func tapped(button: AppButton) { - switch button.accessibilityIdentifier { - case Action.learnAboutPrivacy.rawValue: + switch AccessibilityIdentifier(rawValue: button.accessibilityIdentifier ?? "") { + case .learnAboutPrivacyButton: delegate?.didTapPrivacyButton(view: self, button: button) - case Action.startUsingTheApp.rawValue: + case .startUsingTheAppButton: delegate?.didTapStartingAppButton(view: self, button: button) default: return } diff --git a/ios/MullvadVPN/View controllers/CreationAccount/Welcome/WelcomeContentView.swift b/ios/MullvadVPN/View controllers/CreationAccount/Welcome/WelcomeContentView.swift index 7ee0326900..466a6b24ad 100644 --- a/ios/MullvadVPN/View controllers/CreationAccount/Welcome/WelcomeContentView.swift +++ b/ios/MullvadVPN/View controllers/CreationAccount/Welcome/WelcomeContentView.swift @@ -20,10 +20,6 @@ struct WelcomeViewModel { } final class WelcomeContentView: UIView { - private enum Action: String { - case purchase, redeemVoucher, showInfo - } - private let titleLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .largeTitle, weight: .bold) @@ -79,7 +75,7 @@ final class WelcomeContentView: UIView { private let infoButton: UIButton = { let button = IncreasedHitButton(type: .system) - button.accessibilityIdentifier = Action.showInfo.rawValue + button.accessibilityIdentifier = .infoButton button.tintColor = .white button.translatesAutoresizingMaskIntoConstraints = false button.setImage(UIImage(named: "IconInfo"), for: .normal) @@ -111,7 +107,7 @@ final class WelcomeContentView: UIView { private let purchaseButton: InAppPurchaseButton = { let button = InAppPurchaseButton() - button.accessibilityIdentifier = Action.purchase.rawValue + button.accessibilityIdentifier = .purchaseButton let localizedString = NSLocalizedString( "BUY_CREDIT_BUTTON", tableName: "Welcome", @@ -124,7 +120,7 @@ final class WelcomeContentView: UIView { private let redeemVoucherButton: AppButton = { let button = AppButton(style: .success) - button.accessibilityIdentifier = Action.redeemVoucher.rawValue + button.accessibilityIdentifier = .redeemVoucherButton button.setTitle(NSLocalizedString( "REDEEM_VOUCHER_BUTTON_TITLE", tableName: "Account", @@ -252,12 +248,12 @@ final class WelcomeContentView: UIView { } @objc private func tapped(button: AppButton) { - switch button.accessibilityIdentifier { - case Action.purchase.rawValue: + switch AccessibilityIdentifier(rawValue: button.accessibilityIdentifier ?? "") { + case .purchaseButton: delegate?.didTapPurchaseButton(welcomeContentView: self, button: button) - case Action.redeemVoucher.rawValue: + case .redeemVoucherButton: delegate?.didTapRedeemVoucherButton(welcomeContentView: self, button: button) - case Action.showInfo.rawValue: + case .infoButton: delegate?.didTapInfoButton(welcomeContentView: self, button: button) default: return } diff --git a/ios/MullvadVPN/View controllers/Login/LoginContentView.swift b/ios/MullvadVPN/View controllers/Login/LoginContentView.swift index 5bcce9b6b5..940317347c 100644 --- a/ios/MullvadVPN/View controllers/Login/LoginContentView.swift +++ b/ios/MullvadVPN/View controllers/Login/LoginContentView.swift @@ -103,7 +103,7 @@ class LoginContentView: UIView { backgroundColor = .primaryColor directionalLayoutMargins = UIMetrics.contentLayoutMargins - accountInputGroup.textField.accessibilityIdentifier = "LoginTextField" + accountInputGroup.textField.accessibilityIdentifier = .loginTextField keyboardResponder = AutomaticKeyboardResponder( targetView: self, diff --git a/ios/MullvadVPN/View controllers/Login/LoginViewController.swift b/ios/MullvadVPN/View controllers/Login/LoginViewController.swift index a2af008753..e2bde94b0c 100644 --- a/ios/MullvadVPN/View controllers/Login/LoginViewController.swift +++ b/ios/MullvadVPN/View controllers/Login/LoginViewController.swift @@ -59,7 +59,7 @@ class LoginViewController: UIViewController, RootContainment { target: self, action: #selector(doLogin) ) - barButtonItem.accessibilityIdentifier = "LoginBarButtonItem" + barButtonItem.accessibilityIdentifier = .loginBarButton return barButtonItem }() diff --git a/ios/MullvadVPN/View controllers/Preferences/CustomDNSCellFactory.swift b/ios/MullvadVPN/View controllers/Preferences/CustomDNSCellFactory.swift index 93b354dcd9..18729b56a1 100644 --- a/ios/MullvadVPN/View controllers/Preferences/CustomDNSCellFactory.swift +++ b/ios/MullvadVPN/View controllers/Preferences/CustomDNSCellFactory.swift @@ -44,7 +44,7 @@ final class CustomDNSCellFactory: CellFactoryProtocol { guard let cell = cell as? SettingsSwitchCell else { return } cell.titleLabel.text = title - cell.accessibilityHint = nil + cell.accessibilityIdentifier = preference.accessibilityIdentifier cell.applySubCellStyling() cell.setOn(toggleSetting, animated: false) cell.action = { [weak self] isOn in @@ -185,6 +185,7 @@ final class CustomDNSCellFactory: CellFactoryProtocol { cell.textField.text = dnsServerEntry.address cell.isValidInput = dnsEntryIsValid(identifier: entryIdentifier, cell: cell) + cell.accessibilityIdentifier = "\(item.accessibilityIdentifier) (\(entryIdentifier))" cell.onTextChange = { [weak self] cell in cell.isValidInput = self? diff --git a/ios/MullvadVPN/View controllers/Preferences/CustomDNSDataSource.swift b/ios/MullvadVPN/View controllers/Preferences/CustomDNSDataSource.swift index 105d7be1af..ea7217b1ea 100644 --- a/ios/MullvadVPN/View controllers/Preferences/CustomDNSDataSource.swift +++ b/ios/MullvadVPN/View controllers/Preferences/CustomDNSDataSource.swift @@ -64,28 +64,28 @@ final class CustomDNSDataSource: UITableViewDiffableDataSource< [.blockAdvertising, .blockTracking, .blockMalware, .blockAdultContent, .blockGambling, .blockSocialMedia] } - var accessibilityIdentifier: String { + var accessibilityIdentifier: AccessibilityIdentifier { switch self { case .blockAdvertising: - return "blockAdvertising" + return .blockAdvertising case .blockTracking: - return "blockTracking" + return .blockTracking case .blockMalware: - return "blockMalware" + return .blockMalware case .blockGambling: - return "blockGambling" + return .blockGambling case .blockAdultContent: - return "blockAdultContent" + return .blockAdultContent case .blockSocialMedia: - return "blockSocialMedia" + return .blockSocialMedia case .useCustomDNS: - return "useCustomDNS" + return .useCustomDNS case .addDNSServer: - return "addDNSServer" - case let .dnsServer(uuid): - return "dnsServer(\(uuid.uuidString))" + return .addDNSServer + case .dnsServer: + return .dnsServer case .dnsServerInfo: - return "dnsServerInfo" + return .dnsServerInfo } } diff --git a/ios/MullvadVPN/View controllers/Preferences/PreferencesCellFactory.swift b/ios/MullvadVPN/View controllers/Preferences/PreferencesCellFactory.swift index 00cfc5a304..bf734b5f83 100644 --- a/ios/MullvadVPN/View controllers/Preferences/PreferencesCellFactory.swift +++ b/ios/MullvadVPN/View controllers/Preferences/PreferencesCellFactory.swift @@ -49,7 +49,7 @@ final class PreferencesCellFactory: CellFactoryProtocol { ) cell.disclosureType = .chevron - cell.accessibilityHint = nil + cell.accessibilityIdentifier = item.accessibilityIdentifier case let .wireGuardPort(port): guard let cell = cell as? SelectableSettingsCell else { return } @@ -65,7 +65,7 @@ final class PreferencesCellFactory: CellFactoryProtocol { } cell.titleLabel.text = portString - cell.accessibilityHint = nil + cell.accessibilityIdentifier = "\(item.accessibilityIdentifier.rawValue) (\(portString))" cell.applySubCellStyling() case .wireGuardCustomPort: @@ -84,7 +84,7 @@ final class PreferencesCellFactory: CellFactoryProtocol { comment: "" ) - cell.accessibilityHint = nil + cell.accessibilityIdentifier = item.accessibilityIdentifier cell.applySubCellStyling() cell.inputDidChange = { [weak self] text in @@ -117,7 +117,7 @@ final class PreferencesCellFactory: CellFactoryProtocol { value: "Automatic", comment: "" ) - cell.accessibilityHint = nil + cell.accessibilityIdentifier = item.accessibilityIdentifier cell.applySubCellStyling() case .wireGuardObfuscationOn: @@ -129,7 +129,7 @@ final class PreferencesCellFactory: CellFactoryProtocol { value: "On (UDP-over-TCP)", comment: "" ) - cell.accessibilityHint = nil + cell.accessibilityIdentifier = item.accessibilityIdentifier cell.applySubCellStyling() case .wireGuardObfuscationOff: guard let cell = cell as? SelectableSettingsCell else { return } @@ -140,21 +140,20 @@ final class PreferencesCellFactory: CellFactoryProtocol { value: "Off", comment: "" ) - cell.accessibilityHint = nil + cell.accessibilityIdentifier = item.accessibilityIdentifier cell.applySubCellStyling() case let .wireGuardObfuscationPort(port): guard let cell = cell as? SelectableSettingsCell else { return } - let portValue = port == 0 ? "Automatic" : "\(port)" - + let portString = port == 0 ? "Automatic" : "\(port)" cell.titleLabel.text = NSLocalizedString( "WIRE_GUARD_OBFUSCATION_PORT_LABEL", tableName: "Preferences", - value: portValue, + value: portString, comment: "" ) - cell.accessibilityHint = nil + cell.accessibilityIdentifier = "\(item.accessibilityIdentifier.rawValue) (\(portString))" cell.applySubCellStyling() } } diff --git a/ios/MullvadVPN/View controllers/Preferences/PreferencesDataSource.swift b/ios/MullvadVPN/View controllers/Preferences/PreferencesDataSource.swift index 176c843aff..b726bded69 100644 --- a/ios/MullvadVPN/View controllers/Preferences/PreferencesDataSource.swift +++ b/ios/MullvadVPN/View controllers/Preferences/PreferencesDataSource.swift @@ -76,29 +76,22 @@ final class PreferencesDataSource: UITableViewDiffableDataSource< [.wireGuardObfuscationPort(0), wireGuardObfuscationPort(80), wireGuardObfuscationPort(5001)] } - var accessibilityIdentifier: String { + var accessibilityIdentifier: AccessibilityIdentifier { switch self { case .dnsSettings: - return "DNS settings" - case let .wireGuardPort(port): - if let port { - return "wireGuardPort(\(port))" - } else { - return "wireGuardPort" - } + return .dnsSettings + case .wireGuardPort: + return .wireGuardPort case .wireGuardCustomPort: - return "wireGuardCustomPort" + return .wireGuardCustomPort case .wireGuardObfuscationAutomatic: - return "Automatic" + return .wireGuardObfuscationAutomatic case .wireGuardObfuscationOn: - return "On (UDP-over-TCP)" + return .wireGuardObfuscationOn case .wireGuardObfuscationOff: - return "Off" - case let .wireGuardObfuscationPort(port): - if port == 0 { - return "Automatic" - } - return "\(port)" + return .wireGuardObfuscationOff + case .wireGuardObfuscationPort: + return .wireGuardObfuscationAutomatic } } diff --git a/ios/MullvadVPN/View controllers/RelayFilter/RelayFilterCellFactory.swift b/ios/MullvadVPN/View controllers/RelayFilter/RelayFilterCellFactory.swift index 29aec029a3..99c341863e 100644 --- a/ios/MullvadVPN/View controllers/RelayFilter/RelayFilterCellFactory.swift +++ b/ios/MullvadVPN/View controllers/RelayFilter/RelayFilterCellFactory.swift @@ -50,7 +50,7 @@ struct RelayFilterCellFactory: CellFactoryProtocol { ) cell.applySubCellStyling() - cell.accessibilityIdentifier = "RelayFilterOwnershipCell" + cell.accessibilityIdentifier = .relayFilterOwnershipCell } private func configureProviderCell(_ cell: UITableViewCell, item: RelayFilterDataSource.Item) { @@ -78,7 +78,7 @@ struct RelayFilterCellFactory: CellFactoryProtocol { ) cell.applySubCellStyling() - cell.accessibilityIdentifier = "RelayFilterProviderCell" + cell.accessibilityIdentifier = .relayFilterProviderCell } private func setFontWeight(_ weight: UIFont.Weight, to label: UILabel) { diff --git a/ios/MullvadVPN/View controllers/RelayFilter/RelayFilterViewController.swift b/ios/MullvadVPN/View controllers/RelayFilter/RelayFilterViewController.swift index 8728a4761b..8cfb00473b 100644 --- a/ios/MullvadVPN/View controllers/RelayFilter/RelayFilterViewController.swift +++ b/ios/MullvadVPN/View controllers/RelayFilter/RelayFilterViewController.swift @@ -21,7 +21,7 @@ class RelayFilterViewController: UIViewController { private let applyButton: AppButton = { let button = AppButton(style: .success) - button.accessibilityIdentifier = "ApplyButton" + button.accessibilityIdentifier = .applyButton button.setTitle(NSLocalizedString( "RELAY_FILTER_BUTTON_TITLE", tableName: "RelayFilter", diff --git a/ios/MullvadVPN/View controllers/SelectLocation/SelectLocationCell.swift b/ios/MullvadVPN/View controllers/SelectLocation/SelectLocationCell.swift index 80edfcceb7..05a9c46664 100644 --- a/ios/MullvadVPN/View controllers/SelectLocation/SelectLocationCell.swift +++ b/ios/MullvadVPN/View controllers/SelectLocation/SelectLocationCell.swift @@ -111,7 +111,7 @@ class SelectLocationCell: UITableViewCell { tickImageView.tintColor = .white - collapseButton.accessibilityIdentifier = "CollapseButton" + collapseButton.accessibilityIdentifier = .collapseButton collapseButton.isAccessibilityElement = false collapseButton.tintColor = .white collapseButton.addTarget(self, action: #selector(handleCollapseButton(_:)), for: .touchUpInside) diff --git a/ios/MullvadVPN/View controllers/Settings/SettingsCell.swift b/ios/MullvadVPN/View controllers/Settings/SettingsCell.swift index 33dd84f849..e29c5f7593 100644 --- a/ios/MullvadVPN/View controllers/Settings/SettingsCell.swift +++ b/ios/MullvadVPN/View controllers/Settings/SettingsCell.swift @@ -62,7 +62,7 @@ class SettingsCell: UITableViewCell, CustomCellDisclosureHandling { private let buttonWidth: CGFloat = 24 private let infoButton: UIButton = { let button = UIButton(type: .custom) - button.accessibilityIdentifier = "InfoButton" + button.accessibilityIdentifier = .infoButton button.tintColor = .white button.setImage(UIImage(named: "IconInfo"), for: .normal) button.isHidden = true diff --git a/ios/MullvadVPN/View controllers/Settings/SettingsCellFactory.swift b/ios/MullvadVPN/View controllers/Settings/SettingsCellFactory.swift index 6955c3870d..4cd7884aef 100644 --- a/ios/MullvadVPN/View controllers/Settings/SettingsCellFactory.swift +++ b/ios/MullvadVPN/View controllers/Settings/SettingsCellFactory.swift @@ -38,7 +38,7 @@ struct SettingsCellFactory: CellFactoryProtocol { comment: "" ) cell.detailTitleLabel.text = nil - cell.accessibilityIdentifier = "PreferencesCell" + cell.accessibilityIdentifier = item.accessibilityIdentifier cell.disclosureType = .chevron case .version: @@ -51,7 +51,7 @@ struct SettingsCellFactory: CellFactoryProtocol { comment: "" ) cell.detailTitleLabel.text = Bundle.main.productVersion - cell.accessibilityIdentifier = nil + cell.accessibilityIdentifier = item.accessibilityIdentifier cell.disclosureType = .none case .problemReport: @@ -64,7 +64,7 @@ struct SettingsCellFactory: CellFactoryProtocol { comment: "" ) cell.detailTitleLabel.text = nil - cell.accessibilityIdentifier = nil + cell.accessibilityIdentifier = item.accessibilityIdentifier cell.disclosureType = .chevron case .faq: @@ -77,7 +77,7 @@ struct SettingsCellFactory: CellFactoryProtocol { comment: "" ) cell.detailTitleLabel.text = nil - cell.accessibilityIdentifier = nil + cell.accessibilityIdentifier = item.accessibilityIdentifier cell.disclosureType = .externalLink case .apiAccess: @@ -90,7 +90,7 @@ struct SettingsCellFactory: CellFactoryProtocol { comment: "" ) cell.detailTitleLabel.text = nil - cell.accessibilityIdentifier = nil + cell.accessibilityIdentifier = item.accessibilityIdentifier cell.disclosureType = .chevron } } diff --git a/ios/MullvadVPN/View controllers/Settings/SettingsDataSource.swift b/ios/MullvadVPN/View controllers/Settings/SettingsDataSource.swift index 535871c742..a7615bdf98 100644 --- a/ios/MullvadVPN/View controllers/Settings/SettingsDataSource.swift +++ b/ios/MullvadVPN/View controllers/Settings/SettingsDataSource.swift @@ -40,6 +40,21 @@ final class SettingsDataSource: UITableViewDiffableDataSource<SettingsDataSource case faq case apiAccess + var accessibilityIdentifier: AccessibilityIdentifier { + switch self { + case .preferences: + return .preferencesCell + case .version: + return .versionCell + case .problemReport: + return .problemReportCell + case .faq: + return .faqCell + case .apiAccess: + return .apiAccessCell + } + } + var reuseIdentifier: CellReuseIdentifiers { .basicCell } diff --git a/ios/MullvadVPN/View controllers/Settings/SettingsHeaderView.swift b/ios/MullvadVPN/View controllers/Settings/SettingsHeaderView.swift index ea790a8c28..956367e5e0 100644 --- a/ios/MullvadVPN/View controllers/Settings/SettingsHeaderView.swift +++ b/ios/MullvadVPN/View controllers/Settings/SettingsHeaderView.swift @@ -23,7 +23,7 @@ class SettingsHeaderView: UITableViewHeaderFooterView { let infoButton: UIButton = { let button = UIButton(type: .custom) - button.accessibilityIdentifier = "InfoButton" + button.accessibilityIdentifier = .infoButton button.tintColor = .white button.setImage(UIImage(named: "IconInfo"), for: .normal) return button @@ -31,7 +31,7 @@ class SettingsHeaderView: UITableViewHeaderFooterView { let collapseButton: UIButton = { let button = UIButton(type: .custom) - button.accessibilityIdentifier = "CollapseButton" + button.accessibilityIdentifier = .collapseButton button.tintColor = .white return button }() diff --git a/ios/MullvadVPN/View controllers/TermsOfService/TermsOfServiceContentView.swift b/ios/MullvadVPN/View controllers/TermsOfService/TermsOfServiceContentView.swift index ec4541dabf..e4292d2a80 100644 --- a/ios/MullvadVPN/View controllers/TermsOfService/TermsOfServiceContentView.swift +++ b/ios/MullvadVPN/View controllers/TermsOfService/TermsOfServiceContentView.swift @@ -66,7 +66,7 @@ class TermsOfServiceContentView: UIView { let agreeButton: AppButton = { let button = AppButton(style: .default) button.translatesAutoresizingMaskIntoConstraints = false - button.accessibilityIdentifier = "AgreeButton" + button.accessibilityIdentifier = .agreeButton button.setTitle(NSLocalizedString( "CONTINUE_BUTTON_TITLE", tableName: "TermsOfService", diff --git a/ios/MullvadVPN/View controllers/Tunnel/TunnelControlView.swift b/ios/MullvadVPN/View controllers/Tunnel/TunnelControlView.swift index e1493f27fa..75d2b012c8 100644 --- a/ios/MullvadVPN/View controllers/Tunnel/TunnelControlView.swift +++ b/ios/MullvadVPN/View controllers/Tunnel/TunnelControlView.swift @@ -70,14 +70,14 @@ final class TunnelControlView: UIView { private let cancelButton: AppButton = { let button = AppButton(style: .translucentDanger) - button.accessibilityIdentifier = "CancelButton" + button.accessibilityIdentifier = .cancelButton button.translatesAutoresizingMaskIntoConstraints = false return button }() private let selectLocationButton: AppButton = { let button = AppButton(style: .translucentNeutral) - button.accessibilityIdentifier = "SelectLocationButton" + button.accessibilityIdentifier = .selectLocationButton button.translatesAutoresizingMaskIntoConstraints = false return button }() @@ -88,7 +88,7 @@ final class TunnelControlView: UIView { private let splitDisconnectButton: DisconnectSplitButton = { let button = DisconnectSplitButton() - button.primaryButton.accessibilityIdentifier = "DisconnectButton" + button.primaryButton.accessibilityIdentifier = .disconnectButton button.translatesAutoresizingMaskIntoConstraints = false return button }() diff --git a/ios/MullvadVPNScreenshots/MullvadVPNScreenshots.swift b/ios/MullvadVPNScreenshots/MullvadVPNScreenshots.swift index 77a8380f4e..4a16bc3e2d 100644 --- a/ios/MullvadVPNScreenshots/MullvadVPNScreenshots.swift +++ b/ios/MullvadVPNScreenshots/MullvadVPNScreenshots.swift @@ -9,6 +9,8 @@ import XCTest class MullvadVPNScreenshots: XCTestCase { + let app = XCUIApplication() + override func setUp() { // Put setup code here. This method is called before the invocation of // each test method in the class. @@ -16,6 +18,9 @@ class MullvadVPNScreenshots: XCTestCase { // In UI tests it is usually best to stop immediately when a failure occurs. continueAfterFailure = false + // Disable animations to speed up tests. This argument is picked up in AppDelegate.didFinishLaunchingWithOptions. + app.launchArguments = ["DisableAnimations"] + // In UI tests it’s important to set the initial state - such as interface orientation - // required for your tests before they run. The setUp method is a good place to do this. } @@ -29,21 +34,19 @@ class MullvadVPNScreenshots: XCTestCase { let accountToken = Bundle(for: Self.self).infoDictionary?["MullvadAccountToken"] as! String // UI tests must launch the application that they test. - let app = XCUIApplication() - setupSnapshot(app) - + setupSnapshot(app, waitForAnimations: false) app.launch() // Dismiss terms of service screen - _ = app.buttons["AgreeButton"].waitForExistence(timeout: 10) - app.buttons["AgreeButton"].tap() + _ = app.buttons[AccessibilityIdentifier.agreeButton.rawValue].waitForExistence(timeout: 10) + app.buttons[AccessibilityIdentifier.agreeButton.rawValue].tap() // Dismiss changelog screen - _ = app.buttons["Got it!"].waitForExistence(timeout: 10) - app.buttons["Got it!"].tap() + _ = app.buttons[AccessibilityIdentifier.alertOkButton.rawValue].waitForExistence(timeout: 10) + app.buttons[AccessibilityIdentifier.alertOkButton.rawValue].tap() // Wait for Login screen - let textField = app.textFields["LoginTextField"] + let textField = app.textFields[AccessibilityIdentifier.loginTextField.rawValue] _ = textField.waitForExistence(timeout: 5) // Enter account token @@ -52,15 +55,15 @@ class MullvadVPNScreenshots: XCTestCase { // Tap "Log in" button to log in if case .phone = UIDevice.current.userInterfaceIdiom { - app.toolbars["Toolbar"].buttons["LoginBarButtonItem"].tap() + app.toolbars["Toolbar"].buttons[AccessibilityIdentifier.loginBarButton.rawValue].tap() } else { textField.typeText("\n") } // Select Sweden, Gothenburg in Select location controller if case .phone = UIDevice.current.userInterfaceIdiom { - _ = app.buttons["SelectLocationButton"].waitForExistence(timeout: 10) - app.buttons["SelectLocationButton"].tap() + _ = app.buttons[AccessibilityIdentifier.selectLocationButton.rawValue].waitForExistence(timeout: 10) + app.buttons[AccessibilityIdentifier.selectLocationButton.rawValue].tap() } let countryCell = app.cells["se"] @@ -71,26 +74,26 @@ class MullvadVPNScreenshots: XCTestCase { if cityCell.exists { cityCell.tap() } else { - _ = countryCell.buttons["CollapseButton"].waitForExistence(timeout: 5) - countryCell.buttons["CollapseButton"].tap() + _ = countryCell.buttons[AccessibilityIdentifier.collapseButton.rawValue].waitForExistence(timeout: 5) + countryCell.buttons[AccessibilityIdentifier.collapseButton.rawValue].tap() cityCell.tap() } // Wait for Disconnect button to appear - _ = app.buttons["DisconnectButton"].waitForExistence(timeout: 2) + _ = app.buttons[AccessibilityIdentifier.disconnectButton.rawValue].waitForExistence(timeout: 2) snapshot("MainSecured") // Re-open Select location controller (iPhone only) if case .phone = UIDevice.current.userInterfaceIdiom { - app.buttons["SelectLocationButton"].tap() - cityCell.buttons["CollapseButton"].tap() + app.buttons[AccessibilityIdentifier.selectLocationButton.rawValue].tap() + cityCell.buttons[AccessibilityIdentifier.collapseButton.rawValue].tap() snapshot("SelectLocation") // Tap the "Filter" button and expand each relay filter app.navigationBars.buttons["Filter"].tap() - app.otherElements["Ownership"].buttons["CollapseButton"].tap() - app.otherElements["Providers"].buttons["CollapseButton"].tap() + app.otherElements["Ownership"].buttons[AccessibilityIdentifier.collapseButton.rawValue].tap() + app.otherElements["Providers"].buttons[AccessibilityIdentifier.collapseButton.rawValue].tap() snapshot("RelayFilter") app.navigationBars.buttons["Cancel"].tap() @@ -98,11 +101,11 @@ class MullvadVPNScreenshots: XCTestCase { } // Open Settings - app.buttons["SettingsButton"].tap() + app.buttons[AccessibilityIdentifier.settingsButton.rawValue].tap() // Tap on preferences cell - _ = app.tables.cells["PreferencesCell"].waitForExistence(timeout: 2) - app.tables.cells["PreferencesCell"].tap() + _ = app.tables.cells[AccessibilityIdentifier.preferencesCell.rawValue].waitForExistence(timeout: 2) + app.tables.cells[AccessibilityIdentifier.preferencesCell.rawValue].tap() app.tables.element .cells @@ -120,25 +123,25 @@ class MullvadVPNScreenshots: XCTestCase { app.navigationBars.buttons.firstMatch.tap() // Open Account - app.buttons["AccountButton"].tap() + app.buttons[AccessibilityIdentifier.accountButton.rawValue].tap() // Wait for StoreKit to fetch subscriptions - _ = app.buttons["PurchaseButton"].waitForExistence(timeout: 2) + _ = app.buttons[AccessibilityIdentifier.purchaseButton.rawValue].waitForExistence(timeout: 2) wait(for: [ expectation( for: NSPredicate(format: "isEnabled = YES"), - evaluatedWith: app.buttons["PurchaseButton"] + evaluatedWith: app.buttons[AccessibilityIdentifier.purchaseButton.rawValue] ), ], timeout: 10) snapshot("Account") // Hit "Log out" button - _ = app.buttons["LogoutButton"].waitForExistence(timeout: 2) - app.buttons["LogoutButton"].tap() + _ = app.buttons[AccessibilityIdentifier.logoutButton.rawValue].waitForExistence(timeout: 2) + app.buttons[AccessibilityIdentifier.logoutButton.rawValue].tap() app.alerts.buttons.allElementsBoundByIndex.last?.tap() // Wait for Login view to appear after log out - _ = app.textFields["LoginTextField"].waitForExistence(timeout: 10) + _ = app.textFields[AccessibilityIdentifier.loginTextField.rawValue].waitForExistence(timeout: 10) } } |
