# UI Test Rules These rules are non-negotiable. Every test, every suite, every helper must follow them. ## Element Interaction 1. **All text fields use `fillTextField(identifier:)`** — never raw `tap()` + `typeText()` in test bodies 2. **All buttons/elements found by accessibility identifier** — never `label CONTAINS` for app elements 3. **No coordinate taps anywhere** — `app.coordinate(withNormalizedOffset:)` is banned ## Timeouts 4. **`defaultTimeout` = 2 seconds** — if an element on the current screen isn't there in 2s, the app is broken 5. **`navigationTimeout` = 5 seconds** — screen transitions, tab switches 6. **`loginTimeout` = 15 seconds** — initial auth flow only (cold start) 7. **No retry loops in test helpers** — tap once, check once, fail fast ## Independence 8. **Every suite runs alone, in combination, or in parallel** — no ordering dependencies 9. **Every test creates its own data in setUp, cleans up in tearDown** 10. **No shared mutable state** — no `static var`, no class-level properties mutated across tests ## Clarity 11. **One logical assertion per test** — test name describes the exact behavior 12. **`XCTFail` with a message that tells you what went wrong** without reading the code 13. **No `guard ... else { return }` that silently passes** — if a precondition fails, `XCTFail` and stop ## Speed 14. **No `sleep()`, `usleep()`, or `Thread.sleep`** in tests — condition-based waits only 15. **If `focusAndType` can't get focus in one tap, the test fails** — no 3-attempt retry loops 16. **Target: each individual test completes in under 15 seconds** (excluding setUp/tearDown) ## Preconditions 17. **Every test assumption is validated before the test runs** — if a task test assumes a residence exists, verify via API in setUp. If the precondition isn't met, create it via API. Preconditions are NOT what the test is testing — they're infrastructure. Use API, not UI, to establish them.