Replace brittle localized-string selectors and broken wait helpers with a robust, identifier-first UI test infrastructure. All 41 UI tests pass on iOS 26.2 simulator (iPhone 17). Foundation: - BaseUITestCase with deterministic launch helpers (launchClean, launchOffline) - WaitHelpers (waitUntilHittable, waitUntilGone, tapWhenReady) replacing sleep() - UITestID enum mirroring AccessibilityIdentifiers from the app target - Screen objects: TabBarScreen, CameraScreen, CollectionScreen, TodayScreen, SettingsScreen, PlantDetailScreen Key fixes: - Tab navigation uses waitForExistence+tap instead of isHittable (unreliable in iOS 26 simulator) - Tests handle real app state (empty collection, no camera permission) - Increased timeouts for parallel clone execution - Added NetworkMonitorProtocol and protocol-typed DI for testability - Fixed actor-isolation issues in unit test mocks Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
50 lines
1.3 KiB
Markdown
50 lines
1.3 KiB
Markdown
# PlantGuide UI Tests
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
# Compile only (no device required)
|
|
xcodebuild build-for-testing \
|
|
-project PlantGuide.xcodeproj \
|
|
-scheme PlantGuide \
|
|
-destination 'platform=iOS Simulator,name=iPhone 17'
|
|
|
|
# Run all UI tests
|
|
xcodebuild test \
|
|
-project PlantGuide.xcodeproj \
|
|
-scheme PlantGuide \
|
|
-destination 'platform=iOS Simulator,name=iPhone 17' \
|
|
-only-testing:PlantGuideUITests
|
|
```
|
|
|
|
## Directory Layout
|
|
|
|
```
|
|
PlantGuideUITests/
|
|
Foundation/ # Shared infrastructure
|
|
BaseUITestCase # Base class for all tests
|
|
UITestID # Accessibility identifier constants
|
|
WaitHelpers # Predicate-based waits (no sleep!)
|
|
Helpers/
|
|
LaunchConfigKey # Launch arg/env constants
|
|
Screens/ # Page objects
|
|
TabBarScreen
|
|
CameraScreen
|
|
CollectionScreen
|
|
TodayScreen
|
|
SettingsScreen
|
|
PlantDetailScreen
|
|
```
|
|
|
|
## Conventions
|
|
|
|
- Inherit `BaseUITestCase`, not `XCTestCase`
|
|
- Use `UITestID.*` identifiers, not localized strings
|
|
- Use screen objects for element access and assertions
|
|
- Launch with `launchClean()`, `launchWithMockData()`, or `launchOffline()`
|
|
- Replace `sleep()` with `waitUntilHittable()` / `waitUntilGone()` / `waitForExistence(timeout:)`
|
|
|
|
## Adding a Test
|
|
|
|
See [Docs/XCUITest-Authoring.md](../Docs/XCUITest-Authoring.md) for full guide.
|