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.
- 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.0.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.0.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.0.manifest.json} +4 -4
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.0.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.0.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.0.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 +49 -0
- package/apple/snapshot-bridge/SnapshotBridge.m +280 -0
- package/apple/snapshot-bridge/SnapshotBridgeRuntime.h +33 -0
- package/apple/snapshot-bridge/SnapshotBridgeRuntime.m +382 -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/RunnerAlertVerification.swift +36 -0
- 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/RunnerTapPointPolicy.swift +2 -2
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +16 -8
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +21 -88
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AlertObservation.swift +124 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +106 -103
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +6 -14
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +63 -91
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +13 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +72 -155
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXElementTypes.swift +12 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +74 -78
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +17 -9
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +42 -11
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +185 -461
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotBackendCapabilities.swift +98 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +224 -164
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentationInvariant.swift +19 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTiming.swift +110 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedCommitDeadline.swift +206 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +147 -25
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +1 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +24 -307
- 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+TextTyping.swift +49 -16
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +2 -11
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +4 -19
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +16 -20
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/RecordingExportSupport.swift +111 -0
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +42 -81
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-trim.swift +35 -82
- 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/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/back-mode.js +1 -0
- 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 +69 -50
- 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 +255 -231
- 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/format.js +2 -0
- 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/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/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-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-apple-resources.js +1 -0
- 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 +39 -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 -8
- 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-selector-query.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 +4 -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 +127 -41
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-device.js +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 +472 -144
- 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-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-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/linux/atspi-dump.py +54 -9
- package/package.json +56 -34
- 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
|
// 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,63 +219,53 @@ 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
|
|
|
@@ -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
|
-
|
|
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 =
|
|
370
|
+
if let limit = hint.rawTraversalDepth, depth > limit { return }
|
|
425
371
|
|
|
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
|
-
)
|
|
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(
|
|
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
|
-
|
|
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
|
|
471
|
-
return SnapshotAcquisition(
|
|
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 =
|
|
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(
|
|
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
|
-
|
|
590
|
+
hint: CaptureHint,
|
|
695
591
|
captureDeadline: Date = .distantFuture,
|
|
696
592
|
treeCaptureSliceBudgetOverride: TimeInterval? = nil
|
|
697
593
|
) throws -> SnapshotTraversalContext? {
|
|
698
|
-
let
|
|
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(
|
|
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:
|
|
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:
|
|
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:
|
|
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 =
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
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
|
}
|