agent-device 0.16.7 → 0.16.9

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.
Files changed (43) hide show
  1. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.16.7.apk → agent-device-android-multitouch-helper-0.16.9.apk} +0 -0
  2. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.16.9.apk.sha256 +1 -0
  3. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.16.7.manifest.json → agent-device-android-multitouch-helper-0.16.9.manifest.json} +4 -4
  4. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.16.7.apk → agent-device-android-snapshot-helper-0.16.9.apk} +0 -0
  5. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.9.apk.sha256 +1 -0
  6. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.16.7.manifest.json → agent-device-android-snapshot-helper-0.16.9.manifest.json} +6 -6
  7. package/dist/src/1352.js +1 -1
  8. package/dist/src/2415.js +29 -29
  9. package/dist/src/2805.js +1 -1
  10. package/dist/src/6232.js +1 -0
  11. package/dist/src/7455.js +1 -0
  12. package/dist/src/8114.js +3 -3
  13. package/dist/src/8699.js +1 -1
  14. package/dist/src/940.js +1 -1
  15. package/dist/src/9471.js +1 -1
  16. package/dist/src/9533.js +1 -1
  17. package/dist/src/9542.js +1 -1
  18. package/dist/src/9818.js +1 -1
  19. package/dist/src/android-adb.d.ts +2 -0
  20. package/dist/src/android-snapshot-helper.d.ts +2 -0
  21. package/dist/src/args.js +5 -4
  22. package/dist/src/cli.js +6 -6
  23. package/dist/src/command-metadata.js +1 -1
  24. package/dist/src/find.js +1 -1
  25. package/dist/src/generic.js +11 -7
  26. package/dist/src/interaction.js +1 -1
  27. package/dist/src/react-native.js +1 -1
  28. package/dist/src/record-trace.js +3 -3
  29. package/dist/src/selector-runtime.js +1 -1
  30. package/dist/src/session.js +9 -9
  31. package/dist/src/snapshot.js +2 -2
  32. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +20 -6
  33. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +141 -774
  34. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +8 -33
  35. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +71 -1
  36. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +80 -10
  37. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +743 -0
  38. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +34 -6
  39. package/package.json +4 -6
  40. package/server.json +2 -2
  41. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.16.7.apk.sha256 +0 -1
  42. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.7.apk.sha256 +0 -1
  43. package/dist/src/5186.js +0 -1
@@ -2,7 +2,9 @@ import XCTest
2
2
 
3
3
  enum RunnerInteractionOutcome {
4
4
  case performed
5
- case unsupported(String)
5
+ /// A capability/state gap, surfaced to the caller as an UNSUPPORTED_OPERATION error.
6
+ /// `hint` is an optional actionable next step (mapped to ErrorPayload.hint).
7
+ case unsupported(message: String, hint: String?)
6
8
  }
7
9
 
8
10
  enum TvRemoteButton {
@@ -85,7 +87,10 @@ extension RunnerTests {
85
87
  func selectFocusedTvElement(app: XCUIApplication, point: CGPoint, action: String) -> RunnerInteractionOutcome? {
86
88
  #if os(tvOS)
87
89
  guard let focused = focusedTvElement(app: app), !focused.frame.isEmpty, focused.frame.contains(point) else {
88
- return .unsupported("\(action) is supported on tvOS only when the requested point is inside the focused element")
90
+ return .unsupported(
91
+ message: "\(action) is supported on tvOS only when the requested point is inside the focused element",
92
+ hint: "Move focus with swipe or scroll until the target is focused, then retry."
93
+ )
89
94
  }
90
95
  _ = pressTvRemote(.select)
91
96
  return .performed
@@ -97,7 +102,10 @@ extension RunnerTests {
97
102
  func longSelectFocusedTvElement(app: XCUIApplication, point: CGPoint, duration: TimeInterval) -> RunnerInteractionOutcome? {
98
103
  #if os(tvOS)
99
104
  guard let focused = focusedTvElement(app: app), !focused.frame.isEmpty, focused.frame.contains(point) else {
100
- return .unsupported("long press is supported on tvOS only when the requested point is inside the focused element")
105
+ return .unsupported(
106
+ message: "long press is supported on tvOS only when the requested point is inside the focused element",
107
+ hint: "Move focus with swipe or scroll until the target is focused, then retry."
108
+ )
101
109
  }
102
110
  _ = pressTvRemote(.select, duration: duration)
103
111
  return .performed
@@ -108,17 +116,37 @@ extension RunnerTests {
108
116
 
109
117
  private func performElementTap(_ element: XCUIElement) -> RunnerInteractionOutcome {
110
118
  #if os(tvOS)
111
- return .unsupported("element tap is not supported on tvOS; move focus with swipe or scroll, then select the focused element")
119
+ return .unsupported(
120
+ message: "element tap is not supported on tvOS; move focus with swipe or scroll, then select the focused element",
121
+ hint: "Use swipe/scroll to move focus to the target, then select it; tvOS has no coordinate tap."
122
+ )
112
123
  #else
113
- element.tap()
124
+ let exceptionMessage = RunnerObjCExceptionCatcher.catchException({
125
+ element.tap()
126
+ })
127
+ if let exceptionMessage {
128
+ NSLog("AGENT_DEVICE_RUNNER_ELEMENT_TAP_IGNORED_EXCEPTION=%@", exceptionMessage)
129
+ if isPostTapElementDisappearance(exceptionMessage) {
130
+ return .performed
131
+ }
132
+ return .unsupported(message: "element tap failed: \(exceptionMessage)", hint: nil)
133
+ }
114
134
  return .performed
115
135
  #endif
116
136
  }
117
137
 
138
+ private func isPostTapElementDisappearance(_ message: String) -> Bool {
139
+ message.contains("No matches found")
140
+ || message.contains("Failed to get matching snapshot")
141
+ }
142
+
118
143
  private func selectFocusedTvElement(app: XCUIApplication, element: XCUIElement, action: String) -> RunnerInteractionOutcome? {
119
144
  #if os(tvOS)
120
145
  guard tvFocusedElementMatches(app: app, target: element) else {
121
- return .unsupported("\(action) is supported on tvOS only when the requested element is focused")
146
+ return .unsupported(
147
+ message: "\(action) is supported on tvOS only when the requested element is focused",
148
+ hint: "Move focus to the target element first, then retry."
149
+ )
122
150
  }
123
151
  _ = pressTvRemote(.select)
124
152
  return .performed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-device",
3
- "version": "0.16.7",
3
+ "version": "0.16.9",
4
4
  "description": "Agent-native CLI for AI mobile testing and app automation across iOS, Android, tvOS, Android TV, macOS, and Linux.",
5
5
  "mcpName": "io.github.callstackincubator/agent-device",
6
6
  "license": "MIT",
@@ -98,6 +98,9 @@
98
98
  "ad": "node bin/agent-device.mjs",
99
99
  "size": "node scripts/size-report.mjs",
100
100
  "size:markdown": "node scripts/size-report.mjs --json .tmp/size-report.json --markdown .tmp/size-report.md",
101
+ "perf": "node --experimental-strip-types scripts/perf/run.ts",
102
+ "perf:ios": "node --experimental-strip-types scripts/perf/run.ts --platform ios",
103
+ "perf:android": "node --experimental-strip-types scripts/perf/run.ts --platform android",
101
104
  "lint": "oxlint . --deny-warnings",
102
105
  "format": "oxfmt --write src test skills package.json tsconfig.json tsconfig.lib.json rslib.config.ts vitest.config.ts .github/actions/setup-node-pnpm/action.yml .oxlintrc.json .oxfmtrc.json '!test/skillgym/.skillgym-results/**'",
103
106
  "fallow": "fallow --summary",
@@ -160,11 +163,6 @@
160
163
  "README.md",
161
164
  "LICENSE"
162
165
  ],
163
- "pnpm": {
164
- "overrides": {
165
- "lodash-es": "4.18.1"
166
- }
167
- },
168
166
  "keywords": [
169
167
  "agent",
170
168
  "device",
package/server.json CHANGED
@@ -7,12 +7,12 @@
7
7
  "url": "https://github.com/callstackincubator/agent-device",
8
8
  "source": "github"
9
9
  },
10
- "version": "0.16.7",
10
+ "version": "0.16.9",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "agent-device",
15
- "version": "0.16.7",
15
+ "version": "0.16.9",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  }
@@ -1 +0,0 @@
1
- 45f8780d4d500a67e110b8056cb5bcfe7a9589223e81f6cca5a005e34714c62c agent-device-android-multitouch-helper-0.16.7.apk
@@ -1 +0,0 @@
1
- 5e134ba87fbe184f76138ea59e4577d19a1ccbbb7d573b4d41c8997e29da60fa agent-device-android-snapshot-helper-0.16.7.apk
package/dist/src/5186.js DELETED
@@ -1 +0,0 @@
1
- let e={devices:"List available devices.",boot:"Boot or prepare a selected device without using CLI positional arguments.",apps:"List installed apps.",session:"List active sessions.",open:"Open an app, deep link, URL, or platform surface.",close:"Close an app or end the active session.",install:"Install an app binary.",reinstall:"Reinstall an app binary.","install-from-source":"Install an app from a structured source.",push:"Deliver a push payload.","trigger-app-event":"Trigger an app-defined event.",snapshot:"Capture an accessibility snapshot.",screenshot:"Capture a screenshot.",diff:"Diff accessibility snapshots.",wait:"Wait for duration, text, ref, or selector.",alert:"Inspect or handle platform alerts.",appstate:"Show foreground app or activity.",back:"Navigate back.",home:"Go to the home screen.",rotate:"Rotate device orientation.","app-switcher":"Open the app switcher.",keyboard:"Inspect or dismiss the keyboard.",clipboard:"Read or write clipboard text.","react-native":"Run supported React Native app automation helpers.",replay:"Replay a recorded session.",test:"Run one or more replay scripts.",perf:"Show session performance metrics.",logs:"Manage session app logs.",network:"Show recent HTTP traffic.",record:"Start or stop screen recording.",trace:"Start or stop trace capture.",settings:"Change OS settings and app permissions.",metro:"Prepare Metro runtime or reload React Native apps.",click:"Click or tap a semantic UI target by ref, selector, or point.",press:"Press a semantic UI target by ref, selector, or point.",fill:"Fill text into a semantic UI target by ref, selector, or point.",longpress:"Long press by ref, selector, or point.",swipe:"Swipe between two points.",focus:"Focus input at coordinates.",type:"Type text in the focused field.",scroll:"Scroll in a direction or to an edge.",get:"Get element text or attributes.",is:"Assert UI state.",find:"Find an element and optionally act on it.",gesture:"Run a structured gesture.",batch:"Run multiple structured command steps in one daemon request."};function t(t){let r=e[t];if(!r)throw Error(`Missing command description for ${t}`);return r}function r(){return Object.entries(e).map(([e,t])=>({name:e,description:t}))}export{r as listCommandDescriptionMetadata,t as requireCommandDescription};