diff --git a/SportsTimeUITests/Tests/HomeTests.swift b/SportsTimeUITests/Tests/HomeTests.swift index 3404bb0..c3f390e 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 +// QA Sheet: F-012, F-013, F-014, F-017, F-018, F-019, F-020, F-081, F-083, F-084 // import XCTest @@ -204,4 +204,35 @@ final class HomeTests: BaseUITestCase { captureScreenshot(named: "F083-CreatePollHidden") } + + // MARK: - Pull to Refresh (F-084) + + /// F-084: Pull to refresh on My Trips tab doesn't crash. + @MainActor + func testF084_PullToRefresh() { + let home = HomeScreen(app: app) + home.waitForLoad() + home.switchToTab(home.myTripsTab) + + // Wait briefly for My Trips content to load + sleep(1) + + // Pull down to refresh + app.swipeDown(velocity: .slow) + + // Wait for any refresh to complete + sleep(2) + + // Verify the tab is still functional (no crash) + let groupPolls = app.staticTexts["Group Polls"] + var scrollAttempts = 0 + while !groupPolls.exists && scrollAttempts < 5 { + app.swipeUp(velocity: .slow) + scrollAttempts += 1 + } + XCTAssertTrue(groupPolls.exists, + "My Trips tab should remain functional after pull to refresh") + + captureScreenshot(named: "F084-PullToRefresh") + } } diff --git a/SportsTimeUITests/Tests/SettingsTests.swift b/SportsTimeUITests/Tests/SettingsTests.swift index 5328d3f..62b3647 100644 --- a/SportsTimeUITests/Tests/SettingsTests.swift +++ b/SportsTimeUITests/Tests/SettingsTests.swift @@ -3,7 +3,7 @@ // SportsTimeUITests // // Verifies the Settings screen loads, displays version, and shows all sections. -// QA Sheet: F-123, F-124, F-125, F-126, F-127, F-128, F-135, F-138, F-139 +// QA Sheet: F-123, F-124, F-125, F-126, F-127, F-128, F-133, F-134, F-135, F-138, F-139 // import XCTest @@ -173,6 +173,56 @@ final class SettingsTests: BaseUITestCase { captureScreenshot(named: "F128-AnimationsToggled") } + // MARK: - Manual Sync (F-133) + + /// F-133: Tap "Sync Now" button triggers sync. + @MainActor + func testF133_ManualSyncTrigger() { + let home = HomeScreen(app: app) + home.waitForLoad() + home.switchToTab(home.settingsTab) + + let settings = SettingsScreen(app: app) + settings.assertLoaded() + + let syncButton = settings.syncNowButton + syncButton.scrollIntoView(in: app.collectionViews.firstMatch) + XCTAssertTrue(syncButton.exists, "Sync Now button should exist") + syncButton.tap() + + // After tapping, no crash is the primary assertion. + // Sync may show a progress indicator or message briefly. + captureScreenshot(named: "F133-ManualSync") + } + + // MARK: - Sync Logs (F-134) + + /// F-134: View Sync Logs button opens the log viewer sheet. + @MainActor + func testF134_ViewSyncLogs() { + let home = HomeScreen(app: app) + home.waitForLoad() + home.switchToTab(home.settingsTab) + + let settings = SettingsScreen(app: app) + settings.assertLoaded() + + // Scroll to and tap "View Sync Logs" button + let syncLogsButton = app.buttons.matching(NSPredicate( + format: "label CONTAINS 'Sync Logs'" + )).firstMatch + syncLogsButton.scrollIntoView(in: app.collectionViews.firstMatch) + XCTAssertTrue(syncLogsButton.exists, "View Sync Logs button should exist") + syncLogsButton.tap() + + // Sheet should appear — look for navigation bar or content + let sheetContent = app.navigationBars.firstMatch + XCTAssertTrue(sheetContent.waitForExistence(timeout: BaseUITestCase.defaultTimeout), + "Sync logs sheet should appear") + + captureScreenshot(named: "F134-SyncLogs") + } + // MARK: - Reset to Defaults (F-138, F-139) /// F-138: Reset to Defaults triggers confirmation and resets settings. diff --git a/docs/SportsTime_QA_Test_Plan.xlsx b/docs/SportsTime_QA_Test_Plan.xlsx index 3a3c7f5..86b85a7 100644 Binary files a/docs/SportsTime_QA_Test_Plan.xlsx and b/docs/SportsTime_QA_Test_Plan.xlsx differ