/** * ios-capture.ts - pure helpers for orchestrating iOS snapshot capture. * The exported functions do not spawn processes; scripts wire them to xcrun/xcodebuild. */ /** * Shape of a single Xcode test target as gathered from the .pbxproj. * All booleans must be resolved by the harness before calling checkSnapshotWiring; * this module stays pure and unit-testable offline. */ export type SnapshotTestTarget = { /** Display name of the target (e.g. "CaptureHostUITests") */ name: string; /** * CFBundleProductType value from the pbxproj. * UITest target: "com.apple.product-type.bundle.ui-testing" * Unit-test target: "com.apple.product-type.bundle.unit-test" */ productType: string; /** True iff AccessibilitySnapshot.swift appears in the target's compile-sources build phase */ hasSnapshotDependency: boolean; /** * True iff the target has a TEST_HOST set (hosted unit-test) OR is a UITest target * whose TEST_HOST / host application bundle ref is set to the app under test. * Must be pre-resolved by the harness from build settings. */ isHosted: boolean; }; export type SnapshotWiringInput = { /** True iff scripts/AccessibilitySnapshot.swift is present anywhere in the project dir */ hasSnapshotSwift: boolean; testTargets: SnapshotTestTarget[]; /** Full version string from `xcodebuild -version`, e.g. "Xcode 16.2" or "Xcode 26.0" */ xcodeVersion?: string; }; export type SnapshotWiringResult = { ready: boolean; missing: string[]; guidance: string[]; }; /** * Pure preflight — resolves whether the Xcode project is correctly wired for * AccessibilitySnapshot-based capture WITHOUT shelling out. * * Callers supply already-gathered facts (file-existence + pbxproj parse), * keeping this function fully unit-testable offline. * * ready = hasSnapshotSwift && at least one testTarget where both * hasSnapshotDependency === true && isHosted === true. */ export declare const checkSnapshotWiring: (input: SnapshotWiringInput) => SnapshotWiringResult; /** * Stub documenting WHERE the harness should read the facts that * checkSnapshotWiring() expects. The heavy pbxproj parsing lives in the * harness (scripts/ios-audit.mjs); this stub is the typed contract between * the two so callers know exactly what to gather before invoking the pure check. * * Concretely, the harness should: * 1. hasSnapshotSwift — fs.existsSync(path.join(projectDir, 'scripts/AccessibilitySnapshot.swift')) * 2. testTargets — parse .xcodeproj/project.pbxproj with a pbxproj * library (e.g. xcode-pbxproj or a simple regex pass) and, * for each PBXNativeTarget whose productType is ui-testing or * unit-test, resolve: * - hasSnapshotDependency: the PBXSourcesBuildPhase for that * target contains a file ref whose path ends in * "AccessibilitySnapshot.swift" * - isHosted: build settings resolve TEST_HOST to a non-empty * string (or the UITest target has a "host" application ref) * 3. xcodeVersion — stdout of `xcodebuild -version` (first line, e.g. "Xcode 16.2") * * @param projectDir - Root directory of the Xcode project (the folder containing * *.xcodeproj and the scripts/ subdirectory). */ export declare const gatherWiringFacts: (projectDir: string) => Promise; export type CaptureTarget = { device_id?: string; real_device_required?: boolean; osVersion?: string; scheme?: string; testTarget?: string; }; export type IosInteraction = { id: string; event: "tap" | "swipe" | "focus" | "freeze_animation" | "hover"; delay_ms: number; t_seconds?: number; }; export type DestinationResult = { kind: "device" | "simulator"; destination: string; }; export type BlockResult = { blocked: boolean; reason?: string; }; /** * Build the xcodebuild destination string. Device UDIDs always win. */ export declare function buildDestination(opts: CaptureTarget, bootedSimUdid?: string): DestinationResult; /** * Block unsafe fallback when the caller requires a real device but omitted one. */ export declare function shouldBlock(opts: CaptureTarget): BlockResult; /** * Parse `xcrun simctl list runtimes --json` and return available iOS versions. */ export declare function parseSimRuntimes(simctlRuntimesJson: string): string[]; /** * Check whether any simulator runtime satisfies the target OS. * A target of "17" matches all 17.x runtimes; "17.5" matches 17.5.x. */ export declare function simRuntimeAvailable(runtimes: string[], osVersion?: string): boolean; /** * Parse `xcrun devicectl device info apps ... --json-output -` for CFBundleVersion. */ export declare function parseInstalledBuildVersion(devicectlAppsJson: string, bundleId: string): string | null; /** * Build the exact xcodebuild test invocation args for the snapshot XCUITest. */ export declare function xcodebuildTestArgs(scheme: string, destination: string, testTarget: string): string[]; /** * Parse interaction JSON for the XCUITest env contract. */ export declare function parseInteractions(json: string | undefined): IosInteraction[]; /** * Convert the first freeze_animation marker with t_seconds into launch args. */ export declare function freezeLaunchArgs(interactions: IosInteraction[]): string[]; /** * Merge caller launch args with deterministic freeze args, preserving first wins. */ export declare function buildLaunchArgs(baseArgs: string[], interactions: IosInteraction[]): string[]; /** * Build xcodebuild child env additions for the shared XCUITest contract. */ export declare function captureEnv(interactions: IosInteraction[], finalLaunchArgs: string[]): Record;