From 5bf5b7d7640752114a21a5c8ae62d7431bf7bc88 Mon Sep 17 00:00:00 2001 From: justanotheratom Date: Mon, 1 Jun 2026 07:20:02 +0530 Subject: [PATCH] Fix: add missing simulator QA harness types so the app compiles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Maestro simulator harness (#114–#116) references three types that were never committed, so the IngrediCheck target fails to build on main: - DebugScanQAMode (.isEnabled, .presets) — used by SplashScreen, HomeView, ScanCameraView, and DebugBarcodeInjectorSheet - AppRuntimePolicy (.disablesAnalytics, .skipsDeviceRegistration, .usesLocalUITestAuth) — used by AuthController and AnalyticsService This adds both to IngrediCheck/Testing/UITestHarness.swift, alongside the existing UITestHarness, with behavior reconstructed from their call sites: - DebugScanQAMode mirrors UITestHarness's --debug-scan-qa launch-arg parsing (simulator-only) and exposes the barcode injector presets. Preset labels match what the scan flows tap ("Coca-Cola 12 oz", "Invalid") and map to the barcodes seeded in UITestFixtures.makeScans(). - AppRuntimePolicy centralizes the simulator-isolation switches: suppress analytics and backend device registration under any automated run, and gate the local fake-session path to the fully-mocked UITestHarness flows. With this, the project builds and the full 63-flow Maestro suite runs; 61 pass. (The two settings sign-out/delete flows still fail because the post-sign-out SplashScreen signInState handler is commented out — tracked separately.) Co-Authored-By: Claude Opus 4.8 --- IngrediCheck/Testing/UITestHarness.swift | 76 ++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/IngrediCheck/Testing/UITestHarness.swift b/IngrediCheck/Testing/UITestHarness.swift index 421e8cf..f204918 100644 --- a/IngrediCheck/Testing/UITestHarness.swift +++ b/IngrediCheck/Testing/UITestHarness.swift @@ -1102,6 +1102,82 @@ private enum UITestFixtures { } } +/// Lightweight, simulator-only debug mode that exercises the live barcode-scan QA +/// path through the debug barcode injector. Enabled via the `--debug-scan-qa` launch +/// argument (see `.maestro/subflows/launch_scan_qa.yaml`). Distinct from +/// `UITestHarness`, which mocks the backend; this mode drives the real scan pipeline. +enum DebugScanQAMode { + static let launchArgument = "--debug-scan-qa" + + struct Preset: Identifiable { + let label: String + let barcode: String + var id: String { barcode } + } + + /// Known-good and known-invalid barcodes surfaced as quick-select buttons in the + /// debug barcode injector. Mirrors the products seeded in `UITestFixtures.makeScans()`. + static let presets: [Preset] = [ + Preset(label: "Coca-Cola 12 oz", barcode: "049000028911"), + Preset(label: "Oreo Original", barcode: "044000032547"), + Preset(label: "Invalid", barcode: "000000000000") + ] + + static var isEnabled: Bool { +#if targetEnvironment(simulator) + let arguments = ProcessInfo.processInfo.arguments + if arguments.contains(launchArgument) { + return true + } + if let rawValue = arguments.first(where: { $0.hasPrefix("\(launchArgument)=") })? + .split(separator: "=", maxSplits: 1) + .last + { + return isTruthy(String(rawValue)) + } + return false +#else + false +#endif + } + + private static func isTruthy(_ rawValue: String) -> Bool { + switch rawValue.lowercased() { + case "1", "true", "yes", "y": + true + default: + false + } + } +} + +/// Centralizes the runtime behavior changes that keep automated simulator runs from +/// touching production services (analytics, backend device registration) and from +/// depending on real authentication. Introduced to isolate simulator auth and analytics. +enum AppRuntimePolicy { + /// True under any automated harness: the fully-mocked `UITestHarness` flows or the + /// live-pipeline `DebugScanQAMode` scan QA flows. + static var isAutomatedRun: Bool { + UITestHarness.isEnabled || DebugScanQAMode.isEnabled + } + + /// The mocked UI-test flows install a local fake Supabase session instead of + /// performing real authentication; this gates that install/clear/guard logic. + static var usesLocalUITestAuth: Bool { + UITestHarness.isEnabled + } + + /// Suppress analytics during automated runs so test traffic does not pollute metrics. + static var disablesAnalytics: Bool { + isAutomatedRun + } + + /// Skip backend device registration during automated runs. + static var skipsDeviceRegistration: Bool { + isAutomatedRun + } +} + private extension DTO.ScanAnalysisResult { init( id: String?,