Files
Sportstime/SportsTimeUITests/Tests/TabNavigationTests.swift
Trey t dad3270be7 Add F-010, F-017 UI tests and update QA test plan with 24 automation mappings
- F-010: Tap active tab scrolls to top (TabNavigationTests)
- F-017: Recent trips section with saved trips (HomeTests)
- Update SportsTime_QA_Test_Plan.xlsx with all 60 automated test mappings
- Green highlight on automated cells for visual tracking

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 23:18:00 -06:00

113 lines
3.8 KiB
Swift

//
// TabNavigationTests.swift
// SportsTimeUITests
//
// Verifies navigation through all 5 tabs.
// QA Sheet: F-008, F-009
//
import XCTest
final class TabNavigationTests: BaseUITestCase {
/// F-008: Switch to all 5 tabs each loads without crash.
@MainActor
func testF008_TabNavigationCycle() {
let home = HomeScreen(app: app)
home.waitForLoad()
// Schedule tab
home.switchToTab(home.scheduleTab)
let schedule = ScheduleScreen(app: app)
schedule.assertLoaded()
// My Trips tab
home.switchToTab(home.myTripsTab)
let myTrips = MyTripsScreen(app: app)
myTrips.assertEmpty()
// Progress tab (Pro-gated, but UI test mode forces Pro)
home.switchToTab(home.progressTab)
let progress = ProgressScreen(app: app)
progress.assertLoaded()
// Settings tab
home.switchToTab(home.settingsTab)
let settings = SettingsScreen(app: app)
settings.assertLoaded()
// Return home
home.switchToTab(home.homeTab)
XCTAssertTrue(home.startPlanningButton.waitForExistence(timeout: BaseUITestCase.shortTimeout),
"Should return to Home tab")
captureScreenshot(named: "F008-TabNavigation-ReturnHome")
}
/// F-010: Tapping the active tab scrolls the view back to the top.
@MainActor
func testF010_TapActiveTabScrollsToTop() {
let home = HomeScreen(app: app)
home.waitForLoad()
// Verify "Adventure Awaits" hero card is hittable at the top
XCTAssertTrue(home.adventureAwaitsText.isHittable,
"Adventure Awaits should be hittable initially")
// Scroll down until the hero card is off-screen
for _ in 0..<8 {
app.swipeUp(velocity: .slow)
}
// Verify the hero card is no longer hittable (scrolled off-screen)
XCTAssertFalse(home.adventureAwaitsText.isHittable,
"Adventure Awaits should not be hittable after scrolling down")
captureScreenshot(named: "F010-ScrolledDown")
// Tap the Home tab (already the active tab) to trigger scroll-to-top
home.homeTab.waitUntilHittable(timeout: BaseUITestCase.shortTimeout).tap()
// Hero card should scroll back into view and become hittable
home.adventureAwaitsText.waitUntilHittable(
timeout: BaseUITestCase.defaultTimeout,
"Adventure Awaits should be hittable after tapping active tab (scroll to top)"
)
captureScreenshot(named: "F010-ScrolledToTop")
}
/// F-009: Tab state preserved Schedule filters survive tab switch.
@MainActor
func testF009_TabStatePreservedOnSwitch() {
let home = HomeScreen(app: app)
home.waitForLoad()
// Go to Schedule tab and select a sport filter
home.switchToTab(home.scheduleTab)
let schedule = ScheduleScreen(app: app)
schedule.assertLoaded()
let mlbChip = schedule.sportChip("mlb")
XCTAssertTrue(mlbChip.waitForExistence(timeout: BaseUITestCase.defaultTimeout),
"MLB chip should exist")
mlbChip.tap()
// Switch to Home tab
home.switchToTab(home.homeTab)
home.startPlanningButton.waitForExistenceOrFail(
timeout: BaseUITestCase.shortTimeout,
"Home tab should load"
)
// Switch back to Schedule filter state should be preserved
home.switchToTab(home.scheduleTab)
// All sports start SELECTED; tapping deselects. So MLB should still be "Not selected".
XCTAssertEqual(mlbChip.value as? String, "Not selected",
"MLB chip should still be deselected after switching tabs")
captureScreenshot(named: "F009-TabStatePreserved")
}
}