// // TripSavingTests.swift // SportsTimeUITests // // Tests the end-to-end trip saving flow: plan → select → save → verify in My Trips. // QA Sheet: F-064, F-065, F-077, F-078, F-079, F-080 // import XCTest final class TripSavingTests: BaseUITestCase { // MARK: - Helpers /// Plans a trip, saves it, navigates back to My Trips, and returns the screens. @MainActor private func planSaveAndReturnToMyTrips() -> (home: HomeScreen, myTrips: MyTripsScreen) { let (wizard, detail) = TestFlows.planAndSelectFirstTrip(app: app) detail.assertSaveState(isSaved: false) detail.tapFavorite() detail.assertSaveState(isSaved: true) // Navigate back: Detail → Options → Wizard → Cancel app.navigationBars.buttons.firstMatch.tap() let wizardBackBtn = app.navigationBars.buttons.firstMatch wizardBackBtn.waitUntilHittable(timeout: BaseUITestCase.shortTimeout).tap() wizard.tapCancel() let home = HomeScreen(app: app) home.switchToTab(home.myTripsTab) let myTrips = MyTripsScreen(app: app) return (home, myTrips) } // MARK: - Save Trip (F-043) /// F-043/F-044: Plans a trip, selects an option, saves it, and verifies it appears in My Trips. @MainActor func testF043_SaveTripAppearsInMyTrips() { let (_, myTrips) = planSaveAndReturnToMyTrips() myTrips.assertHasTrips() captureScreenshot(named: "F043-TripSaving-InMyTrips") } // MARK: - Save/Unsave Toggle (F-048, F-049) /// F-048: Save trip — unsaved trip shows "Save to favorites", tap changes to "Remove from favorites". @MainActor func testF048_SaveTrip() { let (_, detail) = TestFlows.planAndSelectFirstTrip(app: app) detail.assertSaveState(isSaved: false) detail.tapFavorite() detail.assertSaveState(isSaved: true) captureScreenshot(named: "F048-TripSaved") } /// F-049: Unsave trip — saved trip can be un-favorited by tapping again. @MainActor func testF049_UnsaveTrip() { let (_, detail) = TestFlows.planAndSelectFirstTrip(app: app) // Save first detail.assertSaveState(isSaved: false) detail.tapFavorite() detail.assertSaveState(isSaved: true) // Unsave detail.tapFavorite() detail.assertSaveState(isSaved: false) captureScreenshot(named: "F049-TripUnsaved") } // MARK: - Saved Trips List (F-059) /// F-059: Saved trips list shows trip card after saving. @MainActor func testF059_SavedTripsList() { let (_, myTrips) = planSaveAndReturnToMyTrips() myTrips.assertHasTrips() // First trip card should exist let firstTrip = myTrips.tripCard(0) XCTAssertTrue( firstTrip.waitForExistence(timeout: BaseUITestCase.defaultTimeout), "First saved trip card should be visible" ) captureScreenshot(named: "F059-SavedTripsList") } // MARK: - Empty State (F-058) /// F-058: My Trips empty state when no trips saved. @MainActor func testF058_MyTripsEmptyState() { let home = HomeScreen(app: app) home.waitForLoad() home.switchToTab(home.myTripsTab) let myTrips = MyTripsScreen(app: app) myTrips.assertEmpty() captureScreenshot(named: "F058-MyTrips-Empty") } // MARK: - Tap Saved Trip Opens Detail (F-079) /// F-079: Tapping a saved trip card opens the detail view. @MainActor func testF079_TapSavedTripOpensDetail() { let (_, myTrips) = planSaveAndReturnToMyTrips() myTrips.assertHasTrips() // Tap the first saved trip myTrips.tapTrip(at: 0) // Trip detail should open let detail = TripDetailScreen(app: app) detail.waitForLoad() detail.assertItineraryVisible() captureScreenshot(named: "F079-TapSavedTripOpensDetail") } // MARK: - Remove Saved Trip (F-080) /// F-080: Unfavoriting a trip removes it from My Trips. @MainActor func testF080_DeleteSavedTrip() { let (_, myTrips) = planSaveAndReturnToMyTrips() myTrips.assertHasTrips() // Tap into the saved trip detail myTrips.tapTrip(at: 0) let detail = TripDetailScreen(app: app) detail.waitForLoad() // Unfavorite to remove from saved trips detail.assertSaveState(isSaved: true) detail.tapFavorite() detail.assertSaveState(isSaved: false) // Navigate back to My Trips app.navigationBars.buttons.firstMatch.tap() // After unfavoriting, should show empty state myTrips.assertEmpty() captureScreenshot(named: "F080-DeleteSavedTrip") } // MARK: - Stats Row (F-061) /// F-061: Trip detail stats row shows city count, game count, distance, driving time. @MainActor func testF061_StatsRowDisplaysCorrectly() { let (_, detail) = TestFlows.planAndSelectFirstTrip(app: app) detail.assertStatsRowVisible() captureScreenshot(named: "F061-StatsRow") } }