agent-device 0.21.1 → 0.21.2
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.1.apk → agent-device-android-ime-helper-0.21.2.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.2.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.1.manifest.json → agent-device-android-ime-helper-0.21.2.manifest.json} +4 -4
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.2.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.2.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.1.manifest.json → agent-device-android-snapshot-helper-0.21.2.manifest.json} +6 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerScrollViewportPolicy.swift +413 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +34 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +56 -31
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +1 -13
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +4 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +9 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +1 -0
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/RecordingExportSupport.swift +0 -4
- package/dist/src/absence-observation-errors.js +1 -0
- package/dist/src/adapter.js +1 -1
- package/dist/src/agent-browser-lifecycle.js +1 -1
- package/dist/src/agent-browser-process-record.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-helpers.js +1 -1
- package/dist/src/app-inventory-contract.js +1 -1
- package/dist/src/app-inventory.js +1 -1
- package/dist/src/app-log-runtime2.js +2 -2
- package/dist/src/auth-session.js +1 -1
- package/dist/src/back-mode.js +1 -0
- package/dist/src/browser-launch.js +1 -0
- package/dist/src/catalog.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +12 -12
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +3 -3
- package/dist/src/client-metro-companion.js +1 -1
- package/dist/src/client-metro.js +1 -1
- package/dist/src/client-types.d.ts +2 -1
- package/dist/src/code-signature-cache.js +1 -1
- package/dist/src/code-signature.js +1 -1
- package/dist/src/command-metadata.js +1 -1
- package/dist/src/command-schema.js +3 -3
- package/dist/src/command-tools.js +2 -2
- package/dist/src/config.js +1 -1
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/daemon-client-lifecycle.js +1 -1
- package/dist/src/daemon-process.js +1 -1
- package/dist/src/daemon-shutdown-report.js +1 -1
- package/dist/src/device-boot.js +1 -0
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-claim-rule.js +1 -1
- package/dist/src/device-input-state.d.ts +1 -1
- package/dist/src/device-session.js +1 -1
- package/dist/src/durable-resource.js +1 -1
- package/dist/src/engine-eval-script.js +1 -0
- package/dist/src/file.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/format.js +1 -0
- 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/helper.js +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/input-actions.js +1 -1
- package/dist/src/interaction-positionals.js +1 -1
- package/dist/src/interaction-ref-policy.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interaction2.js +1 -1
- package/dist/src/interactor.js +5 -5
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +2 -2
- package/dist/src/internal/png-worker.d.ts +3 -0
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/ios-snapshot-acquisition.js +1 -1
- package/dist/src/ios-snapshot-planning.js +1 -1
- package/dist/src/ios-snapshot-runtime.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun.d.ts +1 -1
- package/dist/src/local-interactor-operation-set.js +1 -1
- package/dist/src/mechanics.js +16 -16
- package/dist/src/mobile-snapshot-semantics.js +1 -1
- package/dist/src/mp4-atoms.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 +1 -1
- package/dist/src/perf-runtime-plan.js +1 -1
- package/dist/src/platform-request-scope.js +1 -1
- package/dist/src/platform-runtime-app-log-process.js +1 -1
- package/dist/src/platform-runtime-managed-owner.js +1 -1
- package/dist/src/platform-runtime-operation-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-android-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-runner-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-runner-transport.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-process-host.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 -0
- package/dist/src/png-worker-contract.js +1 -1
- package/dist/src/png.js +1 -0
- package/dist/src/process.js +1 -1
- package/dist/src/provider-webdriver.js +1 -1
- package/dist/src/quality-warnings.js +1 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/registry.js +36 -37
- package/dist/src/replay.js +1 -1
- package/dist/src/request-admission.js +1 -1
- package/dist/src/request-cancellation.js +1 -1
- package/dist/src/request-runtime-binding.js +1 -1
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-presentation.js +1 -1
- package/dist/src/runtime.js +3 -3
- package/dist/src/runtime10.js +1 -0
- package/dist/src/runtime2.js +4 -4
- package/dist/src/runtime4.js +3 -3
- 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-resource-recovery.js +1 -1
- package/dist/src/screenshot-runtime.js +1 -1
- package/dist/src/screenshot3.js +2 -2
- package/dist/src/script.js +1 -1
- package/dist/src/scroll-gesture.js +1 -1
- package/dist/src/sdk-batch.js +1 -1
- package/dist/src/sdk-contracts.d.ts +26 -26
- package/dist/src/sdk-finders.d.ts +1 -1
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-remote-config.d.ts +1 -1
- package/dist/src/sdk-selectors.d.ts +12 -4
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selection.js +0 -0
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/semantic-index.js +1 -1
- package/dist/src/server.js +1 -1
- package/dist/src/session-snapshot.js +1 -1
- package/dist/src/session-store.js +2 -2
- package/dist/src/session-target-evidence.js +1 -1
- package/dist/src/session2.js +5 -5
- package/dist/src/simulator-boot.js +3 -0
- 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/snapshot4.js +1 -1
- package/dist/src/src.js +1 -1
- package/dist/src/src7.js +1 -1
- package/dist/src/src8.js +2 -2
- package/dist/src/telemetry.js +1 -1
- package/dist/src/touch-reference-frame.js +1 -1
- package/dist/src/tree.js +1 -1
- package/dist/src/type-text-runtime.js +1 -1
- package/dist/src/vars.js +2 -0
- package/dist/src/version.js +1 -1
- package/dist/src/video.js +2 -2
- package/dist/src/viewport.js +1 -0
- package/dist/src/webdriver-ios-snapshot.js +1 -1
- package/package.json +2 -1
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.1.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.1.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.1.apk.sha256 +0 -1
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-trim.swift +0 -93
- package/dist/src/snapshot-quality-verdict.js +0 -1
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
17a3645b2baca245adaa37e025a89eb35da7c5c6d53ae2d2d84862474f402cf0 agent-device-android-ime-helper-0.21.2.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.2",
|
|
4
|
+
"assetName": "agent-device-android-ime-helper-0.21.2.apk",
|
|
5
|
+
"sha256": "17a3645b2baca245adaa37e025a89eb35da7c5c6d53ae2d2d84862474f402cf0",
|
|
6
6
|
"packageName": "com.callstack.agentdevice.imehelper",
|
|
7
|
-
"versionCode":
|
|
7
|
+
"versionCode": 21002,
|
|
8
8
|
"serviceComponent": "com.callstack.agentdevice.imehelper/.TestInputMethodService",
|
|
9
9
|
"broadcastProtocol": "android-ime-helper-v1"
|
|
10
10
|
}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ee5d763221ede67f2b6e33e56d3487f3c05aab65a9a6999e456b273c7ccfecec agent-device-android-snapshot-helper-0.21.2.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.2",
|
|
4
|
+
"releaseTag": "v0.21.2",
|
|
5
|
+
"assetName": "agent-device-android-snapshot-helper-0.21.2.apk",
|
|
6
6
|
"apkUrl": null,
|
|
7
|
-
"sha256": "
|
|
8
|
-
"checksumName": "agent-device-android-snapshot-helper-0.21.
|
|
7
|
+
"sha256": "ee5d763221ede67f2b6e33e56d3487f3c05aab65a9a6999e456b273c7ccfecec",
|
|
8
|
+
"checksumName": "agent-device-android-snapshot-helper-0.21.2.apk.sha256",
|
|
9
9
|
"packageName": "com.callstack.agentdevice.snapshothelper",
|
|
10
|
-
"versionCode":
|
|
10
|
+
"versionCode": 21002,
|
|
11
11
|
"instrumentationRunner": "com.callstack.agentdevice.snapshothelper/.SnapshotInstrumentation",
|
|
12
12
|
"minSdk": 23,
|
|
13
13
|
"targetSdk": 36,
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
import XCTest
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
enum RunnerScrollKeyboardClip: Equatable {
|
|
23
|
+
|
|
24
|
+
case unobstructed
|
|
25
|
+
|
|
26
|
+
case avoided(frame: CGRect, keyboardMinY: Double)
|
|
27
|
+
|
|
28
|
+
case occluded(keyboardMinY: Double, visibleHeight: Double)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
enum RunnerScrollViewport {
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
case swipe(planFrame: CGRect, coordinateFrame: CGRect, keyboardMinY: Double?)
|
|
41
|
+
|
|
42
|
+
case occluded(keyboardMinY: Double, visibleHeight: Double)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
struct ScrollGestureDispatch {
|
|
48
|
+
let plan: RunnerScrollGesturePlan
|
|
49
|
+
let planFrame: CGRect
|
|
50
|
+
let coordinateFrame: CGRect
|
|
51
|
+
let keyboardMinY: Double?
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
enum ScrollGestureOutcome {
|
|
56
|
+
case gesture(ScrollGestureDispatch)
|
|
57
|
+
case unusableFrame
|
|
58
|
+
case unusablePlan
|
|
59
|
+
case occluded(keyboardMinY: Double, visibleHeight: Double)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
extension ScrollGestureDispatch {
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
func attachingEvidence(to response: Response) -> Response {
|
|
68
|
+
guard response.ok else { return response }
|
|
69
|
+
var payload = response.data ?? DataPayload()
|
|
70
|
+
payload.referenceWidth = Double(planFrame.width)
|
|
71
|
+
payload.referenceHeight = Double(planFrame.height)
|
|
72
|
+
guard let keyboardMinY else {
|
|
73
|
+
return Response(ok: response.ok, data: payload, error: response.error)
|
|
74
|
+
}
|
|
75
|
+
payload.keyboardAvoided = true
|
|
76
|
+
payload.keyboardMinY = keyboardMinY
|
|
77
|
+
return Response(ok: response.ok, data: payload, error: response.error)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
extension RunnerScrollViewport {
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
func gestureDispatch(
|
|
85
|
+
direction: RunnerScrollDirection,
|
|
86
|
+
amount: Double?,
|
|
87
|
+
pixels: Double?
|
|
88
|
+
) -> ScrollGestureOutcome {
|
|
89
|
+
switch self {
|
|
90
|
+
case .occluded(let keyboardMinY, let visibleHeight):
|
|
91
|
+
return .occluded(keyboardMinY: keyboardMinY, visibleHeight: visibleHeight)
|
|
92
|
+
case .swipe(let planFrame, let coordinateFrame, let keyboardMinY):
|
|
93
|
+
guard planFrame.width > 0, planFrame.height > 0 else {
|
|
94
|
+
return .unusableFrame
|
|
95
|
+
}
|
|
96
|
+
guard let plan = runnerScrollGesturePlan(
|
|
97
|
+
direction: direction,
|
|
98
|
+
amount: amount,
|
|
99
|
+
pixels: pixels,
|
|
100
|
+
referenceWidth: planFrame.width,
|
|
101
|
+
referenceHeight: planFrame.height
|
|
102
|
+
) else {
|
|
103
|
+
return .unusablePlan
|
|
104
|
+
}
|
|
105
|
+
return .gesture(
|
|
106
|
+
ScrollGestureDispatch(
|
|
107
|
+
plan: plan,
|
|
108
|
+
planFrame: planFrame,
|
|
109
|
+
coordinateFrame: coordinateFrame,
|
|
110
|
+
keyboardMinY: keyboardMinY
|
|
111
|
+
)
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
enum ScrollViewportPolicy {
|
|
118
|
+
|
|
119
|
+
static let minVisibleFraction: Double = 0.15
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
static let accessoryAllowance: Double = 12
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
static let occlusionRunnerCode = "SCROLL_KEYBOARD_OCCLUDES_SURFACE"
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
static func clip(viewport: CGRect, keyboard: CGRect) -> RunnerScrollKeyboardClip {
|
|
134
|
+
guard isUsable(viewport), isUsable(keyboard) else {
|
|
135
|
+
return .unobstructed
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
let swipeCenterX = viewport.minX + viewport.width / 2
|
|
141
|
+
if swipeCenterX < keyboard.minX || swipeCenterX >= keyboard.maxX {
|
|
142
|
+
return .unobstructed
|
|
143
|
+
}
|
|
144
|
+
let keyboardMinY = keyboard.minY
|
|
145
|
+
if keyboardMinY >= viewport.maxY || keyboard.maxY <= viewport.minY {
|
|
146
|
+
return .unobstructed
|
|
147
|
+
}
|
|
148
|
+
let visibleHeight = max(0, keyboardMinY - accessoryAllowance - viewport.minY)
|
|
149
|
+
if visibleHeight < minVisibleFraction * viewport.height {
|
|
150
|
+
return .occluded(keyboardMinY: keyboardMinY, visibleHeight: visibleHeight)
|
|
151
|
+
}
|
|
152
|
+
return .avoided(
|
|
153
|
+
frame: CGRect(
|
|
154
|
+
x: viewport.minX,
|
|
155
|
+
y: viewport.minY,
|
|
156
|
+
width: viewport.width,
|
|
157
|
+
height: visibleHeight
|
|
158
|
+
),
|
|
159
|
+
keyboardMinY: keyboardMinY
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
static func frames(referenceFrame: CGRect, clip: RunnerScrollKeyboardClip) -> RunnerScrollViewport {
|
|
167
|
+
switch clip {
|
|
168
|
+
case .unobstructed:
|
|
169
|
+
return .swipe(planFrame: referenceFrame, coordinateFrame: referenceFrame, keyboardMinY: nil)
|
|
170
|
+
case .avoided(let frame, let keyboardMinY):
|
|
171
|
+
return .swipe(planFrame: frame, coordinateFrame: referenceFrame, keyboardMinY: keyboardMinY)
|
|
172
|
+
case .occluded(let keyboardMinY, let visibleHeight):
|
|
173
|
+
return .occluded(keyboardMinY: keyboardMinY, visibleHeight: visibleHeight)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private static func isUsable(_ rect: CGRect) -> Bool {
|
|
178
|
+
return [rect.minX, rect.minY, rect.width, rect.height].allSatisfy(\.isFinite)
|
|
179
|
+
&& rect.width > 0 && rect.height > 0
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
extension RunnerTests {
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
func resolvedScrollViewport(
|
|
189
|
+
app: XCUIApplication,
|
|
190
|
+
context: SynthesizedCoordinateContext
|
|
191
|
+
) -> RunnerScrollViewport {
|
|
192
|
+
#if os(iOS)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
guard context.allowsKeyboardProbe else {
|
|
196
|
+
logScrollViewport(decision: "probeSkipped", keyboardMinY: nil, swipeHeight: context.referenceFrame.height, context: context)
|
|
197
|
+
return ScrollViewportPolicy.frames(referenceFrame: context.referenceFrame, clip: .unobstructed)
|
|
198
|
+
}
|
|
199
|
+
guard let keyboardFrame = visibleKeyboardFrame(app: app) else {
|
|
200
|
+
logScrollViewport(decision: "noKeyboard", keyboardMinY: nil, swipeHeight: context.referenceFrame.height, context: context)
|
|
201
|
+
return ScrollViewportPolicy.frames(referenceFrame: context.referenceFrame, clip: .unobstructed)
|
|
202
|
+
}
|
|
203
|
+
let clip = ScrollViewportPolicy.clip(viewport: context.referenceFrame, keyboard: keyboardFrame)
|
|
204
|
+
switch clip {
|
|
205
|
+
case .unobstructed:
|
|
206
|
+
logScrollViewport(decision: "unobstructed", keyboardMinY: nil, swipeHeight: context.referenceFrame.height, context: context)
|
|
207
|
+
case .avoided(let frame, let keyboardMinY):
|
|
208
|
+
logScrollViewport(
|
|
209
|
+
decision: "avoided",
|
|
210
|
+
keyboardMinY: keyboardMinY,
|
|
211
|
+
swipeHeight: frame.height,
|
|
212
|
+
context: context
|
|
213
|
+
)
|
|
214
|
+
case .occluded(let keyboardMinY, let visibleHeight):
|
|
215
|
+
logScrollViewport(
|
|
216
|
+
decision: "occluded",
|
|
217
|
+
keyboardMinY: keyboardMinY,
|
|
218
|
+
swipeHeight: visibleHeight,
|
|
219
|
+
context: context
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
return ScrollViewportPolicy.frames(referenceFrame: context.referenceFrame, clip: clip)
|
|
223
|
+
#else
|
|
224
|
+
let fallbackFrame = resolvedTouchReferenceFrame(app: app, appFrame: app.frame)
|
|
225
|
+
return ScrollViewportPolicy.frames(referenceFrame: fallbackFrame, clip: .unobstructed)
|
|
226
|
+
#endif
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
#if os(iOS)
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
private func logScrollViewport(
|
|
234
|
+
decision: String,
|
|
235
|
+
keyboardMinY: Double?,
|
|
236
|
+
swipeHeight: Double,
|
|
237
|
+
context: SynthesizedCoordinateContext
|
|
238
|
+
) {
|
|
239
|
+
NSLog(
|
|
240
|
+
"AGENT_DEVICE_RUNNER_SCROLL_VIEWPORT kind=scroll axHealth=%@ keyboardPolicy=%@ decision=%@ keyboardMinY=%@ swipeHeight=%.1f",
|
|
241
|
+
context.accessibilityHealth.rawValue,
|
|
242
|
+
context.keyboardPolicy.rawValue,
|
|
243
|
+
decision,
|
|
244
|
+
keyboardMinY.map { String(format: "%.1f", $0) } ?? "none",
|
|
245
|
+
swipeHeight
|
|
246
|
+
)
|
|
247
|
+
}
|
|
248
|
+
#endif
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
|
package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift
CHANGED
|
@@ -65,6 +65,9 @@ extension RunnerTests {
|
|
|
65
65
|
guard Date() < deadline else {
|
|
66
66
|
return alertVerificationResponse(.timedOut, action: action, activated: false)
|
|
67
67
|
}
|
|
68
|
+
guard waitUntilAlertButtonHittable(button, deadline: deadline) else {
|
|
69
|
+
return alertVerificationResponse(.timedOut, action: action, activated: false)
|
|
70
|
+
}
|
|
68
71
|
let outcome = activateElement(app: alert.ownerApp, element: button, action: "alert \(action)")
|
|
69
72
|
if let response = unsupportedResponse(for: outcome) {
|
|
70
73
|
return response
|
|
@@ -222,6 +225,37 @@ extension RunnerTests {
|
|
|
222
225
|
return enabled
|
|
223
226
|
}
|
|
224
227
|
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
private func waitUntilAlertButtonHittable(_ button: XCUIElement, deadline: Date) -> Bool {
|
|
237
|
+
while Date() < deadline {
|
|
238
|
+
if probeAlertButtonHittable(button, deadline: deadline) {
|
|
239
|
+
return Date() < deadline
|
|
240
|
+
}
|
|
241
|
+
sleepFor(min(0.1, max(0, deadline.timeIntervalSinceNow)))
|
|
242
|
+
}
|
|
243
|
+
return false
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
private func probeAlertButtonHittable(_ button: XCUIElement, deadline: Date) -> Bool {
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
var hittable = false
|
|
253
|
+
_ = RunnerObjCExceptionCatcher.catchException({
|
|
254
|
+
hittable = button.exists && button.isHittable
|
|
255
|
+
})
|
|
256
|
+
return hittable
|
|
257
|
+
}
|
|
258
|
+
|
|
225
259
|
private func isDismissPopupMarker(_ label: String) -> Bool {
|
|
226
260
|
label.trimmingCharacters(in: .whitespacesAndNewlines).caseInsensitiveCompare("dismiss popup") == .orderedSame
|
|
227
261
|
}
|
|
@@ -1953,21 +1953,25 @@ extension RunnerTests {
|
|
|
1953
1953
|
error: ErrorPayload(message: "scroll could not resolve a usable interaction frame")
|
|
1954
1954
|
)
|
|
1955
1955
|
}
|
|
1956
|
-
let
|
|
1957
|
-
|
|
1956
|
+
let viewport = resolvedScrollViewport(app: activeApp, context: scrollContext)
|
|
1957
|
+
let defaults = runnerDragCommandDefaults(command)
|
|
1958
|
+
switch viewport.gestureDispatch(
|
|
1959
|
+
direction: direction,
|
|
1960
|
+
amount: defaults.scrollAmount,
|
|
1961
|
+
pixels: command.pixels
|
|
1962
|
+
) {
|
|
1963
|
+
case .occluded(let occlusionKeyboardMinY, let visibleHeight):
|
|
1964
|
+
return scrollKeyboardOccludedResponse(
|
|
1965
|
+
direction: direction.rawValue,
|
|
1966
|
+
keyboardMinY: occlusionKeyboardMinY,
|
|
1967
|
+
visibleHeight: visibleHeight
|
|
1968
|
+
)
|
|
1969
|
+
case .unusableFrame:
|
|
1958
1970
|
return Response(
|
|
1959
1971
|
ok: false,
|
|
1960
1972
|
error: ErrorPayload(message: "scroll could not resolve a usable interaction frame")
|
|
1961
1973
|
)
|
|
1962
|
-
|
|
1963
|
-
let defaults = runnerDragCommandDefaults(command)
|
|
1964
|
-
guard let plan = runnerScrollGesturePlan(
|
|
1965
|
-
direction: direction,
|
|
1966
|
-
amount: defaults.scrollAmount,
|
|
1967
|
-
pixels: command.pixels,
|
|
1968
|
-
referenceWidth: frame.width,
|
|
1969
|
-
referenceHeight: frame.height
|
|
1970
|
-
) else {
|
|
1974
|
+
case .unusablePlan:
|
|
1971
1975
|
return Response(
|
|
1972
1976
|
ok: false,
|
|
1973
1977
|
error: ErrorPayload(
|
|
@@ -1975,21 +1979,24 @@ extension RunnerTests {
|
|
|
1975
1979
|
message: "scroll could not compute a gesture plan"
|
|
1976
1980
|
)
|
|
1977
1981
|
)
|
|
1982
|
+
case .gesture(let gesture):
|
|
1983
|
+
guard scrollDurationIsValid(command.durationMs) else {
|
|
1984
|
+
return invalidScrollDurationResponse(commandName: "scroll")
|
|
1985
|
+
}
|
|
1986
|
+
return gesture.attachingEvidence(
|
|
1987
|
+
to: executeScrollDragGesture(
|
|
1988
|
+
activeApp: activeApp,
|
|
1989
|
+
x: gesture.planFrame.minX + gesture.plan.x1,
|
|
1990
|
+
y: gesture.planFrame.minY + gesture.plan.y1,
|
|
1991
|
+
x2: gesture.planFrame.minX + gesture.plan.x2,
|
|
1992
|
+
y2: gesture.planFrame.minY + gesture.plan.y2,
|
|
1993
|
+
durationMs: defaults.durationMs,
|
|
1994
|
+
message: "scrolled",
|
|
1995
|
+
context: scrollContext.withReferenceFrame(gesture.coordinateFrame),
|
|
1996
|
+
releaseBehavior: command.scrollReleaseBehavior
|
|
1997
|
+
)
|
|
1998
|
+
)
|
|
1978
1999
|
}
|
|
1979
|
-
guard scrollDurationIsValid(command.durationMs) else {
|
|
1980
|
-
return invalidScrollDurationResponse(commandName: "scroll")
|
|
1981
|
-
}
|
|
1982
|
-
return executeScrollDragGesture(
|
|
1983
|
-
activeApp: activeApp,
|
|
1984
|
-
x: frame.minX + plan.x1,
|
|
1985
|
-
y: frame.minY + plan.y1,
|
|
1986
|
-
x2: frame.minX + plan.x2,
|
|
1987
|
-
y2: frame.minY + plan.y2,
|
|
1988
|
-
durationMs: defaults.durationMs,
|
|
1989
|
-
message: "scrolled",
|
|
1990
|
-
context: scrollContext.withReferenceFrame(frame),
|
|
1991
|
-
releaseBehavior: command.scrollReleaseBehavior
|
|
1992
|
-
)
|
|
1993
2000
|
case .desktopScroll:
|
|
1994
2001
|
guard let rawDirection = command.direction,
|
|
1995
2002
|
let direction = RunnerScrollDirection(rawValue: rawDirection)
|
|
@@ -2564,12 +2571,30 @@ extension RunnerTests {
|
|
|
2564
2571
|
)
|
|
2565
2572
|
}
|
|
2566
2573
|
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2574
|
+
|
|
2575
|
+
|
|
2576
|
+
|
|
2577
|
+
|
|
2578
|
+
|
|
2579
|
+
|
|
2580
|
+
|
|
2581
|
+
private func scrollKeyboardOccludedResponse(
|
|
2582
|
+
direction: String,
|
|
2583
|
+
keyboardMinY: Double,
|
|
2584
|
+
visibleHeight: Double
|
|
2585
|
+
) -> Response {
|
|
2586
|
+
return Response(
|
|
2587
|
+
ok: false,
|
|
2588
|
+
error: ErrorPayload(
|
|
2589
|
+
code: ScrollViewportPolicy.occlusionRunnerCode,
|
|
2590
|
+
message: String(
|
|
2591
|
+
format:
|
|
2592
|
+
"scroll %@ refused: the keyboard leaves %.0fpt of visible surface above it, too little to swipe",
|
|
2593
|
+
direction,
|
|
2594
|
+
visibleHeight
|
|
2595
|
+
)
|
|
2596
|
+
)
|
|
2597
|
+
)
|
|
2573
2598
|
}
|
|
2574
2599
|
|
|
2575
2600
|
private func dragCommandName(message: String) -> String {
|
package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift
CHANGED
|
@@ -11,7 +11,7 @@ private struct RunnerUnsupportedOperationError: LocalizedError {
|
|
|
11
11
|
var errorDescription: String? { message }
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
enum RunnerInterfaceOrientation {
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
|
|
@@ -909,18 +909,6 @@ extension RunnerTests {
|
|
|
909
909
|
return CGRect(x: 0, y: 0, width: width, height: height)
|
|
910
910
|
}
|
|
911
911
|
|
|
912
|
-
func synthesizedFrameAvoidingKeyboardWhenAllowed(
|
|
913
|
-
app: XCUIApplication,
|
|
914
|
-
context: SynthesizedCoordinateContext
|
|
915
|
-
) -> CGRect {
|
|
916
|
-
#if os(iOS)
|
|
917
|
-
guard context.allowsKeyboardProbe else { return context.referenceFrame }
|
|
918
|
-
return frameAvoidingKeyboard(app: app, frame: context.referenceFrame)
|
|
919
|
-
#else
|
|
920
|
-
return context.referenceFrame
|
|
921
|
-
#endif
|
|
922
|
-
}
|
|
923
|
-
|
|
924
912
|
func keyboardAvoidingSynthesizedDragPoints(
|
|
925
913
|
app: XCUIApplication,
|
|
926
914
|
x: Double,
|
package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift
CHANGED
|
@@ -268,6 +268,10 @@ struct DataPayload: Codable {
|
|
|
268
268
|
var gestureFallback: String?
|
|
269
269
|
var gestureFallbackMessage: String?
|
|
270
270
|
var gestureFallbackHint: String?
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
var keyboardAvoided: Bool?
|
|
274
|
+
var keyboardMinY: Double?
|
|
271
275
|
var maestroNonHittableCoordinateFallbackUsed: Bool?
|
|
272
276
|
var textEntryRoute: String?
|
|
273
277
|
var runnerFatal: Bool?
|
|
@@ -89,8 +89,14 @@ func synthesizedGesturePolicy(_ kind: SynthesizedGesturePolicyKind) -> Synthesiz
|
|
|
89
89
|
fallbackPolicy: .xctestCoordinateAllowed
|
|
90
90
|
)
|
|
91
91
|
case .scroll:
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
92
98
|
return SynthesizedGesturePolicy(
|
|
93
|
-
keyboardPolicy: .
|
|
99
|
+
keyboardPolicy: .requiredWhenAvailable,
|
|
94
100
|
fallbackPolicy: .privateSynthesisRequired
|
|
95
101
|
)
|
|
96
102
|
case .synthesizedDrag:
|
|
@@ -225,6 +231,8 @@ extension RunnerTests {
|
|
|
225
231
|
|
|
226
232
|
|
|
227
233
|
|
|
234
|
+
|
|
235
|
+
|
|
228
236
|
|
|
229
237
|
|
|
230
238
|
|