fix(limrun): list the tabs of a collapsed iOS tab bar in snapshots

TH
2h ago
+855-6

Summary

On a Limrun iPhone, a native UITabBar arrives from elementTree() as one childless Group "Tab Bar", so snapshot had no tabs. The adapter now hit-tests across it with elementTree(point) and publishes the tabs as its children, with labels, frames and selected state.

  • Candidates: childless, wide Groups docked along the bottom edge, ranked by tab-bar height (44–100 pt), then lowest top edge.
  • Probes: at most 24 per snapshot, shared evenly, at least one per 44 pt, in parallel under a 1.5 s timeout.
  • Tabs: TabButton hits passing the runner's rule; geometry shared via contracts/fixtures/ios-collapsed-tab-geometry.json.
  • Failure: all or nothing. The bar stays as reported with a typed residue, collapsed-tab-bar-probe-failed (rejected, timed-out, budget-exhausted), shown as a warning. Exhaustion is reported only for tab-bar-sized candidates.

iPhone scope: a bar wider than 1,056 pt reports budget-exhausted before any probe. #3967 edits the same call; on rebase, probes use its source option.

Fixes #3992

Validation

  • Regressions fail on base, pass at head; 1323 provider-limrun and capture-kit tests passed.
  • Live at 5e8c71d (this head's code), Limrun iPhone 16 Pro, iOS 26.4, test app, 5 runs: 13 concurrent probes, batch 155–157 ms, each 108–157 ms (~10× under 1.5 s). snapshot --json lists Home*, Catalog, Form, Audio, Settings under Tab Bar, no tab-bar warning, 925–991 ms. press label="Catalog" then shows Catalog selected.
  • Swift golden test compiles locally; the macOS host lane runs it.
  • check:affected --run --head fa03636: passed, exactCommit: true.

🤖 Generated with Claude Code