@dyyz1993/agent-browser 0.13.2 → 0.24.0

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 (164) hide show
  1. package/README.md +108 -0
  2. package/bin/agent-browser-darwin-arm64 +0 -0
  3. package/bin/agent-browser-darwin-x64 +0 -0
  4. package/bin/agent-browser-linux-arm64 +0 -0
  5. package/bin/agent-browser-linux-x64 +0 -0
  6. package/bin/agent-browser-win32-x64.exe +0 -0
  7. package/dist/__tests__/e2e/utils/test-helpers.d.ts +1 -0
  8. package/dist/__tests__/e2e/utils/test-helpers.d.ts.map +1 -1
  9. package/dist/__tests__/e2e/utils/test-helpers.js +14 -1
  10. package/dist/__tests__/e2e/utils/test-helpers.js.map +1 -1
  11. package/dist/__tests__/utils/free-port.d.ts +2 -0
  12. package/dist/__tests__/utils/free-port.d.ts.map +1 -0
  13. package/dist/__tests__/utils/free-port.js +18 -0
  14. package/dist/__tests__/utils/free-port.js.map +1 -0
  15. package/dist/__tests__/utils/parseCli.d.ts.map +1 -1
  16. package/dist/__tests__/utils/parseCli.js +83 -9
  17. package/dist/__tests__/utils/parseCli.js.map +1 -1
  18. package/dist/actions.d.ts.map +1 -1
  19. package/dist/actions.js +298 -9
  20. package/dist/actions.js.map +1 -1
  21. package/dist/browser.d.ts +11 -1
  22. package/dist/browser.d.ts.map +1 -1
  23. package/dist/browser.js +75 -19
  24. package/dist/browser.js.map +1 -1
  25. package/dist/cli/commands.d.ts.map +1 -1
  26. package/dist/cli/commands.js +172 -15
  27. package/dist/cli/commands.js.map +1 -1
  28. package/dist/cli/connection.d.ts +13 -0
  29. package/dist/cli/connection.d.ts.map +1 -1
  30. package/dist/cli/connection.js +137 -48
  31. package/dist/cli/connection.js.map +1 -1
  32. package/dist/cli/flags.d.ts.map +1 -1
  33. package/dist/cli/flags.js +0 -1
  34. package/dist/cli/flags.js.map +1 -1
  35. package/dist/cli/help.d.ts.map +1 -1
  36. package/dist/cli/help.js +63 -22
  37. package/dist/cli/help.js.map +1 -1
  38. package/dist/cli/output.d.ts.map +1 -1
  39. package/dist/cli/output.js +0 -32
  40. package/dist/cli/output.js.map +1 -1
  41. package/dist/cli.js +20 -2
  42. package/dist/cli.js.map +1 -1
  43. package/dist/daemon.d.ts +1 -0
  44. package/dist/daemon.d.ts.map +1 -1
  45. package/dist/daemon.js +291 -264
  46. package/dist/daemon.js.map +1 -1
  47. package/dist/diff.d.ts.map +1 -1
  48. package/dist/diff.js +1 -1
  49. package/dist/diff.js.map +1 -1
  50. package/dist/flow/exporters/cypress.d.ts +9 -0
  51. package/dist/flow/exporters/cypress.d.ts.map +1 -0
  52. package/dist/flow/exporters/cypress.js +256 -0
  53. package/dist/flow/exporters/cypress.js.map +1 -0
  54. package/dist/flow/exporters/index.d.ts +6 -0
  55. package/dist/flow/exporters/index.d.ts.map +1 -0
  56. package/dist/flow/exporters/index.js +5 -0
  57. package/dist/flow/exporters/index.js.map +1 -0
  58. package/dist/flow/exporters/playwright.d.ts +20 -0
  59. package/dist/flow/exporters/playwright.d.ts.map +1 -0
  60. package/dist/flow/exporters/playwright.js +175 -0
  61. package/dist/flow/exporters/playwright.js.map +1 -0
  62. package/dist/flow/exporters/python.d.ts +20 -0
  63. package/dist/flow/exporters/python.d.ts.map +1 -0
  64. package/dist/flow/exporters/python.js +163 -0
  65. package/dist/flow/exporters/python.js.map +1 -0
  66. package/dist/flow/exporters/selenium.d.ts +9 -0
  67. package/dist/flow/exporters/selenium.d.ts.map +1 -0
  68. package/dist/flow/exporters/selenium.js +298 -0
  69. package/dist/flow/exporters/selenium.js.map +1 -0
  70. package/dist/flow/exporters/types.d.ts +13 -0
  71. package/dist/flow/exporters/types.d.ts.map +1 -0
  72. package/dist/flow/exporters/types.js +2 -0
  73. package/dist/flow/exporters/types.js.map +1 -0
  74. package/dist/flow/flow-executor.d.ts +57 -0
  75. package/dist/flow/flow-executor.d.ts.map +1 -0
  76. package/dist/flow/flow-executor.js +1263 -0
  77. package/dist/flow/flow-executor.js.map +1 -0
  78. package/dist/flow/index.d.ts +15 -0
  79. package/dist/flow/index.d.ts.map +1 -0
  80. package/dist/flow/index.js +10 -0
  81. package/dist/flow/index.js.map +1 -0
  82. package/dist/flow/output.d.ts +11 -0
  83. package/dist/flow/output.d.ts.map +1 -0
  84. package/dist/flow/output.js +84 -0
  85. package/dist/flow/output.js.map +1 -0
  86. package/dist/flow/plugin-system.d.ts +48 -0
  87. package/dist/flow/plugin-system.d.ts.map +1 -0
  88. package/dist/flow/plugin-system.js +132 -0
  89. package/dist/flow/plugin-system.js.map +1 -0
  90. package/dist/flow/plugins/file-output-plugin.d.ts +8 -0
  91. package/dist/flow/plugins/file-output-plugin.d.ts.map +1 -0
  92. package/dist/flow/plugins/file-output-plugin.js +31 -0
  93. package/dist/flow/plugins/file-output-plugin.js.map +1 -0
  94. package/dist/flow/plugins/index.d.ts +4 -0
  95. package/dist/flow/plugins/index.d.ts.map +1 -0
  96. package/dist/flow/plugins/index.js +4 -0
  97. package/dist/flow/plugins/index.js.map +1 -0
  98. package/dist/flow/plugins/logging-plugin.d.ts +7 -0
  99. package/dist/flow/plugins/logging-plugin.d.ts.map +1 -0
  100. package/dist/flow/plugins/logging-plugin.js +40 -0
  101. package/dist/flow/plugins/logging-plugin.js.map +1 -0
  102. package/dist/flow/plugins/webhook-plugin.d.ts +7 -0
  103. package/dist/flow/plugins/webhook-plugin.d.ts.map +1 -0
  104. package/dist/flow/plugins/webhook-plugin.js +24 -0
  105. package/dist/flow/plugins/webhook-plugin.js.map +1 -0
  106. package/dist/flow/presets/index.d.ts +10 -0
  107. package/dist/flow/presets/index.d.ts.map +1 -0
  108. package/dist/flow/presets/index.js +29 -0
  109. package/dist/flow/presets/index.js.map +1 -0
  110. package/dist/flow/recorder-to-flow.d.ts +70 -0
  111. package/dist/flow/recorder-to-flow.d.ts.map +1 -0
  112. package/dist/flow/recorder-to-flow.js +392 -0
  113. package/dist/flow/recorder-to-flow.js.map +1 -0
  114. package/dist/flow/site-manager.d.ts +24 -0
  115. package/dist/flow/site-manager.d.ts.map +1 -0
  116. package/dist/flow/site-manager.js +125 -0
  117. package/dist/flow/site-manager.js.map +1 -0
  118. package/dist/flow/types.d.ts +196 -0
  119. package/dist/flow/types.d.ts.map +1 -0
  120. package/dist/flow/types.js +2 -0
  121. package/dist/flow/types.js.map +1 -0
  122. package/dist/flow/yaml-parser.d.ts +15 -0
  123. package/dist/flow/yaml-parser.d.ts.map +1 -0
  124. package/dist/flow/yaml-parser.js +216 -0
  125. package/dist/flow/yaml-parser.js.map +1 -0
  126. package/dist/human-mouse.d.ts.map +1 -1
  127. package/dist/protocol.d.ts.map +1 -1
  128. package/dist/protocol.js +15 -11
  129. package/dist/protocol.js.map +1 -1
  130. package/dist/rc-config.d.ts.map +1 -1
  131. package/dist/rc-config.js +1 -2
  132. package/dist/rc-config.js.map +1 -1
  133. package/dist/recorder/inject.js +730 -332
  134. package/dist/snapshot-store.d.ts +83 -0
  135. package/dist/snapshot-store.d.ts.map +1 -0
  136. package/dist/snapshot-store.js +112 -0
  137. package/dist/snapshot-store.js.map +1 -0
  138. package/dist/snapshot.d.ts +6 -7
  139. package/dist/snapshot.d.ts.map +1 -1
  140. package/dist/snapshot.js +471 -17
  141. package/dist/snapshot.js.map +1 -1
  142. package/dist/stream-server-standalone.d.ts.map +1 -1
  143. package/dist/stream-server-standalone.js.map +1 -1
  144. package/dist/stream-server.d.ts.map +1 -1
  145. package/dist/stream-server.js +38 -13
  146. package/dist/stream-server.js.map +1 -1
  147. package/dist/test-live.js +5 -5
  148. package/dist/test-live.js.map +1 -1
  149. package/dist/types.d.ts +13 -9
  150. package/dist/types.d.ts.map +1 -1
  151. package/dist/types.js.map +1 -1
  152. package/dist/viewer-script.d.ts.map +1 -1
  153. package/dist/viewer-script.js +12 -6
  154. package/dist/viewer-script.js.map +1 -1
  155. package/package.json +18 -5
  156. package/skills/agent-browser/SKILL.md +151 -3
  157. package/dist/ios-actions.d.ts +0 -11
  158. package/dist/ios-actions.d.ts.map +0 -1
  159. package/dist/ios-actions.js +0 -228
  160. package/dist/ios-actions.js.map +0 -1
  161. package/dist/ios-manager.d.ts +0 -266
  162. package/dist/ios-manager.d.ts.map +0 -1
  163. package/dist/ios-manager.js +0 -1076
  164. package/dist/ios-manager.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dyyz1993/agent-browser",
3
- "version": "0.13.2",
3
+ "version": "0.24.0",
4
4
  "description": "Headless browser automation CLI for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/daemon.js",
@@ -11,7 +11,7 @@
11
11
  "skills"
12
12
  ],
13
13
  "bin": {
14
- "agent-browser": "./dist/cli.js"
14
+ "agent-browser": "./bin/agent-browser.js"
15
15
  },
16
16
  "scripts": {
17
17
  "prepare": "husky",
@@ -27,10 +27,14 @@
27
27
  "release": "npm run version:sync && npm run build && npm run build:all-platforms && npm publish",
28
28
  "start": "node dist/daemon.js",
29
29
  "dev": "tsx src/daemon.ts",
30
+ "lint": "eslint src/ --ext .ts",
31
+ "lint:fix": "eslint src/ --ext .ts --fix",
30
32
  "typecheck": "tsc --noEmit",
31
33
  "format": "prettier --write 'src/**/*.ts'",
32
34
  "format:check": "prettier --check 'src/**/*.ts'",
33
35
  "test": "vitest run",
36
+ "test:integration": "vitest run --config vitest.integration.config.ts",
37
+ "test:e2e": "vitest run --config vitest.integration.config.ts src/__tests__/e2e/snapshot-selector-store.e2e.test.ts",
34
38
  "test:watch": "vitest",
35
39
  "postinstall": "node scripts/postinstall.js",
36
40
  "changeset": "changeset",
@@ -55,18 +59,21 @@
55
59
  },
56
60
  "homepage": "https://github.com/xuyingzhou/agent-browser#readme",
57
61
  "dependencies": {
58
- "node-simctl": "^7.4.0",
62
+ "js-yaml": "^4.1.1",
59
63
  "playwright-core": "^1.57.0",
60
64
  "sharp": "^0.34.5",
61
- "undici": "^8.2.0",
62
- "webdriverio": "^9.15.0",
65
+ "undici": "^7.25.0",
63
66
  "ws": "^8.19.0",
64
67
  "zod": "^3.22.4"
65
68
  },
66
69
  "devDependencies": {
67
70
  "@changesets/cli": "^2.29.8",
71
+ "@types/js-yaml": "^4.0.9",
68
72
  "@types/node": "^20.10.0",
69
73
  "@types/ws": "^8.18.1",
74
+ "@typescript-eslint/eslint-plugin": "^8.59.2",
75
+ "@typescript-eslint/parser": "^8.59.2",
76
+ "eslint": "^10.3.0",
70
77
  "happy-dom": "^20.7.0",
71
78
  "husky": "^9.1.7",
72
79
  "lint-staged": "^15.2.11",
@@ -74,6 +81,7 @@
74
81
  "prettier": "^3.7.4",
75
82
  "tsx": "^4.6.0",
76
83
  "typescript": "^5.3.0",
84
+ "typescript-eslint": "^8.59.2",
77
85
  "vitest": "^4.0.16"
78
86
  },
79
87
  "lint-staged": {
@@ -83,5 +91,10 @@
83
91
  "doc": "docs",
84
92
  "test": "test"
85
93
  },
94
+ "pnpm": {
95
+ "overrides": {
96
+ "lodash": "^4.18.0"
97
+ }
98
+ },
86
99
  "author": "xuyingzhou"
87
100
  }
@@ -83,6 +83,150 @@ agent-browser reload # Trigger requests
83
83
  agent-browser network requests # Now shows captured requests
84
84
  ```
85
85
 
86
+ ### WebSocket Monitoring
87
+
88
+ WebSocket tracking activates on first use and captures all WS connections at the CDP level (no JS injection needed, survives page navigation):
89
+
90
+ ```bash
91
+ agent-browser network websockets # Activate tracking + show connections
92
+ agent-browser network websockets --json # Structured JSON output
93
+ agent-browser network websockets --filter "ws://" # Filter by URL
94
+ agent-browser network websockets --clear # Clear captured data
95
+ ```
96
+
97
+ ### Snapshot ID System
98
+
99
+ Every `snapshot -i` now returns a unique snapshot ID (snap_1, snap_2, ...) in the output. This ID is used to query stable CSS selectors for any element captured in that snapshot.
100
+
101
+ ```bash
102
+ agent-browser snapshot -i
103
+ # Output includes:
104
+ # ## Snapshot: snap_3
105
+ # - searchbox "Search" [ref=e1]
106
+ # - button "Submit" [ref=e2]
107
+ # Tip: Use --selector-for snap_3:@e1 to get a stable selector
108
+ ```
109
+
110
+ ### Stable Selectors & Command History
111
+
112
+ After taking a snapshot, use the snapshot ID to query stable CSS selectors that survive across page changes (unlike refs, which are invalidated by DOM mutations). Selectors are generated using an 8-strategy algorithm that always produces the shortest, most semantically meaningful unique selector.
113
+
114
+ ```bash
115
+ # Get selector for a specific element (by ref)
116
+ agent-browser snapshot --selector-for snap_3:@e1
117
+ # Output: snap_3 e1 (button "Submit")
118
+ # CSS: #submit-btn
119
+ # XPath: //*[@id="submit-btn"]
120
+
121
+ # Get selector by index
122
+ agent-browser snapshot --selector-for snap_3:1
123
+
124
+ # List all selectors for a snapshot
125
+ agent-browser snapshot --selectors-of snap_3
126
+ # Output:
127
+ # [1] e1 searchbox "Search" -> #search-input
128
+ # [2] e2 button "Submit" -> #submit-btn
129
+
130
+ # Validate selectors still match after page changes
131
+ agent-browser snapshot --validate snap_3
132
+ # Output:
133
+ # [1] e1 #search-input -> valid
134
+ # [2] e2 #submit-btn -> not found (element removed)
135
+ ```
136
+
137
+ Selector strategies (tried in order, first unique match wins):
138
+
139
+ 1. `#id`
140
+ 2. `[data-testid="..."]`
141
+ 3. `tag[name="..."]`
142
+ 4. `tag[aria-label="..."]`
143
+ 5. `tag.semantic-class`
144
+ 6. `tag.class[attr="..."]`
145
+ 7. Composed path (`ancestor > tag`)
146
+ 8. `tag:nth-child(n)` fallback
147
+
148
+ Each strategy validates uniqueness via `querySelectorAll`, ensuring the selector matches exactly one element.
149
+
150
+ ```bash
151
+ # Get recorded interaction history (auto-captured)
152
+ agent-browser history # Show all recorded interactions
153
+ agent-browser history --filter "fill" # Filter by action type
154
+ agent-browser history --clear # Clear history
155
+ ```
156
+
157
+ **Note:** `history` records `fill`, `click`, `select`, `check`, `uncheck`, and `eval` commands. `eval` entries have `action: "eval"`, `selector: "javascript"`, and `value` containing the script (truncated at 200 chars). Failed eval commands are also recorded with `success: false`.
158
+
159
+ ### Strict Mode Auto-Fallback
160
+
161
+ When `find text`, `find role`, or `find label` matches multiple elements, Playwright throws a "strict mode violation" error. agent-browser now automatically falls back to the first matching element instead of failing.
162
+
163
+ The command succeeds with a yellow warning in the output:
164
+ ```
165
+ ⚠ Matched 3 elements, used first match. Use 'find nth <index> text "X" --click' for a specific match.
166
+ ```
167
+
168
+ To target a specific element, use `find nth <index> text "X" --click` or a more specific CSS selector (`#id`, `[data-testid]`).
169
+
170
+ ### Self-Healing Replay
171
+
172
+ When replaying recorded flows, the engine automatically tries fallback selectors and element identity matching when the primary selector fails. This makes replays resilient to DOM changes, class renames, and structural reorganizations.
173
+
174
+ Healing strategies (tried in order):
175
+
176
+ 1. **fallback** — Try the top-3 alternative selectors captured during recording
177
+ 2. **identity_text** — Match by tagName + visible text content
178
+ 3. **identity_attr** — Match by tagName + stable attribute combination
179
+ 4. **identity_parent** — Match by parent signature + position
180
+
181
+ The healing log is included in flow results when `--output json` is used:
182
+
183
+ ```bash
184
+ agent-browser flow run my-site.my-flow --output json
185
+ # healingLog entries show which strategy succeeded and the original vs healed selector
186
+ ```
187
+
188
+ ### Script Export
189
+
190
+ Flows and recordings can be exported as standalone scripts that run without agent-browser:
191
+
192
+ ```bash
193
+ # Export as Playwright TypeScript
194
+ agent-browser flow export recording.yaml --format playwright
195
+
196
+ # Export as Python Playwright
197
+ agent-browser flow export recording.yaml --format python
198
+
199
+ # With options
200
+ agent-browser flow export recording.yaml --format playwright --headless
201
+ agent-browser flow export recording.yaml --format python --base-url https://staging.example.com
202
+ ```
203
+
204
+ Options:
205
+
206
+ - `--format <playwright|python>` — Export format (required)
207
+ - `--headless` — Include headless mode in the exported script
208
+ - `--base-url <url>` — Override base URL in the exported script
209
+
210
+ ### Enhanced Recording
211
+
212
+ The recorder captures additional metadata beyond basic selectors, enabling self-healing replay and robust script export:
213
+
214
+ - **Fallback selectors** — Top-3 alternative CSS selectors per element, so replay can recover when the primary selector breaks
215
+ - **Element identity** — tagName, visible text, key attributes, and parent signature for fuzzy matching
216
+ - **SPA URL change detection** — Tracks `pushState` and `replaceState` calls to accurately record navigation in single-page applications
217
+ - **DOM stability signals** — Uses MutationObserver to wait for DOM settling before capturing selectors, avoiding stale captures during dynamic rendering
218
+
219
+ ### Snapshot --all (Include Visually Hidden Elements)
220
+
221
+ By default, `snapshot -i --selectors` only includes elements that are visually visible. Elements with `opacity: 0`, zero dimensions, or positioned off-screen are filtered out.
222
+
223
+ Use `--all` to include all elements present in the accessibility tree:
224
+ ```bash
225
+ agent-browser snapshot -i --selectors --all
226
+ ```
227
+
228
+ **Limitation:** Elements with `display: none` or `visibility: hidden` are excluded by Playwright's accessibility tree generator and cannot be included, even with `--all`. For such elements, use `eval` to discover them via DOM queries.
229
+
86
230
  ## Capabilities
87
231
 
88
232
  | Area | Key Commands | Deep Dive |
@@ -91,7 +235,7 @@ agent-browser network requests # Now shows captured requests
91
235
  | Snapshot & Element Inspection | `snapshot` | [snapshot-refs](references/snapshot-refs.md) |
92
236
  | Finding Elements | `find by role`, `text`, `label` | [commands](references/commands.md) |
93
237
  | Data Extraction | `eval` | [data-extraction](references/data-extraction.md) |
94
- | Network Control | `request monitoring`, `API mocking`, `URL blocking` | [network-monitoring](references/network-monitoring.md) |
238
+ | Network Control | `request monitoring`, `WebSocket monitoring`, `API mocking`, `URL blocking` | [network-monitoring](references/network-monitoring.md) |
95
239
  | Session & State | `connect`, `close`, `cookies`, `storage`, `tab` | [session-management](references/session-management.md) |
96
240
  | Authentication | `login flows`, `OAuth`, `2FA` | [authentication](references/authentication.md) |
97
241
  | Recording & Replay | `record`, `recorder` | [recorder](references/recorder.md) |
@@ -104,9 +248,11 @@ agent-browser network requests # Now shows captured requests
104
248
  ### Core Workflow Pattern
105
249
 
106
250
  1. `open <url>` → navigate
107
- 2. `snapshot -i` → get element refs (`@e1`, `@e2`, ...)
251
+ 2. `snapshot -i` → get element refs (`@e1`, `@e2`, ...) and a snapshot ID (`snap_N`)
108
252
  3. `fill` / `click` / `select` → interact using refs
109
- 4. Re-`snapshot` after any page change (refs are invalidated)
253
+ 4. After page changes, `snapshot --validate snap_N` to check which selectors still work
254
+ 5. Use `snapshot --selectors-of snap_N` to collect stable selectors for later use
255
+ 6. Re-`snapshot -i` after significant page changes (refs are invalidated)
110
256
 
111
257
  ### Session Isolation
112
258
 
@@ -125,6 +271,8 @@ If ref errors occur unexpectedly, check whether another process is operating on
125
271
 
126
272
  Refs (`@e1`, `@e2`) are **session-scoped** — valid across Bash processes within the same session, but invalidated by any page change (navigation, form submit, dynamic load). Always re-snapshot after DOM mutations. See [snapshot-refs.md](references/snapshot-refs.md).
127
273
 
274
+ For selectors that survive page changes, use the stable selector system (`--selector-for`, `--selectors-of`, `--validate`) with snapshot IDs. Stable selectors are CSS selectors computed once per snapshot and can be validated later even after the DOM mutates.
275
+
128
276
  When multiple elements share the same role+name, each gets a unique ref with a `[nth=N]` annotation. Just use the ref — the nth index is built in:
129
277
 
130
278
  ```
@@ -1,11 +0,0 @@
1
- /**
2
- * iOS command execution - mirrors actions.ts but for iOS Safari via Appium.
3
- * Provides 1:1 command parity where possible.
4
- */
5
- import type { IOSManager } from './ios-manager.js';
6
- import type { Command, Response } from './types.js';
7
- /**
8
- * Execute a command on the iOS manager
9
- */
10
- export declare function executeIOSCommand(command: Command, manager: IOSManager): Promise<Response>;
11
- //# sourceMappingURL=ios-actions.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ios-actions.d.ts","sourceRoot":"","sources":["../src/ios-actions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAUpD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CA6PhG"}
@@ -1,228 +0,0 @@
1
- /**
2
- * iOS command execution - mirrors actions.ts but for iOS Safari via Appium.
3
- * Provides 1:1 command parity where possible.
4
- */
5
- function successResponse(id, data) {
6
- return { id, success: true, data };
7
- }
8
- function errorResponse(id, error) {
9
- return { id, success: false, error };
10
- }
11
- /**
12
- * Execute a command on the iOS manager
13
- */
14
- export async function executeIOSCommand(command, manager) {
15
- const { id, action } = command;
16
- try {
17
- switch (action) {
18
- case 'launch': {
19
- const cmd = command;
20
- await manager.launch({
21
- device: cmd.device,
22
- udid: cmd.udid,
23
- });
24
- const info = manager.getDeviceInfo();
25
- return successResponse(id, {
26
- launched: true,
27
- device: info?.name ?? 'iOS Simulator',
28
- udid: info?.udid,
29
- });
30
- }
31
- case 'navigate': {
32
- const cmd = command;
33
- const result = await manager.navigate(cmd.url);
34
- return successResponse(id, result);
35
- }
36
- case 'click': {
37
- const cmd = command;
38
- await manager.click(cmd.selector);
39
- return successResponse(id, { clicked: true });
40
- }
41
- case 'tap': {
42
- const cmd = command;
43
- await manager.tap(cmd.selector);
44
- return successResponse(id, { tapped: true });
45
- }
46
- case 'type': {
47
- const cmd = command;
48
- await manager.type(cmd.selector, cmd.text, {
49
- delay: cmd.delay,
50
- clear: cmd.clear,
51
- });
52
- return successResponse(id, { typed: true });
53
- }
54
- case 'fill': {
55
- const cmd = command;
56
- await manager.fill(cmd.selector, cmd.value);
57
- return successResponse(id, { filled: true });
58
- }
59
- case 'screenshot': {
60
- const cmd = command;
61
- const result = await manager.screenshot({
62
- path: cmd.path,
63
- fullPage: cmd.fullPage,
64
- });
65
- return successResponse(id, result);
66
- }
67
- case 'snapshot': {
68
- const cmd = command;
69
- const result = await manager.getSnapshot({
70
- interactive: cmd.interactive,
71
- });
72
- return successResponse(id, { snapshot: result.tree, refs: result.refs });
73
- }
74
- case 'scroll': {
75
- const cmd = command;
76
- await manager.scroll({
77
- selector: cmd.selector,
78
- x: cmd.x,
79
- y: cmd.y,
80
- direction: cmd.direction,
81
- amount: cmd.amount,
82
- });
83
- return successResponse(id, { scrolled: true });
84
- }
85
- case 'swipe': {
86
- const cmd = command;
87
- await manager.swipe(cmd.direction, { distance: cmd.distance });
88
- return successResponse(id, { swiped: true });
89
- }
90
- case 'evaluate': {
91
- const cmd = command;
92
- const result = await manager.evaluate(cmd.script, ...(cmd.args ?? []));
93
- return successResponse(id, { result });
94
- }
95
- case 'wait': {
96
- const cmd = command;
97
- await manager.wait({
98
- selector: cmd.selector,
99
- timeout: cmd.timeout,
100
- state: cmd.state,
101
- });
102
- return successResponse(id, { waited: true });
103
- }
104
- case 'press': {
105
- const cmd = command;
106
- await manager.press(cmd.key);
107
- return successResponse(id, { pressed: true });
108
- }
109
- case 'hover': {
110
- const cmd = command;
111
- await manager.hover(cmd.selector);
112
- return successResponse(id, { hovered: true });
113
- }
114
- case 'content': {
115
- const cmd = command;
116
- const html = await manager.getContent(cmd.selector);
117
- return successResponse(id, { html });
118
- }
119
- case 'gettext': {
120
- const cmd = command;
121
- const text = await manager.getText(cmd.selector);
122
- return successResponse(id, { text });
123
- }
124
- case 'getattribute': {
125
- const cmd = command;
126
- const value = await manager.getAttribute(cmd.selector, cmd.attribute);
127
- return successResponse(id, { value });
128
- }
129
- case 'isvisible': {
130
- const cmd = command;
131
- const visible = await manager.isVisible(cmd.selector);
132
- return successResponse(id, { visible });
133
- }
134
- case 'isenabled': {
135
- const cmd = command;
136
- const enabled = await manager.isEnabled(cmd.selector);
137
- return successResponse(id, { enabled });
138
- }
139
- case 'url': {
140
- const url = await manager.getUrl();
141
- return successResponse(id, { url });
142
- }
143
- case 'title': {
144
- const title = await manager.getTitle();
145
- return successResponse(id, { title });
146
- }
147
- case 'back': {
148
- await manager.goBack();
149
- return successResponse(id, { navigated: 'back' });
150
- }
151
- case 'forward': {
152
- await manager.goForward();
153
- return successResponse(id, { navigated: 'forward' });
154
- }
155
- case 'reload': {
156
- await manager.reload();
157
- return successResponse(id, { reloaded: true });
158
- }
159
- case 'select': {
160
- const cmd = command;
161
- await manager.select(cmd.selector, cmd.values);
162
- return successResponse(id, { selected: true });
163
- }
164
- case 'check': {
165
- const cmd = command;
166
- await manager.check(cmd.selector);
167
- return successResponse(id, { checked: true });
168
- }
169
- case 'uncheck': {
170
- const cmd = command;
171
- await manager.uncheck(cmd.selector);
172
- return successResponse(id, { unchecked: true });
173
- }
174
- case 'focus': {
175
- const cmd = command;
176
- await manager.focus(cmd.selector);
177
- return successResponse(id, { focused: true });
178
- }
179
- case 'clear': {
180
- const cmd = command;
181
- await manager.clear(cmd.selector);
182
- return successResponse(id, { cleared: true });
183
- }
184
- case 'count': {
185
- const cmd = command;
186
- const count = await manager.count(cmd.selector);
187
- return successResponse(id, { count });
188
- }
189
- case 'boundingbox': {
190
- const cmd = command;
191
- const box = await manager.getBoundingBox(cmd.selector);
192
- return successResponse(id, { box });
193
- }
194
- case 'close': {
195
- await manager.close();
196
- return successResponse(id, { closed: true });
197
- }
198
- // iOS-specific: device list
199
- case 'device_list': {
200
- const devices = await manager.listDevices();
201
- return successResponse(id, { devices });
202
- }
203
- // Commands that don't apply to iOS Safari
204
- case 'tab_new':
205
- case 'tab_list':
206
- case 'tab_switch':
207
- case 'tab_close':
208
- case 'window_new':
209
- return errorResponse(id, `Command '${action}' is not supported on iOS Safari. Mobile Safari does not support programmatic tab management.`);
210
- case 'pdf':
211
- return errorResponse(id, 'PDF generation is not supported on iOS Safari.');
212
- case 'screencast_start':
213
- case 'screencast_stop':
214
- return errorResponse(id, 'Screencast is not supported on iOS (requires CDP).');
215
- case 'recording_start':
216
- case 'recording_stop':
217
- case 'recording_restart':
218
- return errorResponse(id, 'Video recording is not yet supported on iOS.');
219
- default:
220
- return errorResponse(id, `Unknown or unsupported iOS command: ${action}`);
221
- }
222
- }
223
- catch (error) {
224
- const message = error instanceof Error ? error.message : String(error);
225
- return errorResponse(id, message);
226
- }
227
- }
228
- //# sourceMappingURL=ios-actions.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ios-actions.js","sourceRoot":"","sources":["../src/ios-actions.ts"],"names":[],"mappings":"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"}