agent-device 0.20.10 → 0.21.1

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 (510) hide show
  1. package/README.md +2 -2
  2. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.10.apk → agent-device-android-ime-helper-0.21.1.apk} +0 -0
  3. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.1.apk.sha256 +1 -0
  4. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.10.manifest.json → agent-device-android-ime-helper-0.21.1.manifest.json} +4 -4
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.1.apk +0 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.1.apk.sha256 +1 -0
  7. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.10.manifest.json → agent-device-android-snapshot-helper-0.21.1.manifest.json} +6 -6
  8. package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/AudioProbe.swift +35 -33
  9. package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/main.swift +6 -1
  10. package/apple/snapshot-bridge/LICENSE.idb +23 -0
  11. package/apple/snapshot-bridge/README.md +106 -0
  12. package/apple/snapshot-bridge/SnapshotBridge.m +286 -0
  13. package/apple/snapshot-bridge/SnapshotBridgeCapture.h +25 -0
  14. package/apple/snapshot-bridge/SnapshotBridgeCapture.m +138 -0
  15. package/apple/snapshot-bridge/SnapshotBridgeRuntime.h +34 -0
  16. package/apple/snapshot-bridge/SnapshotBridgeRuntime.m +411 -0
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +58 -0
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +19 -0
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +12 -0
  20. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +20 -0
  21. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAlertVerification.swift +36 -0
  22. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSelectorMatchPolicy.swift +15 -15
  23. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerStringNormalization.swift +8 -0
  24. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +12 -1
  25. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +100 -6
  26. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSystemSurfaceHostPolicy.swift +72 -0
  27. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +63 -14
  28. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +677 -83
  29. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +35 -92
  30. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AlertObservation.swift +124 -0
  31. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+BlockingSystemModalResolution.swift +39 -4
  32. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +1058 -213
  33. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +296 -14
  34. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +1 -1
  35. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +10 -10
  36. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +309 -149
  37. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +101 -42
  38. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +24 -17
  39. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +124 -199
  40. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +71 -4
  41. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXElementTypes.swift +12 -0
  42. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +211 -78
  43. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +30 -10
  44. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +254 -24
  45. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +206 -22
  46. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +465 -494
  47. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotBackendCapabilities.swift +168 -0
  48. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +802 -247
  49. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentationInvariant.swift +19 -0
  50. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTiming.swift +185 -0
  51. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedCommitDeadline.swift +206 -0
  52. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +83 -5
  53. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +156 -34
  54. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +5 -4
  55. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +35 -318
  56. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +206 -0
  57. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryReadiness.swift +158 -0
  58. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextInputCandidatePolicy.swift +28 -0
  59. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextInputProbe.swift +101 -0
  60. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +56 -23
  61. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +56 -27
  62. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +30 -24
  63. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +126 -80
  64. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/RecordingExportSupport.swift +111 -0
  65. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +47 -86
  66. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-trim.swift +32 -79
  67. package/dist/apple/snapshot-presentation/Package.swift +21 -0
  68. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotGeometry.swift +56 -0
  69. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotModels.swift +259 -0
  70. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentation.swift +153 -0
  71. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationFailure.swift +27 -0
  72. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationInvariant.swift +91 -0
  73. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationProjection.swift +161 -0
  74. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotScopePolicy.swift +53 -0
  75. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFold.swift +242 -0
  76. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFoldProjection.swift +97 -0
  77. package/dist/src/adapter.js +1 -0
  78. package/dist/src/adb-executor.js +2 -0
  79. package/dist/src/adb-failure.js +1 -0
  80. package/dist/src/adb-host.js +1 -0
  81. package/dist/src/adb.js +1 -0
  82. package/dist/src/agent-browser-lifecycle.js +1 -0
  83. package/dist/src/agent-browser-process-record.js +1 -0
  84. package/dist/src/agent-browser-provider.js +1 -0
  85. package/dist/src/agent-browser-tool.js +1 -1
  86. package/dist/src/agent-device-client.js +2 -2
  87. package/dist/src/ai-sdk.d.ts +2 -2
  88. package/dist/src/ai-sdk.js +1 -1
  89. package/dist/src/alert-contract.js +1 -0
  90. package/dist/src/alert-runtime.js +1 -0
  91. package/dist/src/android-adb.d.ts +27 -19
  92. package/dist/src/android-adb.js +1 -1
  93. package/dist/src/android-input-ownership.js +1 -0
  94. package/dist/src/android-system-chrome.js +1 -0
  95. package/dist/src/android.js +1 -1
  96. package/dist/src/api.js +11 -0
  97. package/dist/src/app-catalog.js +1 -0
  98. package/dist/src/app-deployment-resolution.js +2 -0
  99. package/dist/src/app-helpers.js +1 -1
  100. package/dist/src/app-inventory-contract.js +1 -0
  101. package/dist/src/app-inventory.js +1 -0
  102. package/dist/src/app-launch.js +2 -0
  103. package/dist/src/app-lifecycle-facade.js +1 -0
  104. package/dist/src/app-lifecycle.js +3 -6
  105. package/dist/src/app-lifecycle2.js +2 -2
  106. package/dist/src/app-lifecycle3.js +1 -0
  107. package/dist/src/app-log-files.js +1 -1
  108. package/dist/src/app-log-reconnect.js +1 -1
  109. package/dist/src/app-log-runtime.js +1 -4
  110. package/dist/src/app-log-runtime2.js +4 -0
  111. package/dist/src/app-parsers.js +4 -0
  112. package/dist/src/app-resolution-cache.js +1 -0
  113. package/dist/src/app-resolution-facade.js +1 -0
  114. package/dist/src/app-resolution.js +2 -2
  115. package/dist/src/app-state.js +1 -2
  116. package/dist/src/apple-runner-platform.js +1 -0
  117. package/dist/src/application-lifecycle-interaction.js +1 -0
  118. package/dist/src/application-lifecycle-runtime.js +1 -0
  119. package/dist/src/apps-simctl.js +1 -0
  120. package/dist/src/archive.js +4 -0
  121. package/dist/src/artifact-download.js +1 -0
  122. package/dist/src/artifacts.d.ts +6 -2
  123. package/dist/src/artifacts.js +1 -1
  124. package/dist/src/async-lifecycle.js +1 -0
  125. package/dist/src/audio-probe-result.js +1 -0
  126. package/dist/src/audio-probe-runtime.js +1 -0
  127. package/dist/src/audio-probe-support.js +1 -0
  128. package/dist/src/auth-session.js +1 -1
  129. package/dist/src/auth.js +1 -1
  130. package/dist/src/backend-snapshot-options.js +1 -1
  131. package/dist/src/{url.js → base-url.js} +1 -1
  132. package/dist/src/boot-diagnostics.js +2 -2
  133. package/dist/src/byte-limit-stream.js +1 -1
  134. package/dist/src/capabilities.js +1 -0
  135. package/dist/src/capture.js +1 -0
  136. package/dist/src/catalog.js +1 -0
  137. package/dist/src/cli-command-aliases.js +1 -0
  138. package/dist/src/cli-config.js +1 -1
  139. package/dist/src/cli-help.js +74 -51
  140. package/dist/src/cli-output.js +1 -1
  141. package/dist/src/cli-runner.js +1 -1
  142. package/dist/src/cli.js +4 -6
  143. package/dist/src/click-button.js +1 -0
  144. package/dist/src/client-metro-companion.js +1 -0
  145. package/dist/src/client-metro.js +1 -1
  146. package/dist/src/client-types.d.ts +280 -242
  147. package/dist/src/clipboard.js +1 -0
  148. package/dist/src/code-signature-cache.js +1 -0
  149. package/dist/src/code-signature.js +1 -0
  150. package/dist/src/color.js +1 -0
  151. package/dist/src/command-metadata.js +1 -1
  152. package/dist/src/command-schema.js +3 -3
  153. package/dist/src/command-surface.js +1 -1
  154. package/dist/src/command-tools.js +2 -2
  155. package/dist/src/command.js +1 -0
  156. package/dist/src/compatibility-policy.js +1 -0
  157. package/dist/src/config.js +1 -1
  158. package/dist/src/config2.js +1 -0
  159. package/dist/src/connection-runtime.js +1 -1
  160. package/dist/src/connection.js +5 -5
  161. package/dist/src/contracts.d.ts +1 -1
  162. package/dist/src/contracts.js +1 -1
  163. package/dist/src/daemon-client-lifecycle.js +1 -0
  164. package/dist/src/daemon-process.js +1 -0
  165. package/dist/src/daemon-registration.js +1 -0
  166. package/dist/src/daemon-shutdown-report.js +1 -1
  167. package/dist/src/daemon.js +2 -2
  168. package/dist/src/debug-symbols-facade.js +5 -0
  169. package/dist/src/deploy-result-target.js +1 -0
  170. package/dist/src/device-claim-inspection.js +1 -1
  171. package/dist/src/device-claim-rule.js +1 -0
  172. package/dist/src/device-input-state.d.ts +190 -3
  173. package/dist/src/device-inventory-context.js +1 -0
  174. package/dist/src/device-isolation.js +1 -0
  175. package/dist/src/device-release.js +1 -0
  176. package/dist/src/device-rotation.js +1 -0
  177. package/dist/src/device-selection-resolver.js +1 -0
  178. package/dist/src/device-session.js +1 -0
  179. package/dist/src/device.js +1 -1
  180. package/dist/src/device2.js +3 -2
  181. package/dist/src/diagnostics.js +3 -0
  182. package/dist/src/diagnostics2.js +1 -0
  183. package/dist/src/dispatch-resolve.js +1 -0
  184. package/dist/src/doctor-facade.js +1 -0
  185. package/dist/src/doctor-output.js +1 -0
  186. package/dist/src/doctor.js +1 -0
  187. package/dist/src/doctor2.js +1 -0
  188. package/dist/src/doctor3.js +1 -0
  189. package/dist/src/durable-resource.js +1 -0
  190. package/dist/src/entities.js +1 -1
  191. package/dist/src/error.js +2 -0
  192. package/dist/src/exec.js +1 -0
  193. package/dist/src/file.js +1 -0
  194. package/dist/src/find.js +1 -1
  195. package/dist/src/finders.js +1 -1
  196. package/dist/src/generic-settle.js +1 -1
  197. package/dist/src/generic.js +1 -1
  198. package/dist/src/gesture-admission.js +1 -0
  199. package/dist/src/gesture-plan-types.js +1 -0
  200. package/dist/src/gesture-plan.js +1 -0
  201. package/dist/src/gesture-runtime.js +1 -0
  202. package/dist/src/harmonyos.js +1 -1
  203. package/dist/src/hdc.js +1 -1
  204. package/dist/src/helper.js +2 -2
  205. package/dist/src/host-file.js +1 -0
  206. package/dist/src/human-control-contract.js +1 -0
  207. package/dist/src/human-control.js +1 -0
  208. package/dist/src/index.d.ts +1 -1
  209. package/dist/src/index.js +1 -1
  210. package/dist/src/input-actions.js +1 -4
  211. package/dist/src/input-actions2.js +2 -1
  212. package/dist/src/install-artifact-facade.js +1 -0
  213. package/dist/src/install-source-network-transport.js +1 -0
  214. package/dist/src/install-source.d.ts +3 -10
  215. package/dist/src/install-source2.js +1 -1
  216. package/dist/src/interaction-positionals.js +1 -0
  217. package/dist/src/interaction-ref-policy.js +1 -0
  218. package/dist/src/interaction.js +1 -1
  219. package/dist/src/interaction2.js +1 -1
  220. package/dist/src/interactor-operation-catalog.js +1 -0
  221. package/dist/src/interactor-types.js +1 -0
  222. package/dist/src/interactor.js +6 -2
  223. package/dist/src/interactor2.js +1 -1
  224. package/dist/src/interactors.js +1 -1
  225. package/dist/src/internal/bin.d.ts +1 -1
  226. package/dist/src/internal/bin.js +1 -2
  227. package/dist/src/internal/companion-tunnel.d.ts +1 -1
  228. package/dist/src/internal/companion-tunnel.js +1 -1
  229. package/dist/src/internal/daemon.d.ts +1 -1
  230. package/dist/src/internal/daemon.js +2 -4
  231. package/dist/src/internal/png-worker.d.ts +4 -4
  232. package/dist/src/internal/png-worker.js +1 -1
  233. package/dist/src/internal/run-script-http-child.d.ts +4 -0
  234. package/dist/src/internal/run-script-http-child.js +1 -0
  235. package/dist/src/internal/update-check-entry.d.ts +1 -1
  236. package/dist/src/inventory.js +4 -4
  237. package/dist/src/inventory2.js +1 -1
  238. package/dist/src/inventory3.js +1 -1
  239. package/dist/src/inventory5.js +1 -1
  240. package/dist/src/inventory6.js +1 -1
  241. package/dist/src/ios-client.js +16 -0
  242. package/dist/src/ios-snapshot-acquisition.js +1 -0
  243. package/dist/src/ios-snapshot-adapter.js +1 -0
  244. package/dist/src/ios-snapshot-planning.js +1 -0
  245. package/dist/src/ios-snapshot-runtime.js +1 -0
  246. package/dist/src/ios-system-surface.js +1 -0
  247. package/dist/src/json.js +1 -0
  248. package/dist/src/keyboard-actions.js +1 -0
  249. package/dist/src/launch-console.js +1 -0
  250. package/dist/src/lease-context.js +1 -1
  251. package/dist/src/lease-scope.js +1 -0
  252. package/dist/src/lease.js +1 -1
  253. package/dist/src/limrun-runtime-dependencies.js +1 -1
  254. package/dist/src/limrun.d.ts +1610 -7
  255. package/dist/src/limrun.js +1 -1
  256. package/dist/src/linux.js +1 -1
  257. package/dist/src/local-interactor-operation-set.js +1 -0
  258. package/dist/src/location-coordinates.js +1 -1
  259. package/dist/src/logcat.js +1 -1
  260. package/dist/src/macos-facade.js +1 -0
  261. package/dist/src/managed-device-scope.js +1 -0
  262. package/dist/src/mechanics.js +19 -0
  263. package/dist/src/metro.d.ts +4 -2
  264. package/dist/src/metro.js +1 -1
  265. package/dist/src/metro2.js +1 -1
  266. package/dist/src/mobile-snapshot-semantics.js +1 -1
  267. package/dist/src/multitouch-support.js +1 -0
  268. package/dist/src/numeric.js +1 -0
  269. package/dist/src/observability.js +1 -1
  270. package/dist/src/observation.js +2 -0
  271. package/dist/src/open-target-resolution.js +1 -0
  272. package/dist/src/output-path.js +1 -1
  273. package/dist/src/owner-identity.js +3 -1
  274. package/dist/src/parameterized-recorded-fill.js +1 -0
  275. package/dist/src/parser.js +1 -1
  276. package/dist/src/perf-facade.js +2 -0
  277. package/dist/src/perf-process-identity.js +1 -0
  278. package/dist/src/perf-runtime-operation-builder.js +1 -0
  279. package/dist/src/perf-runtime-plan.js +1 -0
  280. package/dist/src/perf-runtime.js +1 -0
  281. package/dist/src/perf.js +1 -4
  282. package/dist/src/physical-device-control.js +1 -1
  283. package/dist/src/physical-device-facade.js +1 -0
  284. package/dist/src/platform-request-scope.js +1 -0
  285. package/dist/src/platform-runtime-android-adb-host.js +1 -0
  286. package/dist/src/platform-runtime-android-mechanics.js +1 -0
  287. package/dist/src/platform-runtime-app-log-android-transport.js +1 -1
  288. package/dist/src/platform-runtime-app-log-process.js +1 -1
  289. package/dist/src/platform-runtime-host.js +1 -1
  290. package/dist/src/platform-runtime-managed-owner.js +1 -0
  291. package/dist/src/platform-runtime-network-web-transport.js +1 -1
  292. package/dist/src/platform-runtime-open-target.js +1 -1
  293. package/dist/src/platform-runtime-operation-host.js +4 -4
  294. package/dist/src/platform-runtime-runtime-hints.js +2 -2
  295. package/dist/src/platform-runtime-screen-recording-android-host.js +1 -1
  296. package/dist/src/platform-runtime-screen-recording-apple-runner-host.js +1 -1
  297. package/dist/src/platform-runtime-screen-recording-apple-runner-transport.js +1 -1
  298. package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -1
  299. package/dist/src/platform-runtime-screen-recording-apple-transport.js +1 -1
  300. package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
  301. package/dist/src/platform-runtime-screen-recording-harmony-host.js +1 -1
  302. package/dist/src/platform-runtime-screen-recording-process-host.js +1 -0
  303. package/dist/src/platform-runtime-screen-recording-web-host.js +1 -1
  304. package/dist/src/platform-runtime-unavailable.js +1 -0
  305. package/dist/src/platform-runtime.js +1 -1
  306. package/dist/src/platform-runtime2.js +1 -1
  307. package/dist/src/plist.js +1 -1
  308. package/dist/src/png-worker-contract.js +1 -1
  309. package/dist/src/prepare-kind.js +1 -0
  310. package/dist/src/process-exit.js +1 -1
  311. package/dist/src/process.js +1 -0
  312. package/dist/src/provider-device-runtime.js +1 -0
  313. package/dist/src/provider-session-ownership.js +2 -0
  314. package/dist/src/provider-webdriver.js +1 -1
  315. package/dist/src/provider.js +1 -1
  316. package/dist/src/providers.js +1 -0
  317. package/dist/src/proxy.js +2 -2
  318. package/dist/src/react-native-overlay.js +1 -0
  319. package/dist/src/react-native.js +1 -1
  320. package/dist/src/record-runtime.js +1 -1
  321. package/dist/src/record-trace.js +1 -1
  322. package/dist/src/rect-center.js +1 -0
  323. package/dist/src/register-builtins.js +1 -0
  324. package/dist/src/registry.js +40 -28
  325. package/dist/src/remote-config2.js +1 -1
  326. package/dist/src/replay-divergence.js +2 -0
  327. package/dist/src/replay.js +2 -2
  328. package/dist/src/reporting.js +8 -7
  329. package/dist/src/request-admission.js +1 -0
  330. package/dist/src/request-cancel.js +1 -0
  331. package/dist/src/request-cancellation.js +1 -0
  332. package/dist/src/request-progress-protocol.js +1 -0
  333. package/dist/src/request-providers.js +1 -0
  334. package/dist/src/request-runtime-binding.js +1 -0
  335. package/dist/src/request.js +1 -0
  336. package/dist/src/result-serialization.js +1 -0
  337. package/dist/src/retry.js +1 -0
  338. package/dist/src/rolldown-runtime.js +1 -1
  339. package/dist/src/runner-cache-metadata.js +2 -0
  340. package/dist/src/runner-client.js +1 -1
  341. package/dist/src/runner-disposal.js +1 -1
  342. package/dist/src/runner-operations-facade.js +1 -0
  343. package/dist/src/runner-owner-facade.js +1 -0
  344. package/dist/src/runner-owner-state.js +1 -0
  345. package/dist/src/runner-presentation.js +1 -0
  346. package/dist/src/runner.js +1 -0
  347. package/dist/src/{runtime-transport.js → runtime-transport-hints.js} +1 -1
  348. package/dist/src/runtime.js +3 -3
  349. package/dist/src/runtime2.js +4 -4
  350. package/dist/src/runtime3.js +1 -1
  351. package/dist/src/runtime4.js +5 -3
  352. package/dist/src/runtime5.js +1 -1
  353. package/dist/src/runtime6.js +1 -1
  354. package/dist/src/runtime7.js +1 -1
  355. package/dist/src/runtime8.js +1 -1
  356. package/dist/src/runtime9.js +1 -1
  357. package/dist/src/scoped-provider.js +1 -1
  358. package/dist/src/screen-recording-completion.js +1 -0
  359. package/dist/src/screen-recording-live-handle.js +1 -0
  360. package/dist/src/screen-recording-options.js +1 -0
  361. package/dist/src/screen-recording-resource-recovery.js +1 -0
  362. package/dist/src/screen-recording-runtime.js +1 -0
  363. package/dist/src/screenshot-density.js +1 -1
  364. package/dist/src/screenshot-result.js +1 -6
  365. package/dist/src/screenshot-runtime.js +1 -0
  366. package/dist/src/screenshot.js +1 -1
  367. package/dist/src/screenshot2.js +1 -0
  368. package/dist/src/screenshot3.js +5 -0
  369. package/dist/src/script.js +1 -0
  370. package/dist/src/scroll-command.js +1 -0
  371. package/dist/src/scroll-gesture.js +1 -0
  372. package/dist/src/scroll-indicator.js +1 -0
  373. package/dist/src/sdk-batch-runner.d.ts +23 -6
  374. package/dist/src/sdk-batch-runner.js +2 -3
  375. package/dist/src/sdk-batch.js +2 -0
  376. package/dist/src/sdk-contracts.d.ts +170 -41
  377. package/dist/src/sdk-contracts.js +2 -2
  378. package/dist/src/sdk-device.js +1 -1
  379. package/dist/src/sdk-finders.d.ts +1 -1
  380. package/dist/src/sdk-finders.js +1 -1
  381. package/dist/src/sdk-io.js +1 -1
  382. package/dist/src/sdk-remote-config.d.ts +1 -1
  383. package/dist/src/sdk-remote-config.js +1 -1
  384. package/dist/src/sdk-selectors.d.ts +524 -140
  385. package/dist/src/sdk-selectors.js +1 -1
  386. package/dist/src/selection.js +1 -0
  387. package/dist/src/selector-runtime.js +1 -1
  388. package/dist/src/selectors.js +1 -1
  389. package/dist/src/semantic-index.js +1 -0
  390. package/dist/src/server.js +4 -4
  391. package/dist/src/session-allocation.js +1 -0
  392. package/dist/src/session-artifact-paths.js +1 -0
  393. package/dist/src/session-observation.js +1 -0
  394. package/dist/src/session-paths.js +1 -0
  395. package/dist/src/session-repair-tombstone.js +1 -0
  396. package/dist/src/session-routing.js +1 -0
  397. package/dist/src/session-runtime-admission.js +1 -0
  398. package/dist/src/session-snapshot.js +1 -0
  399. package/dist/src/session-store.js +4 -0
  400. package/dist/src/session-target-evidence.js +1 -1
  401. package/dist/src/session2.js +5 -27
  402. package/dist/src/settings.js +1 -0
  403. package/dist/src/shared.js +2 -2
  404. package/dist/src/simctl-facade.js +1 -0
  405. package/dist/src/simctl.js +1 -1
  406. package/dist/src/simulator-facade.js +1 -0
  407. package/dist/src/simulator.js +1 -1
  408. package/dist/src/snapshot-capture-annotations.js +1 -0
  409. package/dist/src/snapshot-desktop-projection.js +1 -0
  410. package/dist/src/snapshot-diagnostics.js +1 -0
  411. package/dist/src/snapshot-process.js +1 -0
  412. package/dist/src/snapshot-quality-backend-capabilities.js +1 -0
  413. package/dist/src/snapshot-quality-verdict.js +1 -0
  414. package/dist/src/snapshot-runtime-binding.js +1 -0
  415. package/dist/src/snapshot-runtime.js +1 -1
  416. package/dist/src/snapshot-scope.js +1 -1
  417. package/dist/src/snapshot-state.js +1 -0
  418. package/dist/src/snapshot.js +1 -8
  419. package/dist/src/snapshot2.js +1 -1
  420. package/dist/src/snapshot3.js +1 -1
  421. package/dist/src/snapshot4.js +1 -0
  422. package/dist/src/src.js +1 -1
  423. package/dist/src/src2.js +1 -1
  424. package/dist/src/src3.js +1 -2
  425. package/dist/src/src4.js +1 -1
  426. package/dist/src/src5.js +1 -0
  427. package/dist/src/src6.js +1 -0
  428. package/dist/src/src7.js +2 -0
  429. package/dist/src/src8.js +115 -0
  430. package/dist/src/startup-recovery-fence.js +1 -0
  431. package/dist/src/status-markers.js +1 -0
  432. package/dist/src/string-enum.js +1 -1
  433. package/dist/src/success-text.js +1 -0
  434. package/dist/src/surface-snapshot.js +1 -0
  435. package/dist/src/surface-snapshot2.js +1 -0
  436. package/dist/src/takeover.js +5 -0
  437. package/dist/src/tool-provider-facade.js +1 -0
  438. package/dist/src/tool-provider.js +4 -3
  439. package/dist/src/tool-provider2.js +1 -1
  440. package/dist/src/tool-provider3.js +1 -1
  441. package/dist/src/toolchain-probe.js +2 -0
  442. package/dist/src/touch-reference-frame.js +1 -0
  443. package/dist/src/touch-runtime.js +1 -0
  444. package/dist/src/transport.js +3 -0
  445. package/dist/src/tree.js +1 -0
  446. package/dist/src/ttl-memo.js +1 -0
  447. package/dist/src/tv-remote.js +1 -0
  448. package/dist/src/type-text-runtime.js +1 -0
  449. package/dist/src/undici.js +99 -0
  450. package/dist/src/update-check.js +1 -1
  451. package/dist/src/verified-file.js +1 -1
  452. package/dist/src/version.js +1 -1
  453. package/dist/src/video.js +2 -2
  454. package/dist/src/web.js +2 -1
  455. package/dist/src/web2.js +1 -0
  456. package/dist/src/webdriver-ios-snapshot.js +1 -0
  457. package/dist/src/webdriver-source.js +1 -0
  458. package/dist/src/window-state.js +1 -0
  459. package/linux/atspi-dump.py +54 -9
  460. package/package.json +58 -35
  461. package/server.json +9 -3
  462. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.10.apk.sha256 +0 -1
  463. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.10.apk +0 -0
  464. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.10.apk.sha256 +0 -1
  465. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CoordinateTextEntryTests.swift +0 -4
  466. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +0 -168
  467. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+LifecycleCacheTests.swift +0 -6
  468. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+RecordingTests.swift +0 -4
  469. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SelectorMatchPolicyTests.swift +0 -4
  470. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentation.swift +0 -183
  471. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentationTests.swift +0 -0
  472. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTraversalIdentityTests.swift +0 -4
  473. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryPolicyTests.swift +0 -4
  474. package/dist/src/appearance.js +0 -1
  475. package/dist/src/apps.js +0 -5
  476. package/dist/src/audio-probe.js +0 -1
  477. package/dist/src/cli-grammar.js +0 -1
  478. package/dist/src/command-catalog.js +0 -1
  479. package/dist/src/debug-symbols.js +0 -5
  480. package/dist/src/device-input-state.js +0 -2
  481. package/dist/src/device-ready.js +0 -1
  482. package/dist/src/dispatch.js +0 -1
  483. package/dist/src/handler-utils.js +0 -1
  484. package/dist/src/helper-package-install.js +0 -1
  485. package/dist/src/host-process.js +0 -3
  486. package/dist/src/ime-lifecycle.js +0 -2
  487. package/dist/src/ime-recovery-marker.js +0 -1
  488. package/dist/src/input-actions3.js +0 -1
  489. package/dist/src/install-artifact.js +0 -1
  490. package/dist/src/install-artifact2.js +0 -1
  491. package/dist/src/interaction-common.js +0 -1
  492. package/dist/src/interaction-runtime.js +0 -1
  493. package/dist/src/interaction-snapshot.js +0 -1
  494. package/dist/src/manifest.js +0 -1
  495. package/dist/src/method-scope.js +0 -1
  496. package/dist/src/png-resize.js +0 -1
  497. package/dist/src/process-lock.js +0 -1
  498. package/dist/src/runner-lease.js +0 -1
  499. package/dist/src/runner-sequence.js +0 -1
  500. package/dist/src/script-source-bundle.js +0 -16
  501. package/dist/src/sdk-android-adb.d.ts +0 -245
  502. package/dist/src/sdk-android-adb.js +0 -4
  503. package/dist/src/sdk.js +0 -1
  504. package/dist/src/setting-state.js +0 -1
  505. package/dist/src/shell-quote.js +0 -1
  506. package/dist/src/snapshot-session.js +0 -1
  507. package/dist/src/timing-safe-equal.js +0 -1
  508. package/dist/src/unsupported-interactor.js +0 -1
  509. package/dist/src/verdict.js +0 -1
  510. /package/dist/src/{recording-telemetry.js → telemetry.js} +0 -0
@@ -0,0 +1,206 @@
1
+ import XCTest
2
+
3
+
4
+
5
+
6
+
7
+
8
+ extension RunnerTests {
9
+ func rememberTextEntryTap(_ element: XCUIElement?) {
10
+ guard let element, isTextEntryElement(element) else {
11
+ clearRememberedTextEntryTap()
12
+ return
13
+ }
14
+ textEntryTapWitness = TextEntryTapWitness(
15
+ element: element,
16
+ bundleId: currentBundleId,
17
+ processIdentifier: currentAppProcessIdentifier
18
+ )
19
+ }
20
+
21
+ func clearRememberedTextEntryTap() {
22
+ textEntryTapWitness = nil
23
+ }
24
+
25
+ private func rememberedTextEntryTarget() -> TextEntryTarget? {
26
+ guard let witness = textEntryTapWitness else {
27
+ return nil
28
+ }
29
+
30
+
31
+ clearRememberedTextEntryTap()
32
+ guard witness.matches(
33
+ bundleId: currentBundleId,
34
+ processIdentifier: currentAppProcessIdentifier
35
+ ) else {
36
+ return nil
37
+ }
38
+ let element = witness.element
39
+
40
+
41
+
42
+
43
+ guard safely("LAST_TAPPED_TEXT_INPUT_EXISTS", false, { element.exists }) else {
44
+ return nil
45
+ }
46
+
47
+
48
+
49
+ return TextEntryTarget(
50
+ element: element,
51
+ refreshPoint: nil,
52
+ prefersFocusedElement: false,
53
+ fromTapWitness: true
54
+ )
55
+ }
56
+
57
+ func stabilizeTextInputBeforeTyping(
58
+ app: XCUIApplication,
59
+ target: XCUIElement?,
60
+ keyboardVisibleBeforeTap: Bool? = nil
61
+ ) -> TextEntryStabilization {
62
+ #if os(tvOS)
63
+ return TextEntryStabilization(element: target, focusConfirmed: true)
64
+ #else
65
+ let latest = target
66
+ let keyboardVisibleAtEntry = keyboardVisibleBeforeTap ?? isKeyboardVisible(app: app)
67
+ let deadline = Date().addingTimeInterval(TextEntryTiming.focusTimeout)
68
+ while Date() < deadline {
69
+ if let focused = focusedTextInput(app: app) {
70
+ return TextEntryStabilization(element: focused, focusConfirmed: true)
71
+ }
72
+
73
+
74
+ if keyboardBecameVisible(app: app, wasVisibleAtEntry: keyboardVisibleAtEntry) {
75
+ return TextEntryStabilization(element: latest, focusConfirmed: true)
76
+ }
77
+ sleepFor(TextEntryTiming.pollInterval)
78
+ }
79
+ return TextEntryStabilization(element: latest, focusConfirmed: false)
80
+ #endif
81
+ }
82
+
83
+ func focusTextInputForTextEntry(app: XCUIApplication, x: Double?, y: Double?) -> TextEntryTarget {
84
+ guard let x, let y else {
85
+ let softwareKeyboardVisible = isKeyboardVisible(app: app)
86
+ if !softwareKeyboardVisible, let rememberedTarget = rememberedTextEntryTarget() {
87
+ return rememberedTarget
88
+ }
89
+
90
+
91
+
92
+
93
+ if softwareKeyboardVisible {
94
+ return TextEntryTarget(
95
+ element: focusedTextInput(app: app),
96
+ refreshPoint: nil,
97
+ prefersFocusedElement: true
98
+ )
99
+ }
100
+ let focused = waitForTextEntryReadiness(
101
+ app: app,
102
+ target: TextEntryTarget(
103
+ element: focusedTextInput(app: app),
104
+ refreshPoint: nil,
105
+ prefersFocusedElement: true
106
+ )
107
+ )
108
+ return TextEntryTarget(element: focused, refreshPoint: nil, prefersFocusedElement: true)
109
+ }
110
+
111
+ let keyboardVisibleBeforeTap = isKeyboardVisible(app: app)
112
+ let target = textInputAt(app: app, x: x, y: y)
113
+ let requestedPoint = CGPoint(x: x, y: y)
114
+ if let target {
115
+ let frame = target.frame
116
+ if !frame.isEmpty {
117
+ _ = tapAt(app: app, x: frame.midX, y: frame.midY)
118
+ } else {
119
+ _ = tapAt(app: app, x: x, y: y)
120
+ }
121
+ } else {
122
+ _ = tapAt(app: app, x: x, y: y)
123
+ }
124
+
125
+
126
+
127
+ if keyboardVisibleBeforeTap, let target {
128
+ return TextEntryTarget(
129
+ element: target,
130
+ refreshPoint: textEntryRefreshPoint(for: target) ?? requestedPoint,
131
+ prefersFocusedElement: false
132
+ )
133
+ }
134
+ let stabilized = stabilizeTextInputBeforeTyping(
135
+ app: app,
136
+ target: target,
137
+ keyboardVisibleBeforeTap: keyboardVisibleBeforeTap
138
+ )
139
+ let readyTarget = TextEntryTarget(
140
+ element: stabilized.element ?? target,
141
+ refreshPoint: requestedPoint,
142
+ prefersFocusedElement: false
143
+ )
144
+ let concreteTargetReady = keyboardVisibleBeforeTap && readyTarget.element != nil
145
+ let element = stabilized.focusConfirmed || concreteTargetReady
146
+ ? (stabilized.element ?? target)
147
+ : (waitForTextEntryReadiness(app: app, target: readyTarget) ?? stabilized.element ?? target)
148
+ return TextEntryTarget(
149
+ element: element,
150
+ refreshPoint: textEntryRefreshPoint(for: element) ?? requestedPoint,
151
+ prefersFocusedElement: false
152
+ )
153
+ }
154
+
155
+ func focusTextInputForTextEntry(app: XCUIApplication, element: XCUIElement) -> TextEntryTarget {
156
+ let point = textEntryRefreshPoint(for: element)
157
+ let keyboardVisibleBeforeTap = isKeyboardVisible(app: app)
158
+ if let point {
159
+ _ = tapAt(app: app, x: point.x, y: point.y)
160
+ }
161
+
162
+
163
+ if keyboardVisibleBeforeTap {
164
+ return TextEntryTarget(
165
+ element: element,
166
+ refreshPoint: textEntryRefreshPoint(for: element) ?? point,
167
+ prefersFocusedElement: false
168
+ )
169
+ }
170
+ let stabilized = stabilizeTextInputBeforeTyping(
171
+ app: app,
172
+ target: element,
173
+ keyboardVisibleBeforeTap: keyboardVisibleBeforeTap
174
+ )
175
+ let readyTarget = TextEntryTarget(
176
+ element: stabilized.element ?? element,
177
+ refreshPoint: point,
178
+ prefersFocusedElement: false
179
+ )
180
+ let resolved = stabilized.focusConfirmed
181
+ ? (stabilized.element ?? element)
182
+ : (waitForTextEntryReadiness(app: app, target: readyTarget) ?? stabilized.element ?? element)
183
+ return TextEntryTarget(
184
+ element: resolved,
185
+ refreshPoint: textEntryRefreshPoint(for: resolved) ?? point,
186
+ prefersFocusedElement: false
187
+ )
188
+ }
189
+
190
+ private func textEntryRefreshPoint(for element: XCUIElement?) -> CGPoint? {
191
+ guard let element else {
192
+ return nil
193
+ }
194
+ let frame = element.frame
195
+ guard !frame.isEmpty else {
196
+ return nil
197
+ }
198
+ return CGPoint(x: frame.midX, y: frame.midY)
199
+ }
200
+
201
+
202
+
203
+
204
+
205
+
206
+ }
@@ -0,0 +1,158 @@
1
+ import XCTest
2
+
3
+
4
+
5
+
6
+
7
+ extension RunnerTests {
8
+ func focusedTextInput(app: XCUIApplication) -> XCUIElement? {
9
+ #if os(iOS)
10
+
11
+
12
+ return nil
13
+ #else
14
+ return safely("FOCUSED_INPUT_QUERY") {
15
+ let candidates = app
16
+ .descendants(matching: .any)
17
+ .matching(NSPredicate(format: "hasKeyboardFocus == 1"))
18
+ .allElementsBoundByIndex
19
+ for candidate in candidates where candidate.exists {
20
+ switch candidate.elementType {
21
+ case .textField, .secureTextField, .searchField, .textView:
22
+ return candidate
23
+ default:
24
+ continue
25
+ }
26
+ }
27
+ return nil
28
+ }
29
+ #endif
30
+ }
31
+
32
+ func waitForTextEntryReadiness(
33
+ app: XCUIApplication,
34
+ target: TextEntryTarget,
35
+ timeout: TimeInterval = TextEntryTiming.readinessTimeout
36
+ ) -> XCUIElement? {
37
+ #if os(iOS)
38
+ var latest = resolveTextEntryElement(app: app, target: target)
39
+ let keyboardVisibleAtEntry = isKeyboardVisible(app: app)
40
+ let deadline = Date().addingTimeInterval(timeout)
41
+ var hardwareKeyboardFallback = Date().addingTimeInterval(
42
+ min(TextEntryTiming.hardwareKeyboardFallbackTimeout, timeout)
43
+ )
44
+ var sawSoftwareKeyboard = false
45
+ while Date() < deadline {
46
+ if let focused = focusedTextInput(app: app) {
47
+ latest = focused
48
+ if isKeyboardVisible(app: app) {
49
+ return focused
50
+ }
51
+ }
52
+
53
+
54
+
55
+
56
+
57
+ if keyboardBecameVisible(app: app, wasVisibleAtEntry: keyboardVisibleAtEntry) {
58
+ return latest
59
+ }
60
+ sawSoftwareKeyboard = sawSoftwareKeyboard || keyboardElementExists(app: app)
61
+
62
+
63
+
64
+
65
+
66
+
67
+ if !sawSoftwareKeyboard, Date() >= hardwareKeyboardFallback, let candidate = latest {
68
+ if keyboardFocusConfirmed(app: app, element: candidate) {
69
+ return candidate
70
+ }
71
+ hardwareKeyboardFallback = Date().addingTimeInterval(
72
+ TextEntryTiming.hardwareKeyboardFallbackTimeout
73
+ )
74
+ }
75
+ sleepFor(TextEntryTiming.pollInterval)
76
+ }
77
+ return focusedTextInput(app: app) ?? latest
78
+ #else
79
+ return resolveTextEntryElement(app: app, target: target)
80
+ #endif
81
+ }
82
+
83
+ func waitForTextEntryReadinessAfterTap(app: XCUIApplication, element: XCUIElement) {
84
+ #if os(iOS)
85
+ switch element.elementType {
86
+ case .textField, .secureTextField, .searchField, .textView:
87
+ if waitForFocusedTextInput(app: app, timeout: TextEntryTiming.readinessTimeout) != nil {
88
+ return
89
+ }
90
+ let frame = element.frame
91
+ if !frame.isEmpty {
92
+ _ = tapAt(app: app, x: frame.midX, y: frame.midY)
93
+ _ = waitForFocusedTextInput(app: app, timeout: TextEntryTiming.readinessTimeout)
94
+ }
95
+ default:
96
+ return
97
+ }
98
+ #endif
99
+ }
100
+
101
+ private func waitForFocusedTextInput(app: XCUIApplication, timeout: TimeInterval) -> XCUIElement? {
102
+ let deadline = Date().addingTimeInterval(timeout)
103
+ while Date() < deadline {
104
+ if let focused = focusedTextInput(app: app) {
105
+ return focused
106
+ }
107
+ sleepFor(TextEntryTiming.pollInterval)
108
+ }
109
+ return focusedTextInput(app: app)
110
+ }
111
+
112
+ func keyboardBecameVisible(app: XCUIApplication, wasVisibleAtEntry: Bool) -> Bool {
113
+ return !wasVisibleAtEntry && isKeyboardVisible(app: app)
114
+ }
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+
124
+
125
+
126
+
127
+ func keyboardFocusConfirmed(app: XCUIApplication, element: XCUIElement) -> Bool {
128
+ #if os(iOS)
129
+ return safely("TEXT_ENTRY_FOCUS_CONFIRMED", false) {
130
+
131
+
132
+
133
+ let frame = element.frame
134
+ guard !frame.isEmpty else {
135
+ return false
136
+ }
137
+ let focused = app
138
+ .descendants(matching: .any)
139
+ .matching(NSPredicate(format: "hasKeyboardFocus == 1"))
140
+ .firstMatch
141
+ guard focused.exists else {
142
+ return false
143
+ }
144
+ return focused.identifier == element.identifier && focused.frame == frame
145
+ }
146
+ #else
147
+ return false
148
+ #endif
149
+ }
150
+
151
+ private func keyboardElementExists(app: XCUIApplication) -> Bool {
152
+ #if os(iOS)
153
+ return safely("KEYBOARD_EXISTS", false) { app.keyboards.firstMatch.exists }
154
+ #else
155
+ return false
156
+ #endif
157
+ }
158
+ }
@@ -0,0 +1,101 @@
1
+ import XCTest
2
+
3
+ final class TextInputProbeIssues {
4
+ let thread = Thread.current
5
+ var count = 0
6
+ }
7
+
8
+ enum TextInputProbeFailure: String {
9
+ case recordedIssue = "text_input_probe_recorded_issue"
10
+ case exception = "text_input_probe_exception"
11
+ }
12
+
13
+ enum TextInputProbeOutcome {
14
+ case matches([XCUIElement])
15
+ case absent
16
+ case unavailable(TextInputProbeFailure)
17
+ }
18
+
19
+ extension RunnerTests {
20
+ func textInputAt(app: XCUIApplication, x: Double, y: Double) -> XCUIElement? {
21
+ textInputCandidatesAt(app: app, point: CGPoint(x: x, y: y)).first
22
+ }
23
+
24
+ func textInputCandidatesAt(app: XCUIApplication, point: CGPoint) -> [XCUIElement] {
25
+ safely("TEXT_INPUT_AT_POINT", []) {
26
+ queryTextInputs(app: app, point: point, shouldStop: { false })
27
+ }
28
+ }
29
+
30
+ func coordinateTapTextInputAt(app: XCUIApplication, x: Double, y: Double) -> XCUIElement? {
31
+ switch probeTextInputs(app: app, point: CGPoint(x: x, y: y)) {
32
+ case .matches(let elements):
33
+ return elements.first
34
+ case .absent:
35
+ return nil
36
+ case .unavailable:
37
+ return nil
38
+ }
39
+ }
40
+
41
+ func probeTextInputs(app: XCUIApplication, point: CGPoint) -> TextInputProbeOutcome {
42
+ precondition(Thread.isMainThread)
43
+ let issues = TextInputProbeIssues()
44
+ suppressedIssueLock.lock()
45
+ let previous = textInputProbeIssues
46
+ textInputProbeIssues = issues
47
+ suppressedIssueLock.unlock()
48
+ defer {
49
+ suppressedIssueLock.lock()
50
+ textInputProbeIssues = previous
51
+ suppressedIssueLock.unlock()
52
+ }
53
+ let (elements, exception) = catchingObjCException(fallback: []) {
54
+ queryTextInputs(app: app, point: point, shouldStop: { self.hasTextInputProbeIssues(issues) })
55
+ }
56
+ if hasTextInputProbeIssues(issues) { return .unavailable(.recordedIssue) }
57
+ if exception != nil { return .unavailable(.exception) }
58
+ return elements.isEmpty ? .absent : .matches(elements)
59
+ }
60
+
61
+ private func hasTextInputProbeIssues(_ scope: TextInputProbeIssues) -> Bool {
62
+ suppressedIssueLock.lock()
63
+ defer { suppressedIssueLock.unlock() }
64
+ return scope.count > 0
65
+ }
66
+
67
+ func containTextInputProbeIssue(_ issue: XCTIssue) -> Bool {
68
+ suppressedIssueLock.lock()
69
+ guard let scope = textInputProbeIssues, scope.thread === Thread.current else {
70
+ suppressedIssueLock.unlock()
71
+ return false
72
+ }
73
+ scope.count += 1
74
+ suppressedIssueLock.unlock()
75
+ NSLog("AGENT_DEVICE_RUNNER_TEXT_INPUT_PROBE_UNAVAILABLE issue=%@", issue.compactDescription)
76
+ return true
77
+ }
78
+
79
+ private func queryTextInputs(
80
+ app: XCUIApplication,
81
+ point: CGPoint,
82
+ shouldStop: () -> Bool
83
+ ) -> [XCUIElement] {
84
+ var candidates: [XCUIElement] = []
85
+ for query in [app.textFields, app.secureTextFields, app.searchFields, app.textViews] {
86
+ if shouldStop() { break }
87
+ candidates.append(contentsOf: query.allElementsBoundByIndex)
88
+
89
+
90
+
91
+
92
+
93
+
94
+ }
95
+ guard !shouldStop() else { return [] }
96
+ return candidates.filter { element in
97
+ guard !shouldStop(), element.exists else { return false }
98
+ return isCoordinateTextInputCandidate(enabled: element.isEnabled, frame: element.frame, point: point)
99
+ }.sorted(by: smallestElementFirst)
100
+ }
101
+ }
@@ -1,7 +1,7 @@
1
1
  import XCTest
2
2
 
3
- // Text typing, verification, and repair. Kept separate from focus/readiness so each
4
- // text-entry policy remains a bounded review surface.
3
+
4
+
5
5
  extension RunnerTests {
6
6
  func typeTextReliably(
7
7
  app: XCUIApplication,
@@ -15,6 +15,36 @@ extension RunnerTests {
15
15
  ) -> TextEntryResult {
16
16
  let totalStartedAt = Date()
17
17
  guard !text.isEmpty else {
18
+
19
+
20
+
21
+
22
+ if repairMode == .replacement {
23
+ guard let clearTarget = resolveTextEntryElement(app: app, target: target) else {
24
+
25
+
26
+
27
+ logTextEntryPhase(commandId: commandId, phase: "total", startedAt: totalStartedAt, chars: 0, mode: repairMode)
28
+ return TextEntryResult(
29
+ verified: nil,
30
+ repaired: false,
31
+ expectedText: "",
32
+ observedText: nil,
33
+ failure: .notFocused
34
+ )
35
+ }
36
+ clearTextInput(clearTarget)
37
+
38
+
39
+ let observed = editableTextValue(for: clearTarget, treatingPlaceholderAsEmpty: true)
40
+ logTextEntryPhase(commandId: commandId, phase: "total", startedAt: totalStartedAt, chars: 0, mode: repairMode)
41
+ return TextEntryResult(
42
+ verified: observed.map { $0.isEmpty },
43
+ repaired: false,
44
+ expectedText: "",
45
+ observedText: observed
46
+ )
47
+ }
18
48
  logTextEntryPhase(commandId: commandId, phase: "total", startedAt: totalStartedAt, chars: 0, mode: repairMode)
19
49
  return TextEntryResult(verified: true, repaired: false, expectedText: "", observedText: "")
20
50
  }
@@ -65,9 +95,9 @@ extension RunnerTests {
65
95
  mode: repairMode
66
96
  )
67
97
 
68
- // Dispatching text through XCTest without a resolved target or evidence of a focused
69
- // responder records a test failure. That tears down the long-lived runner and turns a
70
- // single invalid request into a restart cascade, so fail before entering that channel.
98
+
99
+
100
+
71
101
  guard initialTarget != nil || (activeTarget.prefersFocusedElement && isKeyboardVisible(app: app)) else {
72
102
  logTextEntryPhase(
73
103
  commandId: commandId,
@@ -104,20 +134,20 @@ extension RunnerTests {
104
134
  }
105
135
  }
106
136
 
107
- func typeIntoCurrentTarget(_ value: String) -> (element: XCUIElement?, dispatched: Bool, failure: TextEntryFailure?) {
137
+ func typeIntoCurrentTarget(_ value: String) -> (element: XCUIElement?, failure: TextEntryFailure?) {
108
138
  #if os(iOS)
109
139
  if shouldUseSynthesizedFirstResponderType {
110
140
  guard let currentTarget = resolveTextEntryElement(app: app, target: activeTarget) else {
111
- return (nil, false, .notFocused)
141
+ return (nil, .notFocused)
112
142
  }
113
143
  textEntryRoute = "synthesized-first-responder"
114
144
  NSLog("AGENT_DEVICE_RUNNER_TEXT_ENTRY_ROUTE route=synthesized-first-responder")
115
145
  let textBefore = editableTextValue(for: currentTarget, treatingPlaceholderAsEmpty: true)
116
146
  switch synthesizer.enterText(app: app, text: value, replacingExistingText: false) {
117
147
  case .continueTyping:
118
- // No refresh point: like the tap-witness target itself, the commit wait must observe
119
- // only the element the tap selected, never rediscover a different field.
120
- awaitSynthesizedFirstResponderCommit(
148
+
149
+
150
+ let commit = awaitSynthesizedFirstResponderCommit(
121
151
  app: app,
122
152
  target: TextEntryTarget(
123
153
  element: currentTarget,
@@ -128,9 +158,12 @@ extension RunnerTests {
128
158
  textBefore: textBefore,
129
159
  typedText: value
130
160
  )
131
- return (currentTarget, true, nil)
161
+
162
+
163
+
164
+ return (currentTarget, Self.textEntryFailure(forCommitOutcome: commit))
132
165
  case .fallback:
133
- return (nil, false, .synthesisUnavailable)
166
+ return (nil, .synthesisUnavailable)
134
167
  case .raise(let message):
135
168
  NSException(
136
169
  name: NSExceptionName.internalInconsistencyException,
@@ -142,7 +175,7 @@ extension RunnerTests {
142
175
  if let currentTarget = resolveTextEntryElement(app: app, target: activeTarget) {
143
176
  textEntryRoute = "xctest-element"
144
177
  currentTarget.typeText(value)
145
- return (currentTarget, true, nil)
178
+ return (currentTarget, nil)
146
179
  } else if activeTarget.prefersFocusedElement && isKeyboardVisible(app: app) {
147
180
  #if os(iOS)
148
181
  textEntryRoute = "synthesized-first-responder"
@@ -167,9 +200,9 @@ extension RunnerTests {
167
200
  #else
168
201
  app.typeText(value)
169
202
  #endif
170
- return (resolveTextEntryElement(app: app, target: activeTarget), true, nil)
203
+ return (resolveTextEntryElement(app: app, target: activeTarget), nil)
171
204
  }
172
- return (nil, false, .notFocused)
205
+ return (nil, .notFocused)
173
206
  }
174
207
 
175
208
  func dispatchFailureResult(_ failure: TextEntryFailure) -> TextEntryResult {
@@ -203,8 +236,8 @@ extension RunnerTests {
203
236
  let delayedTypeStartedAt = Date()
204
237
  for (index, character) in characters.enumerated() {
205
238
  let dispatch = typeIntoCurrentTarget(String(character))
206
- guard dispatch.dispatched else {
207
- return dispatchFailureResult(dispatch.failure ?? .notFocused)
239
+ if let failure = dispatch.failure {
240
+ return dispatchFailureResult(failure)
208
241
  }
209
242
  typedTarget = dispatch.element ?? typedTarget
210
243
  if index + 1 < characters.count {
@@ -252,8 +285,8 @@ extension RunnerTests {
252
285
  let firstCharacter = String(characters[0])
253
286
  let firstStartedAt = Date()
254
287
  let firstDispatch = typeIntoCurrentTarget(firstCharacter)
255
- guard firstDispatch.dispatched else {
256
- return dispatchFailureResult(firstDispatch.failure ?? .notFocused)
288
+ if let failure = firstDispatch.failure {
289
+ return dispatchFailureResult(failure)
257
290
  }
258
291
  var firstTypedTarget = firstDispatch.element
259
292
  logTextEntryPhase(
@@ -281,8 +314,8 @@ extension RunnerTests {
281
314
  let remainingText = String(characters.dropFirst())
282
315
  let remainingStartedAt = Date()
283
316
  let remainingDispatch = typeIntoCurrentTarget(remainingText)
284
- guard remainingDispatch.dispatched else {
285
- return dispatchFailureResult(remainingDispatch.failure ?? .notFocused)
317
+ if let failure = remainingDispatch.failure {
318
+ return dispatchFailureResult(failure)
286
319
  }
287
320
  firstTypedTarget = remainingDispatch.element ?? firstTypedTarget
288
321
  logTextEntryPhase(
@@ -296,8 +329,8 @@ extension RunnerTests {
296
329
  } else {
297
330
  let typeStartedAt = Date()
298
331
  let dispatch = typeIntoCurrentTarget(text)
299
- guard dispatch.dispatched else {
300
- return dispatchFailureResult(dispatch.failure ?? .notFocused)
332
+ if let failure = dispatch.failure {
333
+ return dispatchFailureResult(failure)
301
334
  }
302
335
  typedTarget = dispatch.element
303
336
  logTextEntryPhase(