agent-device 0.20.10 → 0.21.0

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 (490) 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.0.apk} +0 -0
  3. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.0.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.0.manifest.json} +4 -4
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.0.apk +0 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.0.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.0.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 +49 -0
  12. package/apple/snapshot-bridge/SnapshotBridge.m +280 -0
  13. package/apple/snapshot-bridge/SnapshotBridgeRuntime.h +33 -0
  14. package/apple/snapshot-bridge/SnapshotBridgeRuntime.m +382 -0
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +58 -0
  16. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +19 -0
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAlertVerification.swift +36 -0
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerStringNormalization.swift +8 -0
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +12 -1
  20. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +100 -6
  21. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +2 -2
  22. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +16 -8
  23. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +21 -88
  24. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AlertObservation.swift +124 -0
  25. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +106 -103
  26. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +6 -14
  27. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +63 -91
  28. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +13 -6
  29. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +72 -155
  30. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXElementTypes.swift +12 -0
  31. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +74 -78
  32. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +17 -9
  33. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +42 -11
  34. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +185 -461
  35. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotBackendCapabilities.swift +98 -0
  36. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +224 -164
  37. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentationInvariant.swift +19 -0
  38. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTiming.swift +110 -0
  39. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedCommitDeadline.swift +206 -0
  40. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +147 -25
  41. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +1 -0
  42. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +24 -307
  43. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +206 -0
  44. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryReadiness.swift +158 -0
  45. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +49 -16
  46. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +2 -11
  47. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +4 -19
  48. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +16 -20
  49. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/RecordingExportSupport.swift +111 -0
  50. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +42 -81
  51. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-trim.swift +35 -82
  52. package/dist/apple/snapshot-presentation/Package.swift +21 -0
  53. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotGeometry.swift +56 -0
  54. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotModels.swift +259 -0
  55. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentation.swift +153 -0
  56. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationFailure.swift +27 -0
  57. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationInvariant.swift +91 -0
  58. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationProjection.swift +161 -0
  59. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotScopePolicy.swift +53 -0
  60. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFold.swift +242 -0
  61. package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFoldProjection.swift +97 -0
  62. package/dist/src/adapter.js +1 -0
  63. package/dist/src/adb-executor.js +2 -0
  64. package/dist/src/adb-failure.js +1 -0
  65. package/dist/src/adb-host.js +1 -0
  66. package/dist/src/adb.js +1 -0
  67. package/dist/src/agent-browser-lifecycle.js +1 -0
  68. package/dist/src/agent-browser-process-record.js +1 -0
  69. package/dist/src/agent-browser-provider.js +1 -0
  70. package/dist/src/agent-browser-tool.js +1 -1
  71. package/dist/src/agent-device-client.js +2 -2
  72. package/dist/src/ai-sdk.d.ts +2 -2
  73. package/dist/src/ai-sdk.js +1 -1
  74. package/dist/src/alert-contract.js +1 -0
  75. package/dist/src/alert-runtime.js +1 -0
  76. package/dist/src/android-adb.d.ts +27 -19
  77. package/dist/src/android-adb.js +1 -1
  78. package/dist/src/android-input-ownership.js +1 -0
  79. package/dist/src/android-system-chrome.js +1 -0
  80. package/dist/src/android.js +1 -1
  81. package/dist/src/api.js +11 -0
  82. package/dist/src/app-catalog.js +1 -0
  83. package/dist/src/app-deployment-resolution.js +2 -0
  84. package/dist/src/app-helpers.js +1 -1
  85. package/dist/src/app-inventory-contract.js +1 -0
  86. package/dist/src/app-inventory.js +1 -0
  87. package/dist/src/app-launch.js +2 -0
  88. package/dist/src/app-lifecycle-facade.js +1 -0
  89. package/dist/src/app-lifecycle.js +3 -6
  90. package/dist/src/app-lifecycle2.js +2 -2
  91. package/dist/src/app-lifecycle3.js +1 -0
  92. package/dist/src/app-log-files.js +1 -1
  93. package/dist/src/app-log-reconnect.js +1 -1
  94. package/dist/src/app-log-runtime.js +1 -4
  95. package/dist/src/app-log-runtime2.js +4 -0
  96. package/dist/src/app-parsers.js +4 -0
  97. package/dist/src/app-resolution-cache.js +1 -0
  98. package/dist/src/app-resolution-facade.js +1 -0
  99. package/dist/src/app-resolution.js +2 -2
  100. package/dist/src/app-state.js +1 -2
  101. package/dist/src/application-lifecycle-interaction.js +1 -0
  102. package/dist/src/application-lifecycle-runtime.js +1 -0
  103. package/dist/src/apps-simctl.js +1 -0
  104. package/dist/src/archive.js +4 -0
  105. package/dist/src/artifact-download.js +1 -0
  106. package/dist/src/artifacts.d.ts +6 -2
  107. package/dist/src/artifacts.js +1 -1
  108. package/dist/src/async-lifecycle.js +1 -0
  109. package/dist/src/audio-probe-result.js +1 -0
  110. package/dist/src/audio-probe-runtime.js +1 -0
  111. package/dist/src/audio-probe-support.js +1 -0
  112. package/dist/src/auth-session.js +1 -1
  113. package/dist/src/auth.js +1 -1
  114. package/dist/src/back-mode.js +1 -0
  115. package/dist/src/{url.js → base-url.js} +1 -1
  116. package/dist/src/boot-diagnostics.js +2 -2
  117. package/dist/src/byte-limit-stream.js +1 -1
  118. package/dist/src/capabilities.js +1 -0
  119. package/dist/src/capture.js +1 -0
  120. package/dist/src/catalog.js +1 -0
  121. package/dist/src/cli-command-aliases.js +1 -0
  122. package/dist/src/cli-config.js +1 -1
  123. package/dist/src/cli-help.js +69 -50
  124. package/dist/src/cli-output.js +1 -1
  125. package/dist/src/cli-runner.js +1 -1
  126. package/dist/src/cli.js +4 -6
  127. package/dist/src/click-button.js +1 -0
  128. package/dist/src/client-metro-companion.js +1 -0
  129. package/dist/src/client-metro.js +1 -1
  130. package/dist/src/client-types.d.ts +255 -231
  131. package/dist/src/clipboard.js +1 -0
  132. package/dist/src/code-signature-cache.js +1 -0
  133. package/dist/src/code-signature.js +1 -0
  134. package/dist/src/color.js +1 -0
  135. package/dist/src/command-metadata.js +1 -1
  136. package/dist/src/command-schema.js +3 -3
  137. package/dist/src/command-surface.js +1 -1
  138. package/dist/src/command-tools.js +2 -2
  139. package/dist/src/command.js +1 -0
  140. package/dist/src/compatibility-policy.js +1 -0
  141. package/dist/src/config.js +1 -1
  142. package/dist/src/config2.js +1 -0
  143. package/dist/src/connection-runtime.js +1 -1
  144. package/dist/src/connection.js +5 -5
  145. package/dist/src/contracts.d.ts +1 -1
  146. package/dist/src/contracts.js +1 -1
  147. package/dist/src/daemon-client-lifecycle.js +1 -0
  148. package/dist/src/daemon-process.js +1 -0
  149. package/dist/src/daemon-registration.js +1 -0
  150. package/dist/src/daemon-shutdown-report.js +1 -1
  151. package/dist/src/daemon.js +2 -2
  152. package/dist/src/debug-symbols-facade.js +5 -0
  153. package/dist/src/deploy-result-target.js +1 -0
  154. package/dist/src/device-claim-inspection.js +1 -1
  155. package/dist/src/device-claim-rule.js +1 -0
  156. package/dist/src/device-input-state.d.ts +190 -3
  157. package/dist/src/device-inventory-context.js +1 -0
  158. package/dist/src/device-isolation.js +1 -0
  159. package/dist/src/device-release.js +1 -0
  160. package/dist/src/device-rotation.js +1 -0
  161. package/dist/src/device-selection-resolver.js +1 -0
  162. package/dist/src/device-session.js +1 -0
  163. package/dist/src/device.js +1 -1
  164. package/dist/src/device2.js +3 -2
  165. package/dist/src/diagnostics.js +3 -0
  166. package/dist/src/diagnostics2.js +1 -0
  167. package/dist/src/dispatch-resolve.js +1 -0
  168. package/dist/src/doctor-facade.js +1 -0
  169. package/dist/src/doctor-output.js +1 -0
  170. package/dist/src/doctor.js +1 -0
  171. package/dist/src/doctor2.js +1 -0
  172. package/dist/src/doctor3.js +1 -0
  173. package/dist/src/durable-resource.js +1 -0
  174. package/dist/src/entities.js +1 -1
  175. package/dist/src/error.js +2 -0
  176. package/dist/src/exec.js +1 -0
  177. package/dist/src/file.js +1 -0
  178. package/dist/src/find.js +1 -1
  179. package/dist/src/finders.js +1 -1
  180. package/dist/src/format.js +2 -0
  181. package/dist/src/generic-settle.js +1 -1
  182. package/dist/src/generic.js +1 -1
  183. package/dist/src/gesture-admission.js +1 -0
  184. package/dist/src/gesture-plan-types.js +1 -0
  185. package/dist/src/gesture-plan.js +1 -0
  186. package/dist/src/gesture-runtime.js +1 -0
  187. package/dist/src/harmonyos.js +1 -1
  188. package/dist/src/hdc.js +1 -1
  189. package/dist/src/helper.js +2 -2
  190. package/dist/src/host-file.js +1 -0
  191. package/dist/src/human-control-contract.js +1 -0
  192. package/dist/src/human-control.js +1 -0
  193. package/dist/src/index.d.ts +1 -1
  194. package/dist/src/index.js +1 -1
  195. package/dist/src/input-actions.js +1 -4
  196. package/dist/src/input-actions2.js +2 -1
  197. package/dist/src/install-artifact-facade.js +1 -0
  198. package/dist/src/install-source-network-transport.js +1 -0
  199. package/dist/src/install-source.d.ts +3 -10
  200. package/dist/src/install-source2.js +1 -1
  201. package/dist/src/interaction-positionals.js +1 -0
  202. package/dist/src/interaction-ref-policy.js +1 -0
  203. package/dist/src/interaction.js +1 -1
  204. package/dist/src/interaction2.js +1 -1
  205. package/dist/src/interactor-operation-catalog.js +1 -0
  206. package/dist/src/interactor-types.js +1 -0
  207. package/dist/src/interactor.js +6 -2
  208. package/dist/src/interactor2.js +1 -1
  209. package/dist/src/interactors.js +1 -1
  210. package/dist/src/internal/bin.d.ts +1 -1
  211. package/dist/src/internal/bin.js +1 -2
  212. package/dist/src/internal/companion-tunnel.d.ts +1 -1
  213. package/dist/src/internal/companion-tunnel.js +1 -1
  214. package/dist/src/internal/daemon.d.ts +1 -1
  215. package/dist/src/internal/daemon.js +2 -4
  216. package/dist/src/internal/png-worker.d.ts +4 -4
  217. package/dist/src/internal/png-worker.js +1 -1
  218. package/dist/src/internal/run-script-http-child.d.ts +4 -0
  219. package/dist/src/internal/run-script-http-child.js +1 -0
  220. package/dist/src/internal/update-check-entry.d.ts +1 -1
  221. package/dist/src/inventory.js +4 -4
  222. package/dist/src/inventory2.js +1 -1
  223. package/dist/src/inventory3.js +1 -1
  224. package/dist/src/inventory5.js +1 -1
  225. package/dist/src/inventory6.js +1 -1
  226. package/dist/src/ios-client.js +16 -0
  227. package/dist/src/ios-snapshot-acquisition.js +1 -0
  228. package/dist/src/ios-snapshot-adapter.js +1 -0
  229. package/dist/src/ios-snapshot-planning.js +1 -0
  230. package/dist/src/ios-snapshot-runtime.js +1 -0
  231. package/dist/src/json.js +1 -0
  232. package/dist/src/keyboard-actions.js +1 -0
  233. package/dist/src/launch-console.js +1 -0
  234. package/dist/src/lease-context.js +1 -1
  235. package/dist/src/lease-scope.js +1 -0
  236. package/dist/src/lease.js +1 -1
  237. package/dist/src/limrun-runtime-dependencies.js +1 -1
  238. package/dist/src/limrun.d.ts +1610 -7
  239. package/dist/src/limrun.js +1 -1
  240. package/dist/src/linux.js +1 -1
  241. package/dist/src/local-interactor-operation-set.js +1 -0
  242. package/dist/src/location-coordinates.js +1 -1
  243. package/dist/src/logcat.js +1 -1
  244. package/dist/src/macos-facade.js +1 -0
  245. package/dist/src/managed-device-scope.js +1 -0
  246. package/dist/src/mechanics.js +19 -0
  247. package/dist/src/metro.d.ts +4 -2
  248. package/dist/src/metro.js +1 -1
  249. package/dist/src/metro2.js +1 -1
  250. package/dist/src/mobile-snapshot-semantics.js +1 -1
  251. package/dist/src/multitouch-support.js +1 -0
  252. package/dist/src/numeric.js +1 -0
  253. package/dist/src/observability.js +1 -1
  254. package/dist/src/observation.js +2 -0
  255. package/dist/src/output-path.js +1 -1
  256. package/dist/src/owner-identity.js +3 -1
  257. package/dist/src/parameterized-recorded-fill.js +1 -0
  258. package/dist/src/parser.js +1 -1
  259. package/dist/src/perf-facade.js +2 -0
  260. package/dist/src/perf-runtime-operation-builder.js +1 -0
  261. package/dist/src/perf-runtime-plan.js +1 -0
  262. package/dist/src/perf-runtime.js +1 -0
  263. package/dist/src/perf.js +1 -4
  264. package/dist/src/physical-device-control.js +1 -1
  265. package/dist/src/physical-device-facade.js +1 -0
  266. package/dist/src/platform-request-scope.js +1 -0
  267. package/dist/src/platform-runtime-android-adb-host.js +1 -0
  268. package/dist/src/platform-runtime-android-mechanics.js +1 -0
  269. package/dist/src/platform-runtime-app-log-android-transport.js +1 -1
  270. package/dist/src/platform-runtime-app-log-process.js +1 -1
  271. package/dist/src/platform-runtime-apple-resources.js +1 -0
  272. package/dist/src/platform-runtime-host.js +1 -1
  273. package/dist/src/platform-runtime-managed-owner.js +1 -0
  274. package/dist/src/platform-runtime-network-web-transport.js +1 -1
  275. package/dist/src/platform-runtime-open-target.js +1 -1
  276. package/dist/src/platform-runtime-operation-host.js +4 -4
  277. package/dist/src/platform-runtime-runtime-hints.js +2 -2
  278. package/dist/src/platform-runtime-screen-recording-android-host.js +1 -1
  279. package/dist/src/platform-runtime-screen-recording-apple-runner-host.js +1 -1
  280. package/dist/src/platform-runtime-screen-recording-apple-runner-transport.js +1 -1
  281. package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -1
  282. package/dist/src/platform-runtime-screen-recording-apple-transport.js +1 -1
  283. package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
  284. package/dist/src/platform-runtime-screen-recording-harmony-host.js +1 -1
  285. package/dist/src/platform-runtime-screen-recording-process-host.js +1 -0
  286. package/dist/src/platform-runtime-screen-recording-web-host.js +1 -1
  287. package/dist/src/platform-runtime-unavailable.js +1 -0
  288. package/dist/src/platform-runtime.js +1 -1
  289. package/dist/src/platform-runtime2.js +1 -1
  290. package/dist/src/plist.js +1 -1
  291. package/dist/src/png-worker-contract.js +1 -1
  292. package/dist/src/prepare-kind.js +1 -0
  293. package/dist/src/process-exit.js +1 -1
  294. package/dist/src/process.js +1 -0
  295. package/dist/src/provider-device-runtime.js +1 -0
  296. package/dist/src/provider-session-ownership.js +2 -0
  297. package/dist/src/provider-webdriver.js +1 -1
  298. package/dist/src/provider.js +1 -1
  299. package/dist/src/providers.js +1 -0
  300. package/dist/src/proxy.js +2 -2
  301. package/dist/src/react-native-overlay.js +1 -0
  302. package/dist/src/react-native.js +1 -1
  303. package/dist/src/record-runtime.js +1 -1
  304. package/dist/src/record-trace.js +1 -1
  305. package/dist/src/rect-center.js +1 -0
  306. package/dist/src/register-builtins.js +1 -0
  307. package/dist/src/registry.js +39 -28
  308. package/dist/src/remote-config2.js +1 -1
  309. package/dist/src/replay-divergence.js +2 -0
  310. package/dist/src/replay.js +2 -2
  311. package/dist/src/reporting.js +8 -8
  312. package/dist/src/request-admission.js +1 -0
  313. package/dist/src/request-cancel.js +1 -0
  314. package/dist/src/request-cancellation.js +1 -0
  315. package/dist/src/request-progress-protocol.js +1 -0
  316. package/dist/src/request-providers.js +1 -0
  317. package/dist/src/request-runtime-binding.js +1 -0
  318. package/dist/src/request.js +1 -0
  319. package/dist/src/result-serialization.js +1 -0
  320. package/dist/src/retry.js +1 -0
  321. package/dist/src/rolldown-runtime.js +1 -1
  322. package/dist/src/runner-cache-metadata.js +2 -0
  323. package/dist/src/runner-client.js +1 -1
  324. package/dist/src/runner-disposal.js +1 -1
  325. package/dist/src/runner-operations-facade.js +1 -0
  326. package/dist/src/runner-owner-facade.js +1 -0
  327. package/dist/src/runner-owner-state.js +1 -0
  328. package/dist/src/runner-presentation.js +1 -0
  329. package/dist/src/runner-selector-query.js +1 -0
  330. package/dist/src/runner.js +1 -0
  331. package/dist/src/{runtime-transport.js → runtime-transport-hints.js} +1 -1
  332. package/dist/src/runtime.js +3 -3
  333. package/dist/src/runtime2.js +4 -4
  334. package/dist/src/runtime3.js +1 -1
  335. package/dist/src/runtime4.js +4 -3
  336. package/dist/src/runtime5.js +1 -1
  337. package/dist/src/runtime6.js +1 -1
  338. package/dist/src/runtime7.js +1 -1
  339. package/dist/src/runtime8.js +1 -1
  340. package/dist/src/runtime9.js +1 -1
  341. package/dist/src/scoped-provider.js +1 -1
  342. package/dist/src/screen-recording-completion.js +1 -0
  343. package/dist/src/screen-recording-live-handle.js +1 -0
  344. package/dist/src/screen-recording-options.js +1 -0
  345. package/dist/src/screen-recording-resource-recovery.js +1 -0
  346. package/dist/src/screen-recording-runtime.js +1 -0
  347. package/dist/src/screenshot-density.js +1 -1
  348. package/dist/src/screenshot-result.js +1 -6
  349. package/dist/src/screenshot-runtime.js +1 -0
  350. package/dist/src/screenshot.js +1 -1
  351. package/dist/src/screenshot2.js +1 -0
  352. package/dist/src/screenshot3.js +5 -0
  353. package/dist/src/script.js +1 -0
  354. package/dist/src/scroll-command.js +1 -0
  355. package/dist/src/scroll-gesture.js +1 -0
  356. package/dist/src/scroll-indicator.js +1 -0
  357. package/dist/src/sdk-batch-runner.d.ts +23 -6
  358. package/dist/src/sdk-batch-runner.js +2 -3
  359. package/dist/src/sdk-batch.js +2 -0
  360. package/dist/src/sdk-contracts.d.ts +127 -41
  361. package/dist/src/sdk-contracts.js +2 -2
  362. package/dist/src/sdk-device.js +1 -1
  363. package/dist/src/sdk-finders.js +1 -1
  364. package/dist/src/sdk-io.js +1 -1
  365. package/dist/src/sdk-remote-config.d.ts +1 -1
  366. package/dist/src/sdk-remote-config.js +1 -1
  367. package/dist/src/sdk-selectors.d.ts +472 -144
  368. package/dist/src/sdk-selectors.js +1 -1
  369. package/dist/src/selection.js +1 -0
  370. package/dist/src/selector-runtime.js +1 -1
  371. package/dist/src/selectors.js +1 -1
  372. package/dist/src/semantic-index.js +1 -0
  373. package/dist/src/server.js +4 -4
  374. package/dist/src/session-allocation.js +1 -0
  375. package/dist/src/session-artifact-paths.js +1 -0
  376. package/dist/src/session-paths.js +1 -0
  377. package/dist/src/session-repair-tombstone.js +1 -0
  378. package/dist/src/session-routing.js +1 -0
  379. package/dist/src/session-runtime-admission.js +1 -0
  380. package/dist/src/session-snapshot.js +1 -0
  381. package/dist/src/session-store.js +4 -0
  382. package/dist/src/session-target-evidence.js +1 -1
  383. package/dist/src/session2.js +5 -27
  384. package/dist/src/settings.js +1 -0
  385. package/dist/src/shared.js +2 -2
  386. package/dist/src/simctl-facade.js +1 -0
  387. package/dist/src/simctl.js +1 -1
  388. package/dist/src/simulator-facade.js +1 -0
  389. package/dist/src/simulator.js +1 -1
  390. package/dist/src/snapshot-capture-annotations.js +1 -0
  391. package/dist/src/snapshot-desktop-projection.js +1 -0
  392. package/dist/src/snapshot-diagnostics.js +1 -0
  393. package/dist/src/snapshot-process.js +1 -0
  394. package/dist/src/snapshot-quality-backend-capabilities.js +1 -0
  395. package/dist/src/snapshot-quality-verdict.js +1 -0
  396. package/dist/src/snapshot-runtime-binding.js +1 -0
  397. package/dist/src/snapshot-runtime.js +1 -1
  398. package/dist/src/snapshot-scope.js +1 -1
  399. package/dist/src/snapshot-state.js +1 -0
  400. package/dist/src/snapshot.js +1 -8
  401. package/dist/src/snapshot2.js +1 -1
  402. package/dist/src/snapshot3.js +1 -1
  403. package/dist/src/snapshot4.js +1 -0
  404. package/dist/src/src.js +1 -1
  405. package/dist/src/src2.js +1 -1
  406. package/dist/src/src3.js +1 -2
  407. package/dist/src/src4.js +1 -1
  408. package/dist/src/src5.js +1 -0
  409. package/dist/src/src6.js +1 -0
  410. package/dist/src/src7.js +2 -0
  411. package/dist/src/src8.js +115 -0
  412. package/dist/src/startup-recovery-fence.js +1 -0
  413. package/dist/src/status-markers.js +1 -0
  414. package/dist/src/string-enum.js +1 -1
  415. package/dist/src/success-text.js +1 -0
  416. package/dist/src/surface-snapshot.js +1 -0
  417. package/dist/src/surface-snapshot2.js +1 -0
  418. package/dist/src/takeover.js +5 -0
  419. package/dist/src/tool-provider-facade.js +1 -0
  420. package/dist/src/tool-provider.js +4 -3
  421. package/dist/src/tool-provider2.js +1 -1
  422. package/dist/src/tool-provider3.js +1 -1
  423. package/dist/src/toolchain-probe.js +2 -0
  424. package/dist/src/touch-runtime.js +1 -0
  425. package/dist/src/transport.js +3 -0
  426. package/dist/src/tree.js +1 -0
  427. package/dist/src/ttl-memo.js +1 -0
  428. package/dist/src/tv-remote.js +1 -0
  429. package/dist/src/type-text-runtime.js +1 -0
  430. package/dist/src/undici.js +99 -0
  431. package/dist/src/update-check.js +1 -1
  432. package/dist/src/verified-file.js +1 -1
  433. package/dist/src/version.js +1 -1
  434. package/dist/src/video.js +2 -2
  435. package/dist/src/web.js +2 -1
  436. package/dist/src/web2.js +1 -0
  437. package/dist/src/webdriver-ios-snapshot.js +1 -0
  438. package/dist/src/webdriver-source.js +1 -0
  439. package/linux/atspi-dump.py +54 -9
  440. package/package.json +56 -34
  441. package/server.json +9 -3
  442. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.10.apk.sha256 +0 -1
  443. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.10.apk +0 -0
  444. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.10.apk.sha256 +0 -1
  445. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CoordinateTextEntryTests.swift +0 -4
  446. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +0 -168
  447. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+LifecycleCacheTests.swift +0 -6
  448. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+RecordingTests.swift +0 -4
  449. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SelectorMatchPolicyTests.swift +0 -4
  450. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentation.swift +0 -183
  451. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentationTests.swift +0 -0
  452. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTraversalIdentityTests.swift +0 -4
  453. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryPolicyTests.swift +0 -4
  454. package/dist/src/appearance.js +0 -1
  455. package/dist/src/apps.js +0 -5
  456. package/dist/src/audio-probe.js +0 -1
  457. package/dist/src/cli-grammar.js +0 -1
  458. package/dist/src/command-catalog.js +0 -1
  459. package/dist/src/debug-symbols.js +0 -5
  460. package/dist/src/device-input-state.js +0 -2
  461. package/dist/src/device-ready.js +0 -1
  462. package/dist/src/dispatch.js +0 -1
  463. package/dist/src/handler-utils.js +0 -1
  464. package/dist/src/helper-package-install.js +0 -1
  465. package/dist/src/host-process.js +0 -3
  466. package/dist/src/ime-lifecycle.js +0 -2
  467. package/dist/src/ime-recovery-marker.js +0 -1
  468. package/dist/src/input-actions3.js +0 -1
  469. package/dist/src/install-artifact.js +0 -1
  470. package/dist/src/install-artifact2.js +0 -1
  471. package/dist/src/interaction-common.js +0 -1
  472. package/dist/src/interaction-runtime.js +0 -1
  473. package/dist/src/interaction-snapshot.js +0 -1
  474. package/dist/src/manifest.js +0 -1
  475. package/dist/src/method-scope.js +0 -1
  476. package/dist/src/png-resize.js +0 -1
  477. package/dist/src/process-lock.js +0 -1
  478. package/dist/src/runner-lease.js +0 -1
  479. package/dist/src/runner-sequence.js +0 -1
  480. package/dist/src/script-source-bundle.js +0 -16
  481. package/dist/src/sdk-android-adb.d.ts +0 -245
  482. package/dist/src/sdk-android-adb.js +0 -4
  483. package/dist/src/sdk.js +0 -1
  484. package/dist/src/setting-state.js +0 -1
  485. package/dist/src/shell-quote.js +0 -1
  486. package/dist/src/snapshot-session.js +0 -1
  487. package/dist/src/timing-safe-equal.js +0 -1
  488. package/dist/src/unsupported-interactor.js +0 -1
  489. package/dist/src/verdict.js +0 -1
  490. /package/dist/src/{recording-telemetry.js → telemetry.js} +0 -0
@@ -1,4 +1,5 @@
1
1
  import XCTest
2
+ import AgentDeviceSnapshotPresentation
2
3
 
3
4
  extension RunnerTests {
4
5
  private static let axSnapshotErrorCode = "IOS_AX_SNAPSHOT_FAILED"
@@ -15,78 +16,76 @@ extension RunnerTests {
15
16
  let queryRoot: XCUIElement
16
17
  let rootSnapshot: XCUIElementSnapshot
17
18
  let viewport: CGRect
18
- let flatSnapshots: [XCUIElementSnapshot]
19
- let snapshotRanges: [ObjectIdentifier: (Int, Int)]
20
- let maxDepth: Int
21
19
  }
22
20
 
23
21
  private struct SnapshotEvaluation {
24
22
  let label: String
25
23
  let identifier: String
26
24
  let valueText: String?
27
- let hittable: Bool
28
25
  let focused: Bool
29
26
  let selected: Bool
30
- let visible: Bool
31
27
  }
32
28
 
33
29
  private struct SnapshotTraversalEntry {
34
30
  let snapshot: XCUIElementSnapshot
35
31
  let depth: Int
36
- let visibleDepth: Int
37
32
  let parentIndex: Int?
38
- let nearestScrollAnchor: (index: Int, rect: CGRect)?
39
- let projectionCursor: FlatSnapshotProjectionCursor
33
+ let parentPresentedDepth: Int
34
+ let parentTraversal: SnapshotVisibilityFold.TraversalState
40
35
  }
41
36
 
42
37
  struct SnapshotCaptureFailure: Error {
43
38
  let code: String
44
39
  let message: String
45
40
  let hint: String
41
+ let qualityReasonCode: String?
42
+
43
+ init(code: String, message: String, hint: String, qualityReasonCode: String? = nil) {
44
+ self.code = code
45
+ self.message = message
46
+ self.hint = hint
47
+ self.qualityReasonCode = qualityReasonCode
48
+ }
46
49
  }
47
50
 
48
51
  // MARK: - Snapshot Entry
49
52
 
53
+ /// One raw-value table covers public XCTest cases and the SDK-hidden Keyboard/Key values.
54
+ static let elementTypeNamesByRawValue = [
55
+ XCUIElement.ElementType.application.rawValue: "Application",
56
+ XCUIElement.ElementType.window.rawValue: "Window",
57
+ XCUIElement.ElementType.button.rawValue: "Button",
58
+ XCUIElement.ElementType.cell.rawValue: "Cell",
59
+ XCUIElement.ElementType.staticText.rawValue: "StaticText",
60
+ XCUIElement.ElementType.textField.rawValue: "TextField",
61
+ XCUIElement.ElementType.textView.rawValue: "TextView",
62
+ XCUIElement.ElementType.secureTextField.rawValue: "SecureTextField",
63
+ XCUIElement.ElementType.switch.rawValue: "Switch",
64
+ XCUIElement.ElementType.slider.rawValue: "Slider",
65
+ XCUIElement.ElementType.link.rawValue: "Link",
66
+ XCUIElement.ElementType.image.rawValue: "Image",
67
+ XCUIElement.ElementType.navigationBar.rawValue: "NavigationBar",
68
+ XCUIElement.ElementType.tabBar.rawValue: "TabBar",
69
+ XCUIElement.ElementType.collectionView.rawValue: "CollectionView",
70
+ XCUIElement.ElementType.table.rawValue: "Table",
71
+ XCUIElement.ElementType.scrollView.rawValue: "ScrollView",
72
+ XCUIElement.ElementType.toolbar.rawValue: "Toolbar",
73
+ XCUIElement.ElementType.searchField.rawValue: "SearchField",
74
+ XCUIElement.ElementType.segmentedControl.rawValue: "SegmentedControl",
75
+ XCUIElement.ElementType.stepper.rawValue: "Stepper",
76
+ XCUIElement.ElementType.picker.rawValue: "Picker",
77
+ XCUIElement.ElementType.activityIndicator.rawValue: "ActivityIndicator",
78
+ XCUIElement.ElementType.progressIndicator.rawValue: "ProgressIndicator",
79
+ XCUIElement.ElementType.checkBox.rawValue: "CheckBox",
80
+ XCUIElement.ElementType.menuItem.rawValue: "MenuItem",
81
+ XCUIElement.ElementType.webView.rawValue: "WebView",
82
+ XCUIElement.ElementType.other.rawValue: "Other",
83
+ 19: "Keyboard",
84
+ 20: "Key"
85
+ ]
86
+
50
87
  func elementTypeName(_ type: XCUIElement.ElementType) -> String {
51
- switch type {
52
- case .application: return "Application"
53
- case .window: return "Window"
54
- case .button: return "Button"
55
- case .cell: return "Cell"
56
- case .staticText: return "StaticText"
57
- case .textField: return "TextField"
58
- case .textView: return "TextView"
59
- case .secureTextField: return "SecureTextField"
60
- case .switch: return "Switch"
61
- case .slider: return "Slider"
62
- case .link: return "Link"
63
- case .image: return "Image"
64
- case .navigationBar: return "NavigationBar"
65
- case .tabBar: return "TabBar"
66
- case .collectionView: return "CollectionView"
67
- case .table: return "Table"
68
- case .scrollView: return "ScrollView"
69
- case .toolbar: return "Toolbar"
70
- case .searchField: return "SearchField"
71
- case .segmentedControl: return "SegmentedControl"
72
- case .stepper: return "Stepper"
73
- case .picker: return "Picker"
74
- case .activityIndicator: return "ActivityIndicator"
75
- case .progressIndicator: return "ProgressIndicator"
76
- case .checkBox: return "CheckBox"
77
- case .menuItem: return "MenuItem"
78
- case .webView: return "WebView"
79
- case .other: return "Other"
80
- default:
81
- switch type.rawValue {
82
- case 19:
83
- return "Keyboard"
84
- case 20:
85
- return "Key"
86
- default:
87
- return "Element(\(type.rawValue))"
88
- }
89
- }
88
+ Self.elementTypeNamesByRawValue[type.rawValue] ?? "Element(\(type.rawValue))"
90
89
  }
91
90
 
92
91
  static let structuralOnlyNodeTypes: Set<String> = [
@@ -133,7 +132,7 @@ extension RunnerTests {
133
132
 
134
133
  func recursiveTreeSnapshotAcquisition(
135
134
  context: SnapshotTraversalContext,
136
- options: PresentationOptions
135
+ hint: CaptureHint
137
136
  ) -> SnapshotAcquisition {
138
137
  var cachedDescendantElements: [XCUIElement]?
139
138
  func collapsedTabDescendants() -> [XCUIElement] {
@@ -147,110 +146,68 @@ extension RunnerTests {
147
146
  return result.elements
148
147
  }
149
148
 
149
+ // Acquisition serializes facts: every traversed node is emitted at raw traversal depth, and
150
+ // the regular projection's clip fold runs once inside `SnapshotPresentation` (#1797). The two
151
+ // walks this backend keeps are the raw budget or regular presented-depth frontier, plus
152
+ // collapsed-tab augmentation which needs live element handles; neither walk publishes a
153
+ // presentation node.
150
154
  var nodes: [RawAXNode] = []
151
- var hiddenContentHintsByNodeIndex: [Int: (above: Bool, below: Bool)] = [:]
152
- let rootEvaluation = evaluateSnapshot(context.rootSnapshot, in: context)
155
+ let rootEvaluation = evaluateSnapshot(context.rootSnapshot)
153
156
  nodes.append(
154
157
  makeSnapshotNode(
155
158
  snapshot: context.rootSnapshot,
156
159
  evaluation: rootEvaluation,
157
160
  depth: 0,
158
161
  index: 0,
159
- parentIndex: nil
162
+ parentIndex: nil,
163
+ viewport: context.viewport
160
164
  )
161
165
  )
162
- if context.maxDepth > 0 {
166
+ let shouldVisitRootChildren = SnapshotPresentation.shouldAcquireChildren(
167
+ for: hint,
168
+ rawDepth: 0,
169
+ regularPresentedDepth: 0
170
+ )
171
+ if shouldVisitRootChildren {
163
172
  appendCollapsedTabFallbackNodes(
164
173
  to: &nodes,
165
174
  containerSnapshot: context.rootSnapshot,
166
175
  resolveElements: collapsedTabDescendants,
167
176
  depth: 1,
168
- parentIndex: 0
177
+ parentIndex: 0,
178
+ viewport: context.viewport
169
179
  )
170
180
  }
171
181
 
172
182
  var seen = Set<String>()
173
- let rootScrollAnchor = scrollContainerAnchor(
174
- for: context.rootSnapshot,
175
- visible: rootEvaluation.visible,
176
- nodeIndex: 0
177
- )
178
- #if os(iOS)
179
- let rootProjection = flatSnapshotProjectionTransition(
180
- frame: context.rootSnapshot.frame,
181
- intersectsViewportAndScrollClip: rootEvaluation.visible,
182
- elementType: context.rootSnapshot.elementType,
183
- hasChildren: !context.rootSnapshot.children.isEmpty,
184
- cursor: .root
185
- )
186
- let rootDescendantProjectionCursor = rootProjection.decision.descendants
187
- #else
188
- let rootDescendantProjectionCursor = FlatSnapshotProjectionCursor.root
189
- #endif
190
- var stack: [SnapshotTraversalEntry] = context.rootSnapshot.children.map {
191
- SnapshotTraversalEntry(
192
- snapshot: $0,
193
- depth: 1,
194
- visibleDepth: 1,
195
- parentIndex: 0,
196
- nearestScrollAnchor: rootScrollAnchor,
197
- projectionCursor: rootDescendantProjectionCursor
198
- )
183
+ var stack: [SnapshotTraversalEntry] = []
184
+ if shouldVisitRootChildren {
185
+ stack = context.rootSnapshot.children.map {
186
+ SnapshotTraversalEntry(
187
+ snapshot: $0,
188
+ depth: 1,
189
+ parentIndex: 0,
190
+ parentPresentedDepth: 0,
191
+ parentTraversal: .root
192
+ )
193
+ }
199
194
  }
200
195
 
201
196
  while let entry = stack.popLast() {
202
197
  let snapshot = entry.snapshot
203
198
  let depth = entry.depth
204
- let visibleDepth = entry.visibleDepth
205
199
  let parentIndex = entry.parentIndex
206
- let nearestScrollAnchor = entry.nearestScrollAnchor
207
- let projectionCursor = entry.projectionCursor
208
- if let limit = options.depth, depth > limit { continue }
200
+ if let limit = hint.rawTraversalDepth, depth > limit { continue }
209
201
 
210
- let evaluation = evaluateSnapshot(snapshot, in: context)
211
- let intersectsViewportAndScrollClip = isVisibleInRegularSnapshot(
212
- snapshot.frame,
213
- viewport: context.viewport,
214
- scrollContainerAnchor: nearestScrollAnchor
215
- )
216
- #if os(iOS)
217
- let projectionTransition = flatSnapshotProjectionTransition(
218
- frame: snapshot.frame,
219
- intersectsViewportAndScrollClip: intersectsViewportAndScrollClip,
220
- elementType: snapshot.elementType,
221
- hasChildren: !snapshot.children.isEmpty,
222
- cursor: projectionCursor
223
- )
224
- let projection = projectionTransition.decision
225
- #else
226
- let projectionTransition = FlatSnapshotProjectionTransition(
227
- decision: FlatSnapshotProjectionDecision(
228
- presentationVisible: intersectsViewportAndScrollClip,
229
- descendants: .root
230
- ),
231
- hiddenContentFrame: !intersectsViewportAndScrollClip ? snapshot.frame : nil
232
- )
233
- let projection = projectionTransition.decision
234
- #endif
235
- if let hiddenFrame = projectionTransition.hiddenContentFrame, let nearestScrollAnchor
236
- {
237
- rememberHiddenContentHint(
238
- for: hiddenFrame,
239
- relativeTo: nearestScrollAnchor,
240
- hints: &hiddenContentHintsByNodeIndex
241
- )
242
- }
243
- let include = shouldAcquireSnapshotNode(
202
+ let evaluation = evaluateSnapshot(snapshot)
203
+ let node = makeSnapshotNode(
244
204
  snapshot: snapshot,
245
- label: evaluation.label,
246
- identifier: evaluation.identifier,
247
- valueText: evaluation.valueText,
248
- options: options,
249
- hittable: evaluation.hittable,
250
- visible: projection.presentationVisible,
251
- regularSnapshot: true
205
+ evaluation: evaluation,
206
+ depth: depth,
207
+ index: nodes.count,
208
+ parentIndex: parentIndex,
209
+ viewport: context.viewport
252
210
  )
253
-
254
211
  let key = Self.snapshotTraversalIdentity(
255
212
  elementType: snapshot.elementType,
256
213
  label: evaluation.label,
@@ -262,63 +219,53 @@ extension RunnerTests {
262
219
  seen.insert(key)
263
220
  }
264
221
 
265
- let currentIndex = include && !isDuplicate ? nodes.count : parentIndex
266
- if depth < context.maxDepth {
267
- let nextVisibleDepth = include && !isDuplicate ? visibleDepth + 1 : visibleDepth
268
- let nextScrollContainerAnchor: (index: Int, rect: CGRect)?
269
- if include && !isDuplicate {
270
- nextScrollContainerAnchor =
271
- scrollContainerAnchor(
272
- for: snapshot,
273
- visible: intersectsViewportAndScrollClip,
274
- nodeIndex: currentIndex
275
- )
276
- ?? nearestScrollAnchor
277
- } else {
278
- nextScrollContainerAnchor = nearestScrollAnchor
279
- }
222
+ let currentIndex = !isDuplicate ? nodes.count : parentIndex
223
+ let transition = SnapshotPresentation.regularTraversalTransition(
224
+ for: node,
225
+ parentPresentedDepth: entry.parentPresentedDepth,
226
+ parentTraversal: entry.parentTraversal,
227
+ hint: hint,
228
+ rawDepth: depth,
229
+ viewport: context.viewport,
230
+ hasChildren: !snapshot.children.isEmpty,
231
+ isDuplicate: isDuplicate,
232
+ policy: .platformDefault
233
+ )
234
+ if transition.shouldVisitChildren {
280
235
  for child in snapshot.children.reversed() {
281
236
  stack.append(
282
237
  SnapshotTraversalEntry(
283
238
  snapshot: child,
284
239
  depth: depth + 1,
285
- visibleDepth: nextVisibleDepth,
286
240
  parentIndex: currentIndex,
287
- nearestScrollAnchor: nextScrollContainerAnchor,
288
- projectionCursor: projection.descendants
241
+ parentPresentedDepth: transition.presentedDepth,
242
+ parentTraversal: transition.traversal
289
243
  )
290
244
  )
291
245
  }
292
246
  }
293
247
 
294
- if !include || isDuplicate { continue }
248
+ if isDuplicate { continue }
295
249
 
296
- let index = nodes.count
297
- nodes.append(
298
- makeSnapshotNode(
299
- snapshot: snapshot,
300
- evaluation: evaluation,
301
- depth: min(context.maxDepth, visibleDepth),
302
- index: index,
303
- parentIndex: parentIndex
304
- )
305
- )
306
- if visibleDepth < context.maxDepth {
250
+ nodes.append(node)
251
+ if transition.shouldVisitChildren {
307
252
  appendCollapsedTabFallbackNodes(
308
253
  to: &nodes,
309
254
  containerSnapshot: snapshot,
310
255
  resolveElements: collapsedTabDescendants,
311
- depth: visibleDepth + 1,
312
- parentIndex: index
256
+ depth: depth + 1,
257
+ parentIndex: node.index,
258
+ viewport: context.viewport
313
259
  )
314
260
  }
315
-
316
261
  }
317
262
 
318
263
  return SnapshotAcquisition(
319
- nodes: applyHiddenContentHints(hiddenContentHintsByNodeIndex, to: nodes),
264
+ hint: hint,
265
+ nodes: nodes,
320
266
  truncated: false,
321
- effectiveDepth: nil
267
+ effectiveDepth: nil,
268
+ viewport: context.viewport
322
269
  )
323
270
  }
324
271
 
@@ -369,7 +316,6 @@ extension RunnerTests {
369
316
  let startedAt = Date()
370
317
  do {
371
318
  return try runMainThreadWork(
372
- command: nil,
373
319
  timeout: slice,
374
320
  timeoutError: {
375
321
  SnapshotCaptureFailure(
@@ -416,38 +362,28 @@ extension RunnerTests {
416
362
 
417
363
  func rawTreeSnapshotAcquisition(
418
364
  context: SnapshotTraversalContext,
419
- options: PresentationOptions
365
+ hint: CaptureHint
420
366
  ) throws -> SnapshotAcquisition {
421
367
  var nodes: [RawAXNode] = []
422
368
 
423
369
  func walk(_ snapshot: XCUIElementSnapshot, depth: Int, parentIndex: Int?) throws {
424
- if let limit = options.depth, depth > limit { return }
370
+ if let limit = hint.rawTraversalDepth, depth > limit { return }
425
371
 
426
- let evaluation = evaluateSnapshot(snapshot, in: context)
427
- let include = shouldAcquireSnapshotNode(
428
- snapshot: snapshot,
429
- label: evaluation.label,
430
- identifier: evaluation.identifier,
431
- valueText: evaluation.valueText,
432
- options: options,
433
- hittable: evaluation.hittable,
434
- visible: evaluation.visible
435
- )
436
- let currentIndex = include ? nodes.count : parentIndex
437
- if include {
438
- if nodes.count >= Self.rawSnapshotMaxNodes {
439
- throw rawSnapshotTooLargeFailure(nodeCount: nodes.count + 1)
440
- }
441
- nodes.append(
442
- makeSnapshotNode(
443
- snapshot: snapshot,
444
- evaluation: evaluation,
445
- depth: depth,
446
- index: nodes.count,
447
- parentIndex: parentIndex
448
- )
449
- )
372
+ let evaluation = evaluateSnapshot(snapshot)
373
+ if nodes.count >= Self.rawSnapshotMaxNodes {
374
+ throw rawSnapshotTooLargeFailure(nodeCount: nodes.count + 1)
450
375
  }
376
+ let currentIndex = nodes.count
377
+ nodes.append(
378
+ makeSnapshotNode(
379
+ snapshot: snapshot,
380
+ evaluation: evaluation,
381
+ depth: depth,
382
+ index: currentIndex,
383
+ parentIndex: parentIndex,
384
+ viewport: context.viewport
385
+ )
386
+ )
451
387
 
452
388
  let children = snapshot.children
453
389
  for child in children {
@@ -456,24 +392,36 @@ extension RunnerTests {
456
392
  }
457
393
 
458
394
  try walk(context.rootSnapshot, depth: 0, parentIndex: nil)
459
- return SnapshotAcquisition(nodes: nodes, truncated: false, effectiveDepth: nil)
395
+ return SnapshotAcquisition(
396
+ hint: hint,
397
+ nodes: nodes,
398
+ truncated: false,
399
+ effectiveDepth: nil,
400
+ viewport: context.viewport
401
+ )
460
402
  }
461
403
 
462
404
  func querySweepSnapshotAcquisition(
463
405
  app: XCUIApplication,
464
- options: PresentationOptions,
406
+ hint: CaptureHint,
465
407
  planDeadline: Date = .distantFuture
466
408
  ) -> SnapshotAcquisition {
467
409
  var nodes: [RawAXNode] = [
468
410
  interactiveRootNode(rect: .zero)
469
411
  ]
470
- if options.depth == 0 {
471
- return SnapshotAcquisition(nodes: nodes, truncated: false, effectiveDepth: nil)
412
+ if hint.rawTraversalDepth == 0 || hint.regularPresentedDepth == 0 {
413
+ return SnapshotAcquisition(
414
+ hint: hint,
415
+ nodes: nodes,
416
+ truncated: false,
417
+ effectiveDepth: nil,
418
+ viewport: .infinite
419
+ )
472
420
  }
473
421
 
474
422
  // Bounded by both its own sweep budget and the umbrella capture-plan deadline, so a
475
423
  // chained recovery tier can never push the plan past the main-thread watchdog (#1105).
476
- let sweepDeadline = options.interactiveOnly
424
+ let sweepDeadline = hint.interactiveOnly
477
425
  ? Date().addingTimeInterval(Self.flatInteractiveFallbackBudget)
478
426
  : Date.distantFuture
479
427
  let deadline = min(sweepDeadline, planDeadline)
@@ -492,8 +440,7 @@ extension RunnerTests {
492
440
  element: element,
493
441
  index: 0,
494
442
  parentIndex: 0,
495
- viewport: viewport,
496
- options: options
443
+ viewport: viewport
497
444
  ) else {
498
445
  continue
499
446
  }
@@ -539,7 +486,13 @@ extension RunnerTests {
539
486
  )
540
487
  )
541
488
  }
542
- return SnapshotAcquisition(nodes: nodes, truncated: truncated, effectiveDepth: nil)
489
+ return SnapshotAcquisition(
490
+ hint: hint,
491
+ nodes: nodes,
492
+ truncated: truncated,
493
+ effectiveDepth: nil,
494
+ viewport: viewport
495
+ )
543
496
  }
544
497
 
545
498
  func snapshotAccessibilityUnavailable(failure: SnapshotCaptureFailure) -> DataPayload {
@@ -632,94 +585,29 @@ extension RunnerTests {
632
585
 
633
586
  // MARK: - Snapshot Filtering
634
587
 
635
- /// Conservative acquisition gate. Regular capture keeps every node its visibility policy can
636
- /// supply; `SnapshotPresentation` alone decides eligibility after the backend returns.
637
- private func shouldAcquireSnapshotNode(
638
- snapshot: XCUIElementSnapshot,
639
- label: String,
640
- identifier: String,
641
- valueText: String?,
642
- options: PresentationOptions,
643
- hittable: Bool,
644
- visible: Bool,
645
- regularSnapshot: Bool = false
646
- ) -> Bool {
647
- let type = snapshot.elementType
648
- let hasContent = !label.isEmpty || !identifier.isEmpty || (valueText != nil)
649
- #if os(iOS)
650
- if regularSnapshot && !visible && type != .application && type != .window {
651
- return false
652
- }
653
- #endif
654
- if regularSnapshot {
655
- #if os(macOS)
656
- if options.interactiveOnly && !visible && type != .application {
657
- return false
658
- }
659
- #endif
660
- if type == .application || type == .window { return true }
661
- return visible
662
- }
663
- if options.interactiveOnly {
664
- if isScrollableContainer(snapshot, visible: visible) { return true }
665
- if interactiveTypes.contains(type) { return true }
666
- if hittable && type != .other { return true }
667
- if hasContent { return true }
668
- return false
669
- }
670
- return true
671
- }
672
-
673
- private func computedSnapshotHittable(
674
- _ snapshot: XCUIElementSnapshot,
675
- viewport: CGRect,
676
- laterNodes: ArraySlice<XCUIElementSnapshot>
677
- ) -> Bool {
678
- guard snapshot.isEnabled else { return false }
679
- let frame = snapshot.frame
680
- if frame.isNull || frame.isEmpty { return false }
681
- let center = CGPoint(x: frame.midX, y: frame.midY)
682
- if !viewport.contains(center) { return false }
683
- for node in laterNodes {
684
- if !isOccludingType(node.elementType) { continue }
685
- let nodeFrame = node.frame
686
- if nodeFrame.isNull || nodeFrame.isEmpty { continue }
687
- if nodeFrame.contains(center) { return false }
688
- }
689
- return true
690
- }
691
-
692
588
  func makeSnapshotTraversalContext(
693
589
  app: XCUIApplication,
694
- options: PresentationOptions,
590
+ hint: CaptureHint,
695
591
  captureDeadline: Date = .distantFuture,
696
592
  treeCaptureSliceBudgetOverride: TimeInterval? = nil
697
593
  ) throws -> SnapshotTraversalContext? {
698
- let (viewport, queryRoot) = try runMainThreadWork(
699
- command: nil,
594
+ let viewport = try runMainThreadWork(
700
595
  timeout: min(1.0, max(0.1, captureDeadline.timeIntervalSinceNow)),
701
596
  timeoutError: snapshotMainThreadTimeoutError("preparing tree snapshot")
702
597
  ) {
703
- (
704
- self.safeSnapshotViewport(app: app),
705
- options.scope.flatMap { self.findScopeElement(app: app, scope: $0) } ?? app
706
- )
598
+ self.safeSnapshotViewport(app: app)
707
599
  }
708
600
 
709
601
  let treeSliceBudget = treeCaptureSliceBudgetOverride ?? treeCaptureSliceBudget
710
602
  let slice = min(treeSliceBudget, max(0.5, captureDeadline.timeIntervalSinceNow))
711
- guard let rootSnapshot = try captureSnapshotRootBounded(queryRoot, sliceSeconds: slice) else {
603
+ guard let rootSnapshot = try captureSnapshotRootBounded(app, sliceSeconds: slice) else {
712
604
  return nil
713
605
  }
714
606
 
715
- let (flatSnapshots, snapshotRanges) = flattenedSnapshots(rootSnapshot)
716
607
  return SnapshotTraversalContext(
717
- queryRoot: queryRoot,
608
+ queryRoot: app,
718
609
  rootSnapshot: rootSnapshot,
719
- viewport: viewport,
720
- flatSnapshots: flatSnapshots,
721
- snapshotRanges: snapshotRanges,
722
- maxDepth: options.depth ?? Int.max
610
+ viewport: viewport
723
611
  )
724
612
  }
725
613
 
@@ -758,7 +646,6 @@ extension RunnerTests {
758
646
  return try captureSnapshotRoot(element)
759
647
  }
760
648
  return try runMainThreadWork(
761
- command: nil,
762
649
  timeout: sliceSeconds,
763
650
  timeoutError: treeCaptureTimeoutError(sliceSeconds: sliceSeconds),
764
651
  onAbandoned: {
@@ -856,26 +743,16 @@ extension RunnerTests {
856
743
  failure.code == Self.axSnapshotErrorCode || isAxIllegalArgument(failure.message)
857
744
  }
858
745
 
859
- private func evaluateSnapshot(
860
- _ snapshot: XCUIElementSnapshot,
861
- in context: SnapshotTraversalContext
862
- ) -> SnapshotEvaluation {
746
+ private func evaluateSnapshot(_ snapshot: XCUIElementSnapshot) -> SnapshotEvaluation {
863
747
  let label = aggregatedLabel(for: snapshot) ?? snapshot.label.trimmingCharacters(in: .whitespacesAndNewlines)
864
748
  let identifier = snapshot.identifier.trimmingCharacters(in: .whitespacesAndNewlines)
865
749
  let valueText = snapshotValueText(snapshot)
866
- let laterNodes = laterSnapshots(
867
- for: snapshot,
868
- in: context.flatSnapshots,
869
- ranges: context.snapshotRanges
870
- )
871
750
  return SnapshotEvaluation(
872
751
  label: label,
873
752
  identifier: identifier,
874
753
  valueText: valueText,
875
- hittable: computedSnapshotHittable(snapshot, viewport: context.viewport, laterNodes: laterNodes),
876
754
  focused: snapshotHasFocus(snapshot),
877
- selected: snapshotIsSelected(snapshot),
878
- visible: isVisibleInViewport(snapshot.frame, context.viewport)
755
+ selected: snapshotIsSelected(snapshot)
879
756
  )
880
757
  }
881
758
 
@@ -884,7 +761,8 @@ extension RunnerTests {
884
761
  evaluation: SnapshotEvaluation,
885
762
  depth: Int,
886
763
  index: Int,
887
- parentIndex: Int?
764
+ parentIndex: Int?,
765
+ viewport: CGRect
888
766
  ) -> RawAXNode {
889
767
  return RawAXNode(
890
768
  index: index,
@@ -896,7 +774,11 @@ extension RunnerTests {
896
774
  enabled: snapshot.isEnabled,
897
775
  focused: evaluation.focused ? true : nil,
898
776
  selected: evaluation.selected ? true : nil,
899
- hittable: evaluation.hittable,
777
+ hittable: parentIndex != nil && SnapshotGeometry.isGeometricallyActionable(
778
+ enabled: snapshot.isEnabled,
779
+ frame: snapshot.frame,
780
+ viewport: viewport
781
+ ),
900
782
  depth: depth,
901
783
  parentIndex: parentIndex,
902
784
  hiddenContentAbove: nil,
@@ -904,52 +786,6 @@ extension RunnerTests {
904
786
  )
905
787
  }
906
788
 
907
- private func isOccludingType(_ type: XCUIElement.ElementType) -> Bool {
908
- switch type {
909
- case .application, .window:
910
- return false
911
- default:
912
- return true
913
- }
914
- }
915
-
916
- private func flattenedSnapshots(
917
- _ root: XCUIElementSnapshot
918
- ) -> ([XCUIElementSnapshot], [ObjectIdentifier: (Int, Int)]) {
919
- var ordered: [XCUIElementSnapshot] = []
920
- var ranges: [ObjectIdentifier: (Int, Int)] = [:]
921
-
922
- @discardableResult
923
- func visit(_ snapshot: XCUIElementSnapshot) -> Int {
924
- let start = ordered.count
925
- ordered.append(snapshot)
926
- var end = start
927
- for child in snapshot.children {
928
- end = max(end, visit(child))
929
- }
930
- ranges[ObjectIdentifier(snapshot)] = (start, end)
931
- return end
932
- }
933
-
934
- _ = visit(root)
935
- return (ordered, ranges)
936
- }
937
-
938
- private func laterSnapshots(
939
- for snapshot: XCUIElementSnapshot,
940
- in ordered: [XCUIElementSnapshot],
941
- ranges: [ObjectIdentifier: (Int, Int)]
942
- ) -> ArraySlice<XCUIElementSnapshot> {
943
- guard let (_, subtreeEnd) = ranges[ObjectIdentifier(snapshot)] else {
944
- return ordered.suffix(from: ordered.count)
945
- }
946
- let nextIndex = subtreeEnd + 1
947
- if nextIndex >= ordered.count {
948
- return ordered.suffix(from: ordered.count)
949
- }
950
- return ordered.suffix(from: nextIndex)
951
- }
952
-
953
789
  private func snapshotValueText(_ snapshot: XCUIElementSnapshot) -> String? {
954
790
  guard let value = snapshot.value else { return nil }
955
791
  let text = String(describing: value).trimmingCharacters(in: .whitespacesAndNewlines)
@@ -990,120 +826,32 @@ extension RunnerTests {
990
826
  return nil
991
827
  }
992
828
 
993
- func isVisibleInViewport(_ rect: CGRect, _ viewport: CGRect) -> Bool {
994
- if rect.isNull || rect.isEmpty { return false }
995
- return rect.intersects(viewport)
996
- }
997
-
998
- func isVisibleInRegularSnapshot(
999
- _ rect: CGRect,
1000
- viewport: CGRect,
1001
- scrollContainerAnchor: (index: Int, rect: CGRect)?
1002
- ) -> Bool {
1003
- if !isVisibleInViewport(rect, viewport) { return false }
1004
- guard let scrollContainerAnchor else { return true }
1005
- return isVisibleInViewport(rect, scrollContainerAnchor.rect)
1006
- }
1007
-
1008
829
  private func appendCollapsedTabFallbackNodes(
1009
830
  to nodes: inout [RawAXNode],
1010
831
  containerSnapshot: XCUIElementSnapshot,
1011
832
  resolveElements: () -> [XCUIElement],
1012
833
  depth: Int,
1013
- parentIndex: Int
834
+ parentIndex: Int,
835
+ viewport: CGRect
1014
836
  ) {
1015
837
  let fallbackNodes = collapsedTabFallbackNodes(
1016
838
  for: containerSnapshot,
1017
839
  resolveElements: resolveElements,
1018
840
  startingIndex: nodes.count,
1019
841
  depth: depth,
1020
- parentIndex: parentIndex
842
+ parentIndex: parentIndex,
843
+ viewport: viewport
1021
844
  )
1022
845
  nodes.append(contentsOf: fallbackNodes)
1023
846
  }
1024
847
 
1025
- private func scrollContainerAnchor(
1026
- for snapshot: XCUIElementSnapshot,
1027
- visible: Bool,
1028
- nodeIndex: Int?
1029
- ) -> (index: Int, rect: CGRect)? {
1030
- return scrollContainerAnchor(
1031
- for: snapshot.elementType,
1032
- hasChildren: !snapshot.children.isEmpty,
1033
- visible: visible,
1034
- frame: snapshot.frame,
1035
- nodeIndex: nodeIndex
1036
- )
1037
- }
1038
-
1039
- func scrollContainerAnchor(
1040
- for elementType: XCUIElement.ElementType,
1041
- hasChildren: Bool,
1042
- visible: Bool,
1043
- frame: CGRect,
1044
- nodeIndex: Int?
1045
- ) -> (index: Int, rect: CGRect)? {
1046
- guard let nodeIndex else { return nil }
1047
- if !isScrollableContainer(
1048
- elementType: elementType,
1049
- hasChildren: hasChildren,
1050
- visible: visible
1051
- ) { return nil }
1052
- return (nodeIndex, frame)
1053
- }
1054
-
1055
- func rememberHiddenContentHint(
1056
- for frame: CGRect,
1057
- relativeTo scrollContainerAnchor: (index: Int, rect: CGRect),
1058
- hints: inout [Int: (above: Bool, below: Bool)]
1059
- ) {
1060
- if frame.isNull || frame.isEmpty { return }
1061
- var hint = hints[scrollContainerAnchor.index] ?? (above: false, below: false)
1062
- if frame.maxY <= scrollContainerAnchor.rect.minY {
1063
- hint.above = true
1064
- } else if frame.minY >= scrollContainerAnchor.rect.maxY {
1065
- hint.below = true
1066
- } else {
1067
- return
1068
- }
1069
- hints[scrollContainerAnchor.index] = hint
1070
- }
1071
-
1072
- func applyHiddenContentHints(
1073
- _ hints: [Int: (above: Bool, below: Bool)],
1074
- to nodes: [RawAXNode]
1075
- ) -> [RawAXNode] {
1076
- if hints.isEmpty { return nodes }
1077
- return nodes.map { node in
1078
- guard let hint = hints[node.index] else { return node }
1079
- let hiddenContentAbove: Bool? = (node.hiddenContentAbove == true || hint.above) ? true : nil
1080
- let hiddenContentBelow: Bool? = (node.hiddenContentBelow == true || hint.below) ? true : nil
1081
- return RawAXNode(
1082
- index: node.index,
1083
- type: node.type,
1084
- label: node.label,
1085
- identifier: node.identifier,
1086
- value: node.value,
1087
- rect: node.rect,
1088
- enabled: node.enabled,
1089
- focused: node.focused,
1090
- selected: node.selected,
1091
- hittable: node.hittable,
1092
- depth: node.depth,
1093
- parentIndex: node.parentIndex,
1094
- hiddenContentAbove: hiddenContentAbove,
1095
- hiddenContentBelow: hiddenContentBelow,
1096
- actions: node.actions
1097
- )
1098
- }
1099
- }
1100
-
1101
848
  private func collapsedTabFallbackNodes(
1102
849
  for containerSnapshot: XCUIElementSnapshot,
1103
850
  resolveElements: () -> [XCUIElement],
1104
851
  startingIndex: Int,
1105
852
  depth: Int,
1106
- parentIndex: Int
853
+ parentIndex: Int,
854
+ viewport: CGRect
1107
855
  ) -> [RawAXNode] {
1108
856
  if !containerSnapshot.children.isEmpty { return [] }
1109
857
  guard shouldExpandCollapsedTabContainer(containerSnapshot) else { return [] }
@@ -1117,7 +865,8 @@ extension RunnerTests {
1117
865
  collapsedTabCandidateNode(
1118
866
  element: element,
1119
867
  containerSnapshot: containerSnapshot,
1120
- containerFrame: containerFrame
868
+ containerFrame: containerFrame,
869
+ viewport: viewport
1121
870
  )
1122
871
  }
1123
872
  .sorted { left, right in
@@ -1165,7 +914,8 @@ extension RunnerTests {
1165
914
  private func collapsedTabCandidateNode(
1166
915
  element: XCUIElement,
1167
916
  containerSnapshot: XCUIElementSnapshot,
1168
- containerFrame: CGRect
917
+ containerFrame: CGRect,
918
+ viewport: CGRect
1169
919
  ) -> RawAXNode? {
1170
920
  var node: RawAXNode?
1171
921
  let exceptionMessage = RunnerObjCExceptionCatcher.catchException({
@@ -1205,7 +955,11 @@ extension RunnerTests {
1205
955
  enabled: element.isEnabled,
1206
956
  focused: elementHasFocus(element) ? true : nil,
1207
957
  selected: element.isSelected ? true : nil,
1208
- hittable: element.isHittable,
958
+ hittable: SnapshotGeometry.isGeometricallyActionable(
959
+ enabled: element.isEnabled,
960
+ frame: frame,
961
+ viewport: viewport
962
+ ),
1209
963
  depth: 0,
1210
964
  parentIndex: nil,
1211
965
  hiddenContentAbove: nil,
@@ -1331,40 +1085,25 @@ extension RunnerTests {
1331
1085
  element: XCUIElement,
1332
1086
  index: Int,
1333
1087
  parentIndex: Int?,
1334
- viewport: CGRect,
1335
- options: PresentationOptions
1088
+ viewport: CGRect
1336
1089
  ) -> RawAXNode? {
1337
1090
  var node: RawAXNode?
1338
1091
  let exceptionMessage = RunnerObjCExceptionCatcher.catchException({
1339
1092
  if !element.exists { return }
1093
+ // Declared residue: a flat element query has no hierarchy for geometryless semantics to
1094
+ // attach to, so frameless elements are dropped at acquisition rather than presented.
1340
1095
  let frame = element.frame
1341
1096
  if frame.isNull || frame.isEmpty { return }
1342
- let visible = isVisibleInViewport(frame, viewport)
1343
- if options.interactiveOnly && !visible { return }
1344
- #if os(macOS)
1345
- if !visible { return }
1346
- #endif
1347
1097
  let label = element.label.trimmingCharacters(in: .whitespacesAndNewlines)
1348
1098
  let identifier = element.identifier.trimmingCharacters(in: .whitespacesAndNewlines)
1349
1099
  let valueText = snapshotValueText(element)
1350
1100
  let elementType = element.elementType
1351
1101
  let enabled = element.isEnabled
1352
- let hittable = visible && enabled && element.isHittable
1353
- let filterNode = FlatSnapshotFilterNode(
1354
- isRoot: false,
1355
- label: label,
1356
- identifier: identifier,
1357
- valueText: valueText,
1358
- visible: visible
1102
+ let hittable = SnapshotGeometry.isGeometricallyActionable(
1103
+ enabled: enabled,
1104
+ frame: frame,
1105
+ viewport: viewport
1359
1106
  )
1360
- if !flatSnapshotFilterDecision(
1361
- filterNode,
1362
- options: options,
1363
- visibilityPolicy: .interactiveOnly,
1364
- insideMatchedScope: false
1365
- ).include {
1366
- return
1367
- }
1368
1107
 
1369
1108
  node = RawAXNode(
1370
1109
  index: index,
@@ -1390,19 +1129,4 @@ extension RunnerTests {
1390
1129
  return node
1391
1130
  }
1392
1131
 
1393
- private func isScrollableContainer(_ snapshot: XCUIElementSnapshot, visible: Bool) -> Bool {
1394
- return isScrollableContainer(
1395
- elementType: snapshot.elementType,
1396
- hasChildren: !snapshot.children.isEmpty,
1397
- visible: visible
1398
- )
1399
- }
1400
-
1401
- private func isScrollableContainer(
1402
- elementType: XCUIElement.ElementType,
1403
- hasChildren: Bool,
1404
- visible: Bool
1405
- ) -> Bool {
1406
- return visible && hasChildren && Self.scrollContainerTypes.contains(elementType)
1407
- }
1408
1132
  }