agent-device 0.21.7 → 0.21.9

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 (204) hide show
  1. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.7.apk → agent-device-android-ime-helper-0.21.9.apk} +0 -0
  2. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.9.apk.sha256 +1 -0
  3. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.7.manifest.json → agent-device-android-ime-helper-0.21.9.manifest.json} +4 -4
  4. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.7.apk → agent-device-android-snapshot-helper-0.21.9.apk} +0 -0
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.9.apk.sha256 +1 -0
  6. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.7.manifest.json → agent-device-android-snapshot-helper-0.21.9.manifest.json} +6 -6
  7. package/apple/macos-helper/Package.swift +16 -1
  8. package/apple/macos-helper/Sources/AgentDeviceMacOSDeviceHub/DeviceHubPose.swift +47 -0
  9. package/apple/macos-helper/Sources/AgentDeviceMacOSDeviceHub/DeviceHubWindowInventory.swift +65 -0
  10. package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/DeviceHubPose.swift +225 -0
  11. package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/DeviceHubSidebar.swift +57 -0
  12. package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/DeviceHubWindowDiscovery.swift +108 -0
  13. package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/main.swift +66 -13
  14. package/apple/macos-helper/Sources/AgentDeviceMacOSInput/MouseClickDelivery.swift +116 -0
  15. package/apple/macos-helper/Sources/AgentDeviceMacOSInput/MouseClickSchedule.swift +61 -0
  16. package/apple/macos-helper/Tests/AgentDeviceMacOSDeviceHubTests/DeviceHubPoseTests.swift +30 -0
  17. package/apple/macos-helper/Tests/AgentDeviceMacOSDeviceHubTests/DeviceHubWindowInventoryTests.swift +65 -0
  18. package/apple/macos-helper/Tests/AgentDeviceMacOSInputTests/MouseClickScheduleTests.swift +58 -0
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +1 -0
  20. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAppScreenCapture.swift +175 -0
  21. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +10 -2
  22. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +42 -15
  23. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +8 -0
  24. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +45 -22
  25. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +39 -734
  26. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +20 -4
  27. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +63 -1
  28. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +13 -0
  29. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +25 -10
  30. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +5 -562
  31. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotAcquisition.swift +566 -0
  32. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +5 -1
  33. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedInteraction.swift +594 -0
  34. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerXCTestEventBridge.h +35 -1
  35. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerXCTestEventBridge.m +160 -0
  36. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/RecordingExportSupport.swift +3 -0
  37. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-frames.swift +203 -0
  38. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotCoordinateSpace.swift +5 -0
  39. package/dist/src/absence-observation-errors.js +1 -1
  40. package/dist/src/adapter.js +1 -1
  41. package/dist/src/agent-browser-lifecycle.js +1 -1
  42. package/dist/src/agent-browser-process-record.js +1 -1
  43. package/dist/src/agent-device-client.js +2 -2
  44. package/dist/src/alert-runtime.js +1 -1
  45. package/dist/src/android-adb.js +1 -1
  46. package/dist/src/android-input-ownership.js +1 -1
  47. package/dist/src/android.js +1 -1
  48. package/dist/src/app-launch.js +1 -1
  49. package/dist/src/app-log-runtime2.js +3 -3
  50. package/dist/src/app-resolution.js +2 -2
  51. package/dist/src/apple-runner-platform.js +1 -1
  52. package/dist/src/application-lifecycle-interaction.js +1 -1
  53. package/dist/src/artifact-paths.js +1 -0
  54. package/dist/src/back-mode.js +1 -1
  55. package/dist/src/cli-config.js +1 -1
  56. package/dist/src/cli-help.js +15 -11
  57. package/dist/src/cli.js +4 -4
  58. package/dist/src/client-types.d.ts +51 -1
  59. package/dist/src/command-tools.js +3 -3
  60. package/dist/src/config.js +1 -1
  61. package/dist/src/connection-runtime.js +1 -1
  62. package/dist/src/device-claim-inspection.js +1 -1
  63. package/dist/src/device-claim-rule.js +2 -2
  64. package/dist/src/device-input-state.d.ts +1 -1
  65. package/dist/src/device-rotation.js +1 -1
  66. package/dist/src/device-selection-resolver.js +1 -1
  67. package/dist/src/device-session.js +1 -1
  68. package/dist/src/device.js +1 -1
  69. package/dist/src/device2.js +1 -1
  70. package/dist/src/devicectl.js +1 -1
  71. package/dist/src/dispatch-resolve.js +1 -1
  72. package/dist/src/display-inventory.js +1 -1
  73. package/dist/src/doctor-facade.js +1 -1
  74. package/dist/src/durable-resource.js +1 -1
  75. package/dist/src/exec.js +1 -1
  76. package/dist/src/find.js +1 -1
  77. package/dist/src/finders.js +1 -1
  78. package/dist/src/fold-runtime.js +1 -0
  79. package/dist/src/gesture-admission.js +1 -1
  80. package/dist/src/gesture-runtime.js +1 -1
  81. package/dist/src/harmonyos.js +1 -1
  82. package/dist/src/helper.js +2 -2
  83. package/dist/src/host.js +1 -0
  84. package/dist/src/interaction-positionals.js +1 -1
  85. package/dist/src/interaction-ref-policy.js +1 -1
  86. package/dist/src/interaction.js +1 -1
  87. package/dist/src/interaction2.js +1 -1
  88. package/dist/src/interactor-operation-binding.js +1 -0
  89. package/dist/src/interactor-operation-catalog.js +1 -1
  90. package/dist/src/interactor.js +4 -5
  91. package/dist/src/interactor2.js +1 -1
  92. package/dist/src/interactors.js +1 -1
  93. package/dist/src/internal/bin.js +1 -1
  94. package/dist/src/internal/daemon.js +2 -2
  95. package/dist/src/internal/png-worker.d.ts +5 -0
  96. package/dist/src/internal/png-worker.js +1 -1
  97. package/dist/src/inventory2.js +1 -1
  98. package/dist/src/ios-snapshot-acquisition.js +1 -1
  99. package/dist/src/ios-snapshot-runtime.js +1 -1
  100. package/dist/src/lease.js +1 -1
  101. package/dist/src/linux.js +1 -1
  102. package/dist/src/local-interactor-operation-set.js +1 -1
  103. package/dist/src/location-coordinates.js +1 -1
  104. package/dist/src/macos-facade.js +1 -1
  105. package/dist/src/managed-device-scope.js +1 -1
  106. package/dist/src/mechanics.js +17 -16
  107. package/dist/src/mobile-snapshot-semantics.js +1 -1
  108. package/dist/src/mp4-duration.js +1 -0
  109. package/dist/src/multitouch-support.js +1 -1
  110. package/dist/src/owner-identity.js +1 -1
  111. package/dist/src/parameterized-recorded-fill.js +1 -1
  112. package/dist/src/perf-facade.js +2 -2
  113. package/dist/src/perf-runtime-plan.js +1 -1
  114. package/dist/src/physical-device-control.js +1 -1
  115. package/dist/src/platform-request-scope.js +1 -1
  116. package/dist/src/platform-runtime-managed-owner.js +1 -1
  117. package/dist/src/platform-runtime-open-target.js +1 -1
  118. package/dist/src/platform-runtime-operation-host.js +2 -2
  119. package/dist/src/platform-runtime-runtime-hints.js +1 -1
  120. package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
  121. package/dist/src/platform-runtime-unavailable.js +1 -1
  122. package/dist/src/platform-runtime.js +1 -1
  123. package/dist/src/platform-runtime2.js +1 -1
  124. package/dist/src/png-crop-bytes.js +1 -1
  125. package/dist/src/png-encode.js +1 -0
  126. package/dist/src/png-size.js +1 -0
  127. package/dist/src/png-worker-client.js +1 -1
  128. package/dist/src/provider-webdriver.js +1 -1
  129. package/dist/src/quality-warnings.js +1 -1
  130. package/dist/src/react-native.js +1 -1
  131. package/dist/src/record-runtime.js +1 -1
  132. package/dist/src/recording-export-quality.js +1 -1
  133. package/dist/src/recording-scope.js +1 -0
  134. package/dist/src/recording.js +3 -0
  135. package/dist/src/registry.js +35 -35
  136. package/dist/src/replay.js +1 -1
  137. package/dist/src/request-admission.js +1 -1
  138. package/dist/src/request-runtime-binding.js +1 -1
  139. package/dist/src/result-serialization.js +1 -1
  140. package/dist/src/runner-cache-metadata.js +2 -2
  141. package/dist/src/runner-client.js +1 -1
  142. package/dist/src/runner-contract.js +3 -0
  143. package/dist/src/runner-dev-tools-security.js +1 -0
  144. package/dist/src/runner-device-readiness.js +1 -0
  145. package/dist/src/runner-disposal.js +1 -1
  146. package/dist/src/runner-operations-facade.js +1 -1
  147. package/dist/src/runner-presentation.js +1 -1
  148. package/dist/src/runner.js +1 -1
  149. package/dist/src/runtime.js +2 -2
  150. package/dist/src/runtime10.js +2 -1
  151. package/dist/src/runtime2.js +4 -4
  152. package/dist/src/runtime4.js +5 -5
  153. package/dist/src/runtime5.js +1 -1
  154. package/dist/src/runtime6.js +1 -1
  155. package/dist/src/runtime7.js +1 -1
  156. package/dist/src/runtime8.js +1 -1
  157. package/dist/src/runtime9.js +1 -1
  158. package/dist/src/screen-recording-admission-ledger.js +1 -1
  159. package/dist/src/screen-recording-resource-recovery.js +1 -1
  160. package/dist/src/screen-recording-transport.js +1 -1
  161. package/dist/src/screenshot-density.js +1 -1
  162. package/dist/src/screenshot-image.js +1 -0
  163. package/dist/src/screenshot-overlay-draw.js +1 -0
  164. package/dist/src/screenshot-runtime.js +1 -1
  165. package/dist/src/script.js +1 -1
  166. package/dist/src/scroll-gesture.js +1 -1
  167. package/dist/src/sdk-batch.js +2 -2
  168. package/dist/src/sdk-contracts.d.ts +7 -5
  169. package/dist/src/sdk-contracts.js +2 -2
  170. package/dist/src/sdk-device.js +1 -1
  171. package/dist/src/sdk-finders.js +1 -1
  172. package/dist/src/sdk-selectors.d.ts +58 -6
  173. package/dist/src/sdk-selectors.js +1 -1
  174. package/dist/src/selection.js +0 -0
  175. package/dist/src/selector-runtime.js +1 -1
  176. package/dist/src/selectors.js +1 -1
  177. package/dist/src/semantic-index.js +1 -1
  178. package/dist/src/session-routing.js +1 -1
  179. package/dist/src/session-snapshot.js +1 -1
  180. package/dist/src/session-store.js +3 -3
  181. package/dist/src/session2.js +3 -3
  182. package/dist/src/simctl.js +1 -1
  183. package/dist/src/simulator-boot.js +1 -1
  184. package/dist/src/simulator-facade.js +1 -1
  185. package/dist/src/simulator.js +1 -1
  186. package/dist/src/snapshot-runtime-binding.js +1 -1
  187. package/dist/src/snapshot-runtime.js +1 -1
  188. package/dist/src/snapshot-state.js +1 -1
  189. package/dist/src/snapshot4.js +1 -1
  190. package/dist/src/src.js +1 -1
  191. package/dist/src/src7.js +1 -1
  192. package/dist/src/src8.js +1 -1
  193. package/dist/src/stop-sequence.js +1 -1
  194. package/dist/src/text-entry-focus.js +1 -1
  195. package/dist/src/touch-runtime.js +1 -1
  196. package/dist/src/tree.js +1 -1
  197. package/dist/src/type-text-runtime.js +1 -1
  198. package/dist/src/video.js +2 -2
  199. package/dist/src/web2.js +1 -1
  200. package/package.json +3 -1
  201. package/server.json +2 -2
  202. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.7.apk.sha256 +0 -1
  203. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.7.apk.sha256 +0 -1
  204. package/dist/src/png-transcode.js +0 -1
@@ -6,13 +6,13 @@
6
6
 
7
7
  static NSString *const RunnerGestureSynthesisSurface = @"event";
8
8
 
9
- typedef id (*RunnerMsgSendInitRecord)(id, SEL, NSString *, NSInteger);
9
+ typedef id (*RunnerMsgSendInitRecord)(id, SEL, NSString *, NSUInteger, NSInteger);
10
10
  typedef id (*RunnerMsgSendInitPath)(id, SEL, CGPoint, NSTimeInterval);
11
11
  typedef void (*RunnerMsgSendPathMove)(id, SEL, CGPoint, NSTimeInterval);
12
12
  typedef void (*RunnerMsgSendPathOffset)(id, SEL, NSTimeInterval);
13
13
 
14
- // Gesture-specific extension of the shared bridge: the 2-arg
15
- // `initWithName:interfaceOrientation:` record initializer and the touch-path
14
+ // Gesture-specific extension of the shared bridge: the display-aware
15
+ // `initWithName:displayID:interfaceOrientation:` record initializer and the touch-path
16
16
  // factory/mutator selectors, none of which text-entry synthesis needs.
17
17
  typedef struct {
18
18
  RunnerXCTestEventBridge core;
@@ -37,6 +37,7 @@ static NSString * _Nullable RunnerResolveGestureEventBridge(
37
37
  );
38
38
  static NSString * _Nullable RunnerCreateEventRecord(
39
39
  id application,
40
+ id _Nullable resolvedWindow,
40
41
  NSString *recordName,
41
42
  RunnerGestureEventBridge *bridge,
42
43
  id *record
@@ -74,13 +75,14 @@ static id RunnerSampledDragPointerPath(
74
75
  static double RunnerSmoothstepProgress(double t);
75
76
  static NSString * _Nullable RunnerTrySynthesizeDrag(
76
77
  id application,
78
+ id _Nullable resolvedWindow,
77
79
  CGPoint start,
78
80
  CGPoint end,
79
81
  double durationMs,
80
82
  NSString *recordName,
81
83
  RunnerDragPointerPathFactory pathFactory
82
84
  );
83
- static NSString * _Nullable RunnerTrySynthesizeTap(id application, CGPoint point);
85
+ static NSString * _Nullable RunnerTrySynthesizeTap(id application, id _Nullable resolvedWindow, CGPoint point);
84
86
  // XCTest's proven swipe profile reaches the endpoint in 100 ms, then holds for the planned
85
87
  // fling duration. Fast movement is what lets UIKit distinguish a fling from a timed pan.
86
88
  static const NSTimeInterval RunnerSwipeMovementDurationSeconds = 0.1;
@@ -94,14 +96,16 @@ static id RunnerTapPointerPath(
94
96
  @implementation RunnerSynthesizedGesture
95
97
 
96
98
  + (NSString * _Nullable)synthesizeSwipeWithApplication:(id)application
97
- x:(double)x
98
- y:(double)y
99
- x2:(double)x2
100
- y2:(double)y2
99
+ resolvedWindow:(id _Nullable)resolvedWindow
100
+ x:(double)x
101
+ y:(double)y
102
+ x2:(double)x2
103
+ y2:(double)y2
101
104
  durationMs:(double)durationMs {
102
105
  @try {
103
106
  return RunnerTrySynthesizeDrag(
104
107
  application,
108
+ resolvedWindow,
105
109
  CGPointMake(x, y),
106
110
  CGPointMake(x2, y2),
107
111
  durationMs,
@@ -114,6 +118,7 @@ static id RunnerTapPointerPath(
114
118
  }
115
119
 
116
120
  + (NSString * _Nullable)synthesizeContinuousDragWithApplication:(id)application
121
+ resolvedWindow:(id _Nullable)resolvedWindow
117
122
  x:(double)x
118
123
  y:(double)y
119
124
  x2:(double)x2
@@ -122,6 +127,7 @@ static id RunnerTapPointerPath(
122
127
  @try {
123
128
  return RunnerTrySynthesizeDrag(
124
129
  application,
130
+ resolvedWindow,
125
131
  CGPointMake(x, y),
126
132
  CGPointMake(x2, y2),
127
133
  durationMs,
@@ -134,14 +140,16 @@ static id RunnerTapPointerPath(
134
140
  }
135
141
 
136
142
  + (NSString * _Nullable)synthesizeControlledScrollWithApplication:(id)application
143
+ resolvedWindow:(id _Nullable)resolvedWindow
137
144
  x:(double)x
138
145
  y:(double)y
139
146
  x2:(double)x2
140
- y2:(double)y2
141
- durationMs:(double)durationMs {
147
+ y2:(double)y2
148
+ durationMs:(double)durationMs {
142
149
  @try {
143
150
  return RunnerTrySynthesizeDrag(
144
151
  application,
152
+ resolvedWindow,
145
153
  CGPointMake(x, y),
146
154
  CGPointMake(x2, y2),
147
155
  durationMs,
@@ -154,22 +162,25 @@ static id RunnerTapPointerPath(
154
162
  }
155
163
 
156
164
  + (NSString * _Nullable)synthesizeTapWithApplication:(id)application
165
+ resolvedWindow:(id _Nullable)resolvedWindow
157
166
  x:(double)x
158
167
  y:(double)y {
159
168
  @try {
160
- return RunnerTrySynthesizeTap(application, CGPointMake(x, y));
169
+ return RunnerTrySynthesizeTap(application, resolvedWindow, CGPointMake(x, y));
161
170
  } @catch (NSException *exception) {
162
171
  return RunnerFormatXCTestException(exception, @"private XCTest event synthesis failed");
163
172
  }
164
173
  }
165
174
 
166
175
  + (NSString * _Nullable)synthesizeGestureWithApplication:(id)application
176
+ resolvedWindow:(id _Nullable)resolvedWindow
167
177
  pointerSamples:(NSArray<NSArray<NSDictionary<NSString *, NSNumber *> *> *> *)pointerSamples {
168
178
  @try {
169
179
  RunnerGestureEventBridge bridge;
170
180
  id record = nil;
171
181
  NSString *error = RunnerCreateEventRecord(
172
182
  application,
183
+ resolvedWindow,
173
184
  @"agent-device-gesture-plan",
174
185
  &bridge,
175
186
  &record
@@ -224,6 +235,7 @@ static id RunnerTapPointerPath(
224
235
 
225
236
  static NSString * _Nullable RunnerTrySynthesizeDrag(
226
237
  id application,
238
+ id _Nullable resolvedWindow,
227
239
  CGPoint start,
228
240
  CGPoint end,
229
241
  double durationMs,
@@ -232,7 +244,7 @@ static NSString * _Nullable RunnerTrySynthesizeDrag(
232
244
  ) {
233
245
  RunnerGestureEventBridge bridge;
234
246
  id record = nil;
235
- NSString *error = RunnerCreateEventRecord(application, recordName, &bridge, &record);
247
+ NSString *error = RunnerCreateEventRecord(application, resolvedWindow, recordName, &bridge, &record);
236
248
  if (error != nil) return error;
237
249
 
238
250
  id path = pathFactory(&bridge, start, end, durationMs);
@@ -244,11 +256,12 @@ static NSString * _Nullable RunnerTrySynthesizeDrag(
244
256
  return RunnerSynthesizeEventRecord(&bridge, record);
245
257
  }
246
258
 
247
- static NSString * _Nullable RunnerTrySynthesizeTap(id application, CGPoint point) {
259
+ static NSString * _Nullable RunnerTrySynthesizeTap(id application, id _Nullable resolvedWindow, CGPoint point) {
248
260
  RunnerGestureEventBridge bridge;
249
261
  id record = nil;
250
262
  NSString *error = RunnerCreateEventRecord(
251
263
  application,
264
+ resolvedWindow,
252
265
  @"agent-device-tap",
253
266
  &bridge,
254
267
  &record
@@ -271,14 +284,14 @@ static NSString * _Nullable RunnerResolveGestureEventBridge(
271
284
  NSString *missing = RunnerResolveXCTestEventBridge(application, RunnerGestureSynthesisSurface, &core);
272
285
  if (missing != nil) return missing;
273
286
 
274
- SEL initRecordSelector = NSSelectorFromString(@"initWithName:interfaceOrientation:");
287
+ SEL initRecordSelector = NSSelectorFromString(@"initWithName:displayID:interfaceOrientation:");
275
288
  SEL interfaceOrientationSelector = NSSelectorFromString(@"interfaceOrientation");
276
289
  SEL initPathSelector = NSSelectorFromString(@"initForTouchAtPoint:offset:");
277
290
  SEL moveSelector = NSSelectorFromString(@"moveToPoint:atOffset:");
278
291
  SEL liftSelector = NSSelectorFromString(@"liftUpAtOffset:");
279
292
 
280
293
  missing = RunnerRequireSelector(
281
- core.recordClass, initRecordSelector, @"initWithName:interfaceOrientation:", RunnerGestureSynthesisSurface
294
+ core.recordClass, initRecordSelector, @"initWithName:displayID:interfaceOrientation:", RunnerGestureSynthesisSurface
282
295
  );
283
296
  if (missing != nil) return missing;
284
297
  missing = RunnerRequireSelector(
@@ -311,6 +324,7 @@ static NSString * _Nullable RunnerResolveGestureEventBridge(
311
324
 
312
325
  static NSString * _Nullable RunnerCreateEventRecord(
313
326
  id application,
327
+ id _Nullable resolvedWindow,
314
328
  NSString *recordName,
315
329
  RunnerGestureEventBridge *bridge,
316
330
  id *record
@@ -318,6 +332,12 @@ static NSString * _Nullable RunnerCreateEventRecord(
318
332
  NSString *missing = RunnerResolveGestureEventBridge(application, bridge);
319
333
  if (missing != nil) return missing;
320
334
 
335
+ NSUInteger displayID = 0;
336
+ if (resolvedWindow == nil) {
337
+ return @"private XCTest event synthesis unavailable: no resolved application window";
338
+ }
339
+ NSString *displayError = RunnerResolveWindowDisplayID(resolvedWindow, &displayID);
340
+ if (displayError != nil) return displayError;
321
341
  NSInteger interfaceOrientation =
322
342
  ((RunnerMsgSendInteger)objc_msgSend)(application, bridge->interfaceOrientationSelector);
323
343
  NSInteger targetProcessID =
@@ -330,11 +350,18 @@ static NSString * _Nullable RunnerCreateEventRecord(
330
350
  [bridge->core.recordClass alloc],
331
351
  bridge->initRecordSelector,
332
352
  recordName,
353
+ displayID,
333
354
  interfaceOrientation
334
355
  );
335
356
  if (eventRecord == nil) {
336
357
  return @"private XCTest event synthesis failed: could not create event record";
337
358
  }
359
+ NSLog(
360
+ @"AGENT_DEVICE_RUNNER_SYNTHESIZED_RECORD name=%@ displayID=%lu interfaceOrientation=%ld",
361
+ recordName,
362
+ (unsigned long)displayID,
363
+ (long)interfaceOrientation
364
+ );
338
365
  ((RunnerMsgSendSetInteger)objc_msgSend)(
339
366
  eventRecord,
340
367
  bridge->core.setTargetProcessIDSelector,
@@ -68,6 +68,14 @@ extension RunnerTests {
68
68
  guard waitUntilAlertButtonHittable(button, deadline: deadline) else {
69
69
  return alertVerificationResponse(.timedOut, action: action, activated: false)
70
70
  }
71
+ let buttonFrame = button.frame
72
+ NSLog(
73
+ "AGENT_DEVICE_RUNNER_ALERT_ACTIVATION action=%@ label=%@ frame=(%.1f,%.1f,%.1f,%.1f) point=(%.1f,%.1f)",
74
+ action,
75
+ button.label,
76
+ buttonFrame.origin.x, buttonFrame.origin.y, buttonFrame.size.width, buttonFrame.size.height,
77
+ buttonFrame.midX, buttonFrame.midY
78
+ )
71
79
 
72
80
 
73
81
 
@@ -24,6 +24,7 @@ import AgentDeviceSnapshotPresentation
24
24
 
25
25
 
26
26
 
27
+
27
28
 
28
29
 
29
30
  extension RunnerTests {
@@ -1465,7 +1466,7 @@ extension RunnerTests {
1465
1466
  fps: command.fps.map { Int32($0) }
1466
1467
  )
1467
1468
  try recorder.start { [weak self] in
1468
- return self?.captureRunnerFrame()
1469
+ return self?.captureRunnerFrame(app: activeApp)
1469
1470
  }
1470
1471
  activeRecording = recorder
1471
1472
  return Response(ok: true, data: DataPayload(message: "recording started"))
@@ -2054,7 +2055,6 @@ extension RunnerTests {
2054
2055
  case .snapshot:
2055
2056
  return try executeSnapshotPrepared(command: command, activeApp: activeApp)
2056
2057
  case .screenshot:
2057
- let screenshot: XCUIScreenshot
2058
2058
  #if os(macOS)
2059
2059
 
2060
2060
  if let bundleId = command.appBundleId, !bundleId.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
@@ -2064,6 +2064,7 @@ extension RunnerTests {
2064
2064
 
2065
2065
  sleepFor(0.5)
2066
2066
  }
2067
+ let screenshot: XCUIScreenshot
2067
2068
  if command.fullscreen == true {
2068
2069
  screenshot = XCUIScreen.main.screenshot()
2069
2070
  } else if let bundleId = command.appBundleId, !bundleId.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
@@ -2071,30 +2072,52 @@ extension RunnerTests {
2071
2072
  } else {
2072
2073
  screenshot = XCUIScreen.main.screenshot()
2073
2074
  }
2074
- #else
2075
- screenshot = XCUIScreen.main.screenshot()
2076
- #endif
2077
- guard let pngData = runnerPngData(for: screenshot.image) else {
2078
- return Response(ok: false, error: ErrorPayload(message: "Failed to encode screenshot as PNG"))
2079
- }
2080
- if command.inlineScreenshot == true {
2075
+ return screenshotResponse(
2076
+ image: screenshot.image,
2077
+ inlineScreenshot: command.inlineScreenshot == true
2078
+ )
2079
+ #elseif os(iOS)
2080
+
2081
+
2082
+
2083
+
2084
+
2085
+
2086
+
2087
+
2088
+
2089
+ switch captureObservedScreen(app: resolveAppWithoutActivation(command: command)) {
2090
+ case .failure(let failure):
2081
2091
  return Response(
2082
- ok: true,
2083
- data: DataPayload(imageBase64: pngData.base64EncodedString())
2092
+ ok: false,
2093
+ error: ErrorPayload(code: failure.rawValue, message: failure.message, hint: failure.hint)
2094
+ )
2095
+ case .success(let captured):
2096
+
2097
+
2098
+ NSLog(
2099
+ "AGENT_DEVICE_RUNNER_SCREEN_CAPTURE display=%lu pixels=%ldx%ld pixelsPerPoint=%g",
2100
+ captured.displayID,
2101
+ captured.pixelWidth,
2102
+ captured.pixelHeight,
2103
+ captured.pixelsPerPoint
2104
+ )
2105
+ return screenshotResponse(
2106
+ image: captured.image,
2107
+ inlineScreenshot: command.inlineScreenshot == true,
2108
+ metadata: ScreenshotMetadataPayload(
2109
+ displayID: captured.displayID,
2110
+ pixelWidth: captured.pixelWidth,
2111
+ pixelHeight: captured.pixelHeight,
2112
+ pixelsPerPoint: captured.pixelsPerPoint
2113
+ )
2084
2114
  )
2085
2115
  }
2086
- let fileName = "screenshot-\(Int(Date().timeIntervalSince1970 * 1000)).png"
2087
- let filePath = (NSTemporaryDirectory() as NSString).appendingPathComponent(fileName)
2088
- do {
2089
- try pngData.write(to: URL(fileURLWithPath: filePath))
2090
- } catch {
2091
- return Response(ok: false, error: ErrorPayload(message: "Failed to write screenshot: \(error.localizedDescription)"))
2092
- }
2093
- #if os(macOS)
2094
- return Response(ok: true, data: DataPayload(message: filePath))
2095
2116
  #else
2096
-
2097
- return Response(ok: true, data: DataPayload(message: "tmp/\(fileName)"))
2117
+ return screenshotResponse(
2118
+ image: XCUIScreen.main.screenshot().image,
2119
+ inlineScreenshot: command.inlineScreenshot == true
2120
+ )
2098
2121
  #endif
2099
2122
  case .back, .backInApp:
2100
2123
  if tapInAppBackControl(app: activeApp) {