agent-device 0.21.0 → 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/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.0.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.21.0.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.0.apk → 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.21.0.manifest.json → agent-device-android-snapshot-helper-0.21.1.manifest.json} +6 -6
- package/apple/snapshot-bridge/README.md +58 -1
- package/apple/snapshot-bridge/SnapshotBridge.m +6 -0
- package/apple/snapshot-bridge/SnapshotBridgeCapture.h +25 -0
- package/apple/snapshot-bridge/SnapshotBridgeCapture.m +138 -0
- package/apple/snapshot-bridge/SnapshotBridgeRuntime.h +1 -0
- package/apple/snapshot-bridge/SnapshotBridgeRuntime.m +32 -3
- 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/RunnerSelectorMatchPolicy.swift +15 -15
- 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 +668 -82
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +14 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+BlockingSystemModalResolution.swift +39 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +1065 -223
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +290 -0
- 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 +249 -61
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +101 -42
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +13 -13
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +51 -43
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +71 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +144 -7
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +13 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +216 -17
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +206 -22
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +289 -42
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotBackendCapabilities.swift +92 -22
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +617 -122
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTiming.swift +79 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedCommitDeadline.swift +71 -71
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +83 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +67 -67
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +4 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +17 -17
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +30 -30
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryReadiness.swift +31 -31
- 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 +19 -19
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +55 -17
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +26 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +125 -75
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/RecordingExportSupport.swift +9 -9
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +9 -9
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-trim.swift +4 -4
- package/dist/src/adapter.js +1 -1
- package/dist/src/adb-executor.js +1 -1
- package/dist/src/adb-failure.js +1 -1
- package/dist/src/agent-browser-process-record.js +1 -1
- package/dist/src/agent-browser-provider.js +1 -1
- 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 +1 -1
- package/dist/src/ai-sdk.js +1 -1
- package/dist/src/alert-runtime.js +1 -1
- package/dist/src/android-input-ownership.js +1 -1
- package/dist/src/app-catalog.js +1 -1
- package/dist/src/app-deployment-resolution.js +1 -1
- package/dist/src/app-inventory-contract.js +1 -1
- package/dist/src/app-inventory.js +1 -1
- package/dist/src/app-launch.js +2 -2
- package/dist/src/app-lifecycle.js +3 -3
- package/dist/src/app-lifecycle2.js +1 -1
- package/dist/src/app-log-files.js +1 -1
- package/dist/src/app-log-runtime2.js +3 -3
- package/dist/src/app-resolution.js +1 -1
- package/dist/src/apple-runner-platform.js +1 -0
- package/dist/src/application-lifecycle-interaction.js +1 -1
- package/dist/src/archive.js +1 -1
- package/dist/src/artifact-download.js +1 -1
- 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/boot-diagnostics.js +1 -1
- package/dist/src/capture.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +25 -21
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +4 -4
- package/dist/src/click-button.js +1 -1
- package/dist/src/client-metro-companion.js +1 -1
- package/dist/src/client-metro.js +1 -1
- package/dist/src/client-types.d.ts +27 -13
- package/dist/src/code-signature-cache.js +1 -1
- package/dist/src/code-signature.js +1 -1
- package/dist/src/command-schema.js +3 -3
- package/dist/src/command-tools.js +2 -2
- package/dist/src/command.js +1 -1
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/connection.js +3 -3
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/contracts.js +1 -1
- package/dist/src/daemon-client-lifecycle.js +1 -1
- package/dist/src/daemon.js +1 -1
- package/dist/src/debug-symbols-facade.js +1 -1
- package/dist/src/device-claim-rule.js +1 -1
- package/dist/src/device-inventory-context.js +1 -1
- package/dist/src/device-rotation.js +1 -1
- package/dist/src/device-selection-resolver.js +1 -1
- package/dist/src/device-session.js +1 -1
- package/dist/src/device2.js +1 -1
- package/dist/src/diagnostics.js +1 -1
- package/dist/src/dispatch-resolve.js +1 -1
- package/dist/src/doctor2.js +1 -1
- package/dist/src/error.js +1 -1
- package/dist/src/exec.js +1 -1
- package/dist/src/file.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/generic-settle.js +1 -1
- package/dist/src/gesture-plan.js +1 -1
- package/dist/src/gesture-runtime.js +1 -1
- package/dist/src/harmonyos.js +1 -1
- package/dist/src/hdc.js +1 -1
- package/dist/src/helper.js +2 -2
- package/dist/src/human-control-contract.js +1 -1
- package/dist/src/human-control.js +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +1 -1
- package/dist/src/input-actions2.js +2 -2
- package/dist/src/install-artifact-facade.js +1 -1
- package/dist/src/install-source-network-transport.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/interaction-positionals.js +1 -1
- package/dist/src/interaction-ref-policy.js +1 -1
- package/dist/src/interaction2.js +1 -1
- package/dist/src/interactor.js +5 -5
- package/dist/src/interactor2.js +1 -1
- package/dist/src/interactors.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +2 -2
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/internal/run-script-http-child.js +1 -1
- package/dist/src/inventory.js +2 -2
- package/dist/src/inventory2.js +1 -1
- package/dist/src/inventory3.js +1 -1
- package/dist/src/inventory5.js +1 -1
- package/dist/src/ios-snapshot-runtime.js +1 -1
- package/dist/src/ios-system-surface.js +1 -0
- package/dist/src/lease-scope.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun-runtime-dependencies.js +1 -1
- package/dist/src/limrun.d.ts +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/location-coordinates.js +1 -1
- package/dist/src/managed-device-scope.js +1 -1
- package/dist/src/mechanics.js +16 -16
- package/dist/src/multitouch-support.js +1 -1
- package/dist/src/observation.js +1 -1
- package/dist/src/open-target-resolution.js +1 -0
- package/dist/src/owner-identity.js +3 -3
- package/dist/src/parameterized-recorded-fill.js +1 -1
- package/dist/src/perf-facade.js +2 -2
- package/dist/src/perf-process-identity.js +1 -0
- package/dist/src/perf-runtime-operation-builder.js +1 -1
- package/dist/src/perf-runtime-plan.js +1 -1
- package/dist/src/perf.js +1 -1
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/platform-runtime-android-adb-host.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 -1
- package/dist/src/platform-runtime-open-target.js +1 -1
- package/dist/src/platform-runtime-operation-host.js +2 -2
- 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-simulator-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
- package/dist/src/platform-runtime-unavailable.js +1 -1
- package/dist/src/platform-runtime.js +1 -1
- package/dist/src/platform-runtime2.js +1 -1
- package/dist/src/png-worker-contract.js +1 -1
- package/dist/src/prepare-kind.js +1 -1
- package/dist/src/provider-device-runtime.js +1 -1
- package/dist/src/provider-session-ownership.js +1 -1
- package/dist/src/provider-webdriver.js +1 -1
- package/dist/src/proxy.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/rect-center.js +1 -1
- package/dist/src/register-builtins.js +1 -1
- package/dist/src/registry.js +37 -36
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/replay-divergence.js +1 -1
- package/dist/src/replay.js +2 -2
- package/dist/src/reporting.js +9 -8
- package/dist/src/request-admission.js +1 -1
- package/dist/src/request-cancel.js +1 -1
- package/dist/src/request-runtime-binding.js +1 -1
- package/dist/src/retry.js +1 -1
- package/dist/src/runner-cache-metadata.js +2 -2
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-operations-facade.js +1 -1
- package/dist/src/runner.js +1 -1
- package/dist/src/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 -4
- 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/screen-recording-live-handle.js +1 -1
- package/dist/src/screen-recording-options.js +1 -1
- package/dist/src/screen-recording-resource-recovery.js +1 -1
- package/dist/src/screenshot-density.js +1 -1
- package/dist/src/screenshot-runtime.js +1 -1
- package/dist/src/screenshot.js +1 -1
- package/dist/src/screenshot3.js +3 -3
- package/dist/src/script.js +1 -1
- package/dist/src/scroll-command.js +1 -1
- package/dist/src/scroll-gesture.js +1 -1
- package/dist/src/sdk-batch-runner.js +2 -2
- package/dist/src/sdk-batch.js +2 -2
- package/dist/src/sdk-contracts.d.ts +44 -1
- 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-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 +69 -13
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/server.js +3 -3
- package/dist/src/session-allocation.js +1 -1
- package/dist/src/session-observation.js +1 -0
- package/dist/src/session-routing.js +1 -1
- package/dist/src/session-runtime-admission.js +1 -1
- package/dist/src/session-snapshot.js +1 -1
- package/dist/src/session-store.js +3 -3
- package/dist/src/session-target-evidence.js +1 -1
- package/dist/src/session2.js +5 -5
- package/dist/src/settings.js +1 -1
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-quality-backend-capabilities.js +1 -1
- package/dist/src/snapshot-quality-verdict.js +1 -1
- package/dist/src/snapshot-runtime-binding.js +1 -1
- package/dist/src/snapshot-runtime.js +1 -1
- package/dist/src/snapshot-state.js +1 -1
- package/dist/src/snapshot2.js +1 -1
- package/dist/src/snapshot3.js +1 -1
- package/dist/src/snapshot4.js +1 -1
- package/dist/src/src.js +1 -1
- package/dist/src/src7.js +2 -2
- package/dist/src/src8.js +2 -2
- package/dist/src/string-enum.js +1 -1
- package/dist/src/takeover.js +1 -1
- package/dist/src/tool-provider.js +2 -2
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/tool-provider3.js +1 -1
- package/dist/src/toolchain-probe.js +1 -1
- package/dist/src/touch-reference-frame.js +1 -0
- package/dist/src/touch-runtime.js +1 -1
- package/dist/src/transport.js +1 -1
- package/dist/src/tv-remote.js +1 -1
- package/dist/src/type-text-runtime.js +1 -1
- package/dist/src/update-check.js +1 -1
- package/dist/src/verified-file.js +1 -1
- package/dist/src/video.js +1 -1
- package/dist/src/web.js +1 -1
- package/dist/src/web2.js +1 -1
- package/dist/src/webdriver-source.js +1 -1
- package/dist/src/window-state.js +1 -0
- package/package.json +3 -2
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.0.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.0.apk.sha256 +0 -1
- package/dist/src/back-mode.js +0 -1
- package/dist/src/format.js +0 -2
- package/dist/src/platform-runtime-apple-resources.js +0 -1
- package/dist/src/runner-selector-query.js +0 -1
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
65454a4663596adfc7fccd9a30e42f02b5ecde17eb1514fa115ef3036171b995 agent-device-android-ime-helper-0.21.1.apk
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "android-ime-helper",
|
|
3
|
-
"version": "0.21.
|
|
4
|
-
"assetName": "agent-device-android-ime-helper-0.21.
|
|
5
|
-
"sha256": "
|
|
3
|
+
"version": "0.21.1",
|
|
4
|
+
"assetName": "agent-device-android-ime-helper-0.21.1.apk",
|
|
5
|
+
"sha256": "65454a4663596adfc7fccd9a30e42f02b5ecde17eb1514fa115ef3036171b995",
|
|
6
6
|
"packageName": "com.callstack.agentdevice.imehelper",
|
|
7
|
-
"versionCode":
|
|
7
|
+
"versionCode": 21001,
|
|
8
8
|
"serviceComponent": "com.callstack.agentdevice.imehelper/.TestInputMethodService",
|
|
9
9
|
"broadcastProtocol": "android-ime-helper-v1"
|
|
10
10
|
}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
6ee75909ac499eca439d3663717d8fc1928ada3fec71bf2ae85fb567967a3793 agent-device-android-snapshot-helper-0.21.1.apk
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "android-snapshot-helper",
|
|
3
|
-
"version": "0.21.
|
|
4
|
-
"releaseTag": "v0.21.
|
|
5
|
-
"assetName": "agent-device-android-snapshot-helper-0.21.
|
|
3
|
+
"version": "0.21.1",
|
|
4
|
+
"releaseTag": "v0.21.1",
|
|
5
|
+
"assetName": "agent-device-android-snapshot-helper-0.21.1.apk",
|
|
6
6
|
"apkUrl": null,
|
|
7
|
-
"sha256": "
|
|
8
|
-
"checksumName": "agent-device-android-snapshot-helper-0.21.
|
|
7
|
+
"sha256": "6ee75909ac499eca439d3663717d8fc1928ada3fec71bf2ae85fb567967a3793",
|
|
8
|
+
"checksumName": "agent-device-android-snapshot-helper-0.21.1.apk.sha256",
|
|
9
9
|
"packageName": "com.callstack.agentdevice.snapshothelper",
|
|
10
|
-
"versionCode":
|
|
10
|
+
"versionCode": 21001,
|
|
11
11
|
"instrumentationRunner": "com.callstack.agentdevice.snapshothelper/.SnapshotInstrumentation",
|
|
12
12
|
"minSdk": 23,
|
|
13
13
|
"targetSdk": 36,
|
|
@@ -8,7 +8,7 @@ and is never downloaded, pre-signed, or built by npm installation.
|
|
|
8
8
|
|
|
9
9
|
The guest process uses the `XCTAccessibilityFramework` remote-access client
|
|
10
10
|
from the simulator runtime and the `userTestingSnapshotForElement:options:error:`
|
|
11
|
-
|
|
11
|
+
snapshot API. Requests and responses are length-prefixed JSON frames:
|
|
12
12
|
|
|
13
13
|
```text
|
|
14
14
|
uint32 big-endian byte length
|
|
@@ -47,3 +47,60 @@ app tree. The existing route then uses XCTest, which owns system-modal
|
|
|
47
47
|
resolution. Secondary owners such as the return-to-app status-bar control do
|
|
48
48
|
not replace the native primary owner. The route's generation circuit remains
|
|
49
49
|
disabled after fallback until that app relaunches.
|
|
50
|
+
|
|
51
|
+
## Remote content
|
|
52
|
+
|
|
53
|
+
The reader snapshots one process. A WebKit page — Safari's or a `WKWebView`'s —
|
|
54
|
+
lives in a WebContent process and appears in that tree as an `AXRemoteElement`
|
|
55
|
+
leaf under the web view. The guest returns the leaf as delivered; the host
|
|
56
|
+
refuses a tree in which such a leaf sits under a web view and reaches the
|
|
57
|
+
viewport, or reports no frame (`remote-content-boundary`), and routes that app
|
|
58
|
+
generation to XCTest, which resolves remote elements (#2484). A zero-area or
|
|
59
|
+
off-screen leaf is published: it hosts nothing the capture can miss.
|
|
60
|
+
|
|
61
|
+
## Bounded depth recovery
|
|
62
|
+
|
|
63
|
+
A healthy capture uses one native request. If native acquisition rejects it,
|
|
64
|
+
`SnapshotBridgeCapture.m` retries supported native failure codes at lower depths
|
|
65
|
+
and fetches withheld children from their accessibility elements. The completed
|
|
66
|
+
tree keeps the original depth and node limits; partial trees disclose truncation.
|
|
67
|
+
The traversal depth counts edges below the root; native requests count the root
|
|
68
|
+
as one level. Each acquisition allows two lower-depth retries, and recovery
|
|
69
|
+
allows at most 32 native requests within the existing capture deadline,
|
|
70
|
+
checks foreground ownership on every request, and returns a failure when it
|
|
71
|
+
cannot complete a continuation. Budget exhaustion and malformed continuations
|
|
72
|
+
use non-launch failure codes, so the route falls back without launch re-polling.
|
|
73
|
+
At each native fragment boundary, an absent or invalid child count means unknown
|
|
74
|
+
completeness and fails closed. Natural leaves above that boundary need no
|
|
75
|
+
continuation evidence. Unchanged native dictionaries and child arrays are reused.
|
|
76
|
+
|
|
77
|
+
## Accepted-depth hints
|
|
78
|
+
|
|
79
|
+
The host source (`packages/platform-apple/src/snapshot-source/depth-hints.ts`)
|
|
80
|
+
remembers the native levels a finished recovery accepted, keyed by the resolved
|
|
81
|
+
target id, its app generation, and this producer. The next capture of that
|
|
82
|
+
generation sends `nativeLevelsHint`, so the guest's first request asks for the
|
|
83
|
+
accepted levels instead of re-paying the known rejection. A hint changes the
|
|
84
|
+
request strategy only: the delivered depth, node bounds, and completeness rules
|
|
85
|
+
are unchanged. Hints are learned only from a recovery that observed a rejection
|
|
86
|
+
and then finished (a tree bounded by the requested depth or node budget still
|
|
87
|
+
teaches), never cross apps, generations, or producers, and expire after eight
|
|
88
|
+
hinted captures so the next capture probes the full depth again; a capture that
|
|
89
|
+
merely succeeds at the hinted depth does not renew it. Explicit raw-depth
|
|
90
|
+
requests neither use nor teach hints. Every response carries `recovery`
|
|
91
|
+
(`requests`, `rejected`, `continuations`, `acceptedLevels`), which the host
|
|
92
|
+
emits as the `ios_snapshot_source_recovery` diagnostic.
|
|
93
|
+
|
|
94
|
+
## Recovery conformance
|
|
95
|
+
|
|
96
|
+
`contracts/fixtures/ios-ax-recovery-conformance.json` is the shared, executable
|
|
97
|
+
recovery contract for this bridge and the XCTest runner's private AX bridge.
|
|
98
|
+
`packages/platform-apple/src/snapshot-source/fixtures/recovery-conformance.m`
|
|
99
|
+
replays each case through `captureSnapshotTree`; the runner replays the same
|
|
100
|
+
cases through its own bridge in
|
|
101
|
+
`RunnerTests+AXRecoveryConformanceTests.swift`. Each expectation names the
|
|
102
|
+
outcome, the native request accounting, and the delivered tree as a canonical
|
|
103
|
+
preorder signature with its retained node count, so a producer that drops,
|
|
104
|
+
duplicates, reorders, or re-parents nodes cannot pass as complete. The fixture
|
|
105
|
+
records each producer's expectation and documents the intentional differences
|
|
106
|
+
(depth vocabulary, ladders, completeness evidence, budgets, hint lifetime).
|
|
@@ -85,6 +85,11 @@ static NSDictionary *handleRequest(NSDictionary *request)
|
|
|
85
85
|
!validBoundInteger(request[@"maxResponseBytes"], 1024, kMaximumFrameBytes, &maxResponseBytes)) {
|
|
86
86
|
return failureResponse(requestId, @"bad_request", @"bounds-invalid", @"snapshot bridge request bounds are outside the bridge limits");
|
|
87
87
|
}
|
|
88
|
+
NSUInteger nativeLevelsHint = 0;
|
|
89
|
+
if (request[@"nativeLevelsHint"] != nil &&
|
|
90
|
+
!validBoundInteger(request[@"nativeLevelsHint"], 1, kMaximumDepth + 1, &nativeLevelsHint)) {
|
|
91
|
+
return failureResponse(requestId, @"bad_request", @"bounds-invalid", @"nativeLevelsHint is outside the bridge depth limits");
|
|
92
|
+
}
|
|
88
93
|
|
|
89
94
|
NSString *setupError = nil;
|
|
90
95
|
BridgeRuntime *runtime = sharedRuntime(&setupError);
|
|
@@ -98,6 +103,7 @@ static NSDictionary *handleRequest(NSDictionary *request)
|
|
|
98
103
|
NSDictionary *response = [runtime snapshotForProcess:pidValue.intValue
|
|
99
104
|
maxDepth:maxDepth
|
|
100
105
|
maxNodes:maxNodes
|
|
106
|
+
nativeLevelsHint:nativeLevelsHint
|
|
101
107
|
requestId:requestId
|
|
102
108
|
generation:generation
|
|
103
109
|
maxDurationMs:maxDurationMs
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
|
|
3
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
4
|
+
|
|
5
|
+
typedef id _Nullable (^SnapshotElementReader)(id element, NSUInteger depth, NSUInteger nodes, NSError **error);
|
|
6
|
+
|
|
7
|
+
/// Native request accounting for one acquisition: requests issued, requests the accessibility
|
|
8
|
+
/// server rejected at their depth, continuations (requests that reached the reader beyond the
|
|
9
|
+
/// root's accepted one), and the native levels of the last accepted request.
|
|
10
|
+
typedef struct {
|
|
11
|
+
NSUInteger requests;
|
|
12
|
+
NSUInteger rejected;
|
|
13
|
+
NSUInteger continuations;
|
|
14
|
+
NSUInteger acceptedLevels;
|
|
15
|
+
} SnapshotCaptureRecovery;
|
|
16
|
+
|
|
17
|
+
/// Materializes one bounded tree; retries bounded native acquisition failures and re-roots withheld
|
|
18
|
+
/// children. `nativeLevelsHint` (0 for none) caps only the first request's native levels; the
|
|
19
|
+
/// delivered depth, node bounds, and completeness rules are unchanged.
|
|
20
|
+
NSDictionary *_Nullable captureSnapshotTree(id element, NSUInteger maxDepth, NSUInteger maxNodes,
|
|
21
|
+
NSUInteger nativeLevelsHint, SnapshotElementReader reader,
|
|
22
|
+
BOOL *truncated, SnapshotCaptureRecovery *_Nullable recovery,
|
|
23
|
+
NSError **error);
|
|
24
|
+
|
|
25
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#import "SnapshotBridgeCapture.h"
|
|
2
|
+
|
|
3
|
+
static NSString *const attributesKey = @"UIAccessibilitySnapshotKeyAttributes";
|
|
4
|
+
static NSString *const childrenKey = @"UIAccessibilitySnapshotKeyChildren";
|
|
5
|
+
static NSString *const childCountKey = @"UIAccessibilitySnapshotKeyChildrenCount";
|
|
6
|
+
static NSString *const elementKey = @"UIAccessibilitySnapshotKeyElement";
|
|
7
|
+
static const NSUInteger maximumRequests = 32;
|
|
8
|
+
|
|
9
|
+
@interface SnapshotTreeCapture : NSObject
|
|
10
|
+
@property(nonatomic, copy) SnapshotElementReader reader;
|
|
11
|
+
@property(nonatomic) NSUInteger acceptedDepth;
|
|
12
|
+
@property(nonatomic) NSUInteger remainingNodes;
|
|
13
|
+
@property(nonatomic) NSUInteger maximumNodes;
|
|
14
|
+
@property(nonatomic) NSUInteger requests;
|
|
15
|
+
@property(nonatomic) NSUInteger rejected;
|
|
16
|
+
@property(nonatomic) BOOL truncated;
|
|
17
|
+
- (nullable NSDictionary *)read:(id)element depth:(NSUInteger)depth error:(NSError **)error;
|
|
18
|
+
- (nullable NSDictionary *)materialize:(NSDictionary *)tree depth:(NSUInteger)depth nativeLevels:(NSUInteger)nativeLevels error:(NSError **)error;
|
|
19
|
+
@end
|
|
20
|
+
|
|
21
|
+
@implementation SnapshotTreeCapture
|
|
22
|
+
- (nullable NSDictionary *)read:(id)element depth:(NSUInteger)depth error:(NSError **)error
|
|
23
|
+
{
|
|
24
|
+
NSUInteger attemptDepth = MIN(depth, self.acceptedDepth);
|
|
25
|
+
for (NSUInteger retries = 0;; retries++) {
|
|
26
|
+
if (self.requests >= maximumRequests) {
|
|
27
|
+
if (error) *error = [NSError errorWithDomain:@"agent-device.snapshot" code:1
|
|
28
|
+
userInfo:@{NSLocalizedDescriptionKey: @"snapshot continuation request budget exhausted"}];
|
|
29
|
+
return nil;
|
|
30
|
+
}
|
|
31
|
+
self.requests++;
|
|
32
|
+
NSError *failure = nil;
|
|
33
|
+
id tree = self.reader(element, attemptDepth, MIN(self.maximumNodes, self.remainingNodes + 1), &failure);
|
|
34
|
+
if (tree) return tree;
|
|
35
|
+
NSNumber *nativeCode = failure.userInfo[@"accessibility-error"];
|
|
36
|
+
BOOL rejected = ([nativeCode isKindOfClass:NSNumber.class] && nativeCode.integerValue == -25201) ||
|
|
37
|
+
([failure.domain isEqualToString:@"com.apple.dt.xctest.automation-support.error"] && failure.code == 5);
|
|
38
|
+
if (rejected) self.rejected++;
|
|
39
|
+
if (!rejected || attemptDepth <= 1 || retries >= 2) {
|
|
40
|
+
if (error) *error = failure;
|
|
41
|
+
return nil;
|
|
42
|
+
}
|
|
43
|
+
attemptDepth = MAX(1, attemptDepth / 2);
|
|
44
|
+
self.acceptedDepth = attemptDepth;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
- (nullable NSDictionary *)materialize:(NSDictionary *)tree depth:(NSUInteger)depth nativeLevels:(NSUInteger)nativeLevels error:(NSError **)error
|
|
49
|
+
{
|
|
50
|
+
if (![tree isKindOfClass:NSDictionary.class] ||
|
|
51
|
+
![tree[attributesKey] isKindOfClass:NSDictionary.class] ||
|
|
52
|
+
![tree[childrenKey] isKindOfClass:NSArray.class]) {
|
|
53
|
+
if (error) *error = [NSError errorWithDomain:@"agent-device.snapshot" code:2
|
|
54
|
+
userInfo:@{NSLocalizedDescriptionKey: @"malformed snapshot continuation"}];
|
|
55
|
+
return nil;
|
|
56
|
+
}
|
|
57
|
+
if (self.remainingNodes == 0) {
|
|
58
|
+
self.truncated = YES;
|
|
59
|
+
return nil;
|
|
60
|
+
}
|
|
61
|
+
self.remainingNodes--;
|
|
62
|
+
NSArray *children = tree[childrenKey];
|
|
63
|
+
NSNumber *childCount = tree[childCountKey];
|
|
64
|
+
BOOL knownChildCount = [childCount isKindOfClass:NSNumber.class] && childCount.doubleValue >= 0 &&
|
|
65
|
+
childCount.doubleValue == (double)childCount.unsignedIntegerValue;
|
|
66
|
+
if (nativeLevels <= 1 && !knownChildCount && depth <= 1) self.truncated = YES;
|
|
67
|
+
if (depth > 1 && nativeLevels <= 1 && !knownChildCount) {
|
|
68
|
+
if (error) *error = [NSError errorWithDomain:@"agent-device.snapshot" code:6
|
|
69
|
+
userInfo:@{NSLocalizedDescriptionKey: @"snapshot boundary child count unavailable"}];
|
|
70
|
+
return nil;
|
|
71
|
+
}
|
|
72
|
+
BOOL withheld = knownChildCount && childCount.unsignedIntegerValue > children.count;
|
|
73
|
+
if (depth <= 1 || self.remainingNodes == 0) {
|
|
74
|
+
self.truncated |= children.count > 0 || withheld;
|
|
75
|
+
if (children.count == 0) return tree;
|
|
76
|
+
NSMutableDictionary *bounded = [tree mutableCopy];
|
|
77
|
+
bounded[childrenKey] = @[];
|
|
78
|
+
return bounded;
|
|
79
|
+
}
|
|
80
|
+
if (withheld && children.count < self.remainingNodes) {
|
|
81
|
+
id element = tree[elementKey];
|
|
82
|
+
if (!element) {
|
|
83
|
+
if (error) *error = [NSError errorWithDomain:@"agent-device.snapshot" code:3
|
|
84
|
+
userInfo:@{NSLocalizedDescriptionKey: @"snapshot continuation element unavailable"}];
|
|
85
|
+
return nil;
|
|
86
|
+
}
|
|
87
|
+
NSDictionary *continuation = [self read:element depth:depth error:error];
|
|
88
|
+
if (!continuation) return nil;
|
|
89
|
+
nativeLevels = MIN(depth, self.acceptedDepth);
|
|
90
|
+
children = continuation[childrenKey];
|
|
91
|
+
if (![children isKindOfClass:NSArray.class] || children.count < MIN(childCount.unsignedIntegerValue, self.remainingNodes)) {
|
|
92
|
+
if (error) *error = [NSError errorWithDomain:@"agent-device.snapshot" code:4
|
|
93
|
+
userInfo:@{NSLocalizedDescriptionKey: @"snapshot continuation children unavailable"}];
|
|
94
|
+
return nil;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (withheld && children.count < childCount.unsignedIntegerValue) self.truncated = YES;
|
|
98
|
+
NSMutableArray *materialized = nil;
|
|
99
|
+
NSUInteger index = 0;
|
|
100
|
+
for (NSDictionary *child in children) {
|
|
101
|
+
if (self.remainingNodes == 0) {
|
|
102
|
+
self.truncated = YES;
|
|
103
|
+
if (!materialized) materialized = [[children subarrayWithRange:NSMakeRange(0, index)] mutableCopy];
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
NSDictionary *node = [self materialize:child depth:depth - 1 nativeLevels:(nativeLevels > 0 ? nativeLevels - 1 : 0) error:error];
|
|
107
|
+
if (!node) return nil;
|
|
108
|
+
if (node != child && !materialized) materialized = [[children subarrayWithRange:NSMakeRange(0, index)] mutableCopy];
|
|
109
|
+
[materialized addObject:node];
|
|
110
|
+
index++;
|
|
111
|
+
}
|
|
112
|
+
if (!materialized && children == tree[childrenKey]) return tree;
|
|
113
|
+
NSMutableDictionary *result = [tree mutableCopy];
|
|
114
|
+
result[childrenKey] = materialized ?: children;
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
@end
|
|
118
|
+
|
|
119
|
+
NSDictionary *captureSnapshotTree(id element, NSUInteger maxDepth, NSUInteger maxNodes,
|
|
120
|
+
NSUInteger nativeLevelsHint, SnapshotElementReader reader,
|
|
121
|
+
BOOL *truncated, SnapshotCaptureRecovery *recovery, NSError **error)
|
|
122
|
+
{
|
|
123
|
+
SnapshotTreeCapture *capture = [SnapshotTreeCapture new];
|
|
124
|
+
capture.reader = reader;
|
|
125
|
+
capture.acceptedDepth = nativeLevelsHint > 0 ? MIN(maxDepth + 1, nativeLevelsHint) : maxDepth + 1;
|
|
126
|
+
capture.remainingNodes = maxNodes;
|
|
127
|
+
capture.maximumNodes = maxNodes;
|
|
128
|
+
NSDictionary *tree = [capture read:element depth:maxDepth + 1 error:error];
|
|
129
|
+
NSDictionary *result = tree ? [capture materialize:tree depth:maxDepth + 1 nativeLevels:capture.acceptedDepth error:error] : nil;
|
|
130
|
+
*truncated = capture.truncated;
|
|
131
|
+
if (recovery) {
|
|
132
|
+
recovery->requests = capture.requests;
|
|
133
|
+
recovery->rejected = capture.rejected;
|
|
134
|
+
recovery->continuations = capture.requests - capture.rejected - (tree ? 1 : 0);
|
|
135
|
+
recovery->acceptedLevels = tree ? capture.acceptedDepth : 0;
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
@@ -22,6 +22,7 @@ NSDictionary *failureResponse(NSString *requestId,
|
|
|
22
22
|
- (nullable NSDictionary *)snapshotForProcess:(pid_t)pid
|
|
23
23
|
maxDepth:(NSUInteger)maxDepth
|
|
24
24
|
maxNodes:(NSUInteger)maxNodes
|
|
25
|
+
nativeLevelsHint:(NSUInteger)nativeLevelsHint
|
|
25
26
|
requestId:(NSString *)requestId
|
|
26
27
|
generation:(NSString *)generation
|
|
27
28
|
maxDurationMs:(NSUInteger)maxDurationMs
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
#import "SnapshotBridgeRuntime.h"
|
|
8
|
+
#import "SnapshotBridgeCapture.h"
|
|
8
9
|
|
|
9
10
|
#import <CoreGraphics/CoreGraphics.h>
|
|
10
11
|
#import <objc/message.h>
|
|
@@ -17,7 +18,7 @@
|
|
|
17
18
|
NSString *const kProtocolVersionKey = @"protocolVersion";
|
|
18
19
|
NSString *const kSourceVersionKey = @"sourceVersion";
|
|
19
20
|
NSString *const kRequestIdKey = @"requestId";
|
|
20
|
-
NSString *const kSourceVersion = @"agent-device-simulator-ax-v1.5.
|
|
21
|
+
NSString *const kSourceVersion = @"agent-device-simulator-ax-v1.5.5";
|
|
21
22
|
const NSUInteger kProtocolVersion = 1;
|
|
22
23
|
const uint32_t kMaximumFrameBytes = 16 * 1024 * 1024;
|
|
23
24
|
const NSUInteger kMaximumDepth = 128;
|
|
@@ -261,6 +262,7 @@ static void finishRequestWatchdog(dispatch_source_t watchdog, SnapshotWatchdogSt
|
|
|
261
262
|
- (nullable NSDictionary *)snapshotForProcess:(pid_t)pid
|
|
262
263
|
maxDepth:(NSUInteger)maxDepth
|
|
263
264
|
maxNodes:(NSUInteger)maxNodes
|
|
265
|
+
nativeLevelsHint:(NSUInteger)nativeLevelsHint
|
|
264
266
|
requestId:(NSString *)requestId
|
|
265
267
|
generation:(NSString *)generation
|
|
266
268
|
maxDurationMs:(NSUInteger)maxDurationMs
|
|
@@ -311,13 +313,27 @@ static void finishRequestWatchdog(dispatch_source_t watchdog, SnapshotWatchdogSt
|
|
|
311
313
|
BOOL automationEnabled = [self assertAutomationMode:YES];
|
|
312
314
|
NSError *runtimeError = nil;
|
|
313
315
|
id snapshot = nil;
|
|
316
|
+
BOOL acquisitionTruncated = NO;
|
|
317
|
+
SnapshotCaptureRecovery recovery = {0, 0, 0, 0};
|
|
314
318
|
@try {
|
|
315
319
|
if (![self isPrimaryForegroundProcess:pid]) {
|
|
316
320
|
if (error) *error = failureResponse(requestId, @"unsupported", @"foreground-owner-unverified", @"target app is not the primary foreground accessibility owner");
|
|
317
321
|
finishRequestWatchdog(watchdog, watchdogState);
|
|
318
322
|
return nil;
|
|
319
323
|
}
|
|
320
|
-
snapshot =
|
|
324
|
+
snapshot = captureSnapshotTree((__bridge id)raw, maxDepth, maxNodes, nativeLevelsHint,
|
|
325
|
+
^id(id element, NSUInteger depth, NSUInteger nodes, NSError **captureError) {
|
|
326
|
+
if (![self isPrimaryForegroundProcess:pid]) {
|
|
327
|
+
if (captureError) *captureError = [NSError errorWithDomain:@"agent-device.snapshot" code:5
|
|
328
|
+
userInfo:@{NSLocalizedDescriptionKey: @"foreground owner changed during continuation"}];
|
|
329
|
+
return nil;
|
|
330
|
+
}
|
|
331
|
+
NSMutableDictionary *bounded = [options mutableCopy];
|
|
332
|
+
bounded[@"maxDepth"] = @(depth);
|
|
333
|
+
bounded[@"maxChildren"] = @(nodes);
|
|
334
|
+
bounded[@"maxArrayCount"] = @(nodes);
|
|
335
|
+
return [_framework userTestingSnapshotForElement:element options:bounded error:captureError];
|
|
336
|
+
}, &acquisitionTruncated, &recovery, &runtimeError);
|
|
321
337
|
if (![self isPrimaryForegroundProcess:pid]) {
|
|
322
338
|
if (error) *error = failureResponse(requestId, @"unsupported", @"foreground-owner-changed", @"foreground accessibility ownership changed during acquisition");
|
|
323
339
|
finishRequestWatchdog(watchdog, watchdogState);
|
|
@@ -328,6 +344,13 @@ static void finishRequestWatchdog(dispatch_source_t watchdog, SnapshotWatchdogSt
|
|
|
328
344
|
finishRequestWatchdog(watchdog, watchdogState);
|
|
329
345
|
return nil;
|
|
330
346
|
}
|
|
347
|
+
if (!snapshot && [runtimeError.domain isEqualToString:@"agent-device.snapshot"]) {
|
|
348
|
+
BOOL exhausted = runtimeError.code == 1;
|
|
349
|
+
if (error) *error = failureResponse(requestId, exhausted ? @"reader_unavailable" : @"malformed_tree",
|
|
350
|
+
exhausted ? @"continuation-budget-exhausted" : @"snapshot-tree-malformed", runtimeError.localizedDescription);
|
|
351
|
+
finishRequestWatchdog(watchdog, watchdogState);
|
|
352
|
+
return nil;
|
|
353
|
+
}
|
|
331
354
|
if (!snapshot) {
|
|
332
355
|
NSNumber *axError = runtimeError.userInfo[kAccessibilityErrorKey];
|
|
333
356
|
NSInteger code = [axError respondsToSelector:@selector(integerValue)] ? axError.integerValue : runtimeError.code;
|
|
@@ -362,8 +385,14 @@ static void finishRequestWatchdog(dispatch_source_t watchdog, SnapshotWatchdogSt
|
|
|
362
385
|
@"ok" : @YES,
|
|
363
386
|
@"pid" : @(pid),
|
|
364
387
|
@"tree" : tree,
|
|
365
|
-
@"truncated" : @(truncated),
|
|
388
|
+
@"truncated" : @((BOOL)(truncated || acquisitionTruncated)),
|
|
366
389
|
@"automationEnabled" : @(automationEnabled),
|
|
390
|
+
@"recovery" : @{
|
|
391
|
+
@"requests" : @(recovery.requests),
|
|
392
|
+
@"rejected" : @(recovery.rejected),
|
|
393
|
+
@"continuations" : @(recovery.continuations),
|
|
394
|
+
@"acceptedLevels" : @(recovery.acceptedLevels),
|
|
395
|
+
},
|
|
367
396
|
};
|
|
368
397
|
}
|
|
369
398
|
@end
|
package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h
CHANGED
|
@@ -49,6 +49,18 @@ FOUNDATION_EXPORT NSString *const RunnerAXSnapshotCustomActionsBlockedKey;
|
|
|
49
49
|
customActionLimit:(NSInteger)customActionLimit
|
|
50
50
|
deadline:(nullable NSDate *)deadline;
|
|
51
51
|
|
|
52
|
+
/// The capture behind `snapshotTreeForApplication:`, for an AX client and target
|
|
53
|
+
/// application element that are already resolved. Every request, extension, and
|
|
54
|
+
/// custom-action decision happens here; the application entry point only resolves
|
|
55
|
+
/// the two identities.
|
|
56
|
+
+ (NSDictionary<NSString *, id> *)snapshotTreeWithClient:(id)axClient
|
|
57
|
+
target:(id)target
|
|
58
|
+
maxDepth:(NSInteger)maxDepth
|
|
59
|
+
maxNodes:(NSInteger)maxNodes
|
|
60
|
+
deepExtensionCallLimit:(NSInteger)deepExtensionCallLimit
|
|
61
|
+
customActionLimit:(NSInteger)customActionLimit
|
|
62
|
+
deadline:(nullable NSDate *)deadline;
|
|
63
|
+
|
|
52
64
|
/// Names of the element's UIAccessibilityCustomActions, or nil when it has
|
|
53
65
|
/// none.
|
|
54
66
|
///
|
package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m
CHANGED
|
@@ -104,7 +104,27 @@ typedef id (*RunnerAXSnapshotMsgSend)(id, SEL, id, id, id, NSError **);
|
|
|
104
104
|
if (nil == target) {
|
|
105
105
|
return [self failure:@"Could not match active AX application for XCTest application"];
|
|
106
106
|
}
|
|
107
|
+
return [self snapshotTreeWithClient:axClient
|
|
108
|
+
target:target
|
|
109
|
+
maxDepth:maxDepth
|
|
110
|
+
maxNodes:maxNodes
|
|
111
|
+
deepExtensionCallLimit:deepExtensionCallLimit
|
|
112
|
+
customActionLimit:customActionLimit
|
|
113
|
+
deadline:deadline];
|
|
114
|
+
} @catch (NSException *exception) {
|
|
115
|
+
return [self failure:exception.reason ?: exception.name ?: @"AX snapshot bridge exception"];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
107
118
|
|
|
119
|
+
+ (NSDictionary<NSString *, id> *)snapshotTreeWithClient:(id)axClient
|
|
120
|
+
target:(id)target
|
|
121
|
+
maxDepth:(NSInteger)maxDepth
|
|
122
|
+
maxNodes:(NSInteger)maxNodes
|
|
123
|
+
deepExtensionCallLimit:(NSInteger)deepExtensionCallLimit
|
|
124
|
+
customActionLimit:(NSInteger)customActionLimit
|
|
125
|
+
deadline:(nullable NSDate *)deadline
|
|
126
|
+
{
|
|
127
|
+
@try {
|
|
108
128
|
NSArray *attributes = [self snapshotAttributes];
|
|
109
129
|
NSError *error = nil;
|
|
110
130
|
id root = [self requestSnapshotFromClient:axClient
|
package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSelectorMatchPolicy.swift
CHANGED
|
@@ -20,26 +20,26 @@ enum DirectSelectorCandidateDecision: Equatable {
|
|
|
20
20
|
case ambiguous
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
26
|
enum DirectSelectorRawMatchPolicy: Equatable {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
30
|
case rejectDistinctMatches
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
36
|
case preferHittableMatch
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
43
|
func classifyDirectSelectorCandidates(
|
|
44
44
|
_ candidates: [SelectorCandidateFacts],
|
|
45
45
|
allowNonHittableFallback: Bool,
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
enum SystemSurfaceHostKind: String {
|
|
8
|
+
case webAuth = "web-auth"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
struct SystemSurfaceHost: Equatable {
|
|
12
|
+
let bundleId: String
|
|
13
|
+
let kind: SystemSurfaceHostKind
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
enum SystemSurfaceHostRegistry {
|
|
17
|
+
static let hosts: [SystemSurfaceHost] = [
|
|
18
|
+
SystemSurfaceHost(bundleId: "com.apple.SafariViewService", kind: .webAuth)
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
static func host(forBundleId bundleId: String?) -> SystemSurfaceHost? {
|
|
22
|
+
guard let bundleId else { return nil }
|
|
23
|
+
return hosts.first { $0.bundleId == bundleId }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static func isSystemSurfaceHost(_ bundleId: String?) -> Bool {
|
|
27
|
+
host(forBundleId: bundleId) != nil
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import XCTest
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
17
|
enum TapPointPolicy {
|
|
18
18
|
static func isAllowed(elementFrame: CGRect, windowFrame: CGRect) -> Bool {
|
|
19
19
|
if windowFrame.isNull || windowFrame.isEmpty || windowFrame.isInfinite {
|
|
@@ -26,3 +26,52 @@ enum TapPointPolicy {
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|