@@ -36,6 +36,21 @@ extension RunnerTests {
3636 case drag( DragVisualizationFrame )
3737 }
3838
39+ struct GestureFallback {
40+ let strategy : String
41+ let message : String
42+ let hint : String ?
43+ }
44+
45+ private func gestureFallback( strategy: String , from outcome: RunnerInteractionOutcome ) -> GestureFallback ? {
46+ switch outcome {
47+ case . performed:
48+ return nil
49+ case . unsupported( let message, let hint) :
50+ return GestureFallback ( strategy: strategy, message: message, hint: hint)
51+ }
52+ }
53+
3954 /// Runs a gesture action with uniform timing capture. Touch gestures pass `idleTimeout: true`
4055 /// (the default) to run inside the scroll idle-timeout + quiescence-skip wrapper; synthesis
4156 /// gestures (pinch/rotate/transform) pass `false` because RunnerSynthesizedGesture governs its
@@ -64,15 +79,19 @@ extension RunnerTests {
6479 private func gestureResponse(
6580 message: String ,
6681 timing: ( gestureStartUptimeMs: Double , gestureEndUptimeMs: Double ) ,
67- frame: GestureFrame = . none
82+ frame: GestureFrame = . none,
83+ fallback: GestureFallback ? = nil
6884 ) -> Response {
6985 let data : DataPayload
7086 switch frame {
7187 case . none:
7288 data = DataPayload (
7389 message: message,
7490 gestureStartUptimeMs: timing. gestureStartUptimeMs,
75- gestureEndUptimeMs: timing. gestureEndUptimeMs
91+ gestureEndUptimeMs: timing. gestureEndUptimeMs,
92+ gestureFallback: fallback? . strategy,
93+ gestureFallbackMessage: fallback? . message,
94+ gestureFallbackHint: fallback? . hint
7695 )
7796 case . touch( let f) :
7897 data = DataPayload (
@@ -82,7 +101,10 @@ extension RunnerTests {
82101 x: f? . x,
83102 y: f? . y,
84103 referenceWidth: f? . referenceWidth,
85- referenceHeight: f? . referenceHeight
104+ referenceHeight: f? . referenceHeight,
105+ gestureFallback: fallback? . strategy,
106+ gestureFallbackMessage: fallback? . message,
107+ gestureFallbackHint: fallback? . hint
86108 )
87109 case . drag( let f) :
88110 data = DataPayload (
@@ -94,7 +116,10 @@ extension RunnerTests {
94116 x2: f. x2,
95117 y2: f. y2,
96118 referenceWidth: f. referenceWidth,
97- referenceHeight: f. referenceHeight
119+ referenceHeight: f. referenceHeight,
120+ gestureFallback: fallback? . strategy,
121+ gestureFallbackMessage: fallback? . message,
122+ gestureFallbackHint: fallback? . hint
98123 )
99124 }
100125 return Response ( ok: true , data: data)
@@ -507,6 +532,7 @@ extension RunnerTests {
507532 x2: dragPoints. x2,
508533 y2: dragPoints. y2
509534 )
535+ var fallback : GestureFallback ?
510536 if command. synthesized == true {
511537 let durationMs = min ( max ( command. durationMs ?? 250 , 16 ) , 10000 )
512538 let ( timing, outcome) = performGesture ( activeApp, idleTimeout: false ) {
@@ -522,6 +548,7 @@ extension RunnerTests {
522548 if case . performed = outcome {
523549 return gestureResponse ( message: " dragged " , timing: timing, frame: . drag( dragFrame) )
524550 }
551+ fallback = gestureFallback ( strategy: " xctest-coordinate-drag " , from: outcome)
525552 }
526553 let holdDuration = command. synthesized == true
527554 ? synthesizedSwipeFallbackHoldDuration ( durationMs: command. durationMs ?? 250 )
@@ -539,7 +566,12 @@ extension RunnerTests {
539566 if let response = unsupportedResponse ( for: outcome) {
540567 return response
541568 }
542- return gestureResponse ( message: " dragged " , timing: timing, frame: . drag( dragFrame) )
569+ return gestureResponse (
570+ message: " dragged " ,
571+ timing: timing,
572+ frame: . drag( dragFrame) ,
573+ fallback: fallback
574+ )
543575 case . dragSeries:
544576 guard let x = command. x, let y = command. y, let x2 = command. x2, let y2 = command. y2 else {
545577 return Response ( ok: false , error: ErrorPayload ( message: " dragSeries requires x, y, x2, and y2 " ) )
0 commit comments