// // NavigationUITests.swift // PlantGuideUITests // // Tests for tab bar navigation and deep navigation flows. // import XCTest final class NavigationUITests: BaseUITestCase { // MARK: - Tab Bar @MainActor func testAllTabsAreAccessible() throws { launchClean() TabBarScreen(app: app).assertAllTabsExist() } @MainActor func testNavigateToCameraTab() throws { launchClean() let tabs = TabBarScreen(app: app) tabs.tapCollection() // move away first tabs.tapCamera() tabs.assertSelected(UITestID.TabBar.camera) } @MainActor func testNavigateToCollectionTab() throws { launchClean() let collection = TabBarScreen(app: app).tapCollection() XCTAssertTrue(collection.waitForLoad(), "Collection should load") } @MainActor func testNavigateToTodayTab() throws { launchClean() let today = TabBarScreen(app: app).tapToday() XCTAssertTrue(today.waitForLoad(), "Today should load") } @MainActor func testNavigateToSettingsTab() throws { launchClean() let settings = TabBarScreen(app: app).tapSettings() XCTAssertTrue(settings.waitForLoad(), "Settings should load") } @MainActor func testNavigatingBetweenAllTabs() throws { launchClean() let tabs = TabBarScreen(app: app) for label in tabs.allTabLabels { navigateToTab(label) tabs.assertSelected(label) } } @MainActor func testRapidTabSwitching() throws { launchClean() let tabs = TabBarScreen(app: app) for _ in 0..<3 { for label in tabs.allTabLabels { let tab = app.tabBars.buttons[label] if tab.exists { tab.tap() } } } XCTAssertTrue(tabs.tabBar.exists, "Tab bar should survive rapid switching") } // MARK: - Deep Navigation @MainActor func testCollectionToPlantDetailAndBack() throws { launchClean() let collection = TabBarScreen(app: app).tapCollection() XCTAssertTrue(collection.waitForLoad(), "Collection should load") // On a clean install, collection is empty — check empty state or content let hasContent = collection.scrollView.waitForExistence(timeout: 3) if hasContent { // Tap first plant cell let firstItem = collection.scrollView.buttons.firstMatch.exists ? collection.scrollView.buttons.firstMatch : collection.scrollView.otherElements.firstMatch guard firstItem.waitForExistence(timeout: 3) else { return } firstItem.tap() let detail = PlantDetailScreen(app: app) XCTAssertTrue(detail.waitForLoad(), "Detail should load") detail.tapBack() XCTAssertTrue(collection.waitForLoad(), "Should return to collection") } else { // Empty state is valid — verify collection is still displayed XCTAssertTrue(collection.navigationBar.exists, "Collection should remain visible when empty") } } @MainActor func testTappingAlreadySelectedTab() throws { launchClean() let collection = TabBarScreen(app: app).tapCollection() XCTAssertTrue(collection.waitForLoad()) // Tap collection tab again multiple times let tab = app.tabBars.buttons[UITestID.TabBar.collection] tab.tap() tab.tap() XCTAssertTrue(collection.navigationBar.exists, "Collection should remain visible") } @MainActor func testTabBarVisibleOnAllTabs() throws { launchClean() let tabs = TabBarScreen(app: app) let nonCameraTabs = [UITestID.TabBar.collection, UITestID.TabBar.today, UITestID.TabBar.settings] for label in nonCameraTabs { navigateToTab(label) XCTAssertTrue(tabs.tabBar.exists, "Tab bar missing on \(label)") } } }