# MovieMapper iOS UI Testing Guide ## Overview This document describes the UI testing implementation for MovieMapper iOS app using XCUITest framework. ## Test Structure ``` Tests/ ├── BrowseViewUITests.swift # Browse view UI tests ├── SearchViewUITests.swift # Search view UI tests ├── FileListViewUITests.swift # File list view UI tests ├── TestConfiguration.swift # Test configuration utilities ├── TestReportGenerator.swift # Test report generation └── UITestHelper.swift # Common test helper utilities ``` ## Test Coverage ### 1. BrowseViewUITests Tests for the directory browsing and file scanning functionality: - ✅ Directory picker opens correctly - ✅ File scanning shows progress indicator - ✅ File tag toggle functionality - ✅ File movement with tagged files - ✅ Navigation breadcrumb display - ✅ iPad multi-column navigation ### 2. SearchViewUITests Tests for the TVDB search functionality: - ✅ Search bar displays correctly - ✅ Search shows returns results - ✅ Show selection displays seasons - ✅ Season selection shows episodes - ✅ Search navigation flow - ✅ iPad split view search ### 3. FileListViewUITests Tests for the file list management: - ✅ File list displays correctly - ✅ Drag and drop reordering - ✅ Tag toggle in file list - ✅ Floating action button appears - ✅ Move all tagged files - ✅ Multiple tag types support - ✅ iPad multi-column file list ## Running Tests ### Prerequisites - Xcode 15.0 or later - iOS Simulator with iPad Pro (12.9-inch) (17th generation) - iOS 17.0 simulator runtime ### Quick Start ```bash # Run all UI tests ./run-ui-tests.sh # Run specific test target ./run-ui-tests.sh BrowseViewUITests ./run-ui-tests.sh SearchViewUITests ./run-ui-tests.sh FileListViewUITests ``` ### Using Xcode 1. Open `MovieMapper-iOS.xcodeproj` 2. Select the "MovieMapper-iOS" scheme 3. Choose "Any iOS Simulator" as the destination 4. Press ⌘U or select "Test" from the menu ### Using xcodebuild ```bash xcodebuild test \ -project MovieMapper-iOS.xcodeproj \ -scheme "MovieMapper-iOS" \ -destination "platform=iOS Simulator,name=iPad Pro (12.9-inch) (17th generation),OS=17.0" \ -destination-timeout 60 \ -configuration Debug \ -resultBundlePath ./test-results.xcresult ``` ## iPad-Specific Testing All UI tests are configured to run on iPad Pro (12.9-inch) simulator with the following settings: - **Device**: iPad Pro (12.9-inch) (17th generation) - **iOS Version**: 17.0 - **Orientation**: Portrait - **Size**: 1024x768 points minimum ### iPad Features Tested 1. **Multi-Column Navigation**: `NavigationSplitView` sidebar functionality 2. **Split View**: Search on left, files on right 3. **Large Screen Layout**: Optimized use of horizontal space 4. **Touch Targets**: Minimum 44pt tap targets throughout ## Test Configuration ### TestConfiguration.swift Configuration constants for test execution: ```swift static let iPadPro129 = "iPad Pro (12.9-inch) (17th generation)" static let iOSVersion = "17.0" static let testTimeout: TimeInterval = 30 ``` ### Custom Test Helper `UITestHelper.swift` provides convenience methods: ```swift // Launch app with test mode UITestHelper.launchApp() // Wait for element with custom timeout UITestHelper.waitForElementToExist(element, "Message") // Tap element with timeout UITestHelper.tapElement(element, timeout: 5) // Type text into element UITestHelper.typeText("text", into: element) ``` ## Test Report Generation Test results can be exported in JSON format: ```swift let report = TestReportGenerator.generateTestReport( testResults: testResults, outputFormat: "json" ) ``` Report includes: - Test execution timestamp - Test suite name - Individual test results - iPad configuration details - Summary statistics (total, passed, failed, skipped, pass rate) ## Best Practices ### Test Naming Use descriptive test names following the pattern: - `testFeatureAction_Condition_ExpectedResult` Examples: - `testDirectoryPickerOpens` - `testFileScanningShowsProgress` - `testiPadMultiColumnNavigation` ### Wait Strategies Always use explicit waits instead of `Thread.sleep`: ```swift // ❌ Bad Thread.sleep(forTimeInterval: 2) // ✅ Good let element = app.buttons["Submit"] XCTWaiter.wait(for: [expectation], timeout: 5) ``` ### Element Identification Use accessibility identifiers for reliable element targeting: ```swift // Set in code element.accessibilityIdentifier = "BrowseButton" // Test code let browseButton = app.buttons["BrowseButton"] ``` ### Test Isolation Each test should: - Start with a clean state - Not depend on other tests - Clean up after itself ## Troubleshooting ### Test Times Out ```bash # Increase timeout in test XCTWaiter.wait(for: [expectation], timeout: 10) ``` ### Element Not Found ```bash # Check accessibility identifiers print(app.debugDescription) ``` ### iPad Simulator Issues ```bash # Reset simulator xcrun simctl shutdown all xcrun simctl erase all ``` ## CI/CD Integration Add to your CI pipeline: ```yaml - name: Run iOS UI Tests run: | ./run-ui-tests.sh timeout: 10m ``` ## Next Steps - [ ] Add performance testing - [ ] Add snapshot testing with SnapshotTesting - [ ] Add accessibility testing - [ ] Add visual regression testing - [ ] Set up automated test reporting - [ ] Integrate with test management tools ## References - [XCUITest Documentation](https://developer.apple.com/documentation/xctest/xcuitest) - [UI Testing Best Practices](https://developer.apple.com/documentation/xctest/ui_testing) - [iOS Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/) --- *Last updated: March 2026*