appium-session-recorder 0.0.1
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/LICENSE +21 -0
- package/README.md +362 -0
- package/bun.lock +731 -0
- package/package.json +62 -0
- package/skills/appium-cli-selector-navigator/SKILL.md +349 -0
- package/src/cli/arg-parser.ts +311 -0
- package/src/cli/commands/drive.ts +147 -0
- package/src/cli/commands/index.ts +54 -0
- package/src/cli/commands/proxy.ts +41 -0
- package/src/cli/commands/screen.ts +73 -0
- package/src/cli/commands/selectors.ts +42 -0
- package/src/cli/commands/session.ts +64 -0
- package/src/cli/commands/types.ts +11 -0
- package/src/cli/index.ts +158 -0
- package/src/cli/prompts.ts +64 -0
- package/src/cli/response.ts +44 -0
- package/src/core/appium/client.ts +248 -0
- package/src/core/index.ts +5 -0
- package/src/core/selectors/generate-candidates.ts +155 -0
- package/src/core/selectors/score-candidates.ts +184 -0
- package/src/core/types.ts +79 -0
- package/src/core/xml/parse-source.ts +197 -0
- package/src/index.ts +7 -0
- package/src/server/appium-client.ts +24 -0
- package/src/server/index.ts +6 -0
- package/src/server/interaction-recorder.ts +74 -0
- package/src/server/proxy-middleware.ts +68 -0
- package/src/server/routes.ts +53 -0
- package/src/server/server.ts +43 -0
- package/src/server/types.ts +34 -0
- package/src/ui/bun.lock +311 -0
- package/src/ui/index.html +16 -0
- package/src/ui/package.json +20 -0
- package/src/ui/src/App.css +12 -0
- package/src/ui/src/App.tsx +41 -0
- package/src/ui/src/components/ActionCarousel.css +128 -0
- package/src/ui/src/components/ActionCarousel.tsx +92 -0
- package/src/ui/src/components/Inspector.css +314 -0
- package/src/ui/src/components/Inspector.tsx +265 -0
- package/src/ui/src/components/InteractionCard.css +159 -0
- package/src/ui/src/components/InteractionCard.tsx +60 -0
- package/src/ui/src/components/MainInspector.css +304 -0
- package/src/ui/src/components/MainInspector.tsx +304 -0
- package/src/ui/src/components/Stats.css +27 -0
- package/src/ui/src/components/Timeline.css +31 -0
- package/src/ui/src/components/Timeline.tsx +37 -0
- package/src/ui/src/hooks/useInteractions.ts +73 -0
- package/src/ui/src/index.tsx +11 -0
- package/src/ui/src/services/api.ts +41 -0
- package/src/ui/src/styles/tokens.css +126 -0
- package/src/ui/src/types.ts +34 -0
- package/src/ui/src/utils/__tests__/locators.test.ts +304 -0
- package/src/ui/src/utils/__tests__/xml-parser.test.ts +326 -0
- package/src/ui/src/utils/locators.ts +14 -0
- package/src/ui/src/utils/xml-parser.ts +45 -0
- package/src/ui/tsconfig.json +34 -0
- package/src/ui/tsconfig.node.json +11 -0
- package/src/ui/vite.config.ts +22 -0
- package/tests/cli/arg-parser.test.ts +397 -0
- package/tests/cli/drive-commands.test.ts +151 -0
- package/tests/cli/selectors-best.test.ts +42 -0
- package/tests/cli/session-commands.test.ts +53 -0
- package/tests/core/selector-candidates.test.ts +83 -0
- package/tests/core/selector-scoring.test.ts +75 -0
- package/tests/core/xml-parser.test.ts +56 -0
- package/tests/server/appium-client.test.ts +229 -0
- package/tests/server/interaction-recorder.test.ts +377 -0
- package/tests/server/proxy-middleware.test.ts +343 -0
- package/tests/server/routes.test.ts +305 -0
- package/tsconfig.json +26 -0
- package/vitest.config.ts +16 -0
- package/vitest.ui.config.ts +15 -0
- package/workflow.gif +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 JustasM
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
# Appium Session Recorder
|
|
2
|
+
|
|
3
|
+
A modern Appium recorder and automation CLI with real-time UI visualization, session navigation commands, and selector ranking. Built with Bun, Solid.js, and Kobalte.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## ✨ Features
|
|
8
|
+
|
|
9
|
+
- 🎬 **Session Recording**: Intercepts and logs Appium commands (currently focused on `POST /session/:sessionId/*`)
|
|
10
|
+
- 📸 **Screenshot Capture**: Automatically captures screenshots after actions
|
|
11
|
+
- 🤖 **JSON-First Command Mode**: Scriptable subcommands for agent workflows (`session`, `screen`, `selectors`, `drive`)
|
|
12
|
+
- 🧭 **CLI App Navigation**: Drive taps, typing, back navigation, and swipe gestures via Appium
|
|
13
|
+
- 🏆 **Best Selector Ranking**: Heuristic ranking with strategy scoring + match counts + reason codes
|
|
14
|
+
- 🔍 **Element Inspector**: Interactive element inspection with multiple locator strategies
|
|
15
|
+
- 🎯 **Query Tester**: Test locators in real-time on captured screenshots
|
|
16
|
+
- 📊 **Real-time Updates**: Live dashboard with Server-Sent Events
|
|
17
|
+
- 🎨 **Modern UI**: Beautiful dark theme with vibrant accents using Solid.js + Kobalte
|
|
18
|
+
- ⚡ **Fast**: Built with Bun for optimal performance
|
|
19
|
+
- 🛠️ **Interactive CLI**: Beautiful prompts for easy configuration
|
|
20
|
+
|
|
21
|
+
## 🚀 Quick Start
|
|
22
|
+
|
|
23
|
+
### Prerequisites
|
|
24
|
+
|
|
25
|
+
- [Bun](https://bun.sh/) runtime installed
|
|
26
|
+
- [Appium](https://appium.io/) server installed
|
|
27
|
+
|
|
28
|
+
### Start Appium Server
|
|
29
|
+
|
|
30
|
+
Start the Appium server (CORS is only needed if you plan to call Appium directly from a browser):
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
appium --port 4723 --allow-cors
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The recorder proxy itself does not require `--allow-cors` for normal usage.
|
|
37
|
+
|
|
38
|
+
### Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
cd appium-session-recorder # (or your cloned folder name)
|
|
42
|
+
bun install
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Run the CLI
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
bun run cli
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The CLI will interactively prompt you for:
|
|
52
|
+
- **Proxy port** (default: 4724)
|
|
53
|
+
- **Proxy host** (default: 127.0.0.1)
|
|
54
|
+
- **Appium server URL** (default: http://127.0.0.1:4723)
|
|
55
|
+
|
|
56
|
+
Alternatively, use command-line arguments:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
bun run cli --port 8080 --appium-url http://192.168.1.100:4723
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Or run command mode (JSON output by default):
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
bun run cli session create --appium-url http://127.0.0.1:4723 --caps-file ./caps.json --pretty
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Configure Appium Inspector
|
|
69
|
+
|
|
70
|
+
Point Appium Inspector to the recorder proxy:
|
|
71
|
+
|
|
72
|
+
| Setting | Value |
|
|
73
|
+
|---------|-------|
|
|
74
|
+
| Remote Host | `127.0.0.1` |
|
|
75
|
+
| Remote Port | `4724` (or your configured port) |
|
|
76
|
+
| Remote Path | `/` |
|
|
77
|
+
|
|
78
|
+
### Access the UI
|
|
79
|
+
|
|
80
|
+
Open your browser to:
|
|
81
|
+
```
|
|
82
|
+
http://localhost:4724/_recorder
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## 📖 Usage
|
|
86
|
+
|
|
87
|
+
## Security (Local-Only Tool)
|
|
88
|
+
|
|
89
|
+
This project is intended for **local testing and development**. It runs an unauthenticated proxy/UI that can forward commands to Appium. For normal usage, keep it bound to localhost and do not expose it to untrusted networks.
|
|
90
|
+
|
|
91
|
+
**Current known gaps (will be addressed in future updates):**
|
|
92
|
+
- Missing validation for `sessionId`
|
|
93
|
+
- Missing validation for `appiumUrl`
|
|
94
|
+
- Rate limiting for API endpoints
|
|
95
|
+
- Authentication/authorization (likely optional, since local-by-default is intentional)
|
|
96
|
+
|
|
97
|
+
**Practical guidance:**
|
|
98
|
+
- Run the recorder on `127.0.0.1` only (default) and avoid port-forwarding/sharing the port.
|
|
99
|
+
- Be cautious with `appium --allow-cors`; treat the recorder + Appium as a local dev surface while running.
|
|
100
|
+
- Page source is untrusted input; XML is rendered as text (not HTML) to mitigate XSS.
|
|
101
|
+
|
|
102
|
+
### Command Mode (JSON)
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
bun run cli <group> <command> [flags]
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Available command groups:
|
|
109
|
+
|
|
110
|
+
- `proxy start`
|
|
111
|
+
- `session create|delete`
|
|
112
|
+
- `screen snapshot|elements`
|
|
113
|
+
- `selectors best`
|
|
114
|
+
- `drive tap|type|back|swipe`
|
|
115
|
+
|
|
116
|
+
Global command flags:
|
|
117
|
+
|
|
118
|
+
- `--pretty` pretty-print JSON
|
|
119
|
+
- `--output <path>` persist JSON output to a file
|
|
120
|
+
- Legacy mode (`bun run cli [legacy-options]`) does not accept `--pretty` or `--output`
|
|
121
|
+
|
|
122
|
+
### Agent Skill
|
|
123
|
+
|
|
124
|
+
This repo includes a reusable Codex skill at:
|
|
125
|
+
|
|
126
|
+
- `skills/appium-cli-selector-navigator/SKILL.md`
|
|
127
|
+
|
|
128
|
+
The skill is designed for CLI-only navigation + selector discovery loops.
|
|
129
|
+
|
|
130
|
+
### Skill Runbook (What To Run)
|
|
131
|
+
|
|
132
|
+
Use this when you want to drive the app and find selectors with `$appium-cli-selector-navigator`.
|
|
133
|
+
|
|
134
|
+
1. Start Appium:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
appium --port 4723 --allow-cors
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
2. (Optional) Install skill globally for Codex:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
mkdir -p ~/.codex/skills
|
|
144
|
+
cp -R ./skills/appium-cli-selector-navigator ~/.codex/skills/appium-cli-selector-navigator
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
mkdir -p ~/.claude/skills
|
|
149
|
+
cp -R ./skills/appium-cli-selector-navigator ~/.claude/skills/appium-cli-selector-navigator
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Restart Codex after installing the global skill.
|
|
153
|
+
|
|
154
|
+
3. Create a capabilities file (example iOS Safari):
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
cat > /tmp/caps.json <<'JSON'
|
|
158
|
+
{
|
|
159
|
+
"platformName": "iOS",
|
|
160
|
+
"appium:deviceName": "iPhone 17",
|
|
161
|
+
"appium:platformVersion": "26.2",
|
|
162
|
+
"appium:automationName": "XCUITest",
|
|
163
|
+
"appium:bundleId": "com.apple.mobilesafari",
|
|
164
|
+
"appium:newCommandTimeout": 3600,
|
|
165
|
+
"appium:connectHardwareKeyboard": true,
|
|
166
|
+
"appium:includeSafariInWebviews": true
|
|
167
|
+
}
|
|
168
|
+
JSON
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
4. Create session and capture `SESSION_ID`:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
appium-recorder session create \
|
|
175
|
+
--appium-url http://127.0.0.1:4723 \
|
|
176
|
+
--caps-file /tmp/caps.json \
|
|
177
|
+
--output /tmp/session.json \
|
|
178
|
+
--pretty \
|
|
179
|
+
&& SESSION_ID="$(jq -r '.result.sessionId' /tmp/session.json)" \
|
|
180
|
+
&& echo "$SESSION_ID"
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
5. Fetch current elements and save JSON:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
appium-recorder screen elements \
|
|
187
|
+
--appium-url http://127.0.0.1:4723 \
|
|
188
|
+
--session-id "$SESSION_ID" \
|
|
189
|
+
--only-actionable \
|
|
190
|
+
--limit 80 \
|
|
191
|
+
--output /tmp/elements.json \
|
|
192
|
+
--pretty \
|
|
193
|
+
&& jq -r '.result.elements[] | [.elementRef, .type, .name, .label, .resourceId] | @tsv' /tmp/elements.json
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
6. Pick element and get best selectors:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
appium-recorder selectors best \
|
|
200
|
+
--appium-url http://127.0.0.1:4723 \
|
|
201
|
+
--session-id "$SESSION_ID" \
|
|
202
|
+
--element-ref "<ELEMENT_REF>" \
|
|
203
|
+
--pretty
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
7. Drive actions (examples):
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
# Tap an element
|
|
210
|
+
appium-recorder drive tap \
|
|
211
|
+
--appium-url http://127.0.0.1:4723 \
|
|
212
|
+
--session-id "$SESSION_ID" \
|
|
213
|
+
--using "accessibility id" --value "Accept all" --pretty
|
|
214
|
+
|
|
215
|
+
# Type into a field
|
|
216
|
+
appium-recorder drive type \
|
|
217
|
+
--appium-url http://127.0.0.1:4723 \
|
|
218
|
+
--session-id "$SESSION_ID" \
|
|
219
|
+
--using "accessibility id" --value "Address" \
|
|
220
|
+
--text "example.com\n" --clear-first --pretty
|
|
221
|
+
|
|
222
|
+
# Navigate back
|
|
223
|
+
appium-recorder drive back \
|
|
224
|
+
--appium-url http://127.0.0.1:4723 \
|
|
225
|
+
--session-id "$SESSION_ID" --pretty
|
|
226
|
+
|
|
227
|
+
# Swipe gesture
|
|
228
|
+
appium-recorder drive swipe \
|
|
229
|
+
--appium-url http://127.0.0.1:4723 \
|
|
230
|
+
--session-id "$SESSION_ID" \
|
|
231
|
+
--from 900,1800 --to 900,400 --duration-ms 350 --pretty
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
8. Cleanup session:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
appium-recorder session delete \
|
|
238
|
+
--appium-url http://127.0.0.1:4723 \
|
|
239
|
+
--session-id "$SESSION_ID" --pretty
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Legacy CLI Options (Backwards Compatible)
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
bun run cli [options]
|
|
246
|
+
|
|
247
|
+
OPTIONS:
|
|
248
|
+
-p, --port <number> Proxy server port (default: 4724)
|
|
249
|
+
-u, --appium-url <url> Appium server URL (default: http://127.0.0.1:4723)
|
|
250
|
+
--host <host> Proxy server host (default: 127.0.0.1)
|
|
251
|
+
-h, --help Show help message
|
|
252
|
+
-v, --version Show version
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Configuration priority (highest to lowest):
|
|
256
|
+
1. Command-line arguments
|
|
257
|
+
2. Interactive prompts
|
|
258
|
+
3. Environment variables
|
|
259
|
+
4. Default values
|
|
260
|
+
|
|
261
|
+
### Environment Variables
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
APPIUM_URL=http://192.168.1.100:4723
|
|
265
|
+
PROXY_PORT=8080
|
|
266
|
+
PROXY_HOST=127.0.0.1
|
|
267
|
+
|
|
268
|
+
bun run cli
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## 🎨 UI Features
|
|
272
|
+
|
|
273
|
+
### Dashboard
|
|
274
|
+
|
|
275
|
+
- **Total Requests**: Count of all intercepted requests
|
|
276
|
+
- **Actions**: Requests with screenshots (clicks, inputs, etc.)
|
|
277
|
+
- **Real-time Updates**: Automatically refreshes as you interact
|
|
278
|
+
|
|
279
|
+
### Timeline
|
|
280
|
+
|
|
281
|
+
- View all interactions in chronological order
|
|
282
|
+
- Color-coded by HTTP method (mostly `POST`)
|
|
283
|
+
- **Action markers** for requests with screenshots
|
|
284
|
+
- Click screenshots to open inspector
|
|
285
|
+
|
|
286
|
+
### Element Inspector
|
|
287
|
+
|
|
288
|
+
- **Query Tester**: Test different locator strategies
|
|
289
|
+
- accessibility id
|
|
290
|
+
- xpath
|
|
291
|
+
- class name
|
|
292
|
+
- iOS predicate string
|
|
293
|
+
- iOS class chain
|
|
294
|
+
- **Element Details**: View element properties (name, label, value, bounds)
|
|
295
|
+
- **Locators**: Auto-generated locators ready to copy
|
|
296
|
+
- **Click to copy**: One-click locator copying
|
|
297
|
+
|
|
298
|
+
## 🔧 Development
|
|
299
|
+
|
|
300
|
+
### Build the UI
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
cd src/ui
|
|
304
|
+
bun run build
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Run in Development Mode
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
# Terminal 1: Build UI in watch mode
|
|
311
|
+
cd src/ui
|
|
312
|
+
bun run dev
|
|
313
|
+
|
|
314
|
+
# Terminal 2: Run CLI
|
|
315
|
+
bun run cli
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Build for Production
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
bun run build
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
This builds both the UI and the CLI executable.
|
|
325
|
+
|
|
326
|
+
## 📦 What's Recorded
|
|
327
|
+
|
|
328
|
+
The recorder captures:
|
|
329
|
+
- Element clicks
|
|
330
|
+
- Text input (value)
|
|
331
|
+
- Element clear
|
|
332
|
+
- Find element/elements
|
|
333
|
+
- Touch actions
|
|
334
|
+
- Navigation (back, forward, refresh)
|
|
335
|
+
|
|
336
|
+
For each action:
|
|
337
|
+
- ✅ Request details (method, path, body)
|
|
338
|
+
- ✅ Screenshot (base64)
|
|
339
|
+
- ✅ Page source (XML)
|
|
340
|
+
- ✅ Timestamp
|
|
341
|
+
|
|
342
|
+
## 🎯 Use Cases
|
|
343
|
+
|
|
344
|
+
- **Test Debugging**: Review session history to debug failing tests
|
|
345
|
+
- **Element Discovery**: Find reliable locators for automation
|
|
346
|
+
- **Training**: Show team members how to interact with the app
|
|
347
|
+
- **Test Recording**: Generate test scripts from recorded interactions
|
|
348
|
+
|
|
349
|
+
## 🤝 Architecture
|
|
350
|
+
|
|
351
|
+
```
|
|
352
|
+
┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐
|
|
353
|
+
│ Appium Inspector │ ──── │ Session Recorder │ ──── │ Appium Server │
|
|
354
|
+
│ (localhost:4724) │ │ (Bun + Express) │ │ (localhost:4723) │
|
|
355
|
+
└─────────────────────┘ └─────────────────────┘ └─────────────────────┘
|
|
356
|
+
│
|
|
357
|
+
▼
|
|
358
|
+
┌─────────────────────┐
|
|
359
|
+
│ Web UI (Solid.js) │
|
|
360
|
+
│ Real-time Updates │
|
|
361
|
+
└─────────────────────┘
|
|
362
|
+
```
|