diff --git a/Normal.xcodeproj/project.pbxproj b/Normal.xcodeproj/project.pbxproj index c00ff82..ea609be 100644 --- a/Normal.xcodeproj/project.pbxproj +++ b/Normal.xcodeproj/project.pbxproj @@ -119,6 +119,7 @@ NormalUITests.swift, NormalUITestsLaunchTests.swift, RecoveryUITests.swift, + TabNavigation.swift, UnblockDurationsUITests.swift, ); target = 2F58EFFE2EC9C5DF00A38180 /* NormalUITests */; @@ -131,6 +132,7 @@ NormalUITests.swift, NormalUITestsLaunchTests.swift, RecoveryUITests.swift, + TabNavigation.swift, UnblockDurationsUITests.swift, ); target = 2F58EFE72EC9C5DE00A38180 /* Normal */; diff --git a/NormalUITests/BlockingUITests.swift b/NormalUITests/BlockingUITests.swift index 2c0290e..4ced346 100644 --- a/NormalUITests/BlockingUITests.swift +++ b/NormalUITests/BlockingUITests.swift @@ -5,6 +5,7 @@ final class BlockingUITests: XCTestCase { override func setUpWithError() throws { continueAfterFailure = false + XCUIDevice.shared.orientation = .portrait } private func launch(_ extra: [String] = []) -> XCUIApplication { @@ -81,7 +82,7 @@ final class BlockingUITests: XCTestCase { let app = launch() blockViaBypass(app) - app.tabBars.buttons["Keys"].tap() + app.mainTab("Keys").tap() require( app.staticTexts["Unblock all apps to add or delete keys."], "Keys tab should show the locked footer while blocked" @@ -177,7 +178,7 @@ final class BlockingUITests: XCTestCase { func testGroupBlockThenUnblockRepresentsKeyAndDurationSheets() { let app = launch(["-uiTestSeedGroupKey"]) - app.tabBars.buttons["Groups"].tap() + app.mainTab("Groups").tap() let blockButton = app.buttons["group.blockButton"] require(blockButton, "Group block button should render") @@ -245,7 +246,7 @@ final class BlockingUITests: XCTestCase { func testSeededScheduleAppears() { let app = launch(["-uiTestSeedSchedule"]) - app.tabBars.buttons["Schedules"].tap() + app.mainTab("Schedules").tap() require(app.staticTexts["Test Schedule"], "Seeded schedule card should render") XCTAssertTrue(app.switches["schedule.enabledToggle"].exists, "Schedule enable toggle should exist") } @@ -253,7 +254,7 @@ final class BlockingUITests: XCTestCase { func testDuplicateScheduleAddsDisabledCopy() { let app = launch(["-uiTestSeedSchedule"]) - app.tabBars.buttons["Schedules"].tap() + app.mainTab("Schedules").tap() let original = app.staticTexts["Test Schedule"] require(original, "Seeded schedule card should render") original.press(forDuration: 1) @@ -272,7 +273,7 @@ final class BlockingUITests: XCTestCase { func testDuplicateScheduleUnavailableWhileBlocked() { let app = launch(["-uiTestSeedSchedule", "-uiTestStartBlocked"]) - app.tabBars.buttons["Schedules"].tap() + app.mainTab("Schedules").tap() let original = app.staticTexts["Test Schedule"] require(original, "Seeded schedule card should render") original.press(forDuration: 1) diff --git a/NormalUITests/DonationUITests.swift b/NormalUITests/DonationUITests.swift index ba4ccfd..d3e5967 100644 --- a/NormalUITests/DonationUITests.swift +++ b/NormalUITests/DonationUITests.swift @@ -5,6 +5,7 @@ final class DonationUITests: XCTestCase { override func setUpWithError() throws { continueAfterFailure = false + XCUIDevice.shared.orientation = .portrait } private func launch() -> XCUIApplication { diff --git a/NormalUITests/NormalUITests.swift b/NormalUITests/NormalUITests.swift index dd60a2f..4a59bb6 100644 --- a/NormalUITests/NormalUITests.swift +++ b/NormalUITests/NormalUITests.swift @@ -5,6 +5,7 @@ final class NormalUITests: XCTestCase { override func setUpWithError() throws { continueAfterFailure = false + XCUIDevice.shared.orientation = .portrait } private func launch(_ arguments: [String]) -> XCUIApplication { @@ -34,7 +35,7 @@ final class NormalUITests: XCTestCase { require(skip, "Welcome skip button should exist") skip.tap() - require(app.tabBars.buttons["Keys"], "Main tab bar should be visible after skipping onboarding") + require(app.mainTab("Keys"), "Main tab bar should be visible after skipping onboarding") XCTAssertFalse(app.staticTexts["Welcome to Normal"].exists, "Onboarding should be dismissed") } @@ -86,7 +87,7 @@ final class NormalUITests: XCTestCase { func testAddKeyViaScanCreatesKey() { let app = launch(["-uiTestMode", "-uiTestSkipOnboarding"]) - let keysTab = app.tabBars.buttons["Keys"] + let keysTab = app.mainTab("Keys") require(keysTab, "Keys tab should be reachable when onboarding is skipped") keysTab.tap() @@ -116,7 +117,7 @@ final class NormalUITests: XCTestCase { func testAddLocationKeyCreatesKey() { let app = launch(["-uiTestMode", "-uiTestSkipOnboarding"]) - let keysTab = app.tabBars.buttons["Keys"] + let keysTab = app.mainTab("Keys") require(keysTab, "Keys tab should be reachable when onboarding is skipped") keysTab.tap() @@ -156,7 +157,7 @@ final class NormalUITests: XCTestCase { func testLocationPickerShowsMapAndCurrentLocationControl() { let app = launch(["-uiTestMode", "-uiTestSkipOnboarding"]) - let keysTab = app.tabBars.buttons["Keys"] + let keysTab = app.mainTab("Keys") require(keysTab, "Keys tab should be reachable when onboarding is skipped") keysTab.tap() @@ -183,7 +184,7 @@ final class NormalUITests: XCTestCase { func testCustomDomainsEditorHiddenWhenToggleOff() { let app = launch(["-uiTestMode", "-uiTestSkipOnboarding"]) - let appSelectTab = app.tabBars.buttons["App Select"] + let appSelectTab = app.mainTab("App Select") require(appSelectTab, "App Select tab should be reachable") appSelectTab.tap() @@ -197,7 +198,7 @@ final class NormalUITests: XCTestCase { func testCustomDomainsEditorAddsDomainWhenToggleOn() { let app = launch(["-uiTestMode", "-uiTestSkipOnboarding", "-uiTestCustomDomains"]) - let appSelectTab = app.tabBars.buttons["App Select"] + let appSelectTab = app.mainTab("App Select") require(appSelectTab, "App Select tab should be reachable") appSelectTab.tap() @@ -221,7 +222,7 @@ final class NormalUITests: XCTestCase { func testCustomDomainsEditorIsReadOnlyWhileBlocked() { let app = launch(["-uiTestMode", "-uiTestSkipOnboarding", "-uiTestCustomDomains", "-uiTestStartBlocked"]) - let appSelectTab = app.tabBars.buttons["App Select"] + let appSelectTab = app.mainTab("App Select") require(appSelectTab, "App Select tab should be reachable") appSelectTab.tap() @@ -240,7 +241,7 @@ final class NormalUITests: XCTestCase { func testGroupKeyHiddenFromKeysTabAndVisibleInViewer() { let app = launch(["-uiTestMode", "-uiTestSkipOnboarding", "-uiTestSeedGroupKey"]) - let keysTab = app.tabBars.buttons["Keys"] + let keysTab = app.mainTab("Keys") require(keysTab, "Keys tab should be reachable") keysTab.tap() diff --git a/NormalUITests/RecoveryUITests.swift b/NormalUITests/RecoveryUITests.swift index b430a80..5f0852d 100644 --- a/NormalUITests/RecoveryUITests.swift +++ b/NormalUITests/RecoveryUITests.swift @@ -5,6 +5,7 @@ final class RecoveryUITests: XCTestCase { override func setUpWithError() throws { continueAfterFailure = false + XCUIDevice.shared.orientation = .portrait } private func launch(_ extra: [String]) -> XCUIApplication { @@ -96,7 +97,7 @@ final class RecoveryUITests: XCTestCase { func testEmergencyUnblockDisablesSchedules() { let app = launch(["-uiTestSeedSchedule"]) - app.tabBars.buttons["Schedules"].tap() + app.mainTab("Schedules").tap() let toggle = app.switches["schedule.enabledToggle"] require(toggle, "Seeded schedule toggle should exist") XCTAssertEqual(toggle.value as? String, "1", "Seeded schedule starts enabled") @@ -107,7 +108,7 @@ final class RecoveryUITests: XCTestCase { app.alerts.buttons["OK"].tap() app.buttons["Close"].tap() - app.tabBars.buttons["Schedules"].tap() + app.mainTab("Schedules").tap() XCTAssertEqual( app.switches["schedule.enabledToggle"].value as? String, "0", "Emergency unblock must toggle schedules off so they can't re-block" @@ -117,7 +118,7 @@ final class RecoveryUITests: XCTestCase { func testLegacyKeyWithoutScanKindShowsQRCodeLabel() { let app = launch([]) - app.tabBars.buttons["Keys"].tap() + app.mainTab("Keys").tap() require(app.staticTexts["Test Key"].firstMatch, "Seeded key card should be visible") require( app.staticTexts["QR Code"].firstMatch, @@ -128,7 +129,7 @@ final class RecoveryUITests: XCTestCase { func testCannotDeleteLastKey() { let app = launch([]) - app.tabBars.buttons["Keys"].tap() + app.mainTab("Keys").tap() let card = app.staticTexts["Test Key"].firstMatch require(card, "The single seeded key card should be visible") card.press(forDuration: 1.3) diff --git a/NormalUITests/TabNavigation.swift b/NormalUITests/TabNavigation.swift new file mode 100644 index 0000000..92e52b2 --- /dev/null +++ b/NormalUITests/TabNavigation.swift @@ -0,0 +1,10 @@ +import XCTest + +extension XCUIApplication { + func mainTab(_ label: String) -> XCUIElement { + guard UIDevice.current.userInterfaceIdiom == .pad, #available(iOS 18.0, *) else { + return tabBars.buttons[label] + } + return buttons.matching(NSPredicate(format: "label == %@", label)).firstMatch + } +} diff --git a/NormalUITests/UnblockDurationsUITests.swift b/NormalUITests/UnblockDurationsUITests.swift index fcaa5c3..54708b0 100644 --- a/NormalUITests/UnblockDurationsUITests.swift +++ b/NormalUITests/UnblockDurationsUITests.swift @@ -5,6 +5,7 @@ final class UnblockDurationsUITests: XCTestCase { override func setUpWithError() throws { continueAfterFailure = false + XCUIDevice.shared.orientation = .portrait } private func launch(_ extra: [String] = []) -> XCUIApplication {