fix(ios): drive gesture pinch via two-finger synthesis instead of single-finger drag (#634)

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
This commit is contained in:
Michał Pierzchała
2026-05-31 15:09:28 +02:00
committed by GitHub
parent 73c057a442
commit fa4e2d5ee0
@@ -1551,7 +1551,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 {