fix(ios): keep keyboard coverage consistent with the captured tree

Merged
SH
3d ago
+886-141

Summary

Fixes #3957. Derive iOS XCTest keyboard coverage and absence from the complete captured root, normalizing keyboard and assistant geometry through shared policy. Usable keyboards survive stale invalid frames in another window.

Keep hosted app controls tappable, including scoped native captures, while preserving settle observations. Generic providers use UIKit roles; identifier-only native membership travels as producer metadata. Share native assistant-host recognition and reuse the existing geometry validator to reject infinite and overflowing frames.

17 files cover capture, tap classification, native projection, regressions, a public fixture and reproduction, and documentation. Existing wire fields are reused.

Validation

Head: b4a3aa9bdd1c5ea7f962d3831abe4d90a1e8ee20.

  • pnpm check:affected --run --head b4a3aa9bdd: passed; receipt reports exactCommit=true, checkoutChanged=false; 12,454 related tests passed.
  • Focused TypeScript: 53 passed. Shared Swift presentation: 24 passed. Keyboard XCTest: 15 passed. iOS runner build and XCTest-selection checks passed.
  • Added native regressions on original PR head 3dc0b54a05f2d2b68e854e01b9d652ab4c289105: 13 passed, 2 failed; candidate: 15 passed.
  • iPad Pro 13-inch (M5), iOS 27.0: full/scoped XCTest, scoped native AX, and simulator AX presses succeeded; fixture counter reached 4. Scoped XCTest retained keyboard coverage and membership.
  • Independent follow-up review: no findings.

Native/device, Integration Tests, and full Coverage CI remain required at this head. No physical-device pass is claimed.