Add F-100, F-101, F-106 UI tests and page objects for Progress feature
Adds 3 new UI tests covering stadium visit manual entry, required field validation, and games history navigation. Includes accessibility IDs on StadiumVisitSheet/ProgressTabView and new page objects (StadiumVisitSheetScreen, GamesHistoryScreen) in the test framework. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
// SportsTimeUITests
|
||||
//
|
||||
// Tests for the Progress tab (Pro-gated).
|
||||
// QA Sheet: F-095, F-097, F-110
|
||||
// QA Sheet: F-066, F-097, F-100, F-101, F-106, F-110
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@@ -61,6 +61,127 @@ final class ProgressTests: BaseUITestCase {
|
||||
}
|
||||
}
|
||||
|
||||
/// F-101: Add visit — Save button disabled until stadium is selected.
|
||||
@MainActor
|
||||
func testF101_AddVisitRequiredFields() {
|
||||
let home = HomeScreen(app: app)
|
||||
home.waitForLoad()
|
||||
home.switchToTab(home.progressTab)
|
||||
|
||||
let progress = ProgressScreen(app: app)
|
||||
progress.waitForLoad()
|
||||
progress.tapAddManualVisit()
|
||||
|
||||
let visitSheet = StadiumVisitSheetScreen(app: app)
|
||||
visitSheet.waitForLoad()
|
||||
|
||||
// Save button should exist but be disabled (no stadium selected)
|
||||
XCTAssertTrue(
|
||||
visitSheet.saveButton.waitForExistence(timeout: BaseUITestCase.shortTimeout),
|
||||
"Save button should exist"
|
||||
)
|
||||
XCTAssertFalse(
|
||||
visitSheet.saveButton.isEnabled,
|
||||
"Save button should be disabled without a stadium selected"
|
||||
)
|
||||
|
||||
captureScreenshot(named: "F101-SaveDisabledNoStadium")
|
||||
}
|
||||
|
||||
/// F-100: Add visit — full manual entry flow (select stadium, save).
|
||||
@MainActor
|
||||
func testF100_AddVisitManualEntry() {
|
||||
let home = HomeScreen(app: app)
|
||||
home.waitForLoad()
|
||||
home.switchToTab(home.progressTab)
|
||||
|
||||
let progress = ProgressScreen(app: app)
|
||||
progress.waitForLoad()
|
||||
progress.tapAddManualVisit()
|
||||
|
||||
let visitSheet = StadiumVisitSheetScreen(app: app)
|
||||
visitSheet.waitForLoad()
|
||||
|
||||
// Pick a stadium
|
||||
visitSheet.pickFirstStadium()
|
||||
|
||||
// Save button should now be enabled
|
||||
XCTAssertTrue(
|
||||
visitSheet.saveButton.waitForExistence(timeout: BaseUITestCase.shortTimeout),
|
||||
"Save button should exist after picking a stadium"
|
||||
)
|
||||
XCTAssertTrue(
|
||||
visitSheet.saveButton.isEnabled,
|
||||
"Save button should be enabled after selecting a stadium"
|
||||
)
|
||||
|
||||
// Save the visit
|
||||
visitSheet.tapSave()
|
||||
|
||||
// Sheet should dismiss — nav bar disappears
|
||||
visitSheet.navigationBar.waitForNonExistence(
|
||||
timeout: BaseUITestCase.defaultTimeout,
|
||||
"Visit sheet should dismiss after save"
|
||||
)
|
||||
|
||||
captureScreenshot(named: "F100-ManualEntryComplete")
|
||||
}
|
||||
|
||||
/// F-106: View Games History — add a visit, then navigate to history view.
|
||||
@MainActor
|
||||
func testF106_ViewGamesHistory() {
|
||||
let home = HomeScreen(app: app)
|
||||
home.waitForLoad()
|
||||
home.switchToTab(home.progressTab)
|
||||
|
||||
let progress = ProgressScreen(app: app)
|
||||
progress.waitForLoad()
|
||||
|
||||
// Add a visit first (prerequisite: Recent Visits section only shows with visits)
|
||||
progress.tapAddManualVisit()
|
||||
let visitSheet = StadiumVisitSheetScreen(app: app)
|
||||
visitSheet.waitForLoad()
|
||||
visitSheet.pickFirstStadium()
|
||||
visitSheet.tapSave()
|
||||
visitSheet.navigationBar.waitForNonExistence(timeout: BaseUITestCase.defaultTimeout)
|
||||
|
||||
// Wait for data reload — Recent Visits section should appear in hierarchy
|
||||
XCTAssertTrue(
|
||||
progress.recentVisitsTitle.waitForExistence(timeout: BaseUITestCase.longTimeout),
|
||||
"Recent Visits section should appear after adding a visit"
|
||||
)
|
||||
|
||||
// Scroll to Recent Visits (same pattern as F-110 which uses app.swipeUp)
|
||||
var scrollAttempts = 0
|
||||
while !progress.recentVisitsTitle.isHittable && scrollAttempts < 20 {
|
||||
app.swipeUp(velocity: .slow)
|
||||
scrollAttempts += 1
|
||||
}
|
||||
|
||||
// Find and tap "See All" — try button, link, then generic element
|
||||
let seeAllPredicate = NSPredicate(format: "label CONTAINS[c] 'See All'")
|
||||
let seeAllButton = app.buttons.matching(seeAllPredicate).firstMatch
|
||||
let seeAllGeneric = app.descendants(matching: .any).matching(seeAllPredicate).firstMatch
|
||||
|
||||
if seeAllButton.exists && seeAllButton.isHittable {
|
||||
seeAllButton.tap()
|
||||
} else if seeAllGeneric.exists {
|
||||
// One more scroll to ensure it's on screen
|
||||
if !seeAllGeneric.isHittable {
|
||||
app.swipeUp(velocity: .slow)
|
||||
}
|
||||
seeAllGeneric.tap()
|
||||
} else {
|
||||
XCTFail("Could not find 'See All' link in Recent Visits section")
|
||||
}
|
||||
|
||||
// Verify Games History view loads
|
||||
let gamesHistory = GamesHistoryScreen(app: app)
|
||||
gamesHistory.waitForLoad()
|
||||
|
||||
captureScreenshot(named: "F106-GamesHistory")
|
||||
}
|
||||
|
||||
/// F-110: Achievements gallery is visible with badge grid.
|
||||
@MainActor
|
||||
func testF110_AchievementsGalleryVisible() {
|
||||
|
||||
Reference in New Issue
Block a user