109 lines
3.4 KiB
Markdown
109 lines
3.4 KiB
Markdown
# 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=latest' \
|
|
-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=latest' \
|
|
-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=latest' \
|
|
-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=latest' \
|
|
-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.
|