db65db6232
Android UI Tests / ui-tests (push) Has been cancelled
Localize all user-facing strings across iOS (SwiftUI), shared Kotlin, and Android Compose into en/es/fr/de/pt/it/ja/ko/nl/zh: - iOS String Catalogs: main + widget Localizable.xcstrings, InfoPlist.xcstrings (permissions), plural variations, ~200 new keys translated - Shared Kotlin ClientStrings table + Android composeResources/values-* (884 keys ×10), routed Api/ViewModel/util error & UI strings through localization - Backend-localized lookups/suggestions consumed via display names - Widget extension catalog; theme names, home-profile fallbacks, validation, network errors, accessibility labels all localized Add re-runnable verification gates: - scripts/i18n_audit.py — enumerate every literal, partition to GAP=0 - scripts/i18n_coverage.py — all 10 locales translated, format-specifier parity Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
78 lines
2.6 KiB
Swift
78 lines
2.6 KiB
Swift
import Foundation
|
|
import UIKit
|
|
import ComposeApp
|
|
|
|
/// Runtime contract between the app and XCUITests.
|
|
enum UITestRuntime {
|
|
// i18n-ignore-begin: launch-argument flag identifiers for XCUITests (non-UI)
|
|
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"
|
|
// i18n-ignore-end
|
|
|
|
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()
|
|
}
|
|
}
|