fix(ios): route synthesized gestures to the sole screen when no window resolves
Merged
TH
2d ago+170+170+012345678901234567890123456789-12-12-01234567890123456789
Summary
On a deep app tree, XCTest's windows query fails with kAXErrorIllegalArgument. Bluesky's real home feed reaches that at accessibility depth 62. Synthesized taps and scrolls need no tree, but the runner could not name the window to route them. It paid about 2 s of XCTest retries per app.frame read, then:
scrollfailed after 7.8 s ("could not resolve a usable interaction frame");pressfell back to an XCTest coordinate tap and failed after 18 s withNSInternalInconsistencyException, ending the runner test.
When no window resolves on an iPhone with exactly one screen, the runner now uses that screen, laid out in the app's interface orientation, as the reference frame and routes the event record to that screen's display ID. iPad and multi-screen devices still require a window. The synthesized-context lookup no longer falls back to app.frame.
7 files (Swift/ObjC runner).
Validation
pnpm check:affected --run --head e9f7502012: passed, includingxctest-selectionandpackaged-runner-swift.- New runner unit tests (frame per orientation, refusal on unknown orientation or empty screen) pass on an iOS 27.0 simulator.
- Live, Bluesky 1.136.0 (real account), iPhone 17 Pro simulator, iOS 27.0, on a feed screen where a forced XCTest tree capture returns sparse after 3.4 s:
- base
origin/mainrunner:scroll downfailed in 7844 ms;press @reffailed in 17968 ms (24 "Find the Application" retries). - head: scrolls 632โ920 ms and taps ~0.9 s on the sole-screen route, 0 retries. All 3 sampled sole-screen taps landed on the Search screen.
- base
- Healthy screens still resolve their window (no route log line).
๐ค Generated with Claude Code