Rebuild UI test foundation with page objects, wait helpers, and screen objects
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>
This commit is contained in:
67
CLAUDE.md
67
CLAUDE.md
@@ -9,13 +9,19 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||
xcodebuild -project PlantGuide.xcodeproj -scheme PlantGuide -configuration Debug
|
||||
|
||||
# Run all tests
|
||||
xcodebuild test -project PlantGuide.xcodeproj -scheme PlantGuide -destination 'platform=iOS Simulator,name=iPhone 16'
|
||||
xcodebuild test -project PlantGuide.xcodeproj -scheme PlantGuide -destination 'platform=iOS Simulator,name=iPhone 17'
|
||||
|
||||
# Run a single test class
|
||||
xcodebuild test -project PlantGuide.xcodeproj -scheme PlantGuide -destination 'platform=iOS Simulator,name=iPhone 16' -only-testing:PlantGuideTests/HybridIdentificationUseCaseTests
|
||||
xcodebuild test -project PlantGuide.xcodeproj -scheme PlantGuide -destination 'platform=iOS Simulator,name=iPhone 17' -only-testing:PlantGuideTests/HybridIdentificationUseCaseTests
|
||||
|
||||
# Run a single test method
|
||||
xcodebuild test -project PlantGuide.xcodeproj -scheme PlantGuide -destination 'platform=iOS Simulator,name=iPhone 16' -only-testing:PlantGuideTests/SavePlantUseCaseTests/testSavePlant_Success
|
||||
xcodebuild test -project PlantGuide.xcodeproj -scheme PlantGuide -destination 'platform=iOS Simulator,name=iPhone 17' -only-testing:PlantGuideTests/SavePlantUseCaseTests/testSavePlant_Success
|
||||
|
||||
# Build UI tests only (compile check, no simulator required)
|
||||
xcodebuild build-for-testing -project PlantGuide.xcodeproj -scheme PlantGuide -destination 'platform=iOS Simulator,name=iPhone 17' -quiet
|
||||
|
||||
# Run all UI tests
|
||||
xcodebuild test -project PlantGuide.xcodeproj -scheme PlantGuide -destination 'platform=iOS Simulator,name=iPhone 17' -only-testing:PlantGuideUITests
|
||||
```
|
||||
|
||||
## App Structure
|
||||
@@ -109,3 +115,58 @@ Entities (all CloudKit-compatible with optional attributes):
|
||||
- Test fixtures available for `Plant`, `CareTask`, `PlantCareSchedule`
|
||||
- Mock services: `MockPlantCollectionRepository`, `MockNetworkService`, etc.
|
||||
- In-memory Core Data stack for test isolation: `CoreDataStack(inMemory: true)`
|
||||
|
||||
### UI Testing
|
||||
|
||||
UI tests live in `PlantGuideUITests/` using a page-object foundation. See [Docs/XCUITest-Authoring.md](Docs/XCUITest-Authoring.md) for the full guide.
|
||||
|
||||
**Key patterns:**
|
||||
- Inherit `BaseUITestCase`, not `XCTestCase`
|
||||
- Launch with `launchClean()`, `launchWithMockData()`, or `launchOffline()`
|
||||
- Locate elements via `UITestID.*` identifiers (mirrors `AccessibilityIdentifiers` in app)
|
||||
- Navigate with screen objects: `TabBarScreen`, `CameraScreen`, `CollectionScreen`, `TodayScreen`, `SettingsScreen`, `PlantDetailScreen`
|
||||
- Wait with `waitForExistence(timeout:)`, `waitUntilHittable()`, `waitUntilGone()` -- never `sleep()`
|
||||
- One assertion focus per test method
|
||||
|
||||
## Claude GitHub App
|
||||
|
||||
### Installation
|
||||
1. Go to [github.com/apps/claude](https://github.com/apps/claude)
|
||||
2. Click "Install" and select this repository
|
||||
3. Grant the requested permissions (read/write for code, issues, and pull requests)
|
||||
4. Authenticate with your Anthropic account when prompted
|
||||
|
||||
### How It Works
|
||||
- The app reads this `CLAUDE.md` file for project context and contribution rules
|
||||
- Claude responds to `@claude` mentions in issues and PRs
|
||||
- No API key configuration needed - authentication is handled through the GitHub App integration
|
||||
|
||||
### Triggering Claude
|
||||
- **Issues**: Mention `@claude` in an issue to request implementation help
|
||||
- **PRs**: Mention `@claude` to request code review or changes
|
||||
|
||||
## Claude Contribution Rules
|
||||
|
||||
### Scope
|
||||
- Work ONLY on the issue explicitly assigned to you.
|
||||
- One issue = one pull request.
|
||||
- Do not refactor unrelated code.
|
||||
- Do not change public APIs unless the issue explicitly says so.
|
||||
|
||||
### Safety Rules
|
||||
- Never auto-merge.
|
||||
- Never force-push to main.
|
||||
- Never delete code unless instructed.
|
||||
- Preserve existing behavior unless tests say otherwise.
|
||||
|
||||
### iOS Rules
|
||||
- Respect Swift concurrency (MainActor, async/await).
|
||||
- Do not introduce Combine unless already used.
|
||||
- Prefer pure functions for new logic.
|
||||
- No new dependencies without approval.
|
||||
|
||||
### Output Expectations
|
||||
Each PR must include:
|
||||
- Clear summary of changes
|
||||
- Files touched (with rationale)
|
||||
- Risks and how to test
|
||||
|
||||
Reference in New Issue
Block a user