@validate.qa/runner 1.0.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.
package/README.md ADDED
@@ -0,0 +1,555 @@
1
+ # @validate.qa/runner
2
+
3
+ Local test runner for the **[validate.qa](https://validate.qa)** AI testing platform.
4
+
5
+ This package enables you to execute Playwright and Appium tests generated from your voice narrations directly on your local machine, securely connecting to your validate.qa cloud project.
6
+
7
+ **Features:**
8
+ - 🎭 **Web Testing** β€” Execute Playwright tests in headless Chromium
9
+ - πŸ“± **Mobile Testing** β€” Execute Appium tests on iOS Simulator, Android Emulator, AND real devices via USB
10
+ - πŸ”§ **Doctor Command** β€” Check system prerequisites for web + mobile testing
11
+ - πŸ” **Secure Authentication** β€” Project-scoped runner tokens
12
+ - 🌐 **Tunnel Support** β€” Connect HTTPS dashboards to local devices with token-based auth
13
+
14
+ ---
15
+
16
+ ## Quick Start
17
+
18
+ ### 1. Install (Global or NPX)
19
+
20
+ You don't need to install it globally if you use `npx`, but it's completely supported:
21
+
22
+ ```bash
23
+ npm install -g @validate.qa/runner
24
+ ```
25
+
26
+ ### 2. Login
27
+
28
+ Generate a runner token from your validate.qa **Project Settings β†’ Local Runner**. Your credentials will be saved securely to `~/.validate.qa/credentials.json`.
29
+
30
+ ```bash
31
+ npx @validate.qa/runner login --token urt_xxxxxxxxxxxx --server https://your-server.com
32
+ ```
33
+
34
+ ### 3. Start the Runner
35
+
36
+ Starts the runner daemon, polling for pending test runs from the cloud and executing them locally:
37
+
38
+ ```bash
39
+ npx @validate.qa/runner start
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Commands
45
+
46
+ | Command | Description |
47
+ |---------|-------------|
48
+ | `login` | Saves credentials for future test executions |
49
+ | `start` | Starts the local runner (uses saved credentials or CLI flags) |
50
+ | `status` | Pings the server to verify your runner token and connection |
51
+ | `logout` | Clears all saved runner credentials from your machine |
52
+ | `doctor` | Checks system prerequisites for web and mobile testing |
53
+
54
+ ### Command Options
55
+
56
+ #### `login`
57
+ ```bash
58
+ npx @validate.qa/runner login \
59
+ --token <token> \ # Runner token (urt_...) from dashboard
60
+ --server <url> \ # validate.qa server URL
61
+ --project <id> # Optional: Project ID (embedded in urt_ tokens)
62
+ ```
63
+
64
+ #### `start`
65
+ ```bash
66
+ npx @validate.qa/runner start \
67
+ --token <token> \ # Override saved token
68
+ --server <url> \ # Override saved server URL
69
+ --project <id> \ # Override saved project ID
70
+ --mobile \ # Enable mobile testing (Appium + bridge)
71
+ --tunnel \ # Enable ngrok tunnel for HTTPS dashboard access (with token auth)
72
+ --mode <mode> \ # Execution mode: playwright-native (default)
73
+ --poll-interval <ms> # Poll interval: 2000 (default)
74
+ ```
75
+
76
+ #### `status`
77
+ ```bash
78
+ npx @validate.qa/runner status
79
+ # Shows: Server URL, Project ID, Token (masked), Connection status
80
+ ```
81
+
82
+ #### `doctor`
83
+ ```bash
84
+ npx @validate.qa/runner doctor
85
+ # Checks: Node.js, Playwright, Xcode, Android SDK, Appium
86
+ ```
87
+
88
+ ---
89
+
90
+ ## πŸ“± Mobile Testing
91
+
92
+ ### Overview
93
+
94
+ The runner supports native mobile app testing on:
95
+ - **iOS:** Simulators (macOS) + Real devices via USB
96
+ - **Android:** Emulators + Real devices via USB
97
+
98
+ Tests are executed using **Appium 2** with XCUITest (iOS) and UiAutomator2 (Android) drivers.
99
+
100
+ ### How It Works
101
+
102
+ ```
103
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
104
+ β”‚ 1. START RUNNER WITH MOBILE β”‚
105
+ β”‚ npx @validate.qa/runner start --mobile β”‚
106
+ β”‚ β†’ Starts Appium server (port 4723) β”‚
107
+ β”‚ β†’ Starts mobile bridge (port 9515) β”‚
108
+ β”‚ β†’ Discovers available devices β”‚
109
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
110
+ ↓
111
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
112
+ β”‚ 2. RECORD FROM DASHBOARD β”‚
113
+ β”‚ - Open validate.qa dashboard β”‚
114
+ β”‚ - Start Recording β†’ Select iOS/Android Native β”‚
115
+ β”‚ - Interact with mirrored device screen β”‚
116
+ β”‚ - Actions captured with screenshots + UI trees β”‚
117
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
118
+ ↓
119
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
120
+ β”‚ 3. GENERATE TESTS β”‚
121
+ β”‚ - Stop recording β”‚
122
+ β”‚ - Click "Generate from Recording" β”‚
123
+ β”‚ - AI creates MobileTestStep[] array β”‚
124
+ β”‚ - Test saved with framework: 'APPIUM' β”‚
125
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
126
+ ↓
127
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
128
+ β”‚ 4. EXECUTE TESTS β”‚
129
+ β”‚ - Click "Run" in dashboard (or queue from API) β”‚
130
+ β”‚ - Runner claims mobile test run β”‚
131
+ β”‚ β†’ Boots simulator/emulator β”‚
132
+ β”‚ β†’ Launches app via Appium β”‚
133
+ β”‚ β†’ Executes each step (tap, type, swipe, assert) β”‚
134
+ β”‚ β†’ Captures screenshots β”‚
135
+ β”‚ β†’ Reports results back to server β”‚
136
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
137
+ ```
138
+
139
+ ### Prerequisites
140
+
141
+ #### macOS (Required for iOS)
142
+ - **Xcode** β€” Install from Mac App Store
143
+ - **Xcode Command Line Tools**: `xcode-select --install`
144
+ - **iOS Simulator** β€” Included with Xcode
145
+
146
+ #### Android (Optional)
147
+ - **Android Studio** β€” https://developer.android.com/studio
148
+ - **Android SDK** β€” Installed via Android Studio
149
+ - **Environment variables**: `ANDROID_HOME`, `ANDROID_SDK_ROOT`
150
+ - **Emulator** β€” Create via Android Studio β†’ Device Manager
151
+
152
+ #### Node.js
153
+ - **Version**: Node 18 or higher
154
+ - **npm**: Latest stable version
155
+
156
+ ### Setup Steps
157
+
158
+ #### 1. Check Prerequisites
159
+ ```bash
160
+ npx @validate.qa/runner doctor
161
+ ```
162
+
163
+ Expected output:
164
+ ```
165
+ βœ“ Node.js v20.x.x
166
+ βœ“ Playwright installed
167
+ βœ“ Xcode 15.x (iOS SDK)
168
+ βœ“ Android SDK (API 34)
169
+ βœ“ Appium 2.x available
170
+ ```
171
+
172
+ #### 2. Boot a Simulator/Emulator
173
+
174
+ **iOS:**
175
+ ```bash
176
+ # List available simulators
177
+ xcrun simctl list devices
178
+
179
+ # Boot a specific simulator
180
+ xcrun simctl boot "iPhone 15"
181
+
182
+ # Or open Simulator.app and boot from menu
183
+ open -a Simulator
184
+ ```
185
+
186
+ **Android:**
187
+ ```bash
188
+ # List available emulators
189
+ emulator -list-avds
190
+
191
+ # Start an emulator
192
+ emulator -avd Pixel_7_API_34
193
+
194
+ # Or use Android Studio β†’ Device Manager β†’ Start
195
+ ```
196
+
197
+ #### 3. Install Your App
198
+
199
+ **iOS:**
200
+ ```bash
201
+ # Install .app or .ipa on simulator
202
+ xcrun simctl install booted /path/to/YourApp.app
203
+ ```
204
+
205
+ **Android:**
206
+ ```bash
207
+ # Install APK on emulator
208
+ adb install /path/to/YourApp.apk
209
+
210
+ # Or drag-and-drop APK onto emulator window
211
+ ```
212
+
213
+ #### 4. Start Runner with Mobile
214
+
215
+ **For local dashboard (http://localhost):**
216
+ ```bash
217
+ npx @validate.qa/runner start --mobile
218
+ ```
219
+
220
+ **For production dashboard (HTTPS):**
221
+ ```bash
222
+ npx @validate.qa/runner start --mobile --tunnel
223
+ ```
224
+
225
+ Expected output (with tunnel):
226
+ ```
227
+ πŸŽ™οΈ validate.qa Local Runner
228
+ ─────────────────────────────────────
229
+ β„Ή Server: https://your-server.com
230
+ β„Ή Project: your-project-id
231
+ β„Ή Mode: 🎭 Playwright Native + πŸ“± Mobile 🌐 Tunnel
232
+ β„Ή Interval: 2000ms
233
+ βœ“ Browser: Chrome with user profile
234
+ β„Ή πŸ“± Mobile: iOS βœ“ | Android βœ“ | 2 device(s)
235
+ βœ“ πŸ“± Appium server started
236
+ 🌐 Public tunnel started: https://abc123.ngrok.io
237
+ πŸ” Tunnel token: a7f3b2c8d9e1f4a5b6c7d8e9f0a1b2c3d4e5f6a7
238
+ Add this token to your dashboard Project Settings
239
+
240
+ βœ“ Runner started β€” waiting for test runs... (web + mobile)
241
+ ```
242
+
243
+ > **Note:** The tunnel token is automatically sent to your dashboard via the server API. You don't need to manually configure it.
244
+
245
+ #### 5. Record Your First Mobile Test
246
+
247
+ 1. **Open Dashboard** β†’ Your Project
248
+ 2. **Click "Start Recording"** β†’ Select **"iOS Native"** or **"Android Native"**
249
+ 3. **Enter App ID**:
250
+ - iOS: Bundle ID (e.g., `com.example.myapp`)
251
+ - Android: Package name (e.g., `com.example.myapp`)
252
+ 4. **Select Device** from the dropdown (detected automatically)
253
+ 5. **Click "Start"** β€” Device screen mirrors in your browser
254
+ 6. **Interact**:
255
+ - Click on screen β†’ Taps recorded
256
+ - Use swipe buttons β†’ Swipes recorded
257
+ - Click "Type Text" β†’ Keyboard input
258
+ - Back/Home buttons β†’ Navigation
259
+ 7. **Click "Stop Recording"** when done
260
+ 8. **Generate Tests** β†’ Click "Generate from Recording"
261
+
262
+ #### 6. Run Mobile Tests
263
+
264
+ **Note:** The "Run Test" button in the UI is currently disabled for mobile tests (shows "Run Pending"). Tests execute automatically when:
265
+
266
+ 1. You queue a run from the dashboard
267
+ 2. The runner is online with `--mobile` flag
268
+ 3. A matching device is available
269
+
270
+ The runner will:
271
+ - Claim the mobile test run from the queue
272
+ - Launch the app on the target device
273
+ - Execute each step via Appium
274
+ - Capture screenshots after each step
275
+ - Report pass/fail results
276
+
277
+ ---
278
+
279
+ ## Runner Modes
280
+
281
+ ### Web Testing (Default)
282
+ ```bash
283
+ npx @validate.qa/runner start
284
+ # or explicitly:
285
+ npx @validate.qa/runner start --mode playwright-native
286
+ ```
287
+
288
+ Executes Playwright tests in headless Chromium with:
289
+ - Persistent browser profiles (cookies/logins persist)
290
+ - Test variable injection
291
+ - AI healing support (optional)
292
+
293
+ ### Mobile Testing
294
+ ```bash
295
+ npx @validate.qa/runner start --mobile
296
+ ```
297
+
298
+ Enables:
299
+ - Appium 2 server (port 4723)
300
+ - Mobile bridge server (port 9515)
301
+ - Device discovery and capabilities reporting
302
+ - iOS Simulator + Android Emulator support
303
+
304
+ ### Execution Flow Comparison
305
+
306
+ | Feature | Web Tests | Mobile Tests |
307
+ |---------|-----------|--------------|
308
+ | Framework | Playwright | Appium 2 |
309
+ | Browser/Device | Headless Chromium | iOS Simulator / Android Emulator |
310
+ | Locator Strategy | CSS selectors, XPath | Accessibility ID, XPath, Resource ID |
311
+ | Actions | click, fill, navigate | tap, type, swipe, back, home |
312
+ | Screenshots | On failure | After each step |
313
+ | AI Healing | βœ… Supported | ❌ Not supported |
314
+ | Cloud Runner | βœ… Supported | ❌ Local only |
315
+
316
+ ---
317
+
318
+ ## Configuration
319
+
320
+ ### Saved Credentials
321
+
322
+ Credentials are stored in `~/.validate.qa/credentials.json`:
323
+
324
+ ```json
325
+ {
326
+ "token": "urt_xxxxxxxxxxxx",
327
+ "serverUrl": "https://your-server.com",
328
+ "projectId": "your-project-id"
329
+ }
330
+ ```
331
+
332
+ ### Environment Variables
333
+
334
+ | Variable | Description | Default |
335
+ |----------|-------------|---------|
336
+ | `SERVER_URL` | validate.qa server URL | β€” |
337
+ | `AUTH_TOKEN` | Runner token | β€” |
338
+ | `PROJECT_ID` | Project ID | β€” |
339
+ | `POLL_INTERVAL_MS` | Poll interval | `2000` |
340
+ | `RUNS_DIR` | Directory for test run artifacts | `~/.validate.qa/runs` |
341
+ | `CHROME_USER_DATA_DIR` | Chrome profile path | Auto-detected |
342
+
343
+ ### Example: Custom Configuration
344
+
345
+ ```bash
346
+ # Run with environment variables
347
+ SERVER_URL=https://your-server.com \
348
+ AUTH_TOKEN=urt_xxxx \
349
+ POLL_INTERVAL_MS=5000 \
350
+ npx @validate.qa/runner start --mobile
351
+ ```
352
+
353
+ ---
354
+
355
+ ## Troubleshooting
356
+
357
+ ### "No devices found"
358
+ ```bash
359
+ # iOS: Boot a simulator
360
+ xcrun simctl boot "iPhone 15"
361
+
362
+ # Android: Start an emulator
363
+ emulator -avd Pixel_7_API_34
364
+
365
+ # Then restart runner with --mobile
366
+ ```
367
+
368
+ ### "App not installed"
369
+ ```bash
370
+ # iOS
371
+ xcrun simctl install booted /path/to/App.app
372
+
373
+ # Android
374
+ adb install /path/to/App.apk
375
+ ```
376
+
377
+ ### "Bridge not responding"
378
+ ```bash
379
+ # Check if bridge is running
380
+ curl http://127.0.0.1:9515/bridge/health
381
+
382
+ # Restart runner with --mobile flag
383
+ ```
384
+
385
+ ### "Appium failed to start"
386
+ ```bash
387
+ # Check Appium installation
388
+ appium --version
389
+
390
+ # Reinstall Appium drivers
391
+ appium driver install xcuitest
392
+ appium driver install uiautomator2
393
+
394
+ # Run doctor to diagnose
395
+ npx @validate.qa/runner doctor
396
+ ```
397
+
398
+ ### "Tests stay PENDING"
399
+ ```bash
400
+ # 1. Verify runner is online
401
+ npx @validate.qa/runner status
402
+
403
+ # 2. Check runner is started with --mobile
404
+ npx @validate.qa/runner start --mobile
405
+
406
+ # 3. Verify device is booted
407
+ xcrun simctl list devices # iOS
408
+ adb devices # Android
409
+ ```
410
+
411
+ ---
412
+
413
+ ## Security
414
+
415
+ ### Runner Token Security
416
+
417
+ `urt_` runner tokens are:
418
+ - **Project-scoped:** They cannot access sessions, user accounts, or cross-project data.
419
+ - **Revocable:** Instantly cancel tokens from the dashboard if compromised.
420
+ - **Client-only:** Your local browser/device instances run locally and post test results back.
421
+ - **No code upload:** Tests execute on your machine β€” source code never leaves your infrastructure.
422
+
423
+ ### Mobile Tunnel Security
424
+
425
+ When using `--tunnel` for mobile testing from an HTTPS dashboard:
426
+
427
+ **Security Features:**
428
+ - **Token-based authentication:** Each tunnel session generates a random 64-character hex token
429
+ - **Per-session tokens:** Tokens are regenerated every time you restart the runner
430
+ - **Header validation:** All bridge requests require `X-Bridge-Token` header or `tunnelToken` query param
431
+ - **Health endpoint public:** Only `/bridge/health` is accessible without auth (for monitoring)
432
+ - **All other endpoints protected:** Device control, screenshots, and actions require valid token
433
+
434
+ **How It Works:**
435
+ ```
436
+ 1. Runner starts with --tunnel
437
+ β†’ Generates random token (e.g., a7f3b2c8d9e1f4a5...)
438
+ β†’ Starts ngrok tunnel to your local bridge
439
+ β†’ Displays token in console
440
+
441
+ 2. Dashboard fetches tunnel URL + token from server API
442
+ β†’ Server receives tunnel info via runner heartbeat
443
+ β†’ Dashboard stores token in memory (never persisted)
444
+
445
+ 3. All bridge requests include token:
446
+ β†’ HTTP header: X-Bridge-Token: a7f3b2c8d9e1f4a5...
447
+ β†’ Or query param: ?tunnelToken=a7f3b2c8d9e1f4a5...
448
+
449
+ 4. Bridge validates token on every request:
450
+ β†’ Invalid/missing token β†’ 401 Unauthorized
451
+ β†’ Valid token β†’ Request processed
452
+ ```
453
+
454
+ **Best Practices:**
455
+ - βœ… **Safe for production use:** Token is required for all device control operations
456
+ - βœ… **Token never exposed to client:** Dashboard fetches from server API, not console
457
+ - βœ… **Session-limited:** Token changes each time runner restarts
458
+ - ⚠️ **Don't share console output:** The full token is shown in runner console
459
+ - ⚠️ **Use HTTPS dashboard:** Prevents man-in-the-middle attacks on token transmission
460
+
461
+ **For Enterprise Deployments:**
462
+ Consider using a paid ngrok account for:
463
+ - Fixed domain URLs (no changing URLs)
464
+ - IP whitelisting
465
+ - Request inspection
466
+ - Higher bandwidth limits
467
+
468
+ ---
469
+
470
+ ## Architecture
471
+
472
+ ```
473
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
474
+ β”‚ Dashboard │────▢│ Server API │◀────│ Local Runner β”‚
475
+ β”‚ (validate.qa) β”‚ β”‚ (your-infra) β”‚ β”‚ (your-machine) β”‚
476
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
477
+ β”‚ β”‚
478
+ β”‚ β”œβ”€β”€β†’ Playwright (web)
479
+ β”‚ └──→ Appium (mobile)
480
+ β”‚ β”‚
481
+ β”‚ β”œβ”€β”€β†’ iOS Simulator
482
+ β”‚ └──→ Android Emulator
483
+ β–Ό
484
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
485
+ β”‚ PostgreSQL β”‚
486
+ β”‚ (test metadata)β”‚
487
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
488
+ ```
489
+
490
+ ---
491
+
492
+ ## Deploying
493
+
494
+ ### GitHub Actions (Automated)
495
+
496
+ Publishing is automated via GitHub Actions. Push a tag to trigger the workflow:
497
+
498
+ ```bash
499
+ # 1. Bump version in packages/runner/package.json
500
+ # 2. Create and push a tag (format: runner-v<version>)
501
+ git tag runner-v0.1.11
502
+ git push origin runner-v0.1.11
503
+ ```
504
+
505
+ The workflow (`.github/workflows/publish-runner.yml`) will:
506
+ 1. Install dependencies
507
+ 2. Build shared package
508
+ 3. Build runner package
509
+ 4. Publish to npmjs as `@validate.qa/runner`
510
+
511
+ ### Manual (Local)
512
+
513
+ If GitHub Actions is unavailable:
514
+
515
+ ```bash
516
+ # 1. Login to npm
517
+ npm login
518
+
519
+ # 2. Navigate to runner package
520
+ cd packages/runner
521
+
522
+ # 3. Bump version (patch, minor, or major)
523
+ npm version patch
524
+
525
+ # 4. Build and publish
526
+ npm run build
527
+ npm publish --access public
528
+ ```
529
+
530
+ ### Version
531
+
532
+ **Current:** 0.1.10
533
+
534
+ **Changelog:** See [git history](https://github.com/Validate-QA/validate.qa/commits/main/packages/runner) for the full change log. Recent highlights:
535
+
536
+ - **0.1.10** β€” Rename package to `@validate.qa/runner`; API test capabilities; discovery pipeline refactor
537
+ - **0.1.9** β€” Mobile execution improvements; mobile bridge security hardening
538
+ - **0.1.8** β€” Mobile implementation (Appium 2, device discovery, bridge server)
539
+ - **0.1.7** β€” Security hardening; audio race condition fix; Voice Insights filter fix
540
+ - **0.1.6** β€” Pre-deploy bug fixes
541
+ - **0.1.5** β€” Redesigned local runner UI; publish workflow fixes
542
+ - **0.1.2** β€” Build workflow fix
543
+ - **0.1.0** β€” Initial standalone runner package with secure runner tokens
544
+
545
+ ---
546
+
547
+ ## Support
548
+
549
+ - **Documentation:** [validate.qa docs](https://github.com/Validate-QA/validate.qa/tree/main/docs)
550
+ - **npm Package:** https://www.npmjs.com/package/@validate.qa/runner
551
+ - **GitHub:** https://github.com/Validate-QA/validate.qa
552
+
553
+ ---
554
+
555
+ *Generated by validate.qa*
package/dist/cli.d.mts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node