8 Commits

Author SHA1 Message Date
Trey T
2ef1c1ec51 Enable parallel UI test execution via per-session data isolation
Each test class now gets a unique session ID (UUID) passed to the app
via UI_TEST_SESSION_ID environment variable. The app uses this to:

- Route GroupUserDefaults to a session-specific UserDefaults suite,
  preventing tests from clobbering each other's AppStorage state
- Create an in-memory SwiftData container instead of the shared
  on-disk App Group store, eliminating SQLite contention

Refactored 8 test classes that bypassed BaseUITestCase.setUp() with
custom launch args — they now use overridable `localeArguments` and
`extraLaunchArguments` properties, keeping session ID injection
centralized. Added `relaunchApp(resetState:bypassSubscription:)` to
BaseUITestCase for tests that need mid-test relaunch with different
subscription state.

Includes a ParallelUITests.xctestplan with class-level parallelism
enabled and random execution ordering.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 15:04:55 -05:00
Trey t
0442eab1f8 Rebrand entire project from Feels to Reflect
Complete rename across all bundle IDs, App Groups, CloudKit containers,
StoreKit product IDs, data store filenames, URL schemes, logger subsystems,
Swift identifiers, user-facing strings (7 languages), file names, directory
names, Xcode project, schemes, assets, and documentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 11:47:16 -06:00
Trey t
8845ccfd1b Fix cascading crash and remaining UI test failures
- Revert key-by-key UserDefaults iteration that removed system keys
  causing kAXErrorServerNotFound crashes; restore removePersistentDomain
  with explicit subscription key clearing
- Add .accessibilityElement(children: .contain) to UpgradeBannerView
  so subscribe button is discoverable by XCUITest
- Fix AllDayViewStylesTests to use coordinate-based tapping instead of
  button.isHittable/button.tap() for iOS 26 Liquid Glass compatibility
- Improve OnboardingTests with multiple swipe retries and label-based
  fallback for skip button

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 19:57:03 -06:00
Trey t
9157fd2577 Fix remaining 9 UI test failures: subscription state, scroll, timing
- Replace removePersistentDomain with key-by-key removal in resetAppState
  (removePersistentDomain is unreliable on app group UserDefaults suites)
- Add explicit cache clearing in IAPManager.resetForTesting() to prevent
  stale cachedSubscriptionExpiration from restoring .subscribed state
- Use descendants(matching: .any) for upgrade_banner and subscribe_button
  queries (VStack may not match otherElements in SwiftUI)
- Add multiple swipe attempts for icon pack horizontal scroll
- Use coordinate-based drag for onboarding paged TabView advancement
- Add longer wait for Day view refresh after theme change
- Add multiple scroll attempts to find clear data button in Settings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 19:13:18 -06:00
Trey t
c286294cd3 Fix remaining 12 UI test failures: subscription state, hittability, tab selection
- IAPManager: add resetForTesting() to discard stale cached subscription state
- UITestMode: call resetForTesting() after clearing defaults (fixes 5 banner tests)
- StabilityTests: use NSPredicate wait for isSelected (iOS 26 Liquid Glass)
- SettingsActionTests: use coordinate tap for clear data and analytics toggle
- IconPackTests: add horizontal scroll fallback for off-screen icon packs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 17:43:28 -06:00
Trey t
224341fd98 Fix remaining 17 UI test failures: group defaults, identifiers, hittability, date format
- resetAppState: use correct suite name to clear group defaults (fixes stale subscription state)
- Reorder configureIfNeeded: set expireTrial before IAPManager init
- Add browse_themes_button identifier to CustomizeView Browse Themes button
- Add mood_button_* identifiers to Entry Detail mood grid in NoteEditorView
- Use coordinate-based tap throughout all test screens (iOS 26 Liquid Glass hittability)
- Fix HeaderMoodLogging date format: M/d/yyyy → yyyy/MM/dd to match entry_row identifiers
- AppLaunchTests: wait for isSelected state with NSPredicate instead of immediate check
- OnboardingTests: add waits between swipes and retry logic for skip button

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 16:46:18 -06:00
Trey t
44b46f88e2 Fix 23 failing UI tests: accessibility hierarchy, test mode, and interaction issues
App fixes:
- Remove empty_state identifier from EmptyHomeView VStack (was overriding mood_header)
- Fix resetAppState to set needsOnboarding=true (fresh state) instead of false
- Set bypassSubscription explicitly based on launch arg presence (was defaulting to true in DEBUG)

Test fixes:
- TabBarScreen: use coordinate tap to avoid iOS 26 Liquid Glass hittability issues
- SettingsScreen: use coordinate tap for segments, handle Settings label ambiguity with tab bar
- EntryDetailScreen: use mood_button_ identifiers instead of label matching (was matching entry rows)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 16:14:16 -06:00
Trey t
277e277750 Add XCUITest suite with 27 test files covering unmapped P1 test cases
- Add 8 new test files: HeaderMoodLogging (TC-002), DayViewGrouping (TC-019),
  AllDayViewStyles (TC-021), MonthViewInteraction (TC-030), PaywallGate
  (TC-032/039/048), AppTheme (TC-070), IconPack (TC-072),
  PremiumCustomization (TC-075)
- Add accessibility IDs for paywall overlays, icon packs, app theme cards,
  and day view section headers
- Add --expire-trial launch argument to UITestMode for paywall gate testing
- Update QA test plan spreadsheet with XCUITest names for 14 test cases
- Include existing test infrastructure: screen objects, helpers, base class,
  and 19 previously written test files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:37:54 -06:00