fix(ios): synthesize long presses and the gesture viewport on deep trees

Merged
TH
3d ago
+340-14

Summary

On deep React Native trees (heavy-feed fixture #3884, Bluesky), these iOS gestures failed after #3870:

  • longpress used XCTest's coordinate press. It retried kAXErrorIllegalArgument for about 16 s, then threw point.x != INFINITY, which ended the runner test. On iOS, longPress and press-series hold steps are now synthesized like a tap. While the tree answers, XCTest's press is still the fallback.
  • swipe failed with "Active app interaction viewport is unavailable". gestureViewport now uses the synthesized context: the resolved window, or the sole screen on a one-screen iPhone.
  • The 8–30 s scroll came from the runner that longpress killed.

6 runner Swift files, no wire fields.

Validation

Head 9f5cbc9ebd (main 5f6dfb3e6f merged).

  • Live CLI runs on an iPhone 17 Pro simulator (iOS 27.0) reached kind=coordinateLongPress … fallbackAttempted=false and showed the effect in a snapshot. Covered: the automation-lab long-press canary (ref, x/y, selector, 2-step sequence), the heavy feed (held post N), and a Safari Tabs UIKit context menu. Holds of 200/350 ms acted as taps; 650/1000 ms fired the long press. Details: https://github.com/callstack/agent-device/pull/3893#issuecomment-6337370101
  • Heavy-feed suite (#3885), base 9935ef51c2 vs 844842171b, 3 rounds: longpress 3/3 fail → 2197 ms; scroll down 12808 → 924 ms; swipe 3/3 fail → 1093 ms.
  • Runner unit tests: 44/44 on iPhone, 27/27 on iPad. Combined with #3894: 54/54 on both.
  • check:xctest-selection passed. check:affected --run --head 9f5cbc9ebd passed (exactCommit: true).

Open: on iPad deep trees, long press still falls back to XCTest's press. back on the heavy feed is fixed in #3894.

🤖 Generated with Claude Code