years-fix-and-ui-tests.md 4.4 KB

Years Decoding Bug Fix + Full UI Test Suite

Part 1: Fix Years Decoding Bug

Problem

Navigating to Cloud → Browse → Years shows "Failed to decode response: The data couldn't be read because it isn't in the correct format."

Root cause investigation needed

The ChadCategory model expects item: String and count: Int?. The /api/cat/year endpoint likely returns item as a number (e.g., 2012 instead of "2012"), causing JSONDecoder to fail on the String type.

Fix approach

  1. Check what the API actually returns — add temporary logging or use the flexible decoding approach
  2. Make ChadCategory.item decode flexibly — accept both String and numeric values via custom init(from decoder:)
  3. Verify all category endpoints work after the fix (artist, genre, year, publisher, country, type, status)

Acceptance criteria

  • Browse → Years loads and displays year items without error
  • All other category types still work (artist, genre, publisher, country, type, status)
  • Year items display as clean integers (e.g., "2012" not "2012.0")
  • Tapping a year navigates to filtered album list (from the previous fix)

Files to change

  • Sources/Models/ChadMusic.swiftChadCategory: add custom Decodable init to handle numeric item values

Part 2: UI Test Suite (All Phases)

Prerequisites

Add accessibilityIdentifiers to key views:

  • CloudBrowserView — browse section items, stat badges, search field
  • CategoryDetailView — category item rows, error text, loading indicator
  • FilteredAlbumListView — album rows, empty state
  • AlbumDetailView — track rows, play button, album header
  • QueueView — now playing section, user queue items, up next items, clear button
  • NowPlayingView — play/pause, next, previous, progress bar
  • MiniPlayerView — track title, play/pause

Phase 1: Cloud Browser Smoke Tests (P1 — highest value)

4 test methods:

  1. testCloudHomeLoads — Cloud tab shows stats + Browse section with all category types
  2. testAllCategoriesLoad — Each category type loads without error text
  3. testAlbumDetailOpens — Browse → Albums → tap first album → tracks appear
  4. testCategoryDrillDown — Browse → Artists → tap first artist → filtered albums appear

Phase 2: Playback & Queue Tests

4 test methods:

  1. testPlayCloudTrack — Albums → tap album → tap track → mini player appears with track title
  2. testAddToQueue — Long-press track → "Add to Queue" → queue view shows entry
  3. testQueuePlayNext — Long-press track → "Play Next" → queue view shows it at top
  4. testQueueClear — Add tracks to queue → tap Clear → queue is empty

Phase 3: CI-Reliable Offline Tests

3 test methods using URLProtocol stubs:

  1. testCloudBrowserWithMockData — Stub stats + categories → verify UI renders
  2. testDecodingErrorShowsMessage — Stub malformed JSON → verify error text appears
  3. testAlbumTracksWithMockData — Stub album tracks → verify track list renders

Technical approach

  • Phase 1-2: Test against real Chad Music server. Tests require server to be running. Mark with @MainActor and use XCUIApplication with launch arguments.
  • Phase 3: Use URLProtocol subclass registered via -UITesting launch argument. App code checks for this flag and registers the stub protocol.
  • Add -UITesting flag handling in app startup to enable test-specific behaviors.

Files to create/modify

  • UITests/MixBoardUITests.swift — add new test methods
  • UITests/CloudBrowserUITests.swift — new file for cloud browser tests (Phase 1)
  • UITests/PlaybackUITests.swift — new file for playback tests (Phase 2)
  • UITests/MockURLProtocol.swift — new file for URL stubs (Phase 3)
  • Multiple view files — add accessibilityIdentifier calls

Appetite

  • Phase 1: ~4 files changed, ~150 lines new code (tests + accessibility IDs)
  • Phase 2: ~3 files changed, ~120 lines
  • Phase 3: ~3 files changed, ~200 lines
  • Total: reasonable for one builder session

Constraints

  • Don't modify existing 20 UI tests
  • Keep test file organization clean (separate files per test area)
  • accessibilityIdentifier values must use dot-notation: "cloud.browse.artists", "queue.clearButton", etc.
  • Tests must compile and pass xcodebuild test on iPhone 17 Pro simulator

Dependencies

  • Part 1 (Years fix) must be done first — Phase 1 tests will verify it
  • Chad Music server must be running for Phase 1-2 tests