From 1fc88db0268d142953df5162ff39f44c0c37ec26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Sun, 31 May 2026 13:03:26 +0200 Subject: [PATCH] fix(ios): drive gesture pinch via two-finger synthesis instead of single-finger drag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On iOS the runner lowered `pinch` to performCoordinatePinch — a tap() then a single-finger press(forDuration:thenDragTo:). React Native reads that as a pan, so the pinch scale never changes (reported in #629: scale stays 1.00). Route iOS pinch through the existing two-finger XCTest synthesis path (transformGesture / RunnerSynthesizedGesture) with zero translation and rotation, so RN's pinch recognizer fires. macOS keeps the coordinate path. Validated on iPhone 17 Pro against examples/test-app: the gesture-lab.ad oracle now passes 1/1 (fling/pan/pinch/rotate); it previously failed at the pinch step. Refs #629 --- .../RunnerTests+Interaction.swift | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift b/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift index cd231a953..2742d97cf 100644 --- a/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +++ b/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift @@ -1510,7 +1510,27 @@ extension RunnerTests { } func pinch(app: XCUIApplication, scale: Double, x: Double?, y: Double?) -> RunnerInteractionOutcome { +#if os(iOS) + // A coordinate tap+drag is a single-finger gesture: React Native reads it as a pan + // and the pinch scale never changes (#629). Drive the two-finger XCTest synthesis + // path (the same one transformGesture uses) with zero translation/rotation so RN's + // pinch recognizer actually fires. + let frame = interactionRoot(app: app).frame + let centerX = x ?? Double(frame.midX) + let centerY = y ?? Double(frame.midY) + return transformGesture( + app: app, + x: centerX, + y: centerY, + dx: 0, + dy: 0, + scale: scale, + degrees: 0, + durationMs: 300 + ) +#else return performCoordinatePinch(app: app, scale: scale, x: x, y: y) +#endif } func rotateGesture(app: XCUIApplication, degrees: Double, x: Double?, y: Double?, velocity: Double) -> RunnerInteractionOutcome {