agent-device 0.21.14 → 0.21.16
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.14.apk → agent-device-android-ime-helper-0.21.16.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.16.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.14.manifest.json → agent-device-android-ime-helper-0.21.16.manifest.json} +4 -4
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.16.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.16.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.14.manifest.json → agent-device-android-snapshot-helper-0.21.16.manifest.json} +6 -6
- package/apple/snapshot-bridge/SnapshotBridgeRuntime.m +11 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +84 -2
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +4 -2
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerMainOwnedState.swift +27 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedTextEntry.h +10 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedTextEntry.m +21 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSystemSurfaceHostPolicy.swift +0 -9
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +40 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandDispatch.swift +179 -91
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +5 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+GestureExecution.swift +1 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +36 -49
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+MainThreadWork.swift +11 -15
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +136 -29
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +4 -2
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +3 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +6 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollDragExecution.swift +4 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +2 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +8 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotAcquisition.swift +56 -14
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +18 -8
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCaptureTarget.swift +9 -7
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotExecution.swift +5 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTiming.swift +2 -2
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +4 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedInteraction.swift +5 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +245 -41
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +47 -2
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +7 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +115 -111
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +17 -10
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +8 -9
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TypeExecution.swift +2 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +12 -11
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotGeometry.swift +7 -4
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotModels.swift +15 -8
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotPresentationProjection.swift +1 -0
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFold.swift +26 -9
- package/dist/apple/snapshot-presentation/Sources/AgentDeviceSnapshotPresentation/SnapshotVisibilityFoldProjection.swift +1 -0
- 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/adb-transport.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.js +1 -1
- package/dist/src/alert-runtime.js +1 -1
- package/dist/src/android-adb.d.ts +1 -8
- package/dist/src/android-input-ownership.js +1 -1
- package/dist/src/android-snapshot-quality.js +1 -0
- package/dist/src/android-system-chrome.js +1 -1
- package/dist/src/android.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.js +1 -1
- package/dist/src/app-launch.js +1 -1
- package/dist/src/app-lifecycle.js +1 -1
- package/dist/src/app-lifecycle2.js +1 -1
- package/dist/src/app-log-files.js +1 -1
- package/dist/src/app-log-runtime2.js +1 -1
- package/dist/src/app-resolution.js +2 -2
- package/dist/src/apple-runner-platform.js +1 -1
- 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-disclosure.js +1 -1
- package/dist/src/capture.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +3 -2
- package/dist/src/cli.js +4 -4
- package/dist/src/click-button.js +1 -1
- package/dist/src/client-metro.js +1 -1
- package/dist/src/client-types.d.ts +103 -96
- package/dist/src/clipboard-shell-response.js +1 -1
- package/dist/src/command-schema.js +1 -1
- package/dist/src/command-tools.js +3 -3
- 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-lease-beat.js +1 -0
- package/dist/src/daemon-client-lifecycle.js +1 -1
- package/dist/src/daemon-client-transport.js +1 -0
- package/dist/src/daemon-shutdown-report.js +1 -1
- package/dist/src/daemon.js +1 -1
- package/dist/src/debug-symbols-facade.js +1 -1
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-claim-rule.js +2 -2
- package/dist/src/device-input-state.d.ts +15 -2
- 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/device-shell.js +1 -1
- package/dist/src/device.js +1 -1
- package/dist/src/device2.js +1 -1
- package/dist/src/devicectl.js +1 -1
- package/dist/src/diagnostics.js +1 -1
- package/dist/src/dispatch-resolve.js +1 -1
- package/dist/src/doctor-facade.js +1 -1
- package/dist/src/doctor2.js +1 -1
- package/dist/src/durable-resource.js +1 -1
- package/dist/src/engine-eval-script.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/format.js +1 -1
- package/dist/src/gesture-admission.js +1 -1
- package/dist/src/gesture-plan-types.d.ts +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/helper.js +2 -2
- package/dist/src/host.js +1 -1
- package/dist/src/human-control-contract.js +1 -1
- package/dist/src/human-control.js +1 -1
- package/dist/src/index.d.ts +7 -3
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +1 -1
- package/dist/src/input-actions2.js +1 -1
- 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-operation-binding.js +1 -1
- package/dist/src/interactor.js +5 -4
- 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 +1 -1
- 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-acquisition.js +1 -1
- package/dist/src/ios-snapshot-engine.js +1 -0
- package/dist/src/ios-snapshot-runtime.js +1 -1
- package/dist/src/lease-context.js +1 -1
- package/dist/src/lease-scope.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun-download-file.js +1 -1
- package/dist/src/limrun-runtime-dependencies.js +1 -1
- package/dist/src/limrun.d.ts +16 -3
- 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 +17 -17
- package/dist/src/mobile-snapshot-semantics.js +1 -1
- package/dist/src/multitouch-support.js +1 -1
- package/dist/src/native-build-cache.js +1 -1
- package/dist/src/observation.js +1 -1
- package/dist/src/overlay.js +3 -0
- package/dist/src/parameterized-recorded-fill.js +1 -1
- package/dist/src/perf-facade.js +1 -1
- package/dist/src/perf-runtime-operation-builder.js +1 -1
- package/dist/src/perf-runtime-plan.js +1 -1
- package/dist/src/perf-target.js +1 -1
- package/dist/src/perf.js +1 -1
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/platform-request-scope.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 +4 -4
- package/dist/src/platform-runtime-runtime-hints.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-screen-recording-process-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-crop-bytes.js +1 -1
- package/dist/src/png-size.js +1 -1
- package/dist/src/png-worker-client.js +1 -1
- package/dist/src/png.js +1 -1
- package/dist/src/prepare-kind.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/quality-warnings.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/recording.js +1 -1
- package/dist/src/rect-center.js +1 -1
- package/dist/src/register-builtins.js +1 -1
- package/dist/src/registry.js +36 -36
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/replay-divergence.js +1 -1
- package/dist/src/replay.js +1 -1
- package/dist/src/reporting.js +1 -1
- 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/result-serialization.js +1 -1
- package/dist/src/retry.js +1 -1
- package/dist/src/runner-artifact-manifest.js +1 -0
- package/dist/src/runner-cache-metadata.js +3 -2
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-dev-tools-security.js +1 -1
- package/dist/src/runner-device-readiness.js +1 -1
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-error-classification.js +3 -3
- 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 +1 -3
- package/dist/src/runtime10.js +2 -2
- package/dist/src/runtime2.js +4 -4
- package/dist/src/runtime3.js +1 -1
- package/dist/src/runtime4.js +5 -5
- 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-admission-ledger.js +1 -1
- package/dist/src/screen-recording-completion.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/screen-recording-transport.js +1 -1
- package/dist/src/screenshot-density.js +1 -1
- package/dist/src/screenshot-image.js +1 -1
- package/dist/src/screenshot-overlay-draw.js +1 -1
- package/dist/src/screenshot-runtime.js +1 -1
- package/dist/src/screenshot.js +1 -1
- package/dist/src/screenshot3.js +1 -1
- package/dist/src/script.js +1 -1
- package/dist/src/scroll-command.d.ts +13 -6
- 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 +38 -10
- 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.js +1 -1
- package/dist/src/sdk-selectors.d.ts +1 -1
- package/dist/src/selection.js +0 -0
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/server.js +1 -1
- package/dist/src/session-allocation.js +1 -1
- 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.js +1 -1
- package/dist/src/session2.js +4 -4
- package/dist/src/settings.js +1 -1
- package/dist/src/settings2.js +1 -0
- package/dist/src/simctl.js +1 -1
- package/dist/src/simulator-boot.js +1 -1
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-capture-annotations.js +1 -1
- package/dist/src/snapshot-desktop-projection.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/src4.js +1 -1
- package/dist/src/src7.js +1 -1
- package/dist/src/src8.js +2 -2
- package/dist/src/stop-sequence.js +1 -1
- package/dist/src/string-enum.js +1 -1
- package/dist/src/surface-snapshot.js +1 -1
- package/dist/src/takeover.js +1 -1
- package/dist/src/text-entry-focus.js +1 -1
- package/dist/src/tool-provider.js +1 -1
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/touch-runtime.js +1 -1
- package/dist/src/transport.js +1 -1
- package/dist/src/tree.js +1 -1
- package/dist/src/tv-remote.js +1 -1
- package/dist/src/type-text-runtime.js +1 -1
- package/dist/src/verified-file.js +1 -1
- package/dist/src/video.js +1 -1
- package/dist/src/viewport.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/package.json +2 -2
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.14.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.14.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.14.apk.sha256 +0 -1
- package/dist/src/absence-observation-errors.js +0 -1
- package/dist/src/runner-presentation.js +0 -1
- package/dist/src/semantic-index.js +0 -1
- package/dist/src/snapshot-scope.js +0 -1
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2b9f418df9ee3ddce97502fbb39dd34d06562d2747cf45e41393725a928d1007 agent-device-android-ime-helper-0.21.16.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.16",
|
|
4
|
+
"assetName": "agent-device-android-ime-helper-0.21.16.apk",
|
|
5
|
+
"sha256": "2b9f418df9ee3ddce97502fbb39dd34d06562d2747cf45e41393725a928d1007",
|
|
6
6
|
"packageName": "com.callstack.agentdevice.imehelper",
|
|
7
|
-
"versionCode":
|
|
7
|
+
"versionCode": 21016,
|
|
8
8
|
"serviceComponent": "com.callstack.agentdevice.imehelper/.TestInputMethodService",
|
|
9
9
|
"broadcastProtocol": "android-ime-helper-v1"
|
|
10
10
|
}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
a7db56d04eaee4009721cc4bf0947a12de4eb491b4a16e6b2bfa3b987a43012d agent-device-android-snapshot-helper-0.21.16.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.16",
|
|
4
|
+
"releaseTag": "v0.21.16",
|
|
5
|
+
"assetName": "agent-device-android-snapshot-helper-0.21.16.apk",
|
|
6
6
|
"apkUrl": null,
|
|
7
|
-
"sha256": "
|
|
8
|
-
"checksumName": "agent-device-android-snapshot-helper-0.21.
|
|
7
|
+
"sha256": "a7db56d04eaee4009721cc4bf0947a12de4eb491b4a16e6b2bfa3b987a43012d",
|
|
8
|
+
"checksumName": "agent-device-android-snapshot-helper-0.21.16.apk.sha256",
|
|
9
9
|
"packageName": "com.callstack.agentdevice.snapshothelper",
|
|
10
|
-
"versionCode":
|
|
10
|
+
"versionCode": 21016,
|
|
11
11
|
"instrumentationRunner": "com.callstack.agentdevice.snapshothelper/.SnapshotInstrumentation",
|
|
12
12
|
"minSdk": 23,
|
|
13
13
|
"targetSdk": 36,
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
NSString *const kProtocolVersionKey = @"protocolVersion";
|
|
19
19
|
NSString *const kSourceVersionKey = @"sourceVersion";
|
|
20
20
|
NSString *const kRequestIdKey = @"requestId";
|
|
21
|
-
NSString *const kSourceVersion = @"agent-device-simulator-ax-v1.
|
|
21
|
+
NSString *const kSourceVersion = @"agent-device-simulator-ax-v1.8.0";
|
|
22
22
|
const NSUInteger kProtocolVersion = 1;
|
|
23
23
|
const uint32_t kMaximumFrameBytes = 16 * 1024 * 1024;
|
|
24
24
|
const NSUInteger kMaximumDepth = 128;
|
|
@@ -29,6 +29,7 @@ static NSString *const kAttributeElementType = @"XC_kAXXCAttributeElementType";
|
|
|
29
29
|
static NSString *const kAttributeElementBaseType = @"XC_kAXXCAttributeElementBaseType";
|
|
30
30
|
static NSString *const kAttributeLabel = @"XC_kAXXCAttributeLabel";
|
|
31
31
|
static NSString *const kAttributeValue = @"XC_kAXXCAttributeValue";
|
|
32
|
+
static NSString *const kAttributePlaceholderValue = @"XC_kAXXCAttributePlaceholderValue";
|
|
32
33
|
static NSString *const kAttributeIdentifier = @"XC_kAXXCAttributeIdentifier";
|
|
33
34
|
static NSString *const kAttributeFrame = @"XC_kAXXCAttributeFrame";
|
|
34
35
|
static NSString *const kAttributeAutomationType = @"XC_kAXXCAttributeAutomationType";
|
|
@@ -330,6 +331,7 @@ static void finishRequestWatchdog(dispatch_source_t watchdog, SnapshotWatchdogSt
|
|
|
330
331
|
kAttributeElementBaseType,
|
|
331
332
|
kAttributeLabel,
|
|
332
333
|
kAttributeValue,
|
|
334
|
+
kAttributePlaceholderValue,
|
|
333
335
|
kAttributeIdentifier,
|
|
334
336
|
kAttributeFrame,
|
|
335
337
|
kAttributeAutomationType,
|
|
@@ -337,6 +339,14 @@ static void finishRequestWatchdog(dispatch_source_t watchdog, SnapshotWatchdogSt
|
|
|
337
339
|
kAttributeChildren,
|
|
338
340
|
];
|
|
339
341
|
NSArray<NSNumber *> *numbers = _attributeNumbersForNames(names);
|
|
342
|
+
if (![numbers isKindOfClass:NSArray.class] || numbers.count != names.count) {
|
|
343
|
+
// The placeholder attribute is optional: a runtime whose vocabulary lacks it serves the capture
|
|
344
|
+
// without placeholders rather than failing every capture over a fact no consumer depends on.
|
|
345
|
+
NSMutableArray<NSString *> *required = [names mutableCopy];
|
|
346
|
+
[required removeObject:kAttributePlaceholderValue];
|
|
347
|
+
names = required;
|
|
348
|
+
numbers = _attributeNumbersForNames(names);
|
|
349
|
+
}
|
|
340
350
|
if (![numbers isKindOfClass:NSArray.class] || numbers.count != names.count) {
|
|
341
351
|
if (error) *error = failureResponse(requestId, @"reader_unavailable", @"attribute-vocabulary-mismatch", @"AX attribute vocabulary is incompatible");
|
|
342
352
|
finishRequestWatchdog(watchdog, watchdogState);
|
|
@@ -65,6 +65,14 @@ int main(int argc, const char *argv[]) {
|
|
|
65
65
|
@property(nonatomic, strong) UILabel *alertActivationBusyAnswer;
|
|
66
66
|
@property(nonatomic, assign) NSUInteger firstAlertActions;
|
|
67
67
|
@property(nonatomic, assign) NSUInteger replacementAlertActions;
|
|
68
|
+
@property(nonatomic, strong) UILabel *textEntryWriteBackStatus;
|
|
69
|
+
@property(nonatomic, assign) NSUInteger textEntryWriteBacks;
|
|
70
|
+
@property(nonatomic, copy, nullable) NSString *textEntryRenderedValue;
|
|
71
|
+
@property(nonatomic, assign) NSTimeInterval textEntryLastEditTime;
|
|
72
|
+
@property(nonatomic, assign) NSTimeInterval textEntryBurstStartTime;
|
|
73
|
+
@property(nonatomic, assign) NSUInteger textEntryBurstEdits;
|
|
74
|
+
@property(nonatomic, assign) NSTimeInterval textEntryBurstMinGap;
|
|
75
|
+
@property(nonatomic, assign) NSTimeInterval textEntryAcknowledgeWindowSeconds;
|
|
68
76
|
@property(nonatomic, assign) BOOL alertFixtureStarted;
|
|
69
77
|
@property(nonatomic, strong) NSTimer *alertActivationBusyBackstop;
|
|
70
78
|
@property(nonatomic, strong) NSTimer *alertBannerRepost;
|
|
@@ -175,6 +183,16 @@ static NSTimeInterval AgentDeviceAlertActivationBusyWindow(void) {
|
|
|
175
183
|
(unsigned long)self.replacementAlertActions];
|
|
176
184
|
}
|
|
177
185
|
|
|
186
|
+
- (void)updateTextEntryWriteBackStatus {
|
|
187
|
+
NSTimeInterval burstSpan = self.textEntryLastEditTime - self.textEntryBurstStartTime;
|
|
188
|
+
self.textEntryWriteBackStatus.text = [NSString
|
|
189
|
+
stringWithFormat:@"write-backs=%lu burst-edits=%lu burst-ms=%lu min-gap-ms=%lu",
|
|
190
|
+
(unsigned long)self.textEntryWriteBacks,
|
|
191
|
+
(unsigned long)self.textEntryBurstEdits,
|
|
192
|
+
(unsigned long)llround(burstSpan * 1000),
|
|
193
|
+
(unsigned long)llround(self.textEntryBurstMinGap * 1000)];
|
|
194
|
+
}
|
|
195
|
+
|
|
178
196
|
- (void)presentAlertFixtureReplacement:(BOOL)replacement {
|
|
179
197
|
NSArray<NSString *> *arguments = NSProcessInfo.processInfo.arguments;
|
|
180
198
|
BOOL sameTitle = [arguments containsObject:@"--agent-device-alert-same-title"];
|
|
@@ -230,14 +248,57 @@ static NSTimeInterval AgentDeviceAlertActivationBusyWindow(void) {
|
|
|
230
248
|
}
|
|
231
249
|
}
|
|
232
250
|
}
|
|
233
|
-
|
|
251
|
+
|
|
252
|
+
// How fast an app that owns this field's value can acknowledge edits: one render per window, passed
|
|
253
|
+
// by the test as `--agent-device-text-entry-acknowledge-window <seconds>`. An edit that arrives
|
|
254
|
+
// inside that window overtook the render still in flight, so the value that render commits predates
|
|
255
|
+
// it and writing it erases the characters that got ahead of the app. The app then reads its own
|
|
256
|
+
// erasure back into its model, which is why the field stays wrong instead of healing when the burst
|
|
257
|
+
// finishes. The window is decided at the edit rather than scheduled, so a loaded host, which
|
|
258
|
+
// stretches the gaps between characters, can only make this app keep up better.
|
|
259
|
+
static NSTimeInterval AgentDeviceTextEntryAcknowledgeWindow(void) {
|
|
260
|
+
NSArray<NSString *> *arguments = NSProcessInfo.processInfo.arguments;
|
|
261
|
+
NSUInteger index = [arguments indexOfObject:@"--agent-device-text-entry-acknowledge-window"];
|
|
262
|
+
return index == NSNotFound || index + 1 >= arguments.count ? 0 : [arguments[index + 1] doubleValue];
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Edits further apart than this belong to different bursts: one runner command's characters arrive
|
|
266
|
+
// well inside it, and two commands are separated by at least a commit-wait poll and a status read.
|
|
267
|
+
static const NSTimeInterval AgentDeviceTextEntryBurstBreakSeconds = 1.0;
|
|
234
268
|
|
|
235
269
|
- (void)agentDeviceTextEntryDidChange:(UITextField *)textField {
|
|
270
|
+
// A field whose app owns its value, the way a controlled React Native `TextInput` does. A burst
|
|
271
|
+
// typed faster than the app renders loses the characters that arrived while a render was in
|
|
272
|
+
// flight, and the field settles stable short of the request.
|
|
273
|
+
if ([NSProcessInfo.processInfo.arguments containsObject:@"--agent-device-text-entry-app-owned-value"]) {
|
|
274
|
+
NSTimeInterval now = NSProcessInfo.processInfo.systemUptime;
|
|
275
|
+
NSTimeInterval gap = now - self.textEntryLastEditTime;
|
|
276
|
+
BOOL overtookARender = self.textEntryRenderedValue != nil && gap < self.textEntryAcknowledgeWindowSeconds;
|
|
277
|
+
if (self.textEntryBurstEdits == 0 || gap > AgentDeviceTextEntryBurstBreakSeconds) {
|
|
278
|
+
self.textEntryBurstStartTime = now;
|
|
279
|
+
self.textEntryBurstEdits = 0;
|
|
280
|
+
self.textEntryBurstMinGap = 0;
|
|
281
|
+
} else if (self.textEntryBurstEdits == 1 || gap < self.textEntryBurstMinGap) {
|
|
282
|
+
self.textEntryBurstMinGap = gap;
|
|
283
|
+
}
|
|
284
|
+
self.textEntryBurstEdits += 1;
|
|
285
|
+
self.textEntryLastEditTime = now;
|
|
286
|
+
if (overtookARender) {
|
|
287
|
+
if (![textField.text isEqualToString:self.textEntryRenderedValue]) {
|
|
288
|
+
textField.text = self.textEntryRenderedValue;
|
|
289
|
+
self.textEntryWriteBacks += 1;
|
|
290
|
+
}
|
|
291
|
+
} else {
|
|
292
|
+
self.textEntryRenderedValue = [textField.text copy];
|
|
293
|
+
}
|
|
294
|
+
[self updateTextEntryWriteBackStatus];
|
|
295
|
+
}
|
|
236
296
|
if ([NSProcessInfo.processInfo.arguments containsObject:@"--agent-device-text-entry-disappear-after-input"] &&
|
|
237
297
|
textField.text.length > 0) {
|
|
238
298
|
[textField removeFromSuperview];
|
|
239
299
|
}
|
|
240
300
|
}
|
|
301
|
+
#endif
|
|
241
302
|
|
|
242
303
|
- (void)viewDidLoad {
|
|
243
304
|
[super viewDidLoad];
|
|
@@ -281,7 +342,13 @@ static NSTimeInterval AgentDeviceAlertActivationBusyWindow(void) {
|
|
|
281
342
|
UITextField *textField = [[UITextField alloc] init];
|
|
282
343
|
textField.accessibilityIdentifier = @"agent-device-hardware-keyboard-input";
|
|
283
344
|
textField.borderStyle = UITextBorderStyleRoundedRect;
|
|
284
|
-
|
|
345
|
+
// An empty input view keeps the software keyboard down, which is the hardware-keyboard responder
|
|
346
|
+
// these routes are addressed to. `--agent-device-text-entry-soft-keyboard` leaves the real input
|
|
347
|
+
// view in place, so a lane test can reach the branch that requires a visible keyboard.
|
|
348
|
+
if (![NSProcessInfo.processInfo.arguments
|
|
349
|
+
containsObject:@"--agent-device-text-entry-soft-keyboard"]) {
|
|
350
|
+
textField.inputView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
|
|
351
|
+
}
|
|
285
352
|
[textField addTarget:self
|
|
286
353
|
action:@selector(agentDeviceTextEntryDidChange:)
|
|
287
354
|
forControlEvents:UIControlEventEditingChanged];
|
|
@@ -293,6 +360,21 @@ static NSTimeInterval AgentDeviceAlertActivationBusyWindow(void) {
|
|
|
293
360
|
[textField.widthAnchor constraintEqualToConstant:240],
|
|
294
361
|
[textField.heightAnchor constraintEqualToConstant:44],
|
|
295
362
|
]];
|
|
363
|
+
if ([NSProcessInfo.processInfo.arguments containsObject:@"--agent-device-text-entry-app-owned-value"]) {
|
|
364
|
+
self.textEntryAcknowledgeWindowSeconds = AgentDeviceTextEntryAcknowledgeWindow();
|
|
365
|
+
// Reports how many edits this app rendered and how many writes it had to make because a
|
|
366
|
+
// character overtook one, so a lane test can tell a burst the app kept up with from an inert
|
|
367
|
+
// fixture. Counts only: no field content crosses into the test.
|
|
368
|
+
self.textEntryWriteBackStatus = [[UILabel alloc] init];
|
|
369
|
+
self.textEntryWriteBackStatus.accessibilityIdentifier = @"agent-device-text-entry-write-backs";
|
|
370
|
+
self.textEntryWriteBackStatus.translatesAutoresizingMaskIntoConstraints = NO;
|
|
371
|
+
[self.view addSubview:self.textEntryWriteBackStatus];
|
|
372
|
+
[NSLayoutConstraint activateConstraints:@[
|
|
373
|
+
[self.textEntryWriteBackStatus.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
|
|
374
|
+
[self.textEntryWriteBackStatus.topAnchor constraintEqualToAnchor:textField.bottomAnchor constant:12],
|
|
375
|
+
]];
|
|
376
|
+
[self updateTextEntryWriteBackStatus];
|
|
377
|
+
}
|
|
296
378
|
}
|
|
297
379
|
|
|
298
380
|
if ([NSProcessInfo.processInfo.arguments containsObject:@"--agent-device-crowded-screen"]) {
|
package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m
CHANGED
|
@@ -365,6 +365,7 @@ typedef id (*RunnerAXSnapshotMsgSend)(id, SEL, id, id, id, NSError **);
|
|
|
365
365
|
@"identifier",
|
|
366
366
|
@"label",
|
|
367
367
|
@"value",
|
|
368
|
+
@"placeholderValue",
|
|
368
369
|
@"frame",
|
|
369
370
|
@"enabled",
|
|
370
371
|
@"selected",
|
|
@@ -388,8 +389,8 @@ typedef id (*RunnerAXSnapshotMsgSend)(id, SEL, id, id, id, NSError **);
|
|
|
388
389
|
// The mapper expands keypaths with extra attributes (automation type, window display
|
|
389
390
|
// id, base type) that are disproportionately expensive for the AX server to compute
|
|
390
391
|
// on large React Native trees. Keep only the attributes we actually consume.
|
|
391
|
-
NSArray *needed = @[ @"ElementType", @"Identifier", @"Label", @"Value", @"
|
|
392
|
-
@"Enabled", @"Selected", @"Focus" ];
|
|
392
|
+
NSArray *needed = @[ @"ElementType", @"Identifier", @"Label", @"Value", @"PlaceholderValue",
|
|
393
|
+
@"Frame", @"Enabled", @"Selected", @"Focus" ];
|
|
393
394
|
NSMutableArray *filtered = [NSMutableArray array];
|
|
394
395
|
for (id attribute in (NSArray *)mapped) {
|
|
395
396
|
NSString *name = [attribute description];
|
|
@@ -764,6 +765,7 @@ typedef id (*RunnerAXSnapshotMsgSend)(id, SEL, id, id, id, NSError **);
|
|
|
764
765
|
result[@"identifier"] = [self stringValueForKey:@"identifier" snapshot:snapshot] ?: @"";
|
|
765
766
|
result[@"label"] = [self stringValueForKey:@"label" snapshot:snapshot] ?: @"";
|
|
766
767
|
result[@"value"] = [self stringValueForKey:@"value" snapshot:snapshot] ?: @"";
|
|
768
|
+
result[@"placeholder"] = [self stringValueForKey:@"placeholderValue" snapshot:snapshot] ?: @"";
|
|
767
769
|
result[@"frame"] = [self frameValueForSnapshot:snapshot];
|
|
768
770
|
result[@"enabled"] = [self boolNumberForKey:@"enabled" snapshot:snapshot defaultValue:YES];
|
|
769
771
|
result[@"selected"] = [self boolNumberForKey:@"selected" snapshot:snapshot defaultValue:NO];
|
package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerMainOwnedState.swift
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import XCTest
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@MainActor
|
|
6
|
+
final class RunnerMainOwnedState {
|
|
7
|
+
var app: XCUIApplication?
|
|
8
|
+
var bundleId: String?
|
|
9
|
+
var processIdentifier: Int?
|
|
10
|
+
var accessibilityHealth: RunnerAccessibilityHealth = .unknown
|
|
11
|
+
var needsPostSnapshotInteractionDelay = false
|
|
12
|
+
|
|
13
|
+
nonisolated init() {}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
func runOnMainActor<T>(_ work: @MainActor () throws -> T) -> Result<T, Error> {
|
|
22
|
+
var result: Result<T, Error>?
|
|
23
|
+
MainActor.assumeIsolated {
|
|
24
|
+
result = Result { try work() }
|
|
25
|
+
}
|
|
26
|
+
return result!
|
|
27
|
+
}
|
package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedTextEntry.h
CHANGED
|
@@ -19,13 +19,19 @@ typedef NS_ENUM(NSInteger, RunnerSynthesizedTextEntryStatus) {
|
|
|
19
19
|
|
|
20
20
|
// Synthesizes keyboard input for the current first responder without resolving an
|
|
21
21
|
// XCUIElement or serializing the application's accessibility tree.
|
|
22
|
+
//
|
|
23
|
+
// `charactersPerSecond` is XCTest's `typingSpeed:` argument. The caller declares it because the
|
|
24
|
+
// same number is what the caller's delivery budget charges a burst (#2955): a pace owned here and
|
|
25
|
+
// read back from Swift would let a call site type at a speed its own budget never charged.
|
|
22
26
|
+ (RunnerSynthesizedTextEntryResult *)synthesizeTextWithApplication:(id)application
|
|
23
|
-
text:(NSString *)text
|
|
27
|
+
text:(NSString *)text
|
|
28
|
+
charactersPerSecond:(NSUInteger)charactersPerSecond;
|
|
24
29
|
|
|
25
|
-
// Replaces the current first responder's contents
|
|
26
|
-
//
|
|
30
|
+
// Replaces the current first responder's contents with one synthesized Command-A record
|
|
31
|
+
// followed by a text-input record, typed at the pace the caller declares.
|
|
27
32
|
+ (RunnerSynthesizedTextEntryResult *)replaceTextWithApplication:(id)application
|
|
28
|
-
text:(NSString *)text
|
|
33
|
+
text:(NSString *)text
|
|
34
|
+
charactersPerSecond:(NSUInteger)charactersPerSecond;
|
|
29
35
|
|
|
30
36
|
@end
|
|
31
37
|
|
package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedTextEntry.m
CHANGED
|
@@ -5,6 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
static NSString *const RunnerTextSynthesisSurface = @"text";
|
|
7
7
|
|
|
8
|
+
// The pace (`typingSpeed:`) is a caller argument, not a constant here: TextEntryTiming owns it so
|
|
9
|
+
// the synthesized delivery budget charges the pace the app actually sees (#2955). XCTest's
|
|
10
|
+
// `typingSpeed:` is characters per second, and it spaces them unevenly — two characters of a paced
|
|
11
|
+
// burst can reach the app a few milliseconds apart at any pace.
|
|
12
|
+
|
|
8
13
|
typedef id (*RunnerTextMsgSendInit)(id, SEL, NSString *);
|
|
9
14
|
typedef id (*RunnerTextMsgSendInitPath)(id, SEL);
|
|
10
15
|
typedef void (*RunnerTextMsgSendType)(id, SEL, NSString *, NSTimeInterval, NSUInteger, BOOL);
|
|
@@ -35,6 +40,7 @@ static RunnerSynthesizedTextEntryResult *RunnerTextEntryFailed(NSString *message
|
|
|
35
40
|
static RunnerSynthesizedTextEntryResult *RunnerSynthesizeTextWithMode(
|
|
36
41
|
id application,
|
|
37
42
|
NSString *text,
|
|
43
|
+
NSUInteger charactersPerSecond,
|
|
38
44
|
BOOL replace
|
|
39
45
|
);
|
|
40
46
|
|
|
@@ -52,13 +58,15 @@ static RunnerSynthesizedTextEntryResult *RunnerSynthesizeTextWithMode(
|
|
|
52
58
|
@implementation RunnerSynthesizedTextEntry
|
|
53
59
|
|
|
54
60
|
+ (RunnerSynthesizedTextEntryResult *)synthesizeTextWithApplication:(id)application
|
|
55
|
-
text:(NSString *)text
|
|
56
|
-
|
|
61
|
+
text:(NSString *)text
|
|
62
|
+
charactersPerSecond:(NSUInteger)charactersPerSecond {
|
|
63
|
+
return RunnerSynthesizeTextWithMode(application, text, charactersPerSecond, NO);
|
|
57
64
|
}
|
|
58
65
|
|
|
59
66
|
+ (RunnerSynthesizedTextEntryResult *)replaceTextWithApplication:(id)application
|
|
60
|
-
text:(NSString *)text
|
|
61
|
-
|
|
67
|
+
text:(NSString *)text
|
|
68
|
+
charactersPerSecond:(NSUInteger)charactersPerSecond {
|
|
69
|
+
return RunnerSynthesizeTextWithMode(application, text, charactersPerSecond, YES);
|
|
62
70
|
}
|
|
63
71
|
|
|
64
72
|
@end
|
|
@@ -66,6 +74,7 @@ static RunnerSynthesizedTextEntryResult *RunnerSynthesizeTextWithMode(
|
|
|
66
74
|
static RunnerSynthesizedTextEntryResult *RunnerSynthesizeTextWithMode(
|
|
67
75
|
id application,
|
|
68
76
|
NSString *text,
|
|
77
|
+
NSUInteger charactersPerSecond,
|
|
69
78
|
BOOL replace
|
|
70
79
|
) {
|
|
71
80
|
@try {
|
|
@@ -128,7 +137,14 @@ static RunnerSynthesizedTextEntryResult *RunnerSynthesizeTextWithMode(
|
|
|
128
137
|
);
|
|
129
138
|
}
|
|
130
139
|
((RunnerMsgSendSetInteger)objc_msgSend)(record, bridge.core.setTargetProcessIDSelector, targetProcessID);
|
|
131
|
-
((RunnerTextMsgSendType)objc_msgSend)(
|
|
140
|
+
((RunnerTextMsgSendType)objc_msgSend)(
|
|
141
|
+
path,
|
|
142
|
+
bridge.typeTextSelector,
|
|
143
|
+
text,
|
|
144
|
+
0.0,
|
|
145
|
+
charactersPerSecond,
|
|
146
|
+
YES
|
|
147
|
+
);
|
|
132
148
|
((RunnerMsgSendAddPath)objc_msgSend)(record, bridge.core.addPathSelector, path);
|
|
133
149
|
|
|
134
150
|
NSError *error = nil;
|
|
@@ -20,13 +20,4 @@ enum SystemSurfaceHostRegistry {
|
|
|
20
20
|
SystemSurfaceHost(bundleId: "com.apple.SafariViewService", kind: .webAuth),
|
|
21
21
|
SystemSurfaceHost(bundleId: "com.apple.PassbookUIService", kind: .payment),
|
|
22
22
|
]
|
|
23
|
-
|
|
24
|
-
static func host(forBundleId bundleId: String?) -> SystemSurfaceHost? {
|
|
25
|
-
guard let bundleId else { return nil }
|
|
26
|
-
return hosts.first { $0.bundleId == bundleId }
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
static func isSystemSurfaceHost(_ bundleId: String?) -> Bool {
|
|
30
|
-
host(forBundleId: bundleId) != nil
|
|
31
|
-
}
|
|
32
23
|
}
|
package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift
CHANGED
|
@@ -21,6 +21,7 @@ extension RunnerTests {
|
|
|
21
21
|
return max(0.001, timeoutMs / 1000)
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
@MainActor
|
|
24
25
|
func resolveAlert(app activeApp: XCUIApplication, deadline: Date) -> RunnerAlert? {
|
|
25
26
|
|
|
26
27
|
|
|
@@ -50,6 +51,7 @@ extension RunnerTests {
|
|
|
50
51
|
return nil
|
|
51
52
|
}
|
|
52
53
|
|
|
54
|
+
@MainActor
|
|
53
55
|
func handleAlert(_ alert: RunnerAlert, action: String, deadline: Date) -> Response {
|
|
54
56
|
if action == "accept" || action == "dismiss" {
|
|
55
57
|
guard let button = chooseAlertButton(alert.buttons, action: action) else {
|
|
@@ -69,6 +71,14 @@ extension RunnerTests {
|
|
|
69
71
|
return alertVerificationResponse(.timedOut, action: action, activated: false)
|
|
70
72
|
}
|
|
71
73
|
let buttonFrame = button.frame
|
|
74
|
+
guard Date() < deadline else {
|
|
75
|
+
return alertVerificationResponse(.timedOut, action: action, activated: false)
|
|
76
|
+
}
|
|
77
|
+
#if !os(tvOS)
|
|
78
|
+
guard !buttonFrame.isEmpty else {
|
|
79
|
+
return alertVerificationResponse(.unconfirmed, action: action, activated: false)
|
|
80
|
+
}
|
|
81
|
+
#endif
|
|
72
82
|
NSLog(
|
|
73
83
|
"AGENT_DEVICE_RUNNER_ALERT_ACTIVATION action=%@ label=%@ frame=(%.1f,%.1f,%.1f,%.1f) point=(%.1f,%.1f)",
|
|
74
84
|
action,
|
|
@@ -82,11 +92,8 @@ extension RunnerTests {
|
|
|
82
92
|
|
|
83
93
|
|
|
84
94
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
withBoundedInteractionIdleTimeoutIfSupported(alert.ownerApp, waits: .preEventSkipped) {
|
|
88
|
-
outcome = activateElement(app: alert.ownerApp, element: button, action: "alert \(action)")
|
|
89
|
-
}
|
|
95
|
+
guard let outcome = activateAlertButton(alert, button: button, action: action, frame: buttonFrame, deadline: deadline) else {
|
|
96
|
+
return alertVerificationResponse(.timedOut, action: action, activated: false)
|
|
90
97
|
}
|
|
91
98
|
if let response = unsupportedResponse(for: outcome) {
|
|
92
99
|
return response
|
|
@@ -116,6 +123,32 @@ extension RunnerTests {
|
|
|
116
123
|
)
|
|
117
124
|
}
|
|
118
125
|
|
|
126
|
+
@MainActor
|
|
127
|
+
func activateAlertButton(
|
|
128
|
+
_ alert: RunnerAlert,
|
|
129
|
+
button: XCUIElement,
|
|
130
|
+
action: String,
|
|
131
|
+
frame: CGRect,
|
|
132
|
+
deadline: Date
|
|
133
|
+
) -> RunnerInteractionOutcome? {
|
|
134
|
+
var outcome: RunnerInteractionOutcome?
|
|
135
|
+
withUIInterruptionHandlingDisabledIfSupported(alert.ownerApp) {
|
|
136
|
+
withBoundedInteractionIdleTimeoutIfSupported(alert.ownerApp, waits: .preEventSkipped) {
|
|
137
|
+
guard Date() < deadline else { return }
|
|
138
|
+
#if !os(tvOS)
|
|
139
|
+
guard !frame.isEmpty else { return }
|
|
140
|
+
#endif
|
|
141
|
+
outcome = activateElement(
|
|
142
|
+
app: alert.ownerApp,
|
|
143
|
+
element: button,
|
|
144
|
+
action: "alert \(action)",
|
|
145
|
+
resolvedFrame: frame
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return outcome
|
|
150
|
+
}
|
|
151
|
+
|
|
119
152
|
|
|
120
153
|
|
|
121
154
|
|
|
@@ -266,6 +299,7 @@ extension RunnerTests {
|
|
|
266
299
|
|
|
267
300
|
|
|
268
301
|
|
|
302
|
+
@MainActor
|
|
269
303
|
private func waitUntilAlertButtonHittable(_ button: XCUIElement, deadline: Date) -> Bool {
|
|
270
304
|
while Date() < deadline {
|
|
271
305
|
if probeAlertButtonHittable(button, deadline: deadline) {
|
|
@@ -276,6 +310,7 @@ extension RunnerTests {
|
|
|
276
310
|
return false
|
|
277
311
|
}
|
|
278
312
|
|
|
313
|
+
@MainActor
|
|
279
314
|
private func probeAlertButtonHittable(_ button: XCUIElement, deadline: Date) -> Bool {
|
|
280
315
|
|
|
281
316
|
|