MovieMapper/docs/UI_TESTS_README.md
Jarian Cottingham 1a35eb346e chore: reorganize repo layout, remove dead files
- Move phase/plan docs into docs/
- Move legacy node:test files into tests/legacy/ with README
- Remove .backup file, test audit artifacts, and unused AI prompt/skill files
- Remove broken iOS GitHub workflows (reference missing MovieMapper-iOS/)
2026-08-20 20:11:57 +00:00

5.6 KiB

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

# 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

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:

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:

// 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:

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:

// ❌ 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:

// 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

# Increase timeout in test
XCTWaiter.wait(for: [expectation], timeout: 10)

Element Not Found

# Check accessibility identifiers
print(app.debugDescription)

iPad Simulator Issues

# Reset simulator
xcrun simctl shutdown all
xcrun simctl erase all

CI/CD Integration

Add to your CI pipeline:

- 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


Last updated: March 2026