diff --git a/SportsTimeUITests/Tests/HomeTests.swift b/SportsTimeUITests/Tests/HomeTests.swift index c3f390e..992842d 100644 --- a/SportsTimeUITests/Tests/HomeTests.swift +++ b/SportsTimeUITests/Tests/HomeTests.swift @@ -3,7 +3,7 @@ // SportsTimeUITests // // Tests for the Home tab: hero card, start planning, toolbar button, recent trips, polls. -// QA Sheet: F-012, F-013, F-014, F-017, F-018, F-019, F-020, F-081, F-083, F-084 +// QA Sheet: F-012, F-013, F-014, F-015, F-017, F-018, F-019, F-020, F-081, F-083, F-084 // import XCTest @@ -59,6 +59,42 @@ final class HomeTests: BaseUITestCase { captureScreenshot(named: "F020-ToolbarCreateTrip") } + /// F-015: Featured trips refresh button reloads suggestions. + @MainActor + func testF015_FeaturedTripsRefreshButton() { + let home = HomeScreen(app: app) + home.waitForLoad() + + // Wait for featured trips section to load + let section = home.featuredTripsSection + if !section.waitForExistence(timeout: BaseUITestCase.longTimeout) { + section.scrollIntoView(in: app.scrollViews.firstMatch, maxScrolls: 15) + } + + guard section.exists else { + XCTFail("Featured trips section not found — cannot test refresh") + return + } + + // Find the refresh button by accessibility label + let refreshButton = app.buttons["Refresh trips"] + refreshButton.scrollIntoView(in: app.scrollViews.firstMatch) + XCTAssertTrue(refreshButton.exists, + "Refresh trips button should exist in featured section") + + // Tap refresh and verify no crash + refreshButton.tap() + + // Wait briefly for reload + sleep(2) + + // Featured section should still exist after refresh + XCTAssertTrue(section.exists, + "Featured trips section should remain after refresh") + + captureScreenshot(named: "F015-FeaturedTripsRefresh") + } + /// F-014: Featured trips carousel loads and is visible. @MainActor func testF014_FeaturedTripsCarouselLoads() { diff --git a/SportsTimeUITests/Tests/ScheduleTests.swift b/SportsTimeUITests/Tests/ScheduleTests.swift index b82c276..73f8c8c 100644 --- a/SportsTimeUITests/Tests/ScheduleTests.swift +++ b/SportsTimeUITests/Tests/ScheduleTests.swift @@ -3,7 +3,7 @@ // SportsTimeUITests // // Verifies the Schedule tab loads and displays content. -// QA Sheet: F-085, F-086, F-087, F-088, F-089, F-090, F-092 +// QA Sheet: F-085, F-086, F-087, F-088, F-089, F-090, F-092, F-094 // import XCTest @@ -190,4 +190,33 @@ final class ScheduleTests: BaseUITestCase { captureScreenshot(named: "F092-ScheduleEmptyState") } + + // MARK: - Diagnostics (F-094) + + /// F-094: Diagnostics button opens the diagnostics sheet. + @MainActor + func testF094_ScheduleDiagnostics() { + let home = HomeScreen(app: app) + home.waitForLoad() + home.switchToTab(home.scheduleTab) + + let schedule = ScheduleScreen(app: app) + schedule.assertLoaded() + + // Tap the filter menu button to open the menu + schedule.filterButton.tap() + + // Tap "Diagnostics" in the menu + let diagnosticsButton = app.buttons["Diagnostics"] + XCTAssertTrue(diagnosticsButton.waitForExistence(timeout: BaseUITestCase.shortTimeout), + "Diagnostics menu item should exist") + diagnosticsButton.tap() + + // Diagnostics sheet should appear with game count info + let sheetContent = app.navigationBars.firstMatch + XCTAssertTrue(sheetContent.waitForExistence(timeout: BaseUITestCase.defaultTimeout), + "Diagnostics sheet should appear") + + captureScreenshot(named: "F094-ScheduleDiagnostics") + } } diff --git a/SportsTimeUITests/Tests/TripOptionsTests.swift b/SportsTimeUITests/Tests/TripOptionsTests.swift index 567e876..4ff8a13 100644 --- a/SportsTimeUITests/Tests/TripOptionsTests.swift +++ b/SportsTimeUITests/Tests/TripOptionsTests.swift @@ -3,7 +3,7 @@ // SportsTimeUITests // // Tests the Trip Options results screen: sorting, selection, navigation. -// QA Sheet: F-051, F-052, F-053, F-054, F-055, F-058, F-059 +// QA Sheet: F-051, F-052, F-053, F-054, F-055, F-058, F-059, F-076 // import XCTest @@ -107,6 +107,29 @@ final class TripOptionsTests: BaseUITestCase { captureScreenshot(named: "F058-SelectTripOpensDetail") } + // MARK: - Trip Detail Variants (F-076) + + /// F-076: Trip detail works correctly with a single-stop (minimal) trip. + @MainActor + func testF076_TripDetailWithSingleStop() { + let options = planTripAndGetOptions() + + // Select the first trip option + options.selectTrip(at: 0) + + // Trip detail should load with itinerary + let detail = TripDetailScreen(app: app) + detail.waitForLoad() + detail.assertItineraryVisible() + + // Verify the detail screen is functional (favorite button exists) + XCTAssertTrue(detail.favoriteButton.waitForExistence( + timeout: BaseUITestCase.shortTimeout), + "Favorite button should exist on trip detail") + + captureScreenshot(named: "F076-TripDetailSingleStop") + } + // MARK: - Back Navigation (F-059) /// F-059: Back button on Trip Options returns to wizard with selections preserved. diff --git a/docs/SportsTime_QA_Test_Plan.xlsx b/docs/SportsTime_QA_Test_Plan.xlsx index 2156f73..3ce005a 100644 Binary files a/docs/SportsTime_QA_Test_Plan.xlsx and b/docs/SportsTime_QA_Test_Plan.xlsx differ