# XCUITest Authoring Guide

This guide documents the current SportsTime UI test foundation and how to add new tests safely.

## Current Foundation

## Layout

- Test target: `SportsTimeUITests`
- Base setup/helpers: `SportsTimeUITests/Framework/BaseUITestCase.swift`
- Page objects + shared flows: `SportsTimeUITests/Framework/Screens.swift`
- Suite files: `SportsTimeUITests/Tests/*.swift`
- Legacy mixed tests: `SportsTimeUITests/SportsTimeUITests.swift` and `SportsTimeUITests/SportsTimeUITestsLaunchTests.swift`

## Existing Suite Coverage

- `AppLaunchTests`
- `HomeTests`
- `TabNavigationTests`
- `ScheduleTests`
- `TripWizardFlowTests`
- `TripOptionsTests`
- `TripSavingTests`
- `ProgressTests`
- `SettingsTests`
- `AccessibilityTests`
- `StabilityTests`

## Key Conventions

- Inherit from `BaseUITestCase`.
- Use `@MainActor` test methods.
- Prefer page-object actions over direct element taps.
- Prefer existing high-level flows (`TestFlows.planDateRangeTrip`, `TestFlows.planAndSelectFirstTrip`) for shared setup.
- Use deterministic selectors with accessibility identifiers.
- Use `waitForExistenceOrFail` and `waitUntilHittable` instead of arbitrary sleeps.

## Adding a New UI Test

1. Pick the closest existing suite in `SportsTimeUITests/Tests/`.
2. If none fits, create a new suite using `XCUITestSuiteTemplate.swift`.
3. Add/extend page-object methods in `Screens.swift` before writing raw element code.
4. Reuse `TestFlows` when setup overlaps existing end-to-end flows.
5. Keep assertion messages explicit and behavior-focused.
6. Capture screenshot(s) for key milestone state in longer flows.
7. Run targeted tests, then full UI tests.

## When to Edit `Screens.swift`

Edit page objects when:

- A new screen element needs a stable selector.
- The interaction is reused across multiple tests.
- The flow can be standardized (especially wizard planning flow).

Do not add one-off test-only branching logic unless it removes a real flake.

## Running Tests

## Fast Loop (single test)

```bash
xcodebuild test-without-building \
  -project SportsTime.xcodeproj \
  -scheme SportsTime \
  -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' \
  -parallel-testing-enabled NO \
  -only-testing:SportsTimeUITests/TripWizardFlowTests/testF026_DateRangeSelection
```

## Per Class

```bash
xcodebuild test-without-building \
  -project SportsTime.xcodeproj \
  -scheme SportsTime \
  -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' \
  -parallel-testing-enabled NO \
  -only-testing:SportsTimeUITests/TripOptionsTests
```

## Full UI Suite

```bash
xcodebuild test-without-building \
  -project SportsTime.xcodeproj \
  -scheme SportsTime \
  -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' \
  -parallel-testing-enabled NO \
  -only-testing:SportsTimeUITests
```

## Full Scheme Validation (unit + UI)

```bash
xcodebuild test-without-building \
  -project SportsTime.xcodeproj \
  -scheme SportsTime \
  -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' \
  -parallel-testing-enabled NO
```

## Flake Prevention Notes

- Keep simulator orientation consistent (portrait baseline from `BaseUITestCase`).
- For wizard date selection, navigate by month/year first and use day-cell fallback when specific IDs are unavailable.
- For cross-season planning tests, prefer deterministic fallback sports if selected sport has no viable schedule for current test data.
- Increase waits only where planning computation is the actual bottleneck.
