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
|
@@ -42,8 +42,16 @@ extension RunnerTests {
|
|
|
42
42
|
#if os(iOS)
|
|
43
43
|
let postStartedAt = Date()
|
|
44
44
|
let result = replacingExistingText
|
|
45
|
-
? RunnerSynthesizedTextEntry.replaceText(
|
|
46
|
-
|
|
45
|
+
? RunnerSynthesizedTextEntry.replaceText(
|
|
46
|
+
withApplication: app,
|
|
47
|
+
text: text,
|
|
48
|
+
charactersPerSecond: TextEntryTiming.synthesizedCharactersPerSecond
|
|
49
|
+
)
|
|
50
|
+
: RunnerSynthesizedTextEntry.synthesizeText(
|
|
51
|
+
withApplication: app,
|
|
52
|
+
text: text,
|
|
53
|
+
charactersPerSecond: TextEntryTiming.synthesizedCharactersPerSecond
|
|
54
|
+
)
|
|
47
55
|
NSLog(
|
|
48
56
|
"[DEBUG-1874] synthesize posted %d chars status=%d tookMs=%.0f",
|
|
49
57
|
text.count, result.status.rawValue, postStartedAt.timeIntervalSinceNow * -1000
|
|
@@ -73,59 +81,255 @@ extension RunnerTests {
|
|
|
73
81
|
#endif
|
|
74
82
|
}
|
|
75
83
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
struct SynthesizedTextPlan: Equatable {
|
|
89
|
+
|
|
90
|
+
struct Step: Equatable {
|
|
91
|
+
let characterCount: Int
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
var replacesExistingText = false
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
var pauseAfterSeconds: TimeInterval = 0
|
|
100
|
+
|
|
101
|
+
var warmsUpField = false
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
var synthesizeCallCount: Int {
|
|
105
|
+
replacesExistingText ? 2 : 1
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
let steps: [Step]
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
static func spacedSteps(
|
|
114
|
+
characterCount: Int,
|
|
115
|
+
delaySeconds: Double,
|
|
116
|
+
replacesExistingTextOnFirstPost: Bool = false
|
|
117
|
+
) -> [Step] {
|
|
118
|
+
(0..<characterCount).map { index in
|
|
119
|
+
Step(
|
|
120
|
+
characterCount: 1,
|
|
121
|
+
replacesExistingText: replacesExistingTextOnFirstPost && index == 0,
|
|
122
|
+
pauseAfterSeconds: index + 1 < characterCount ? delaySeconds : 0
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
var seconds: TimeInterval {
|
|
130
|
+
steps.reduce(0) { total, step in
|
|
131
|
+
total
|
|
132
|
+
+ Double(step.characterCount) * TextEntryTiming.synthesizedCharacterInterval
|
|
133
|
+
+ Double(step.synthesizeCallCount) * TextEntryTiming.synthesizeCallOverhead
|
|
134
|
+
+ step.pauseAfterSeconds
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
var pacesEveryCharacter: Bool {
|
|
142
|
+
steps.count > 1 && !steps.contains(where: \.warmsUpField)
|
|
143
|
+
}
|
|
79
144
|
}
|
|
80
145
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
static func synthesizedDeliveryIsSpaced(characterCount: Int, delaySeconds: Double) -> Bool {
|
|
149
|
+
delaySeconds > 0 && characterCount > 1
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
static func synthesizedTextPlan(
|
|
161
|
+
characterCount: Int,
|
|
162
|
+
delaySeconds: Double,
|
|
163
|
+
selectsExistingText: Bool,
|
|
164
|
+
peelsWarmupCharacter: Bool = false
|
|
165
|
+
) -> SynthesizedTextPlan {
|
|
166
|
+
if synthesizedDeliveryIsSpaced(characterCount: characterCount, delaySeconds: delaySeconds) {
|
|
167
|
+
return SynthesizedTextPlan(
|
|
168
|
+
steps: SynthesizedTextPlan.spacedSteps(
|
|
169
|
+
characterCount: characterCount,
|
|
170
|
+
delaySeconds: delaySeconds,
|
|
171
|
+
replacesExistingTextOnFirstPost: selectsExistingText
|
|
172
|
+
)
|
|
173
|
+
)
|
|
88
174
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
175
|
+
guard peelsWarmupCharacter && characterCount > 1 else {
|
|
176
|
+
return SynthesizedTextPlan(
|
|
177
|
+
steps: [
|
|
178
|
+
SynthesizedTextPlan.Step(
|
|
179
|
+
characterCount: characterCount,
|
|
180
|
+
replacesExistingText: selectsExistingText
|
|
181
|
+
),
|
|
182
|
+
]
|
|
93
183
|
)
|
|
94
184
|
}
|
|
185
|
+
return SynthesizedTextPlan(
|
|
186
|
+
steps: [
|
|
187
|
+
SynthesizedTextPlan.Step(
|
|
188
|
+
characterCount: 1,
|
|
189
|
+
pauseAfterSeconds: TextEntryTiming.pollInterval,
|
|
190
|
+
warmsUpField: true
|
|
191
|
+
),
|
|
192
|
+
SynthesizedTextPlan.Step(characterCount: characterCount - 1),
|
|
193
|
+
]
|
|
194
|
+
)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
enum SynthesizedDeliveryBudget {
|
|
200
|
+
static func exceeds(_ plan: SynthesizedTextPlan) -> Bool {
|
|
201
|
+
plan.seconds > TextEntryTiming.synthesizedDeliveryCeiling
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
static func maxTextLength(delaySeconds: TimeInterval) -> Int {
|
|
208
|
+
var length = 1
|
|
209
|
+
while !exceeds(
|
|
210
|
+
synthesizedTextPlan(
|
|
211
|
+
characterCount: length + 1,
|
|
212
|
+
delaySeconds: delaySeconds,
|
|
213
|
+
selectsExistingText: true
|
|
214
|
+
)
|
|
215
|
+
) {
|
|
216
|
+
length += 1
|
|
217
|
+
}
|
|
218
|
+
return length
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
enum SynthesizedStepDispatch {
|
|
225
|
+
case posted
|
|
226
|
+
case stop
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
struct SynthesizedPlanRun {
|
|
230
|
+
let postedCharacterCount: Int
|
|
231
|
+
|
|
232
|
+
let stoppedEarly: Bool
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
@MainActor
|
|
246
|
+
func runSynthesizedTextPlan(
|
|
247
|
+
_ plan: SynthesizedTextPlan,
|
|
248
|
+
text: String,
|
|
249
|
+
post: (_ characters: String, _ step: SynthesizedTextPlan.Step) -> SynthesizedStepDispatch,
|
|
250
|
+
waitAfterWarmupCharacter: (_ characters: String) -> Void,
|
|
251
|
+
didPostStep: (_ step: SynthesizedTextPlan.Step) -> Void = { _ in }
|
|
252
|
+
) -> SynthesizedPlanRun {
|
|
253
|
+
let characters = Array(text)
|
|
254
|
+
var postedCount = 0
|
|
255
|
+
for step in plan.steps {
|
|
256
|
+
let nextCount = postedCount + step.characterCount
|
|
257
|
+
if post(String(characters[postedCount..<nextCount]), step) == .stop {
|
|
258
|
+
|
|
259
|
+
return SynthesizedPlanRun(postedCharacterCount: postedCount, stoppedEarly: true)
|
|
260
|
+
}
|
|
261
|
+
postedCount = nextCount
|
|
262
|
+
didPostStep(step)
|
|
263
|
+
if step.warmsUpField {
|
|
264
|
+
waitAfterWarmupCharacter(String(characters[postedCount - step.characterCount..<postedCount]))
|
|
265
|
+
} else if step.pauseAfterSeconds > 0 {
|
|
266
|
+
sleepFor(step.pauseAfterSeconds)
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return SynthesizedPlanRun(postedCharacterCount: postedCount, stoppedEarly: false)
|
|
95
270
|
}
|
|
96
271
|
|
|
272
|
+
@MainActor
|
|
97
273
|
func runSynthesizedReplacementRoute(
|
|
98
274
|
_ request: SynthesizedReplacementRequest
|
|
99
275
|
) -> SynthesizedReplacementRouteOutcome {
|
|
100
276
|
#if os(iOS)
|
|
101
277
|
NSLog("AGENT_DEVICE_RUNNER_TEXT_ENTRY_ROUTE route=synthesized-first-responder-replacement")
|
|
102
|
-
let
|
|
103
|
-
|
|
104
|
-
delaySeconds: request.delaySeconds
|
|
278
|
+
let plan = Self.synthesizedTextPlan(
|
|
279
|
+
characterCount: request.text.count,
|
|
280
|
+
delaySeconds: request.delaySeconds,
|
|
281
|
+
selectsExistingText: true
|
|
105
282
|
)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
283
|
+
if SynthesizedDeliveryBudget.exceeds(plan) {
|
|
284
|
+
NSLog(
|
|
285
|
+
"AGENT_DEVICE_RUNNER_TEXT_ENTRY_ROUTE route=synthesized-first-responder-replacement "
|
|
286
|
+
+ "reason=delivery-budget-refused chars=%d budgetChars=%d",
|
|
287
|
+
request.text.count,
|
|
288
|
+
SynthesizedDeliveryBudget.maxTextLength(delaySeconds: request.delaySeconds)
|
|
289
|
+
)
|
|
290
|
+
return .completed(
|
|
291
|
+
TextEntryResult(
|
|
292
|
+
verified: nil,
|
|
293
|
+
repaired: false,
|
|
294
|
+
expectedText: request.text,
|
|
295
|
+
observedText: nil,
|
|
296
|
+
textEntryRoute: "synthesized-first-responder-replacement",
|
|
297
|
+
failure: .synthesisBudgetExceeded
|
|
117
298
|
)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
299
|
+
)
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
let synthesisAvailable = runSynthesizedTextPlan(
|
|
304
|
+
plan,
|
|
305
|
+
text: request.text,
|
|
306
|
+
post: { slice, step in
|
|
307
|
+
switch request.synthesizer.enterText(
|
|
308
|
+
app: request.app,
|
|
309
|
+
text: slice,
|
|
310
|
+
replacingExistingText: step.replacesExistingText
|
|
311
|
+
) {
|
|
312
|
+
case .continueTyping:
|
|
313
|
+
return .posted
|
|
314
|
+
case .fallback:
|
|
315
|
+
return .stop
|
|
316
|
+
case .raise(let message):
|
|
317
|
+
NSException(
|
|
318
|
+
name: NSExceptionName.internalInconsistencyException,
|
|
319
|
+
reason: message ?? "private XCTest text synthesis failed"
|
|
320
|
+
).raise()
|
|
321
|
+
return .stop
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
|
|
325
|
+
waitAfterWarmupCharacter: { _ in }
|
|
326
|
+
)
|
|
327
|
+
if synthesisAvailable.stoppedEarly {
|
|
328
|
+
NSLog("AGENT_DEVICE_RUNNER_TEXT_ENTRY_ROUTE route=verified-fallback reason=synthesis-unavailable")
|
|
329
|
+
guard let point = request.target.refreshPoint else { return .notApplicable }
|
|
330
|
+
return .fallback(
|
|
331
|
+
focusTextInputForTextEntry(app: request.app, x: point.x, y: point.y)
|
|
332
|
+
)
|
|
129
333
|
}
|
|
130
334
|
|
|
131
335
|
|
package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift
CHANGED
|
@@ -8,6 +8,7 @@ extension RunnerTests {
|
|
|
8
8
|
case notFocused = "TEXT_INPUT_NOT_FOCUSED"
|
|
9
9
|
case synthesisUnavailable = "TEXT_INPUT_SYNTHESIS_UNAVAILABLE"
|
|
10
10
|
case commitNotObserved = "TEXT_INPUT_COMMIT_NOT_OBSERVED"
|
|
11
|
+
case synthesisBudgetExceeded = "TEXT_INPUT_SYNTHESIS_BUDGET_EXCEEDED"
|
|
11
12
|
|
|
12
13
|
var message: String {
|
|
13
14
|
switch self {
|
|
@@ -17,6 +18,8 @@ extension RunnerTests {
|
|
|
17
18
|
return "Reliable text synthesis is unavailable while the software keyboard is hidden."
|
|
18
19
|
case .commitNotObserved:
|
|
19
20
|
return "The runner could not confirm the typed text reached the field."
|
|
21
|
+
case .synthesisBudgetExceeded:
|
|
22
|
+
return "The text is longer than one runner command can type at this pace."
|
|
20
23
|
}
|
|
21
24
|
}
|
|
22
25
|
|
|
@@ -27,7 +30,17 @@ extension RunnerTests {
|
|
|
27
30
|
case .synthesisUnavailable:
|
|
28
31
|
return "Show the software keyboard, then retry type."
|
|
29
32
|
case .commitNotObserved:
|
|
30
|
-
return "The field may hold none, part, or all of the text. Run snapshot -i and inspect the field: if it already matches, continue; otherwise retry fill with the full text quoted and --delay-ms
|
|
33
|
+
return "The field may hold none, part, or all of the text. Run snapshot -i and inspect the field: if it already matches, continue; otherwise retry fill with the full text quoted and --delay-ms \(TextEntryTiming.recoveryDelayMilliseconds). Do not use type, which appends to whatever committed."
|
|
34
|
+
case .synthesisBudgetExceeded:
|
|
35
|
+
let recoveryDelay = TextEntryTiming.recoveryDelayMilliseconds
|
|
36
|
+
let recoveryBudget = SynthesizedDeliveryBudget.maxTextLength(
|
|
37
|
+
delaySeconds: Double(recoveryDelay) / 1000
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
return "Fill at most \(SynthesizedDeliveryBudget.maxTextLength(delaySeconds: 0)) characters per command without --delay-ms and append the rest with separate type commands. --delay-ms lowers the limit: each character then gets its own synthesize call and each gap pays the delay, so \(recoveryDelay) ms fits \(recoveryBudget). This route is chosen when the accessibility channel is already degraded, so a longer timeout does not help."
|
|
31
44
|
}
|
|
32
45
|
}
|
|
33
46
|
}
|
|
@@ -51,8 +64,40 @@ extension RunnerTests {
|
|
|
51
64
|
static let synthesizedCommitStallTimeout: TimeInterval = 3.0
|
|
52
65
|
|
|
53
66
|
|
|
54
|
-
|
|
55
67
|
static let synthesizedCommitCeiling: TimeInterval = 10.0
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
static let synthesizedReplacementFocusAllowance: TimeInterval = 2.0
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
static let synthesizedDeliveryCeiling: TimeInterval = RunnerTests.mainThreadExecutionTimeout
|
|
76
|
+
- synthesizedReplacementFocusAllowance
|
|
77
|
+
- synthesizedCommitCeiling
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
static let synthesizedCharactersPerSecond: UInt = 12
|
|
93
|
+
|
|
94
|
+
static let synthesizedCharacterInterval: TimeInterval = 1.0 / Double(synthesizedCharactersPerSecond)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
static let synthesizeCallOverhead: TimeInterval = 0.15
|
|
99
|
+
|
|
100
|
+
static let recoveryDelayMilliseconds = 80
|
|
56
101
|
static let synthesizedCommitPollInterval: TimeInterval = 0.2
|
|
57
102
|
}
|
|
58
103
|
|
|
@@ -6,6 +6,7 @@ import XCTest
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
extension RunnerTests {
|
|
9
|
+
@MainActor
|
|
9
10
|
func rememberTextEntryTap(_ element: XCUIElement?) {
|
|
10
11
|
guard let element, isTextEntryElement(element) else {
|
|
11
12
|
clearRememberedTextEntryTap()
|
|
@@ -13,8 +14,8 @@ extension RunnerTests {
|
|
|
13
14
|
}
|
|
14
15
|
textEntryTapWitness = TextEntryTapWitness(
|
|
15
16
|
element: element,
|
|
16
|
-
bundleId:
|
|
17
|
-
processIdentifier:
|
|
17
|
+
bundleId: mainOwned.bundleId,
|
|
18
|
+
processIdentifier: mainOwned.processIdentifier
|
|
18
19
|
)
|
|
19
20
|
}
|
|
20
21
|
|
|
@@ -22,6 +23,7 @@ extension RunnerTests {
|
|
|
22
23
|
textEntryTapWitness = nil
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
@MainActor
|
|
25
27
|
private func rememberedTextEntryTarget() -> TextEntryTarget? {
|
|
26
28
|
guard let witness = textEntryTapWitness else {
|
|
27
29
|
return nil
|
|
@@ -30,8 +32,8 @@ extension RunnerTests {
|
|
|
30
32
|
|
|
31
33
|
clearRememberedTextEntryTap()
|
|
32
34
|
guard witness.matches(
|
|
33
|
-
bundleId:
|
|
34
|
-
processIdentifier:
|
|
35
|
+
bundleId: mainOwned.bundleId,
|
|
36
|
+
processIdentifier: mainOwned.processIdentifier
|
|
35
37
|
) else {
|
|
36
38
|
return nil
|
|
37
39
|
}
|
|
@@ -80,6 +82,7 @@ extension RunnerTests {
|
|
|
80
82
|
#endif
|
|
81
83
|
}
|
|
82
84
|
|
|
85
|
+
@MainActor
|
|
83
86
|
func focusTextInputForTextEntry(app: XCUIApplication, x: Double?, y: Double?) -> TextEntryTarget {
|
|
84
87
|
guard let x, let y else {
|
|
85
88
|
let softwareKeyboardVisible = isKeyboardVisible(app: app)
|