feat(ios): route iPad Simulator snapshots through the host AX bridge

Merged
TH
2d ago
+228-80

Summary

iPad Simulators (appleOs: 'ipados') now use the host AX bridge. The route and launch observation admitted only ios, so every iPad capture went to XCTest (#3844). hasSimulatorBridge now uses isHandheldAppleSimulator; devices, providers, tvOS, visionOS, and macOS stay excluded.

Live checks found two iPad gaps, fixed here:

  • Floating tab items are Cell/Other with the tab-button trait (bit 28). XCTest types them Button; the bridge now does too.
  • Windowed Apps and Stage Manager report frames relative to the window, so bridge taps missed. The guest refuses (app-window-not-full-screen, capture-scoped) when the app frame โ‰  the screen frame. The XCTest fallback is also offset there (runner gap, not fixed; the warning says so).

14 files; ADR 0004 and bridge README amended. Refs #3844.

Validation

Head 4fa5bd595e: check:affected --run --head and pnpm gate unit-ci pass except apple-platform-output-guard (record exceeds 20 s; same with base sources) and one 5 s timeout in coordinate.contract errorTaxonomy under load (passes alone, cause unproven). New tests fail at base.

iOS 27.0 iPad Pro 11" M5, iPad Air 11" M4, iPhone 17 Pro; bridge vs forced tree:

CaseBridgeParity
Portrait, landscape, keyboardservedrects equal
Alert, sheetservedrects equal
Apple PayXCTest, then bridgeโ€”
Permission alertXCTest (ownership)โ€”
Windowed, Stage ManagerXCTest (new refusal)runner offset
Bluesky feed285 vs 453 ms p50266/266 types
iPhone140 vs 241 ms p50unchanged

Slide Over untested.

๐Ÿค– Generated with Claude Code