Added comprehensive documentation for the KMM project structure, build commands, and UI testing setup/troubleshooting. Documentation added: - CLAUDE.md: Complete KMM project guide for Claude Code with architecture, build commands, common tasks, and development patterns - iosApp/UI_TESTS_*.md: UI testing strategy, implementation guides, summaries - iosApp/XCUITEST_*.md: XCUITest implementation and debugging guides - iosApp/TEST_FAILURES_ANALYSIS.md: Analysis of common test failures - iosApp/ACCESSIBILITY_IDENTIFIERS_FIX.md: Guide for fixing accessibility issues - iosApp/FIX_TEST_TARGET*.md: Guides for fixing test target configuration - iosApp/fix_test_target.sh: Script to automate test target setup The CLAUDE.md serves as the primary documentation for working with this repository, providing quick access to build commands, architecture overview, and common development tasks for both iOS and Android platforms. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
159 lines
4.2 KiB
Markdown
159 lines
4.2 KiB
Markdown
# Accessibility Identifiers - Duplicate Fix
|
|
|
|
## Issue
|
|
The original `AccessibilityIdentifiers.swift` file had duplicate `cancelButton` declarations within the same struct, causing a compiler error:
|
|
```
|
|
Invalid redeclaration of 'cancelButton'
|
|
```
|
|
|
|
## Root Cause
|
|
Multiple forms within the same feature area (e.g., Task) had cancel buttons, and they were all named `cancelButton`:
|
|
- `Task.cancelButton` (line 103) - for TaskForm
|
|
- `Task.cancelButton` (line 111) - for TaskDetail
|
|
|
|
This occurred in multiple structs:
|
|
- `Authentication.cancelButton` (Register)
|
|
- `Residence.cancelButton` (Form)
|
|
- `Task.cancelButton` (Form) ❌ Duplicate
|
|
- `Task.cancelButton` (Detail) ❌ Duplicate
|
|
- `Contractor.cancelButton` (Form)
|
|
- `Document.cancelButton` (Form)
|
|
- `Alert.cancelButton` (Generic alerts)
|
|
|
|
## Solution
|
|
Renamed context-specific cancel buttons to be more descriptive:
|
|
|
|
### Authentication Struct
|
|
```swift
|
|
// Before
|
|
static let cancelButton = "Register.CancelButton"
|
|
|
|
// After
|
|
static let registerCancelButton = "Register.CancelButton"
|
|
```
|
|
|
|
### Residence Struct
|
|
```swift
|
|
// Before
|
|
static let cancelButton = "ResidenceForm.CancelButton"
|
|
|
|
// After
|
|
static let formCancelButton = "ResidenceForm.CancelButton"
|
|
```
|
|
|
|
### Task Struct
|
|
```swift
|
|
// Before (DUPLICATE ERROR)
|
|
static let cancelButton = "TaskForm.CancelButton" // Line 103
|
|
static let cancelButton = "TaskDetail.CancelButton" // Line 111 ❌
|
|
|
|
// After (FIXED)
|
|
static let formCancelButton = "TaskForm.CancelButton"
|
|
static let detailCancelButton = "TaskDetail.CancelButton"
|
|
```
|
|
|
|
### Contractor Struct
|
|
```swift
|
|
// Before
|
|
static let cancelButton = "ContractorForm.CancelButton"
|
|
|
|
// After
|
|
static let formCancelButton = "ContractorForm.CancelButton"
|
|
```
|
|
|
|
### Document Struct
|
|
```swift
|
|
// Before
|
|
static let cancelButton = "DocumentForm.CancelButton"
|
|
|
|
// After
|
|
static let formCancelButton = "DocumentForm.CancelButton"
|
|
```
|
|
|
|
### Alert Struct (Unchanged)
|
|
```swift
|
|
// Generic cancel button for alerts - no conflict
|
|
static let cancelButton = "Alert.CancelButton"
|
|
```
|
|
|
|
## Files Modified
|
|
|
|
1. **`iosApp/Helpers/AccessibilityIdentifiers.swift`**
|
|
- Renamed 6 cancel button identifiers to be context-specific
|
|
|
|
2. **`iosApp/MyCribTests/ComprehensiveResidenceTests.swift`**
|
|
- Updated reference from `Residence.cancelButton` → `Residence.formCancelButton`
|
|
|
|
## Usage Examples
|
|
|
|
### Before (Would cause conflicts)
|
|
```swift
|
|
// Task Form
|
|
Button("Cancel") { }
|
|
.accessibilityIdentifier(AccessibilityIdentifiers.Task.cancelButton) // ❌ Which one?
|
|
|
|
// Task Detail
|
|
Button("Cancel") { }
|
|
.accessibilityIdentifier(AccessibilityIdentifiers.Task.cancelButton) // ❌ Duplicate!
|
|
```
|
|
|
|
### After (Clear and unambiguous)
|
|
```swift
|
|
// Task Form
|
|
Button("Cancel") { }
|
|
.accessibilityIdentifier(AccessibilityIdentifiers.Task.formCancelButton) // ✅ Clear
|
|
|
|
// Task Detail
|
|
Button("Cancel") { }
|
|
.accessibilityIdentifier(AccessibilityIdentifiers.Task.detailCancelButton) // ✅ Clear
|
|
```
|
|
|
|
## Naming Convention
|
|
|
|
For cancel buttons in different contexts:
|
|
- **Forms**: `formCancelButton`
|
|
- **Detail/View screens**: `detailCancelButton`
|
|
- **Registration**: `registerCancelButton`
|
|
- **Generic alerts**: `cancelButton` (in Alert struct)
|
|
|
|
## Test Updates Required
|
|
|
|
When adding identifiers to views, use the updated names:
|
|
|
|
```swift
|
|
// Residence Form
|
|
Button("Cancel") { dismiss() }
|
|
.accessibilityIdentifier(AccessibilityIdentifiers.Residence.formCancelButton)
|
|
|
|
// Task Form
|
|
Button("Cancel") { dismiss() }
|
|
.accessibilityIdentifier(AccessibilityIdentifiers.Task.formCancelButton)
|
|
|
|
// Task Detail
|
|
Button("Cancel Task") { }
|
|
.accessibilityIdentifier(AccessibilityIdentifiers.Task.detailCancelButton)
|
|
```
|
|
|
|
## Verification
|
|
|
|
The file should now compile without errors. To verify:
|
|
|
|
```bash
|
|
cd /Users/treyt/Desktop/code/MyCrib/MyCribKMM/iosApp
|
|
xcodebuild -project iosApp.xcodeproj -scheme iosApp -destination 'generic/platform=iOS Simulator' clean build
|
|
```
|
|
|
|
Or simply build in Xcode (⌘+B).
|
|
|
|
## Status
|
|
|
|
✅ **Fixed** - All duplicate identifiers resolved
|
|
✅ **Test files updated** - ComprehensiveResidenceTests uses new names
|
|
✅ **No breaking changes** - Only internal identifier names changed, not the actual string values
|
|
|
|
---
|
|
|
|
**Last Updated:** November 18, 2025
|
|
**Issue:** Duplicate cancelButton declarations
|
|
**Resolution:** Renamed to context-specific names (formCancelButton, detailCancelButton, etc.)
|