Files
honeyDueKMP/iosApp/iosApp/Helpers/UITestRuntime.swift
T
Trey T 5bb27034aa Fix UI test failures: registration dismiss cascade, onboarding reset, test stability
- Fix registration flow dismiss cascade: chain fullScreenCover → sheet onDismiss
  so auth state is set only after all UIKit presentations are removed, preventing
  RootView from swapping LoginView→MainTabView behind a stale sheet
- Fix onboarding reset: set hasCompletedOnboarding directly instead of calling
  completeOnboarding() which has an auth guard that fails after DataManager.clear()
- Stabilize Suite1 registration tests, Suite6 task tests, Suite7 contractor tests
- Add clean-slate-per-suite via AuthenticatedUITestCase reset state
- Improve test account seeding and screen object reliability

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 16:11:47 -05:00

76 lines
2.5 KiB
Swift

import Foundation
import UIKit
import ComposeApp
/// Runtime contract between the app and XCUITests.
enum UITestRuntime {
static let uiTestingFlag = "--ui-testing"
static let disableAnimationsFlag = "--disable-animations"
static let resetStateFlag = "--reset-state"
static let mockAuthFlag = "--ui-test-mock-auth"
static let completeOnboardingFlag = "--complete-onboarding"
static var launchArguments: [String] {
ProcessInfo.processInfo.arguments
}
static var isEnabled: Bool {
launchArguments.contains(uiTestingFlag)
}
static var shouldDisableAnimations: Bool {
isEnabled && launchArguments.contains(disableAnimationsFlag)
}
static var shouldResetState: Bool {
isEnabled && launchArguments.contains(resetStateFlag)
}
static var shouldMockAuth: Bool {
isEnabled && launchArguments.contains(mockAuthFlag)
}
static var shouldCompleteOnboarding: Bool {
isEnabled && launchArguments.contains(completeOnboardingFlag)
}
static func configureForLaunch() {
guard isEnabled else { return }
if shouldDisableAnimations {
UIView.setAnimationsEnabled(false)
}
UserDefaults.standard.set(true, forKey: "ui_testing_mode")
// Mark onboarding complete synchronously before SwiftUI renders,
// so RootView routes to the standalone LoginView instead of OnboardingCoordinator.
if shouldCompleteOnboarding {
UserDefaults.standard.set(true, forKey: "hasCompletedOnboarding")
}
}
@MainActor static func resetStateIfRequested() {
guard shouldResetState else { return }
DataManager.shared.clear()
OnboardingState.shared.reset()
ThemeManager.shared.currentTheme = .bright
UserDefaults.standard.removeObject(forKey: "ui_test_user_verified")
// Re-apply onboarding completion after reset. Set the flag directly
// because completeOnboarding() has an auth guard that fails here
// (DataManager was just cleared, so isAuthenticated is false).
if shouldCompleteOnboarding {
OnboardingState.shared.hasCompletedOnboarding = true
}
}
/// Mark onboarding as complete so the app shows the standalone login
/// instead of the onboarding coordinator. Called after resetState (if any).
@MainActor static func completeOnboardingIfRequested() {
guard shouldCompleteOnboarding else { return }
OnboardingState.shared.completeOnboarding()
}
}