// // TabBarScreen.swift // PlantGuideUITests // // Screen object for the main tab bar. // import XCTest struct TabBarScreen { let app: XCUIApplication // MARK: - Elements var tabBar: XCUIElement { app.tabBars.firstMatch } var cameraTab: XCUIElement { tabBar.buttons[UITestID.TabBar.camera] } var collectionTab: XCUIElement { tabBar.buttons[UITestID.TabBar.collection] } var todayTab: XCUIElement { tabBar.buttons[UITestID.TabBar.today] } var settingsTab: XCUIElement { tabBar.buttons[UITestID.TabBar.settings] } var allTabLabels: [String] { [UITestID.TabBar.camera, UITestID.TabBar.collection, UITestID.TabBar.today, UITestID.TabBar.settings] } // MARK: - Actions /// Taps a tab button using existence-based wait (not hittable — tab bar buttons /// report isHittable == false in iOS 26 simulator despite being tappable). private func tapTab(_ tab: XCUIElement) { XCTAssertTrue(tab.waitForExistence(timeout: 10), "Tab '\(tab.label)' not found within 10s") tab.tap() } @discardableResult func tapCamera() -> CameraScreen { tapTab(cameraTab) return CameraScreen(app: app) } @discardableResult func tapCollection() -> CollectionScreen { tapTab(collectionTab) return CollectionScreen(app: app) } @discardableResult func tapToday() -> TodayScreen { tapTab(todayTab) return TodayScreen(app: app) } @discardableResult func tapSettings() -> SettingsScreen { tapTab(settingsTab) return SettingsScreen(app: app) } // MARK: - Assertions func assertAllTabsExist() { XCTAssertTrue(tabBar.waitForExistence(timeout: 10), "Tab bar missing") for label in allTabLabels { XCTAssertTrue(tabBar.buttons[label].waitForExistence(timeout: 5), "Tab '\(label)' missing") } } func assertSelected(_ label: String) { let tab = tabBar.buttons[label] XCTAssertTrue(tab.waitForExistence(timeout: 5), "Tab '\(label)' not found") XCTAssertTrue(tab.isSelected, "Tab '\(label)' not selected") } }