agent-device 0.21.11 → 0.21.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.11.apk → agent-device-android-ime-helper-0.21.13.apk} +0 -0
  2. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.13.apk.sha256 +1 -0
  3. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.11.manifest.json → agent-device-android-ime-helper-0.21.13.manifest.json} +4 -4
  4. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.11.apk → agent-device-android-snapshot-helper-0.21.13.apk} +0 -0
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.13.apk.sha256 +1 -0
  6. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.11.manifest.json → agent-device-android-snapshot-helper-0.21.13.manifest.json} +6 -6
  7. package/apple/fold-helper/Fold.m +97 -0
  8. package/apple/macos-helper/Package.swift +3 -6
  9. package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/main.swift +3 -8
  10. package/apple/macos-helper/Tests/AgentDeviceMacOSHelperTests/ScreenshotResponseTests.swift +15 -0
  11. package/apple/snapshot-bridge/SnapshotBridgeRuntime.m +47 -1
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +99 -42
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/Info.plist +23 -0
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +17 -0
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAppScreenCapture.swift +21 -13
  16. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerScrollViewportPolicy.swift +1 -162
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +0 -9
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +0 -56
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSystemSurfaceHostPolicy.swift +0 -48
  20. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +0 -50
  21. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +22 -568
  22. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +21 -9
  23. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+BlockingSystemModalResolution.swift +0 -36
  24. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandDispatch.swift +630 -0
  25. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +18 -2236
  26. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +1 -338
  27. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +0 -12
  28. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+GestureExecution.swift +165 -0
  29. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +0 -24
  30. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +0 -142
  31. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +90 -39
  32. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+MainThreadWork.swift +78 -106
  33. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +23 -2
  34. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +147 -95
  35. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +0 -209
  36. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +86 -10
  37. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollDragExecution.swift +287 -0
  38. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +1 -200
  39. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +0 -185
  40. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +75 -285
  41. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotAcquisition.swift +23 -10
  42. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotBackendCapabilities.swift +0 -78
  43. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +83 -578
  44. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCaptureTarget.swift +106 -0
  45. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotExecution.swift +142 -0
  46. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTiming.swift +49 -78
  47. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedCommitDeadline.swift +0 -44
  48. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +27 -97
  49. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedInteraction.swift +1 -11
  50. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +11 -87
  51. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +2 -10
  52. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +1 -1
  53. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +0 -35
  54. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextInputCandidatePolicy.swift +0 -31
  55. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +2 -18
  56. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +34 -52
  57. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +0 -22
  58. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TypeExecution.swift +142 -0
  59. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +22 -6
  60. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +140 -20
  61. package/dist/src/absence-observation-errors.js +1 -1
  62. package/dist/src/adapter.js +1 -1
  63. package/dist/src/agent-device-client.js +1 -1
  64. package/dist/src/alert-runtime.js +1 -1
  65. package/dist/src/android-adb.d.ts +1 -1
  66. package/dist/src/app-launch.js +2 -2
  67. package/dist/src/app-log-runtime2.js +3 -3
  68. package/dist/src/app-resolution.js +2 -2
  69. package/dist/src/back-mode.js +1 -1
  70. package/dist/src/capture-disclosure.js +1 -1
  71. package/dist/src/capture.js +1 -1
  72. package/dist/src/cli-config.js +1 -1
  73. package/dist/src/cli-help.js +10 -7
  74. package/dist/src/cli-runner.js +1 -1
  75. package/dist/src/cli.js +1 -1
  76. package/dist/src/client-types.d.ts +5 -8
  77. package/dist/src/code-signature.js +1 -1
  78. package/dist/src/command-schema.js +3 -3
  79. package/dist/src/command-tools.js +3 -3
  80. package/dist/src/connection.js +1 -1
  81. package/dist/src/daemon-client-lifecycle.js +1 -1
  82. package/dist/src/daemon-resolution.js +1 -1
  83. package/dist/src/device-claim-rule.js +2 -2
  84. package/dist/src/device-input-state.d.ts +1 -1
  85. package/dist/src/device-rotation.js +1 -1
  86. package/dist/src/device-session.js +1 -1
  87. package/dist/src/devicectl.js +1 -1
  88. package/dist/src/display-inventory.js +1 -1
  89. package/dist/src/doctor-facade.js +1 -1
  90. package/dist/src/find.js +1 -1
  91. package/dist/src/gesture-plan-types.d.ts +38 -0
  92. package/dist/src/harmonyos.js +1 -1
  93. package/dist/src/helper.js +2 -2
  94. package/dist/src/host.js +1 -1
  95. package/dist/src/install-source-network-transport.js +1 -1
  96. package/dist/src/install-source2.js +1 -1
  97. package/dist/src/interaction-ref-policy.js +1 -1
  98. package/dist/src/interaction2.js +1 -1
  99. package/dist/src/interactor-operation-catalog.js +1 -1
  100. package/dist/src/interactor.js +4 -4
  101. package/dist/src/interactor2.js +1 -1
  102. package/dist/src/internal/bin.js +1 -1
  103. package/dist/src/internal/daemon.js +2 -2
  104. package/dist/src/inventory2.js +1 -1
  105. package/dist/src/ios-snapshot-acquisition.js +1 -1
  106. package/dist/src/ios-snapshot-runtime.js +1 -1
  107. package/dist/src/limrun-runtime-dependencies.js +1 -1
  108. package/dist/src/limrun.d.ts +435 -4
  109. package/dist/src/linux.js +1 -1
  110. package/dist/src/local-interactor-operation-set.js +1 -1
  111. package/dist/src/macos-facade.js +1 -1
  112. package/dist/src/managed-device-scope.js +1 -1
  113. package/dist/src/mechanics.js +4 -4
  114. package/dist/src/mobile-snapshot-semantics.js +1 -1
  115. package/dist/src/perf-facade.js +1 -2
  116. package/dist/src/perf-runtime-plan.js +1 -1
  117. package/dist/src/perf-target.js +2 -0
  118. package/dist/src/physical-device-apps.js +1 -0
  119. package/dist/src/physical-device-control.js +1 -1
  120. package/dist/src/platform-request-scope.js +1 -1
  121. package/dist/src/platform-runtime-operation-host.js +1 -1
  122. package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
  123. package/dist/src/platform-runtime-unavailable.js +1 -1
  124. package/dist/src/platform-runtime.js +1 -1
  125. package/dist/src/platform-runtime2.js +1 -1
  126. package/dist/src/provider-webdriver.js +1 -1
  127. package/dist/src/proxy.js +1 -1
  128. package/dist/src/quality-warnings.js +1 -1
  129. package/dist/src/react-native.js +1 -1
  130. package/dist/src/record-runtime.js +1 -1
  131. package/dist/src/registry.js +35 -35
  132. package/dist/src/request-admission.js +1 -1
  133. package/dist/src/request-runtime-binding.js +1 -1
  134. package/dist/src/runner-client.js +1 -1
  135. package/dist/src/runner-dev-tools-security.js +1 -1
  136. package/dist/src/runner-device-readiness.js +1 -1
  137. package/dist/src/runner-disposal.js +1 -1
  138. package/dist/src/runner-error-classification.js +3 -0
  139. package/dist/src/runner-operations-facade.js +1 -1
  140. package/dist/src/runner-presentation.js +1 -1
  141. package/dist/src/runner.js +1 -1
  142. package/dist/src/runtime.js +3 -3
  143. package/dist/src/runtime10.js +1 -1
  144. package/dist/src/runtime2.js +2 -2
  145. package/dist/src/runtime4.js +5 -5
  146. package/dist/src/runtime5.js +1 -1
  147. package/dist/src/runtime6.js +1 -1
  148. package/dist/src/runtime7.js +1 -1
  149. package/dist/src/runtime8.js +1 -1
  150. package/dist/src/runtime9.js +1 -1
  151. package/dist/src/screen-recording-admission-ledger.js +1 -1
  152. package/dist/src/screen-recording-resource-recovery.js +1 -1
  153. package/dist/src/screen-recording-transport.js +1 -1
  154. package/dist/src/screenshot-runtime.js +1 -1
  155. package/dist/src/screenshot3.js +1 -1
  156. package/dist/src/script.js +1 -1
  157. package/dist/src/scroll-command.d.ts +377 -0
  158. package/dist/src/scroll-command.js +1 -1
  159. package/dist/src/sdk-batch.js +2 -2
  160. package/dist/src/sdk-contracts.d.ts +9 -0
  161. package/dist/src/sdk-device.js +1 -1
  162. package/dist/src/sdk-selectors.d.ts +23 -715
  163. package/dist/src/selection.js +0 -0
  164. package/dist/src/selector-runtime.js +1 -1
  165. package/dist/src/semantic-index.js +1 -1
  166. package/dist/src/server.js +1 -1
  167. package/dist/src/session-observation.js +1 -1
  168. package/dist/src/session-snapshot.js +1 -1
  169. package/dist/src/session2.js +2 -2
  170. package/dist/src/simctl-facade.js +1 -1
  171. package/dist/src/simctl.js +1 -1
  172. package/dist/src/simulator-facade.js +1 -1
  173. package/dist/src/simulator-state.js +1 -1
  174. package/dist/src/simulator.js +1 -1
  175. package/dist/src/snapshot-runtime-binding.js +1 -1
  176. package/dist/src/snapshot-runtime.js +1 -1
  177. package/dist/src/snapshot-state.js +1 -1
  178. package/dist/src/snapshot4.js +1 -1
  179. package/dist/src/src7.js +1 -1
  180. package/dist/src/text-entry-focus.js +1 -1
  181. package/dist/src/tool-provider.js +1 -1
  182. package/dist/src/touch-runtime.js +1 -1
  183. package/dist/src/tree.js +1 -1
  184. package/dist/src/update-check.js +1 -1
  185. package/dist/src/version.js +1 -1
  186. package/dist/src/web2.js +1 -1
  187. package/package.json +4 -2
  188. package/server.json +2 -2
  189. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.11.apk.sha256 +0 -1
  190. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.11.apk.sha256 +0 -1
  191. package/apple/macos-helper/Sources/AgentDeviceMacOSDeviceHub/DeviceHubPose.swift +0 -47
  192. package/apple/macos-helper/Sources/AgentDeviceMacOSDeviceHub/DeviceHubWindowInventory.swift +0 -65
  193. package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/DeviceHubPose.swift +0 -225
  194. package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/DeviceHubSidebar.swift +0 -57
  195. package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/DeviceHubWindowDiscovery.swift +0 -108
  196. package/apple/macos-helper/Tests/AgentDeviceMacOSDeviceHubTests/DeviceHubPoseTests.swift +0 -30
  197. package/apple/macos-helper/Tests/AgentDeviceMacOSDeviceHubTests/DeviceHubWindowInventoryTests.swift +0 -65
  198. package/dist/src/app-inventory.d.ts +0 -4
  199. package/dist/src/apps-simctl.js +0 -1
  200. package/dist/src/cloud-artifacts.d.ts +0 -61
  201. package/dist/src/runner-contract.js +0 -3
@@ -0,0 +1,287 @@
1
+ import XCTest
2
+ import AgentDeviceSnapshotPresentation
3
+
4
+ extension RunnerTests {
5
+ func invalidScrollDirectionResponse(commandName: String) -> Response {
6
+ Response(
7
+ ok: false,
8
+ error: ErrorPayload(
9
+ code: "INVALID_ARGS",
10
+ message: "\(commandName) requires direction up|down|left|right"
11
+ )
12
+ )
13
+ }
14
+
15
+ func scrollDurationIsValid(_ durationMs: Double?) -> Bool {
16
+ guard let durationMs else { return true }
17
+ return durationMs.isFinite && durationMs >= 0 && durationMs <= 10000
18
+ }
19
+
20
+ func invalidScrollDurationResponse(commandName: String) -> Response {
21
+ return Response(
22
+ ok: false,
23
+ error: ErrorPayload(
24
+ code: "INVALID_ARGS",
25
+ message: "\(commandName) durationMs must be between 0 and 10000"
26
+ )
27
+ )
28
+ }
29
+
30
+ func executeScrollDragGesture(
31
+ activeApp: XCUIApplication,
32
+ x: Double,
33
+ y: Double,
34
+ x2: Double,
35
+ y2: Double,
36
+ durationMs: Double,
37
+ message: String,
38
+ context: SynthesizedCoordinateContext,
39
+ releaseBehavior: ScrollReleaseBehavior?
40
+ ) -> Response {
41
+ #if os(iOS)
42
+ return executeDragGesture(
43
+ activeApp: activeApp,
44
+ x: x,
45
+ y: y,
46
+ x2: x2,
47
+ y2: y2,
48
+ durationMs: durationMs,
49
+ message: message,
50
+ synthesizedContext: context,
51
+ synthesized: (profile: scrollDragProfile(releaseBehavior: releaseBehavior), policyKind: .scroll)
52
+ )
53
+ #else
54
+ return executeDragGesture(
55
+ activeApp: activeApp,
56
+ x: x,
57
+ y: y,
58
+ x2: x2,
59
+ y2: y2,
60
+ durationMs: durationMs,
61
+ message: message
62
+ )
63
+ #endif
64
+ }
65
+
66
+
67
+
68
+ func executeDragGesture(
69
+ activeApp: XCUIApplication,
70
+ x: Double,
71
+ y: Double,
72
+ x2: Double,
73
+ y2: Double,
74
+ durationMs: Double?,
75
+ message: String,
76
+ synthesizedContext: SynthesizedCoordinateContext? = nil,
77
+ synthesized: (profile: SynthesizedDragProfile, policyKind: SynthesizedGesturePolicyKind)? = nil
78
+ ) -> Response {
79
+ let durationMs = durationMs ?? runnerDefaultDragDurationMs
80
+ let commandName = dragCommandName(message: message)
81
+ guard x.isFinite, y.isFinite, x2.isFinite, y2.isFinite else {
82
+ return Response(
83
+ ok: false,
84
+ error: ErrorPayload(code: "INVALID_ARGS", message: "\(commandName) requires finite coordinates")
85
+ )
86
+ }
87
+ if let synthesized, let synthesizedResponse = executeSynthesizedDragGesture(
88
+ activeApp: activeApp,
89
+ x: x,
90
+ y: y,
91
+ x2: x2,
92
+ y2: y2,
93
+ durationMs: durationMs,
94
+ message: message,
95
+ context: synthesizedContext,
96
+ policyKind: synthesized.policyKind,
97
+ profile: synthesized.profile
98
+ ) {
99
+ return synthesizedResponse
100
+ }
101
+ let dragPoints = keyboardAvoidingDragPoints(app: activeApp, x: x, y: y, x2: x2, y2: y2)
102
+ let dragFrame = resolvedDragVisualizationFrame(
103
+ app: activeApp,
104
+ x: dragPoints.x,
105
+ y: dragPoints.y,
106
+ x2: dragPoints.x2,
107
+ y2: dragPoints.y2
108
+ )
109
+ let holdDuration = synthesized == nil
110
+ ? coordinateDragHoldDuration()
111
+ : synthesizedSwipeFallbackHoldDuration(durationMs: durationMs)
112
+ let (timing, outcome) = performGesture(activeApp) {
113
+ dragAt(
114
+ app: activeApp,
115
+ x: dragPoints.x,
116
+ y: dragPoints.y,
117
+ x2: dragPoints.x2,
118
+ y2: dragPoints.y2,
119
+ holdDuration: holdDuration
120
+ )
121
+ }
122
+ if let response = unsupportedResponse(for: outcome) {
123
+ return response
124
+ }
125
+ return gestureResponse(message: message, timing: timing, frame: .drag(dragFrame))
126
+ }
127
+
128
+ private func executeSynthesizedDragGesture(
129
+ activeApp: XCUIApplication,
130
+ x: Double,
131
+ y: Double,
132
+ x2: Double,
133
+ y2: Double,
134
+ durationMs: Double,
135
+ message: String,
136
+ context: SynthesizedCoordinateContext?,
137
+ policyKind: SynthesizedGesturePolicyKind,
138
+ profile: SynthesizedDragProfile
139
+ ) -> Response? {
140
+ #if os(iOS)
141
+ let policy = synthesizedGesturePolicy(policyKind)
142
+ let context = context ?? synthesizedCoordinateContext(app: activeApp, policy: policy)
143
+ guard let plan = axFreeSynthesizedDragPlan(
144
+ app: activeApp,
145
+ x: x,
146
+ y: y,
147
+ x2: x2,
148
+ y2: y2,
149
+ context: context
150
+ )
151
+ else {
152
+ if context?.allowsXCTestCoordinateFallback == true {
153
+ logSynthesizedGesturePolicyDecision(kind: policyKind, context: context, fallbackAttempted: true)
154
+ return executeCoordinateDragFallback(
155
+ activeApp: activeApp,
156
+ x: x,
157
+ y: y,
158
+ x2: x2,
159
+ y2: y2,
160
+ durationMs: durationMs,
161
+ message: message,
162
+ fallback: nil
163
+ )
164
+ }
165
+ logSynthesizedGesturePolicyDecision(kind: policyKind, context: context, fallbackAttempted: false)
166
+ return Response(
167
+ ok: false,
168
+ error: ErrorPayload(
169
+ code: "INVALID_ARGS",
170
+ message: "\(dragCommandName(message: message)) could not resolve a finite synthesized coordinate frame"
171
+ )
172
+ )
173
+ }
174
+ let durationMs = min(max(durationMs, 16), 10000)
175
+ let dragFrame = axFreeDragVisualizationFrame(
176
+ x: plan.points.x,
177
+ y: plan.points.y,
178
+ x2: plan.points.x2,
179
+ y2: plan.points.y2,
180
+ referenceFrame: plan.referenceFrame
181
+ )
182
+ let (timing, outcome) = performGesture(activeApp, idleTimeout: false) {
183
+ synthesizedDragAt(
184
+ app: activeApp,
185
+ x: plan.points.x,
186
+ y: plan.points.y,
187
+ x2: plan.points.x2,
188
+ y2: plan.points.y2,
189
+ durationMs: durationMs,
190
+ profile: profile,
191
+ context: plan.context
192
+ )
193
+ }
194
+ if case .performed = outcome {
195
+ logSynthesizedGesturePolicyDecision(kind: policyKind, context: plan.context, fallbackAttempted: false)
196
+ return gestureResponse(message: message, timing: timing, frame: .drag(dragFrame))
197
+ }
198
+ if plan.context.allowsXCTestCoordinateFallback {
199
+ logSynthesizedGesturePolicyDecision(kind: policyKind, context: plan.context, fallbackAttempted: true)
200
+ return executeCoordinateDragFallback(
201
+ activeApp: activeApp,
202
+ x: plan.points.x,
203
+ y: plan.points.y,
204
+ x2: plan.points.x2,
205
+ y2: plan.points.y2,
206
+ durationMs: durationMs,
207
+ message: message,
208
+ fallback: gestureFallback(strategy: "xctest-coordinate-drag", from: outcome)
209
+ )
210
+ }
211
+ logSynthesizedGesturePolicyDecision(kind: policyKind, context: plan.context, fallbackAttempted: false)
212
+ return unsupportedResponse(for: outcome)
213
+ #else
214
+ return nil
215
+ #endif
216
+ }
217
+
218
+ private func executeCoordinateDragFallback(
219
+ activeApp: XCUIApplication,
220
+ x: Double,
221
+ y: Double,
222
+ x2: Double,
223
+ y2: Double,
224
+ durationMs: Double,
225
+ message: String,
226
+ fallback: GestureFallback?
227
+ ) -> Response {
228
+ let dragPoints = keyboardAvoidingDragPoints(app: activeApp, x: x, y: y, x2: x2, y2: y2)
229
+ let dragFrame = resolvedDragVisualizationFrame(
230
+ app: activeApp,
231
+ x: dragPoints.x,
232
+ y: dragPoints.y,
233
+ x2: dragPoints.x2,
234
+ y2: dragPoints.y2
235
+ )
236
+ let holdDuration = synthesizedSwipeFallbackHoldDuration(durationMs: durationMs)
237
+ let (timing, outcome) = performGesture(activeApp) {
238
+ dragAt(
239
+ app: activeApp,
240
+ x: dragPoints.x,
241
+ y: dragPoints.y,
242
+ x2: dragPoints.x2,
243
+ y2: dragPoints.y2,
244
+ holdDuration: holdDuration
245
+ )
246
+ }
247
+ if let response = unsupportedResponse(for: outcome) {
248
+ return response
249
+ }
250
+ return gestureResponse(
251
+ message: message,
252
+ timing: timing,
253
+ frame: .drag(dragFrame),
254
+ fallback: fallback
255
+ )
256
+ }
257
+
258
+
259
+
260
+
261
+
262
+
263
+
264
+
265
+ func scrollKeyboardOccludedResponse(
266
+ direction: String,
267
+ keyboardMinY: Double,
268
+ visibleHeight: Double
269
+ ) -> Response {
270
+ return Response(
271
+ ok: false,
272
+ error: ErrorPayload(
273
+ code: ScrollViewportPolicy.occlusionRunnerCode,
274
+ message: String(
275
+ format:
276
+ "scroll %@ refused: the keyboard leaves %.0fpt of visible surface above it, too little to swipe",
277
+ direction,
278
+ visibleHeight
279
+ )
280
+ )
281
+ )
282
+ }
283
+
284
+ private func dragCommandName(message: String) -> String {
285
+ return message == "scrolled" ? "scroll" : "drag"
286
+ }
287
+ }
@@ -11,6 +11,7 @@ import XCTest
11
11
 
12
12
 
13
13
 
14
+
14
15
  struct RunnerScrollGesturePlan {
15
16
  let x1: Double
16
17
  let y1: Double
@@ -96,203 +97,3 @@ func runnerDragCommandDefaults(_ command: Command) -> RunnerDragCommandDefaults
96
97
  durationMs: command.durationMs ?? runnerDefaultDragDurationMs
97
98
  )
98
99
  }
99
-
100
-
101
-
102
-
103
-
104
-
105
-
106
-
107
-
108
-
109
-
110
-
111
-
112
-
113
-
114
-
115
-
116
-
117
-
118
-
119
-
120
-
121
-
122
-
123
-
124
-
125
-
126
-
127
-
128
-
129
-
130
-
131
-
132
-
133
-
134
-
135
-
136
-
137
-
138
-
139
-
140
-
141
-
142
-
143
-
144
-
145
-
146
-
147
-
148
-
149
-
150
-
151
-
152
-
153
-
154
-
155
-
156
-
157
-
158
-
159
-
160
-
161
-
162
-
163
-
164
-
165
-
166
-
167
-
168
-
169
-
170
-
171
-
172
-
173
-
174
-
175
-
176
-
177
-
178
-
179
-
180
-
181
-
182
-
183
-
184
-
185
-
186
-
187
-
188
-
189
-
190
-
191
-
192
-
193
-
194
-
195
-
196
-
197
-
198
-
199
-
200
-
201
-
202
-
203
-
204
-
205
-
206
-
207
-
208
-
209
-
210
-
211
-
212
-
213
-
214
-
215
-
216
-
217
-
218
-
219
-
220
-
221
-
222
-
223
-
224
-
225
-
226
-
227
-
228
-
229
-
230
-
231
-
232
-
233
-
234
-
235
-
236
-
237
-
238
-
239
-
240
-
241
-
242
-
243
-
244
-
245
-
246
-
247
-
248
-
249
-
250
-
251
-
252
-
253
-
254
-
255
-
256
-
257
-
258
-
259
-
260
-
261
-
262
-
263
-
264
-
265
-
266
-
267
-
268
-
269
-
270
-
271
-
272
-
273
-
274
-
275
-
276
-
277
-
278
-
279
-
280
-
281
-
282
-
283
-
284
-
285
-
286
-
287
-
288
-
289
-
290
-
291
-
292
-
293
-
294
-
295
-
296
-
297
-
298
-