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.
- package/README.md +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
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.1.apk.sha256 +1 -0
- 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
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.1.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.1.apk.sha256 +1 -0
- 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
- package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/AudioProbe.swift +35 -33
- package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/main.swift +6 -1
- package/apple/snapshot-bridge/LICENSE.idb +23 -0
- package/apple/snapshot-bridge/README.md +106 -0
- package/apple/snapshot-bridge/SnapshotBridge.m +286 -0
- package/apple/snapshot-bridge/SnapshotBridgeCapture.h +25 -0
- package/apple/snapshot-bridge/SnapshotBridgeCapture.m +138 -0
- package/apple/snapshot-bridge/SnapshotBridgeRuntime.h +34 -0
- package/apple/snapshot-bridge/SnapshotBridgeRuntime.m +411 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +58 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +19 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +12 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +20 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAlertVerification.swift +36 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSelectorMatchPolicy.swift +15 -15
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerStringNormalization.swift +8 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +12 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +100 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSystemSurfaceHostPolicy.swift +72 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +63 -14
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +677 -83
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +35 -92
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AlertObservation.swift +124 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+BlockingSystemModalResolution.swift +39 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +1058 -213
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +296 -14
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +10 -10
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +309 -149
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +101 -42
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +24 -17
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +124 -199
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +71 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXElementTypes.swift +12 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +211 -78
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +30 -10
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +254 -24
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +206 -22
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +465 -494
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotBackendCapabilities.swift +168 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +802 -247
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentationInvariant.swift +19 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTiming.swift +185 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedCommitDeadline.swift +206 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +83 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +156 -34
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +5 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +35 -318
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +206 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryReadiness.swift +158 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextInputCandidatePolicy.swift +28 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextInputProbe.swift +101 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +56 -23
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +56 -27
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +30 -24
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +126 -80
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/RecordingExportSupport.swift +111 -0
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +47 -86
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-trim.swift +32 -79
- package/dist/apple/snapshot-presentation/Package.swift +21 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotGeometry.swift +56 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotModels.swift +259 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentation.swift +153 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationFailure.swift +27 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationInvariant.swift +91 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationProjection.swift +161 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotScopePolicy.swift +53 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFold.swift +242 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFoldProjection.swift +97 -0
- package/dist/src/adapter.js +1 -0
- package/dist/src/adb-executor.js +2 -0
- package/dist/src/adb-failure.js +1 -0
- package/dist/src/adb-host.js +1 -0
- package/dist/src/adb.js +1 -0
- package/dist/src/agent-browser-lifecycle.js +1 -0
- package/dist/src/agent-browser-process-record.js +1 -0
- package/dist/src/agent-browser-provider.js +1 -0
- package/dist/src/agent-browser-tool.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/ai-sdk.d.ts +2 -2
- package/dist/src/ai-sdk.js +1 -1
- package/dist/src/alert-contract.js +1 -0
- package/dist/src/alert-runtime.js +1 -0
- package/dist/src/android-adb.d.ts +27 -19
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android-input-ownership.js +1 -0
- package/dist/src/android-system-chrome.js +1 -0
- package/dist/src/android.js +1 -1
- package/dist/src/api.js +11 -0
- package/dist/src/app-catalog.js +1 -0
- package/dist/src/app-deployment-resolution.js +2 -0
- package/dist/src/app-helpers.js +1 -1
- package/dist/src/app-inventory-contract.js +1 -0
- package/dist/src/app-inventory.js +1 -0
- package/dist/src/app-launch.js +2 -0
- package/dist/src/app-lifecycle-facade.js +1 -0
- package/dist/src/app-lifecycle.js +3 -6
- package/dist/src/app-lifecycle2.js +2 -2
- package/dist/src/app-lifecycle3.js +1 -0
- package/dist/src/app-log-files.js +1 -1
- package/dist/src/app-log-reconnect.js +1 -1
- package/dist/src/app-log-runtime.js +1 -4
- package/dist/src/app-log-runtime2.js +4 -0
- package/dist/src/app-parsers.js +4 -0
- package/dist/src/app-resolution-cache.js +1 -0
- package/dist/src/app-resolution-facade.js +1 -0
- package/dist/src/app-resolution.js +2 -2
- package/dist/src/app-state.js +1 -2
- package/dist/src/apple-runner-platform.js +1 -0
- package/dist/src/application-lifecycle-interaction.js +1 -0
- package/dist/src/application-lifecycle-runtime.js +1 -0
- package/dist/src/apps-simctl.js +1 -0
- package/dist/src/archive.js +4 -0
- package/dist/src/artifact-download.js +1 -0
- package/dist/src/artifacts.d.ts +6 -2
- package/dist/src/artifacts.js +1 -1
- package/dist/src/async-lifecycle.js +1 -0
- package/dist/src/audio-probe-result.js +1 -0
- package/dist/src/audio-probe-runtime.js +1 -0
- package/dist/src/audio-probe-support.js +1 -0
- package/dist/src/auth-session.js +1 -1
- package/dist/src/auth.js +1 -1
- package/dist/src/backend-snapshot-options.js +1 -1
- package/dist/src/{url.js → base-url.js} +1 -1
- package/dist/src/boot-diagnostics.js +2 -2
- package/dist/src/byte-limit-stream.js +1 -1
- package/dist/src/capabilities.js +1 -0
- package/dist/src/capture.js +1 -0
- package/dist/src/catalog.js +1 -0
- package/dist/src/cli-command-aliases.js +1 -0
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +74 -51
- package/dist/src/cli-output.js +1 -1
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +4 -6
- package/dist/src/click-button.js +1 -0
- package/dist/src/client-metro-companion.js +1 -0
- package/dist/src/client-metro.js +1 -1
- package/dist/src/client-types.d.ts +280 -242
- package/dist/src/clipboard.js +1 -0
- package/dist/src/code-signature-cache.js +1 -0
- package/dist/src/code-signature.js +1 -0
- package/dist/src/color.js +1 -0
- package/dist/src/command-metadata.js +1 -1
- package/dist/src/command-schema.js +3 -3
- package/dist/src/command-surface.js +1 -1
- package/dist/src/command-tools.js +2 -2
- package/dist/src/command.js +1 -0
- package/dist/src/compatibility-policy.js +1 -0
- package/dist/src/config.js +1 -1
- package/dist/src/config2.js +1 -0
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/connection.js +5 -5
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/contracts.js +1 -1
- package/dist/src/daemon-client-lifecycle.js +1 -0
- package/dist/src/daemon-process.js +1 -0
- package/dist/src/daemon-registration.js +1 -0
- package/dist/src/daemon-shutdown-report.js +1 -1
- package/dist/src/daemon.js +2 -2
- package/dist/src/debug-symbols-facade.js +5 -0
- package/dist/src/deploy-result-target.js +1 -0
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-claim-rule.js +1 -0
- package/dist/src/device-input-state.d.ts +190 -3
- package/dist/src/device-inventory-context.js +1 -0
- package/dist/src/device-isolation.js +1 -0
- package/dist/src/device-release.js +1 -0
- package/dist/src/device-rotation.js +1 -0
- package/dist/src/device-selection-resolver.js +1 -0
- package/dist/src/device-session.js +1 -0
- package/dist/src/device.js +1 -1
- package/dist/src/device2.js +3 -2
- package/dist/src/diagnostics.js +3 -0
- package/dist/src/diagnostics2.js +1 -0
- package/dist/src/dispatch-resolve.js +1 -0
- package/dist/src/doctor-facade.js +1 -0
- package/dist/src/doctor-output.js +1 -0
- package/dist/src/doctor.js +1 -0
- package/dist/src/doctor2.js +1 -0
- package/dist/src/doctor3.js +1 -0
- package/dist/src/durable-resource.js +1 -0
- package/dist/src/entities.js +1 -1
- package/dist/src/error.js +2 -0
- package/dist/src/exec.js +1 -0
- package/dist/src/file.js +1 -0
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/generic-settle.js +1 -1
- package/dist/src/generic.js +1 -1
- package/dist/src/gesture-admission.js +1 -0
- package/dist/src/gesture-plan-types.js +1 -0
- package/dist/src/gesture-plan.js +1 -0
- package/dist/src/gesture-runtime.js +1 -0
- package/dist/src/harmonyos.js +1 -1
- package/dist/src/hdc.js +1 -1
- package/dist/src/helper.js +2 -2
- package/dist/src/host-file.js +1 -0
- package/dist/src/human-control-contract.js +1 -0
- package/dist/src/human-control.js +1 -0
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +1 -4
- package/dist/src/input-actions2.js +2 -1
- package/dist/src/install-artifact-facade.js +1 -0
- package/dist/src/install-source-network-transport.js +1 -0
- package/dist/src/install-source.d.ts +3 -10
- package/dist/src/install-source2.js +1 -1
- package/dist/src/interaction-positionals.js +1 -0
- package/dist/src/interaction-ref-policy.js +1 -0
- package/dist/src/interaction.js +1 -1
- package/dist/src/interaction2.js +1 -1
- package/dist/src/interactor-operation-catalog.js +1 -0
- package/dist/src/interactor-types.js +1 -0
- package/dist/src/interactor.js +6 -2
- package/dist/src/interactor2.js +1 -1
- package/dist/src/interactors.js +1 -1
- package/dist/src/internal/bin.d.ts +1 -1
- package/dist/src/internal/bin.js +1 -2
- package/dist/src/internal/companion-tunnel.d.ts +1 -1
- package/dist/src/internal/companion-tunnel.js +1 -1
- package/dist/src/internal/daemon.d.ts +1 -1
- package/dist/src/internal/daemon.js +2 -4
- package/dist/src/internal/png-worker.d.ts +4 -4
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/internal/run-script-http-child.d.ts +4 -0
- package/dist/src/internal/run-script-http-child.js +1 -0
- package/dist/src/internal/update-check-entry.d.ts +1 -1
- package/dist/src/inventory.js +4 -4
- package/dist/src/inventory2.js +1 -1
- package/dist/src/inventory3.js +1 -1
- package/dist/src/inventory5.js +1 -1
- package/dist/src/inventory6.js +1 -1
- package/dist/src/ios-client.js +16 -0
- package/dist/src/ios-snapshot-acquisition.js +1 -0
- package/dist/src/ios-snapshot-adapter.js +1 -0
- package/dist/src/ios-snapshot-planning.js +1 -0
- package/dist/src/ios-snapshot-runtime.js +1 -0
- package/dist/src/ios-system-surface.js +1 -0
- package/dist/src/json.js +1 -0
- package/dist/src/keyboard-actions.js +1 -0
- package/dist/src/launch-console.js +1 -0
- package/dist/src/lease-context.js +1 -1
- package/dist/src/lease-scope.js +1 -0
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun-runtime-dependencies.js +1 -1
- package/dist/src/limrun.d.ts +1610 -7
- package/dist/src/limrun.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/local-interactor-operation-set.js +1 -0
- package/dist/src/location-coordinates.js +1 -1
- package/dist/src/logcat.js +1 -1
- package/dist/src/macos-facade.js +1 -0
- package/dist/src/managed-device-scope.js +1 -0
- package/dist/src/mechanics.js +19 -0
- package/dist/src/metro.d.ts +4 -2
- package/dist/src/metro.js +1 -1
- package/dist/src/metro2.js +1 -1
- package/dist/src/mobile-snapshot-semantics.js +1 -1
- package/dist/src/multitouch-support.js +1 -0
- package/dist/src/numeric.js +1 -0
- package/dist/src/observability.js +1 -1
- package/dist/src/observation.js +2 -0
- package/dist/src/open-target-resolution.js +1 -0
- package/dist/src/output-path.js +1 -1
- package/dist/src/owner-identity.js +3 -1
- package/dist/src/parameterized-recorded-fill.js +1 -0
- package/dist/src/parser.js +1 -1
- package/dist/src/perf-facade.js +2 -0
- package/dist/src/perf-process-identity.js +1 -0
- package/dist/src/perf-runtime-operation-builder.js +1 -0
- package/dist/src/perf-runtime-plan.js +1 -0
- package/dist/src/perf-runtime.js +1 -0
- package/dist/src/perf.js +1 -4
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/physical-device-facade.js +1 -0
- package/dist/src/platform-request-scope.js +1 -0
- package/dist/src/platform-runtime-android-adb-host.js +1 -0
- package/dist/src/platform-runtime-android-mechanics.js +1 -0
- package/dist/src/platform-runtime-app-log-android-transport.js +1 -1
- package/dist/src/platform-runtime-app-log-process.js +1 -1
- package/dist/src/platform-runtime-host.js +1 -1
- package/dist/src/platform-runtime-managed-owner.js +1 -0
- package/dist/src/platform-runtime-network-web-transport.js +1 -1
- package/dist/src/platform-runtime-open-target.js +1 -1
- package/dist/src/platform-runtime-operation-host.js +4 -4
- package/dist/src/platform-runtime-runtime-hints.js +2 -2
- package/dist/src/platform-runtime-screen-recording-android-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-runner-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-runner-transport.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-transport.js +1 -1
- package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-harmony-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-process-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-web-host.js +1 -1
- package/dist/src/platform-runtime-unavailable.js +1 -0
- package/dist/src/platform-runtime.js +1 -1
- package/dist/src/platform-runtime2.js +1 -1
- package/dist/src/plist.js +1 -1
- package/dist/src/png-worker-contract.js +1 -1
- package/dist/src/prepare-kind.js +1 -0
- package/dist/src/process-exit.js +1 -1
- package/dist/src/process.js +1 -0
- package/dist/src/provider-device-runtime.js +1 -0
- package/dist/src/provider-session-ownership.js +2 -0
- package/dist/src/provider-webdriver.js +1 -1
- package/dist/src/provider.js +1 -1
- package/dist/src/providers.js +1 -0
- package/dist/src/proxy.js +2 -2
- package/dist/src/react-native-overlay.js +1 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/record-trace.js +1 -1
- package/dist/src/rect-center.js +1 -0
- package/dist/src/register-builtins.js +1 -0
- package/dist/src/registry.js +40 -28
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/replay-divergence.js +2 -0
- package/dist/src/replay.js +2 -2
- package/dist/src/reporting.js +8 -7
- package/dist/src/request-admission.js +1 -0
- package/dist/src/request-cancel.js +1 -0
- package/dist/src/request-cancellation.js +1 -0
- package/dist/src/request-progress-protocol.js +1 -0
- package/dist/src/request-providers.js +1 -0
- package/dist/src/request-runtime-binding.js +1 -0
- package/dist/src/request.js +1 -0
- package/dist/src/result-serialization.js +1 -0
- package/dist/src/retry.js +1 -0
- package/dist/src/rolldown-runtime.js +1 -1
- package/dist/src/runner-cache-metadata.js +2 -0
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-operations-facade.js +1 -0
- package/dist/src/runner-owner-facade.js +1 -0
- package/dist/src/runner-owner-state.js +1 -0
- package/dist/src/runner-presentation.js +1 -0
- package/dist/src/runner.js +1 -0
- package/dist/src/{runtime-transport.js → runtime-transport-hints.js} +1 -1
- package/dist/src/runtime.js +3 -3
- package/dist/src/runtime2.js +4 -4
- package/dist/src/runtime3.js +1 -1
- package/dist/src/runtime4.js +5 -3
- package/dist/src/runtime5.js +1 -1
- package/dist/src/runtime6.js +1 -1
- package/dist/src/runtime7.js +1 -1
- package/dist/src/runtime8.js +1 -1
- package/dist/src/runtime9.js +1 -1
- package/dist/src/scoped-provider.js +1 -1
- package/dist/src/screen-recording-completion.js +1 -0
- package/dist/src/screen-recording-live-handle.js +1 -0
- package/dist/src/screen-recording-options.js +1 -0
- package/dist/src/screen-recording-resource-recovery.js +1 -0
- package/dist/src/screen-recording-runtime.js +1 -0
- package/dist/src/screenshot-density.js +1 -1
- package/dist/src/screenshot-result.js +1 -6
- package/dist/src/screenshot-runtime.js +1 -0
- package/dist/src/screenshot.js +1 -1
- package/dist/src/screenshot2.js +1 -0
- package/dist/src/screenshot3.js +5 -0
- package/dist/src/script.js +1 -0
- package/dist/src/scroll-command.js +1 -0
- package/dist/src/scroll-gesture.js +1 -0
- package/dist/src/scroll-indicator.js +1 -0
- package/dist/src/sdk-batch-runner.d.ts +23 -6
- package/dist/src/sdk-batch-runner.js +2 -3
- package/dist/src/sdk-batch.js +2 -0
- package/dist/src/sdk-contracts.d.ts +170 -41
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-device.js +1 -1
- package/dist/src/sdk-finders.d.ts +1 -1
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-io.js +1 -1
- package/dist/src/sdk-remote-config.d.ts +1 -1
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.d.ts +524 -140
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selection.js +1 -0
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/semantic-index.js +1 -0
- package/dist/src/server.js +4 -4
- package/dist/src/session-allocation.js +1 -0
- package/dist/src/session-artifact-paths.js +1 -0
- package/dist/src/session-observation.js +1 -0
- package/dist/src/session-paths.js +1 -0
- package/dist/src/session-repair-tombstone.js +1 -0
- package/dist/src/session-routing.js +1 -0
- package/dist/src/session-runtime-admission.js +1 -0
- package/dist/src/session-snapshot.js +1 -0
- package/dist/src/session-store.js +4 -0
- package/dist/src/session-target-evidence.js +1 -1
- package/dist/src/session2.js +5 -27
- package/dist/src/settings.js +1 -0
- package/dist/src/shared.js +2 -2
- package/dist/src/simctl-facade.js +1 -0
- package/dist/src/simctl.js +1 -1
- package/dist/src/simulator-facade.js +1 -0
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-capture-annotations.js +1 -0
- package/dist/src/snapshot-desktop-projection.js +1 -0
- package/dist/src/snapshot-diagnostics.js +1 -0
- package/dist/src/snapshot-process.js +1 -0
- package/dist/src/snapshot-quality-backend-capabilities.js +1 -0
- package/dist/src/snapshot-quality-verdict.js +1 -0
- package/dist/src/snapshot-runtime-binding.js +1 -0
- package/dist/src/snapshot-runtime.js +1 -1
- package/dist/src/snapshot-scope.js +1 -1
- package/dist/src/snapshot-state.js +1 -0
- package/dist/src/snapshot.js +1 -8
- package/dist/src/snapshot2.js +1 -1
- package/dist/src/snapshot3.js +1 -1
- package/dist/src/snapshot4.js +1 -0
- package/dist/src/src.js +1 -1
- package/dist/src/src2.js +1 -1
- package/dist/src/src3.js +1 -2
- package/dist/src/src4.js +1 -1
- package/dist/src/src5.js +1 -0
- package/dist/src/src6.js +1 -0
- package/dist/src/src7.js +2 -0
- package/dist/src/src8.js +115 -0
- package/dist/src/startup-recovery-fence.js +1 -0
- package/dist/src/status-markers.js +1 -0
- package/dist/src/string-enum.js +1 -1
- package/dist/src/success-text.js +1 -0
- package/dist/src/surface-snapshot.js +1 -0
- package/dist/src/surface-snapshot2.js +1 -0
- package/dist/src/takeover.js +5 -0
- package/dist/src/tool-provider-facade.js +1 -0
- package/dist/src/tool-provider.js +4 -3
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/tool-provider3.js +1 -1
- package/dist/src/toolchain-probe.js +2 -0
- package/dist/src/touch-reference-frame.js +1 -0
- package/dist/src/touch-runtime.js +1 -0
- package/dist/src/transport.js +3 -0
- package/dist/src/tree.js +1 -0
- package/dist/src/ttl-memo.js +1 -0
- package/dist/src/tv-remote.js +1 -0
- package/dist/src/type-text-runtime.js +1 -0
- package/dist/src/undici.js +99 -0
- package/dist/src/update-check.js +1 -1
- package/dist/src/verified-file.js +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/video.js +2 -2
- package/dist/src/web.js +2 -1
- package/dist/src/web2.js +1 -0
- package/dist/src/webdriver-ios-snapshot.js +1 -0
- package/dist/src/webdriver-source.js +1 -0
- package/dist/src/window-state.js +1 -0
- package/linux/atspi-dump.py +54 -9
- package/package.json +58 -35
- package/server.json +9 -3
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.10.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.10.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.10.apk.sha256 +0 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CoordinateTextEntryTests.swift +0 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +0 -168
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+LifecycleCacheTests.swift +0 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+RecordingTests.swift +0 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SelectorMatchPolicyTests.swift +0 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentation.swift +0 -183
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentationTests.swift +0 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTraversalIdentityTests.swift +0 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryPolicyTests.swift +0 -4
- package/dist/src/appearance.js +0 -1
- package/dist/src/apps.js +0 -5
- package/dist/src/audio-probe.js +0 -1
- package/dist/src/cli-grammar.js +0 -1
- package/dist/src/command-catalog.js +0 -1
- package/dist/src/debug-symbols.js +0 -5
- package/dist/src/device-input-state.js +0 -2
- package/dist/src/device-ready.js +0 -1
- package/dist/src/dispatch.js +0 -1
- package/dist/src/handler-utils.js +0 -1
- package/dist/src/helper-package-install.js +0 -1
- package/dist/src/host-process.js +0 -3
- package/dist/src/ime-lifecycle.js +0 -2
- package/dist/src/ime-recovery-marker.js +0 -1
- package/dist/src/input-actions3.js +0 -1
- package/dist/src/install-artifact.js +0 -1
- package/dist/src/install-artifact2.js +0 -1
- package/dist/src/interaction-common.js +0 -1
- package/dist/src/interaction-runtime.js +0 -1
- package/dist/src/interaction-snapshot.js +0 -1
- package/dist/src/manifest.js +0 -1
- package/dist/src/method-scope.js +0 -1
- package/dist/src/png-resize.js +0 -1
- package/dist/src/process-lock.js +0 -1
- package/dist/src/runner-lease.js +0 -1
- package/dist/src/runner-sequence.js +0 -1
- package/dist/src/script-source-bundle.js +0 -16
- package/dist/src/sdk-android-adb.d.ts +0 -245
- package/dist/src/sdk-android-adb.js +0 -4
- package/dist/src/sdk.js +0 -1
- package/dist/src/setting-state.js +0 -1
- package/dist/src/shell-quote.js +0 -1
- package/dist/src/snapshot-session.js +0 -1
- package/dist/src/timing-safe-equal.js +0 -1
- package/dist/src/unsupported-interactor.js +0 -1
- package/dist/src/verdict.js +0 -1
- /package/dist/src/{recording-telemetry.js → telemetry.js} +0 -0
package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift
CHANGED
|
@@ -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
|
|
39
|
-
let
|
|
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
|
+
|
|
52
|
+
|
|
53
|
+
|
|
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
|
+
]
|
|
49
86
|
|
|
50
87
|
func elementTypeName(_ type: XCUIElement.ElementType) -> String {
|
|
51
|
-
|
|
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> = [
|
|
@@ -112,11 +111,11 @@ extension RunnerTests {
|
|
|
112
111
|
|
|
113
112
|
static let flatInteractiveFallbackBudget: TimeInterval = 1.0
|
|
114
113
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
120
119
|
func snapshotFast(app: XCUIApplication, options: PresentationOptions) throws -> DataPayload {
|
|
121
120
|
let deadline = Date().addingTimeInterval(Self.snapshotPlanBudget)
|
|
122
121
|
if let blocking = boundedBlockingSystemAlertSnapshot(deadline: deadline) {
|
|
@@ -133,7 +132,7 @@ extension RunnerTests {
|
|
|
133
132
|
|
|
134
133
|
func recursiveTreeSnapshotAcquisition(
|
|
135
134
|
context: SnapshotTraversalContext,
|
|
136
|
-
|
|
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
|
+
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
150
154
|
var nodes: [RawAXNode] = []
|
|
151
|
-
|
|
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
|
-
|
|
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
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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
|
|
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
|
|
211
|
-
let
|
|
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
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
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,67 +219,57 @@ extension RunnerTests {
|
|
|
262
219
|
seen.insert(key)
|
|
263
220
|
}
|
|
264
221
|
|
|
265
|
-
let currentIndex =
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
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
|
-
|
|
288
|
-
|
|
241
|
+
parentPresentedDepth: transition.presentedDepth,
|
|
242
|
+
parentTraversal: transition.traversal
|
|
289
243
|
)
|
|
290
244
|
)
|
|
291
245
|
}
|
|
292
246
|
}
|
|
293
247
|
|
|
294
|
-
if
|
|
248
|
+
if isDuplicate { continue }
|
|
295
249
|
|
|
296
|
-
|
|
297
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
|
|
325
|
-
|
|
272
|
+
|
|
326
273
|
func snapshotRaw(app: XCUIApplication, options: PresentationOptions) throws -> DataPayload {
|
|
327
274
|
let deadline = Date().addingTimeInterval(Self.snapshotPlanBudget)
|
|
328
275
|
if let blocking = boundedBlockingSystemAlertSnapshot(deadline: deadline) {
|
|
@@ -337,19 +284,24 @@ extension RunnerTests {
|
|
|
337
284
|
)
|
|
338
285
|
}
|
|
339
286
|
|
|
340
|
-
|
|
341
|
-
|
|
287
|
+
|
|
288
|
+
|
|
342
289
|
func boundedBlockingSystemAlertSnapshot(deadline: Date) -> DataPayload? {
|
|
343
290
|
boundedBlockingSystemAlertSnapshotBody(deadline: deadline) { probeDeadline in
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
|
|
344
296
|
return self.blockingSystemAlertSnapshot(deadline: probeDeadline)
|
|
345
297
|
}
|
|
346
298
|
}
|
|
347
299
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
|
|
353
305
|
private func boundedBlockingSystemAlertSnapshotBody(
|
|
354
306
|
deadline: Date,
|
|
355
307
|
probe: @escaping (Date) -> DataPayload?
|
|
@@ -369,7 +321,6 @@ extension RunnerTests {
|
|
|
369
321
|
let startedAt = Date()
|
|
370
322
|
do {
|
|
371
323
|
return try runMainThreadWork(
|
|
372
|
-
command: nil,
|
|
373
324
|
timeout: slice,
|
|
374
325
|
timeoutError: {
|
|
375
326
|
SnapshotCaptureFailure(
|
|
@@ -404,8 +355,8 @@ extension RunnerTests {
|
|
|
404
355
|
#endif
|
|
405
356
|
}
|
|
406
357
|
|
|
407
|
-
|
|
408
|
-
|
|
358
|
+
|
|
359
|
+
|
|
409
360
|
static func systemModalProbeSlice(
|
|
410
361
|
budget: TimeInterval,
|
|
411
362
|
deadlineRemaining: TimeInterval
|
|
@@ -416,38 +367,28 @@ extension RunnerTests {
|
|
|
416
367
|
|
|
417
368
|
func rawTreeSnapshotAcquisition(
|
|
418
369
|
context: SnapshotTraversalContext,
|
|
419
|
-
|
|
370
|
+
hint: CaptureHint
|
|
420
371
|
) throws -> SnapshotAcquisition {
|
|
421
372
|
var nodes: [RawAXNode] = []
|
|
422
373
|
|
|
423
374
|
func walk(_ snapshot: XCUIElementSnapshot, depth: Int, parentIndex: Int?) throws {
|
|
424
|
-
if let limit =
|
|
375
|
+
if let limit = hint.rawTraversalDepth, depth > limit { return }
|
|
425
376
|
|
|
426
|
-
let evaluation = evaluateSnapshot(snapshot
|
|
427
|
-
|
|
428
|
-
|
|
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
|
-
)
|
|
377
|
+
let evaluation = evaluateSnapshot(snapshot)
|
|
378
|
+
if nodes.count >= Self.rawSnapshotMaxNodes {
|
|
379
|
+
throw rawSnapshotTooLargeFailure(nodeCount: nodes.count + 1)
|
|
450
380
|
}
|
|
381
|
+
let currentIndex = nodes.count
|
|
382
|
+
nodes.append(
|
|
383
|
+
makeSnapshotNode(
|
|
384
|
+
snapshot: snapshot,
|
|
385
|
+
evaluation: evaluation,
|
|
386
|
+
depth: depth,
|
|
387
|
+
index: currentIndex,
|
|
388
|
+
parentIndex: parentIndex,
|
|
389
|
+
viewport: context.viewport
|
|
390
|
+
)
|
|
391
|
+
)
|
|
451
392
|
|
|
452
393
|
let children = snapshot.children
|
|
453
394
|
for child in children {
|
|
@@ -456,24 +397,36 @@ extension RunnerTests {
|
|
|
456
397
|
}
|
|
457
398
|
|
|
458
399
|
try walk(context.rootSnapshot, depth: 0, parentIndex: nil)
|
|
459
|
-
return SnapshotAcquisition(
|
|
400
|
+
return SnapshotAcquisition(
|
|
401
|
+
hint: hint,
|
|
402
|
+
nodes: nodes,
|
|
403
|
+
truncated: false,
|
|
404
|
+
effectiveDepth: nil,
|
|
405
|
+
viewport: context.viewport
|
|
406
|
+
)
|
|
460
407
|
}
|
|
461
408
|
|
|
462
409
|
func querySweepSnapshotAcquisition(
|
|
463
410
|
app: XCUIApplication,
|
|
464
|
-
|
|
411
|
+
hint: CaptureHint,
|
|
465
412
|
planDeadline: Date = .distantFuture
|
|
466
413
|
) -> SnapshotAcquisition {
|
|
467
414
|
var nodes: [RawAXNode] = [
|
|
468
415
|
interactiveRootNode(rect: .zero)
|
|
469
416
|
]
|
|
470
|
-
if
|
|
471
|
-
return SnapshotAcquisition(
|
|
417
|
+
if hint.rawTraversalDepth == 0 || hint.regularPresentedDepth == 0 {
|
|
418
|
+
return SnapshotAcquisition(
|
|
419
|
+
hint: hint,
|
|
420
|
+
nodes: nodes,
|
|
421
|
+
truncated: false,
|
|
422
|
+
effectiveDepth: nil,
|
|
423
|
+
viewport: .infinite
|
|
424
|
+
)
|
|
472
425
|
}
|
|
473
426
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
let sweepDeadline =
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
let sweepDeadline = hint.interactiveOnly
|
|
477
430
|
? Date().addingTimeInterval(Self.flatInteractiveFallbackBudget)
|
|
478
431
|
: Date.distantFuture
|
|
479
432
|
let deadline = min(sweepDeadline, planDeadline)
|
|
@@ -492,8 +445,7 @@ extension RunnerTests {
|
|
|
492
445
|
element: element,
|
|
493
446
|
index: 0,
|
|
494
447
|
parentIndex: 0,
|
|
495
|
-
viewport: viewport
|
|
496
|
-
options: options
|
|
448
|
+
viewport: viewport
|
|
497
449
|
) else {
|
|
498
450
|
continue
|
|
499
451
|
}
|
|
@@ -512,9 +464,9 @@ extension RunnerTests {
|
|
|
512
464
|
return left.type < right.type
|
|
513
465
|
}
|
|
514
466
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
|
|
518
470
|
let rootRect = viewport.isInfinite || viewport.isNull || viewport.isEmpty
|
|
519
471
|
? interactiveRootFrame(for: candidates)
|
|
520
472
|
: viewport
|
|
@@ -539,15 +491,21 @@ extension RunnerTests {
|
|
|
539
491
|
)
|
|
540
492
|
)
|
|
541
493
|
}
|
|
542
|
-
return SnapshotAcquisition(
|
|
494
|
+
return SnapshotAcquisition(
|
|
495
|
+
hint: hint,
|
|
496
|
+
nodes: nodes,
|
|
497
|
+
truncated: truncated,
|
|
498
|
+
effectiveDepth: nil,
|
|
499
|
+
viewport: viewport
|
|
500
|
+
)
|
|
543
501
|
}
|
|
544
502
|
|
|
545
503
|
func snapshotAccessibilityUnavailable(failure: SnapshotCaptureFailure) -> DataPayload {
|
|
546
504
|
NSLog("AGENT_DEVICE_RUNNER_SNAPSHOT_AX_UNAVAILABLE=%@", failure.message)
|
|
547
505
|
runnerAccessibilityHealth = .unavailable
|
|
548
506
|
invalidateCachedTarget(reason: Self.axSnapshotUnavailableReason)
|
|
549
|
-
|
|
550
|
-
|
|
507
|
+
|
|
508
|
+
|
|
551
509
|
return sparseTruncatedSnapshotPayload(
|
|
552
510
|
message: recoveredSnapshotMessage(failure),
|
|
553
511
|
snapshotQuality: SnapshotQuality(
|
|
@@ -593,6 +551,248 @@ extension RunnerTests {
|
|
|
593
551
|
}
|
|
594
552
|
|
|
595
553
|
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
|
|
608
|
+
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
|
|
637
|
+
|
|
638
|
+
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
|
|
675
|
+
|
|
676
|
+
|
|
677
|
+
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
|
|
721
|
+
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
|
|
743
|
+
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
|
|
751
|
+
|
|
752
|
+
|
|
753
|
+
|
|
754
|
+
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
|
|
789
|
+
|
|
790
|
+
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
|
|
596
796
|
private func interactiveRootNode(rect: CGRect) -> RawAXNode {
|
|
597
797
|
RawAXNode(
|
|
598
798
|
index: 0,
|
|
@@ -630,96 +830,31 @@ extension RunnerTests {
|
|
|
630
830
|
)
|
|
631
831
|
}
|
|
632
832
|
|
|
633
|
-
// MARK: - Snapshot Filtering
|
|
634
|
-
|
|
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
833
|
|
|
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
834
|
|
|
692
835
|
func makeSnapshotTraversalContext(
|
|
693
836
|
app: XCUIApplication,
|
|
694
|
-
|
|
837
|
+
hint: CaptureHint,
|
|
695
838
|
captureDeadline: Date = .distantFuture,
|
|
696
839
|
treeCaptureSliceBudgetOverride: TimeInterval? = nil
|
|
697
840
|
) throws -> SnapshotTraversalContext? {
|
|
698
|
-
let
|
|
699
|
-
command: nil,
|
|
841
|
+
let viewport = try runMainThreadWork(
|
|
700
842
|
timeout: min(1.0, max(0.1, captureDeadline.timeIntervalSinceNow)),
|
|
701
843
|
timeoutError: snapshotMainThreadTimeoutError("preparing tree snapshot")
|
|
702
844
|
) {
|
|
703
|
-
(
|
|
704
|
-
self.safeSnapshotViewport(app: app),
|
|
705
|
-
options.scope.flatMap { self.findScopeElement(app: app, scope: $0) } ?? app
|
|
706
|
-
)
|
|
845
|
+
self.safeSnapshotViewport(app: app)
|
|
707
846
|
}
|
|
708
847
|
|
|
709
848
|
let treeSliceBudget = treeCaptureSliceBudgetOverride ?? treeCaptureSliceBudget
|
|
710
849
|
let slice = min(treeSliceBudget, max(0.5, captureDeadline.timeIntervalSinceNow))
|
|
711
|
-
guard let rootSnapshot = try captureSnapshotRootBounded(
|
|
850
|
+
guard let rootSnapshot = try captureSnapshotRootBounded(app, sliceSeconds: slice) else {
|
|
712
851
|
return nil
|
|
713
852
|
}
|
|
714
853
|
|
|
715
|
-
let (flatSnapshots, snapshotRanges) = flattenedSnapshots(rootSnapshot)
|
|
716
854
|
return SnapshotTraversalContext(
|
|
717
|
-
queryRoot:
|
|
855
|
+
queryRoot: app,
|
|
718
856
|
rootSnapshot: rootSnapshot,
|
|
719
|
-
viewport: viewport
|
|
720
|
-
flatSnapshots: flatSnapshots,
|
|
721
|
-
snapshotRanges: snapshotRanges,
|
|
722
|
-
maxDepth: options.depth ?? Int.max
|
|
857
|
+
viewport: viewport
|
|
723
858
|
)
|
|
724
859
|
}
|
|
725
860
|
|
|
@@ -731,8 +866,8 @@ extension RunnerTests {
|
|
|
731
866
|
return abandonedTreeCaptureCount > 0
|
|
732
867
|
}
|
|
733
868
|
|
|
734
|
-
|
|
735
|
-
|
|
869
|
+
|
|
870
|
+
|
|
736
871
|
func retainAbandonedXCTestChannelWork() {
|
|
737
872
|
treeCaptureLock.lock()
|
|
738
873
|
abandonedTreeCaptureCount += 1
|
|
@@ -745,11 +880,11 @@ extension RunnerTests {
|
|
|
745
880
|
treeCaptureLock.unlock()
|
|
746
881
|
}
|
|
747
882
|
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
883
|
+
|
|
884
|
+
|
|
885
|
+
|
|
886
|
+
|
|
887
|
+
|
|
753
888
|
private func captureSnapshotRootBounded(
|
|
754
889
|
_ element: XCUIElement,
|
|
755
890
|
sliceSeconds: TimeInterval
|
|
@@ -758,7 +893,6 @@ extension RunnerTests {
|
|
|
758
893
|
return try captureSnapshotRoot(element)
|
|
759
894
|
}
|
|
760
895
|
return try runMainThreadWork(
|
|
761
|
-
command: nil,
|
|
762
896
|
timeout: sliceSeconds,
|
|
763
897
|
timeoutError: treeCaptureTimeoutError(sliceSeconds: sliceSeconds),
|
|
764
898
|
onAbandoned: {
|
|
@@ -856,26 +990,16 @@ extension RunnerTests {
|
|
|
856
990
|
failure.code == Self.axSnapshotErrorCode || isAxIllegalArgument(failure.message)
|
|
857
991
|
}
|
|
858
992
|
|
|
859
|
-
private func evaluateSnapshot(
|
|
860
|
-
_ snapshot: XCUIElementSnapshot,
|
|
861
|
-
in context: SnapshotTraversalContext
|
|
862
|
-
) -> SnapshotEvaluation {
|
|
993
|
+
private func evaluateSnapshot(_ snapshot: XCUIElementSnapshot) -> SnapshotEvaluation {
|
|
863
994
|
let label = aggregatedLabel(for: snapshot) ?? snapshot.label.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
864
995
|
let identifier = snapshot.identifier.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
865
996
|
let valueText = snapshotValueText(snapshot)
|
|
866
|
-
let laterNodes = laterSnapshots(
|
|
867
|
-
for: snapshot,
|
|
868
|
-
in: context.flatSnapshots,
|
|
869
|
-
ranges: context.snapshotRanges
|
|
870
|
-
)
|
|
871
997
|
return SnapshotEvaluation(
|
|
872
998
|
label: label,
|
|
873
999
|
identifier: identifier,
|
|
874
1000
|
valueText: valueText,
|
|
875
|
-
hittable: computedSnapshotHittable(snapshot, viewport: context.viewport, laterNodes: laterNodes),
|
|
876
1001
|
focused: snapshotHasFocus(snapshot),
|
|
877
|
-
selected: snapshotIsSelected(snapshot)
|
|
878
|
-
visible: isVisibleInViewport(snapshot.frame, context.viewport)
|
|
1002
|
+
selected: snapshotIsSelected(snapshot)
|
|
879
1003
|
)
|
|
880
1004
|
}
|
|
881
1005
|
|
|
@@ -884,7 +1008,8 @@ extension RunnerTests {
|
|
|
884
1008
|
evaluation: SnapshotEvaluation,
|
|
885
1009
|
depth: Int,
|
|
886
1010
|
index: Int,
|
|
887
|
-
parentIndex: Int
|
|
1011
|
+
parentIndex: Int?,
|
|
1012
|
+
viewport: CGRect
|
|
888
1013
|
) -> RawAXNode {
|
|
889
1014
|
return RawAXNode(
|
|
890
1015
|
index: index,
|
|
@@ -896,7 +1021,11 @@ extension RunnerTests {
|
|
|
896
1021
|
enabled: snapshot.isEnabled,
|
|
897
1022
|
focused: evaluation.focused ? true : nil,
|
|
898
1023
|
selected: evaluation.selected ? true : nil,
|
|
899
|
-
hittable:
|
|
1024
|
+
hittable: parentIndex != nil && SnapshotGeometry.isGeometricallyActionable(
|
|
1025
|
+
enabled: snapshot.isEnabled,
|
|
1026
|
+
frame: snapshot.frame,
|
|
1027
|
+
viewport: viewport
|
|
1028
|
+
),
|
|
900
1029
|
depth: depth,
|
|
901
1030
|
parentIndex: parentIndex,
|
|
902
1031
|
hiddenContentAbove: nil,
|
|
@@ -904,52 +1033,6 @@ extension RunnerTests {
|
|
|
904
1033
|
)
|
|
905
1034
|
}
|
|
906
1035
|
|
|
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
1036
|
private func snapshotValueText(_ snapshot: XCUIElementSnapshot) -> String? {
|
|
954
1037
|
guard let value = snapshot.value else { return nil }
|
|
955
1038
|
let text = String(describing: value).trimmingCharacters(in: .whitespacesAndNewlines)
|
|
@@ -990,134 +1073,47 @@ extension RunnerTests {
|
|
|
990
1073
|
return nil
|
|
991
1074
|
}
|
|
992
1075
|
|
|
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
1076
|
private func appendCollapsedTabFallbackNodes(
|
|
1009
1077
|
to nodes: inout [RawAXNode],
|
|
1010
1078
|
containerSnapshot: XCUIElementSnapshot,
|
|
1011
1079
|
resolveElements: () -> [XCUIElement],
|
|
1012
1080
|
depth: Int,
|
|
1013
|
-
parentIndex: Int
|
|
1081
|
+
parentIndex: Int,
|
|
1082
|
+
viewport: CGRect
|
|
1014
1083
|
) {
|
|
1015
1084
|
let fallbackNodes = collapsedTabFallbackNodes(
|
|
1016
1085
|
for: containerSnapshot,
|
|
1017
1086
|
resolveElements: resolveElements,
|
|
1018
1087
|
startingIndex: nodes.count,
|
|
1019
1088
|
depth: depth,
|
|
1020
|
-
parentIndex: parentIndex
|
|
1089
|
+
parentIndex: parentIndex,
|
|
1090
|
+
viewport: viewport
|
|
1021
1091
|
)
|
|
1022
1092
|
nodes.append(contentsOf: fallbackNodes)
|
|
1023
1093
|
}
|
|
1024
1094
|
|
|
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
1095
|
private func collapsedTabFallbackNodes(
|
|
1102
1096
|
for containerSnapshot: XCUIElementSnapshot,
|
|
1103
1097
|
resolveElements: () -> [XCUIElement],
|
|
1104
1098
|
startingIndex: Int,
|
|
1105
1099
|
depth: Int,
|
|
1106
|
-
parentIndex: Int
|
|
1100
|
+
parentIndex: Int,
|
|
1101
|
+
viewport: CGRect
|
|
1107
1102
|
) -> [RawAXNode] {
|
|
1108
1103
|
if !containerSnapshot.children.isEmpty { return [] }
|
|
1109
1104
|
guard shouldExpandCollapsedTabContainer(containerSnapshot) else { return [] }
|
|
1110
1105
|
let containerFrame = containerSnapshot.frame
|
|
1111
1106
|
if containerFrame.isNull || containerFrame.isEmpty { return [] }
|
|
1112
1107
|
|
|
1113
|
-
|
|
1114
|
-
|
|
1108
|
+
|
|
1109
|
+
|
|
1115
1110
|
let elements = resolveElements()
|
|
1116
1111
|
let candidates = elements.compactMap { element in
|
|
1117
1112
|
collapsedTabCandidateNode(
|
|
1118
1113
|
element: element,
|
|
1119
1114
|
containerSnapshot: containerSnapshot,
|
|
1120
|
-
containerFrame: containerFrame
|
|
1115
|
+
containerFrame: containerFrame,
|
|
1116
|
+
viewport: viewport
|
|
1121
1117
|
)
|
|
1122
1118
|
}
|
|
1123
1119
|
.sorted { left, right in
|
|
@@ -1130,7 +1126,7 @@ extension RunnerTests {
|
|
|
1130
1126
|
if candidates.count < 2 { return [] }
|
|
1131
1127
|
let rowMidpoints = candidates.map { $0.rect.y + ($0.rect.height / 2) }
|
|
1132
1128
|
let rowSpread = (rowMidpoints.max() ?? 0) - (rowMidpoints.min() ?? 0)
|
|
1133
|
-
|
|
1129
|
+
|
|
1134
1130
|
if rowSpread > max(24.0, Double(containerFrame.height) * 0.6) { return [] }
|
|
1135
1131
|
|
|
1136
1132
|
var seen = Set<String>()
|
|
@@ -1165,7 +1161,8 @@ extension RunnerTests {
|
|
|
1165
1161
|
private func collapsedTabCandidateNode(
|
|
1166
1162
|
element: XCUIElement,
|
|
1167
1163
|
containerSnapshot: XCUIElementSnapshot,
|
|
1168
|
-
containerFrame: CGRect
|
|
1164
|
+
containerFrame: CGRect,
|
|
1165
|
+
viewport: CGRect
|
|
1169
1166
|
) -> RawAXNode? {
|
|
1170
1167
|
var node: RawAXNode?
|
|
1171
1168
|
let exceptionMessage = RunnerObjCExceptionCatcher.catchException({
|
|
@@ -1205,7 +1202,11 @@ extension RunnerTests {
|
|
|
1205
1202
|
enabled: element.isEnabled,
|
|
1206
1203
|
focused: elementHasFocus(element) ? true : nil,
|
|
1207
1204
|
selected: element.isSelected ? true : nil,
|
|
1208
|
-
hittable:
|
|
1205
|
+
hittable: SnapshotGeometry.isGeometricallyActionable(
|
|
1206
|
+
enabled: element.isEnabled,
|
|
1207
|
+
frame: frame,
|
|
1208
|
+
viewport: viewport
|
|
1209
|
+
),
|
|
1209
1210
|
depth: 0,
|
|
1210
1211
|
parentIndex: nil,
|
|
1211
1212
|
hiddenContentAbove: nil,
|
|
@@ -1331,40 +1332,25 @@ extension RunnerTests {
|
|
|
1331
1332
|
element: XCUIElement,
|
|
1332
1333
|
index: Int,
|
|
1333
1334
|
parentIndex: Int?,
|
|
1334
|
-
viewport: CGRect
|
|
1335
|
-
options: PresentationOptions
|
|
1335
|
+
viewport: CGRect
|
|
1336
1336
|
) -> RawAXNode? {
|
|
1337
1337
|
var node: RawAXNode?
|
|
1338
1338
|
let exceptionMessage = RunnerObjCExceptionCatcher.catchException({
|
|
1339
1339
|
if !element.exists { return }
|
|
1340
|
+
|
|
1341
|
+
|
|
1340
1342
|
let frame = element.frame
|
|
1341
1343
|
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
1344
|
let label = element.label.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
1348
1345
|
let identifier = element.identifier.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
1349
1346
|
let valueText = snapshotValueText(element)
|
|
1350
1347
|
let elementType = element.elementType
|
|
1351
1348
|
let enabled = element.isEnabled
|
|
1352
|
-
let hittable =
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
identifier: identifier,
|
|
1357
|
-
valueText: valueText,
|
|
1358
|
-
visible: visible
|
|
1349
|
+
let hittable = SnapshotGeometry.isGeometricallyActionable(
|
|
1350
|
+
enabled: enabled,
|
|
1351
|
+
frame: frame,
|
|
1352
|
+
viewport: viewport
|
|
1359
1353
|
)
|
|
1360
|
-
if !flatSnapshotFilterDecision(
|
|
1361
|
-
filterNode,
|
|
1362
|
-
options: options,
|
|
1363
|
-
visibilityPolicy: .interactiveOnly,
|
|
1364
|
-
insideMatchedScope: false
|
|
1365
|
-
).include {
|
|
1366
|
-
return
|
|
1367
|
-
}
|
|
1368
1354
|
|
|
1369
1355
|
node = RawAXNode(
|
|
1370
1356
|
index: index,
|
|
@@ -1390,19 +1376,4 @@ extension RunnerTests {
|
|
|
1390
1376
|
return node
|
|
1391
1377
|
}
|
|
1392
1378
|
|
|
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
1379
|
}
|