fix(ios-runner): measure the sole-screen frame on the XCTest screen object

Closed
ST
21h ago
+89-11

Root cause

testInAppBackVerifiesSoleScreenWhenXCTestCannotReadFramesOrEnumerate and testInAppBackStillAsksForWindowsWhereNoSoleScreenAnswers have failed the nightly since 10-23 (#3943), the night after #3894 landed — the full-suite lane is the only place those two execute.

The UI-test runner process hosts no scene, so UIKit's UIScreen answers a placeholder panel there. Probe on the nightly's device shape (iPhone 17 Pro, iOS 26.5 simulator):

  • UIScreen.main.bounds → 320×480 points (nativeBounds 960×1440 @3x)
  • XCUIScreen private bounds → 1206×2622 px with private scale 3
  • public XCUIScreen.screenshot() → {402, 874} @3x — the real panel

soleScreenReferenceFrame derived its frame from UIScreen.main, so the window-less back fallback aimed at (28, 56) — the status bar, above the 62–106 pt bar band the fallback exists to hit. The tap changed nothing; the --agent-device-back-regression status stayed "launched". The placeholder sole screen also "answered", so the windows route was skipped, which is why the windows-routed test failed too.

Nightly evidence: AGENT_DEVICE_RUNNER_SYNTHESIZED_SOLE_SCREEN_ROUTE resolved={{0, 0}, {320, 480}}, then IN_APP_BACK_VISUAL_VERIFICATION … changed=no before #3894's assertions failed.

Fix

The bridge grows RunnerResolveSoleScreenPanelGeometry: the same sole-screen rule as the routing resolver, measuring the panel on the XCTest screen object the route gate already trusts, fail-closed through the exception catcher with the shared APP_SCREEN_UNRESOLVED log — a future Xcode that drops either private key refuses the route instead of aiming blind.

  • soleScreenReferenceFrame now measures through that resolver; UIScreen.main is out of the gesture path.
  • testGestureViewportOnAnUnserializableTreeIsTheSoleScreen pins the route answer to the resolver instead of the placeholder panel.
  • New testSoleScreenPanelGeometryMatchesTheCapturedPanel cross-checks the resolver against the one public panel answer in the process (a capture of the same screen).

Verification

Red first, on this simulator against ed798f9cf: both #3894 tests failed with the same signature as the nightly (resolved={{0,0},{320,480}}, 2 failures / 2 tests). After the fix, 10/10 sole-screen and navigation tests pass, including the two previously-red ones (resolved={{0,0},{402,874}}, changed=yes on the regression fixture, status "Back performed").

Fixes #3943