@desplega.ai/qa-use 2.8.6 → 2.9.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 +21 -0
- package/dist/package.json +4 -2
- package/dist/src/cli/commands/api/index.d.ts +3 -0
- package/dist/src/cli/commands/api/index.d.ts.map +1 -0
- package/dist/src/cli/commands/api/index.js +6 -0
- package/dist/src/cli/commands/api/index.js.map +1 -0
- package/dist/src/cli/commands/api/lib/http.d.ts +18 -0
- package/dist/src/cli/commands/api/lib/http.d.ts.map +1 -0
- package/dist/src/cli/commands/api/lib/http.js +51 -0
- package/dist/src/cli/commands/api/lib/http.js.map +1 -0
- package/dist/src/cli/commands/api/lib/openapi-cache.d.ts +10 -0
- package/dist/src/cli/commands/api/lib/openapi-cache.d.ts.map +1 -0
- package/dist/src/cli/commands/api/lib/openapi-cache.js +41 -0
- package/dist/src/cli/commands/api/lib/openapi-cache.js.map +1 -0
- package/dist/src/cli/commands/api/lib/openapi-errors.d.ts +8 -0
- package/dist/src/cli/commands/api/lib/openapi-errors.d.ts.map +1 -0
- package/dist/src/cli/commands/api/lib/openapi-errors.js +20 -0
- package/dist/src/cli/commands/api/lib/openapi-errors.js.map +1 -0
- package/dist/src/cli/commands/api/lib/openapi-spec.d.ts +62 -0
- package/dist/src/cli/commands/api/lib/openapi-spec.d.ts.map +1 -0
- package/dist/src/cli/commands/api/lib/openapi-spec.js +166 -0
- package/dist/src/cli/commands/api/lib/openapi-spec.js.map +1 -0
- package/dist/src/cli/commands/api/lib/output.d.ts +8 -0
- package/dist/src/cli/commands/api/lib/output.d.ts.map +1 -0
- package/dist/src/cli/commands/api/lib/output.js +31 -0
- package/dist/src/cli/commands/api/lib/output.js.map +1 -0
- package/dist/src/cli/commands/api/ls.d.ts +3 -0
- package/dist/src/cli/commands/api/ls.d.ts.map +1 -0
- package/dist/src/cli/commands/api/ls.js +76 -0
- package/dist/src/cli/commands/api/ls.js.map +1 -0
- package/dist/src/cli/commands/api/request.d.ts +11 -0
- package/dist/src/cli/commands/api/request.d.ts.map +1 -0
- package/dist/src/cli/commands/api/request.js +225 -0
- package/dist/src/cli/commands/api/request.js.map +1 -0
- package/dist/src/cli/commands/docs.d.ts +6 -0
- package/dist/src/cli/commands/docs.d.ts.map +1 -0
- package/dist/src/cli/commands/docs.js +71 -0
- package/dist/src/cli/commands/docs.js.map +1 -0
- package/dist/src/cli/commands/setup.d.ts +1 -1
- package/dist/src/cli/commands/setup.d.ts.map +1 -1
- package/dist/src/cli/commands/setup.js +100 -34
- package/dist/src/cli/commands/setup.js.map +1 -1
- package/dist/src/cli/generated/docs-content.d.ts +15 -0
- package/dist/src/cli/generated/docs-content.d.ts.map +1 -0
- package/dist/src/cli/generated/docs-content.js +2420 -0
- package/dist/src/cli/generated/docs-content.js.map +1 -0
- package/dist/src/cli/index.js +50 -3
- package/dist/src/cli/index.js.map +1 -1
- package/package.json +4 -2
|
@@ -0,0 +1,2420 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-generated documentation content for the docs command.
|
|
3
|
+
* DO NOT EDIT MANUALLY — Generated from plugins/qa-use/skills/qa-use/
|
|
4
|
+
* Run 'bun run generate:docs' to regenerate.
|
|
5
|
+
*/
|
|
6
|
+
export const MAIN_DOC = `---
|
|
7
|
+
name: qa-use
|
|
8
|
+
description: E2E testing and browser automation with qa-use CLI. Use when the user needs to run tests, verify features, automate browser interactions, or debug test failures.
|
|
9
|
+
allowed-tools: Bash(qa-use *)
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# qa-use
|
|
13
|
+
|
|
14
|
+
E2E testing and browser automation for AI-driven development workflows.
|
|
15
|
+
|
|
16
|
+
## Critical Insight: Plugin Commands as Shortcuts
|
|
17
|
+
|
|
18
|
+
**For AI Harnesses (codex, opencode, etc.):**
|
|
19
|
+
|
|
20
|
+
Plugin commands (slash commands like \`/qa-use:verify\`) are **convenience shortcuts** that wrap CLI workflows. Harnesses with only the Bash tool can access ALL functionality via CLI commands documented below.
|
|
21
|
+
|
|
22
|
+
**Pattern throughout this document:**
|
|
23
|
+
- **CLI Workflow**: Step-by-step CLI commands (works for ALL harnesses)
|
|
24
|
+
- **Plugin Shortcut**: Optional slash command (convenience)
|
|
25
|
+
|
|
26
|
+
## Core Workflow
|
|
27
|
+
|
|
28
|
+
### 1. Browser Control & Session Lifecycle
|
|
29
|
+
|
|
30
|
+
**CLI Workflow:**
|
|
31
|
+
\`\`\`bash
|
|
32
|
+
# Create browser session
|
|
33
|
+
qa-use browser create --viewport desktop
|
|
34
|
+
|
|
35
|
+
# For localhost testing
|
|
36
|
+
qa-use browser create --tunnel --no-headless
|
|
37
|
+
|
|
38
|
+
# Navigate
|
|
39
|
+
qa-use browser goto https://example.com
|
|
40
|
+
|
|
41
|
+
# Snapshot to get element refs (ALWAYS do this before interacting)
|
|
42
|
+
qa-use browser snapshot
|
|
43
|
+
|
|
44
|
+
# Interact by ref
|
|
45
|
+
qa-use browser click e3
|
|
46
|
+
qa-use browser fill e5 "text"
|
|
47
|
+
|
|
48
|
+
# Close
|
|
49
|
+
qa-use browser close
|
|
50
|
+
\`\`\`
|
|
51
|
+
|
|
52
|
+
**Plugin Shortcut:**
|
|
53
|
+
\`\`\`
|
|
54
|
+
/qa-use:explore https://example.com
|
|
55
|
+
\`\`\`
|
|
56
|
+
(Wraps create + goto + snapshot with autonomous exploration)
|
|
57
|
+
|
|
58
|
+
**Critical:** Always run \`snapshot\` before your **first** interaction on a page. Never guess element refs.
|
|
59
|
+
|
|
60
|
+
**Snapshot Diff Feature (use it to avoid unnecessary snapshots):**
|
|
61
|
+
After each action (goto, click, fill, etc.), the browser automatically shows DOM changes:
|
|
62
|
+
- **Summary**: "5 elements added, 1 element modified"
|
|
63
|
+
- **Added elements**: \`+ [e54] generic "Thanks for agreeing!"\` (green)
|
|
64
|
+
- **Modified elements**: \`~ [e18] checkbox "I agree..."\` with \`+attrs: checked, active\` (yellow)
|
|
65
|
+
- **Removed elements**: \`- [e99] button "Submit"\` (red)
|
|
66
|
+
|
|
67
|
+
**When you can skip a full \`snapshot\`:** If the diff output from your last action already shows the element ref you need to interact with next, use it directly — no need for an intermediate \`snapshot\`. For example, if clicking a button shows \`+ [e54] button "Submit"\` in the diff, you can \`click e54\` immediately.
|
|
68
|
+
|
|
69
|
+
**When you still need a full \`snapshot\`:** Run \`snapshot\` when you need to find elements that weren't in the diff (e.g., pre-existing elements you haven't interacted with yet), or when the diff was truncated (shows "... and N more changes").
|
|
70
|
+
|
|
71
|
+
### 2. Understanding Blocks
|
|
72
|
+
|
|
73
|
+
**What are blocks?**
|
|
74
|
+
|
|
75
|
+
Blocks are atomic recorded interactions from a browser session. They are:
|
|
76
|
+
- Automatically captured during any browser interaction (click, fill, goto, scroll, etc.)
|
|
77
|
+
- Stored server-side with the session
|
|
78
|
+
- Retrieved via \`qa-use browser get-blocks\`
|
|
79
|
+
- The foundation for test generation
|
|
80
|
+
|
|
81
|
+
**Why blocks matter:**
|
|
82
|
+
- **Record-once, replay-many**: Interactive recording becomes automated test
|
|
83
|
+
- **AI-friendly**: Agents can analyze blocks to understand user intent
|
|
84
|
+
- **Version control**: Blocks stored with session enable test iteration
|
|
85
|
+
- **Bridge CLI → Tests**: Natural workflow from exploration to automation
|
|
86
|
+
|
|
87
|
+
**How blocks work:**
|
|
88
|
+
|
|
89
|
+
\`\`\`bash
|
|
90
|
+
# 1. Create session and interact
|
|
91
|
+
qa-use browser create --tunnel --no-headless
|
|
92
|
+
qa-use browser goto https://example.com
|
|
93
|
+
qa-use browser snapshot # Returns: [ref=e1] button
|
|
94
|
+
qa-use browser click e1 # Records as block
|
|
95
|
+
qa-use browser fill e5 "text" # Records as block
|
|
96
|
+
|
|
97
|
+
# 2. Retrieve blocks (JSON array)
|
|
98
|
+
qa-use browser get-blocks
|
|
99
|
+
# Returns:
|
|
100
|
+
# [
|
|
101
|
+
# {"type": "goto", "url": "...", "timestamp": "..."},
|
|
102
|
+
# {"type": "click", "ref": "e1", "timestamp": "..."},
|
|
103
|
+
# {"type": "fill", "ref": "e5", "value": "text", "timestamp": "..."}
|
|
104
|
+
# ]
|
|
105
|
+
|
|
106
|
+
# 3. Generate test YAML from blocks
|
|
107
|
+
qa-use browser generate-test -n "my_test" -o qa-tests/my_test.yaml
|
|
108
|
+
|
|
109
|
+
# 4. Run generated test
|
|
110
|
+
qa-use test run my_test
|
|
111
|
+
\`\`\`
|
|
112
|
+
|
|
113
|
+
**Plugin Shortcut:**
|
|
114
|
+
\`\`\`
|
|
115
|
+
/qa-use:record start my_test
|
|
116
|
+
# ... perform interactions ...
|
|
117
|
+
/qa-use:record stop
|
|
118
|
+
\`\`\`
|
|
119
|
+
(Wraps the interactive workflow with AI-powered test generation)
|
|
120
|
+
|
|
121
|
+
### 3. Test Management
|
|
122
|
+
|
|
123
|
+
**CLI Workflow:**
|
|
124
|
+
\`\`\`bash
|
|
125
|
+
# Run test by name
|
|
126
|
+
qa-use test run login
|
|
127
|
+
|
|
128
|
+
# Run with autofix (AI self-healing)
|
|
129
|
+
qa-use test run login --autofix
|
|
130
|
+
|
|
131
|
+
# Validate syntax
|
|
132
|
+
qa-use test validate login
|
|
133
|
+
|
|
134
|
+
# Show test details
|
|
135
|
+
qa-use test info login
|
|
136
|
+
|
|
137
|
+
# List test runs
|
|
138
|
+
qa-use test runs --status failed
|
|
139
|
+
\`\`\`
|
|
140
|
+
|
|
141
|
+
**Plugin Shortcut:**
|
|
142
|
+
\`\`\`
|
|
143
|
+
/qa-use:test-run login --autofix
|
|
144
|
+
\`\`\`
|
|
145
|
+
(Convenience shortcut for common test execution)
|
|
146
|
+
|
|
147
|
+
### 4. Test Sync Lifecycle
|
|
148
|
+
|
|
149
|
+
**CLI Workflow:**
|
|
150
|
+
\`\`\`bash
|
|
151
|
+
# Pull tests from cloud
|
|
152
|
+
qa-use test sync pull
|
|
153
|
+
|
|
154
|
+
# Push all local tests to cloud
|
|
155
|
+
qa-use test sync push --all
|
|
156
|
+
|
|
157
|
+
# Push specific test
|
|
158
|
+
qa-use test sync push --id <uuid>
|
|
159
|
+
|
|
160
|
+
# Force push (overwrite conflicts)
|
|
161
|
+
qa-use test sync push --force
|
|
162
|
+
|
|
163
|
+
# Compare local vs cloud
|
|
164
|
+
qa-use test diff login.yaml
|
|
165
|
+
\`\`\`
|
|
166
|
+
|
|
167
|
+
**No Plugin Shortcut** - Use CLI commands directly
|
|
168
|
+
|
|
169
|
+
## Essential Commands
|
|
170
|
+
|
|
171
|
+
### Browser Session Management
|
|
172
|
+
|
|
173
|
+
| Command | Description |
|
|
174
|
+
|---------|-------------|
|
|
175
|
+
| \`qa-use browser create\` | Create remote browser session |
|
|
176
|
+
| \`qa-use browser create --tunnel\` | Create local browser with API tunnel |
|
|
177
|
+
| \`qa-use browser create --no-headless\` | Show browser window (tunnel mode only) |
|
|
178
|
+
| \`qa-use browser create --viewport <size>\` | Set viewport: \`desktop\`, \`tablet\`, \`mobile\` |
|
|
179
|
+
| \`qa-use browser create --ws-url <url>\` | Connect to existing WebSocket browser |
|
|
180
|
+
| \`qa-use browser create --after-test-id <uuid>\` | Run a test first, then become interactive |
|
|
181
|
+
| \`qa-use browser create --var <key=value>\` | Override app config variables (repeatable) |
|
|
182
|
+
| \`qa-use browser list\` | List active sessions |
|
|
183
|
+
| \`qa-use browser status\` | Show current session details (app_url, recording_url, etc.) |
|
|
184
|
+
| \`qa-use browser close\` | Close active session |
|
|
185
|
+
|
|
186
|
+
Sessions auto-persist in \`~/.qa-use.json\`. One active session = no \`-s\` flag needed.
|
|
187
|
+
|
|
188
|
+
### Navigation
|
|
189
|
+
|
|
190
|
+
| Command | Description |
|
|
191
|
+
|---------|-------------|
|
|
192
|
+
| \`qa-use browser goto <url>\` | Navigate to URL |
|
|
193
|
+
| \`qa-use browser back\` | Go back |
|
|
194
|
+
| \`qa-use browser forward\` | Go forward |
|
|
195
|
+
| \`qa-use browser reload\` | Reload page |
|
|
196
|
+
|
|
197
|
+
### Element Interaction
|
|
198
|
+
|
|
199
|
+
| Command | Description |
|
|
200
|
+
|---------|-------------|
|
|
201
|
+
| \`qa-use browser click <ref>\` | Click element by ref |
|
|
202
|
+
| \`qa-use browser click --text "Button"\` | Click by semantic description |
|
|
203
|
+
| \`qa-use browser fill <ref> "value"\` | Fill input field |
|
|
204
|
+
| \`qa-use browser type <ref> "text"\` | Type with delays (for autocomplete) |
|
|
205
|
+
| \`qa-use browser press <key>\` | Press key (e.g., \`Enter\`, \`Tab\`) |
|
|
206
|
+
| \`qa-use browser check <ref>\` | Check checkbox |
|
|
207
|
+
| \`qa-use browser uncheck <ref>\` | Uncheck checkbox |
|
|
208
|
+
| \`qa-use browser select <ref> "option"\` | Select dropdown option |
|
|
209
|
+
| \`qa-use browser hover <ref>\` | Hover over element |
|
|
210
|
+
| \`qa-use browser scroll down 500\` | Scroll by pixels |
|
|
211
|
+
| \`qa-use browser scroll-into-view <ref>\` | Scroll element into view |
|
|
212
|
+
| \`qa-use browser drag <ref> --target <ref>\` | Drag element to target |
|
|
213
|
+
| \`qa-use browser mfa-totp [ref] <secret>\` | Generate TOTP code (optionally fill) |
|
|
214
|
+
| \`qa-use browser upload <ref> <file>...\` | Upload file(s) to input (base64-encoded, works remote & tunnel) |
|
|
215
|
+
|
|
216
|
+
### Inspection & Snapshot Diff
|
|
217
|
+
|
|
218
|
+
| Command | Description |
|
|
219
|
+
|---------|-------------|
|
|
220
|
+
| \`qa-use browser snapshot\` | Get full ARIA tree with element refs (use only when diff output is insufficient) |
|
|
221
|
+
| \`qa-use browser url\` | Get current URL |
|
|
222
|
+
| \`qa-use browser screenshot\` | Save screenshot.png |
|
|
223
|
+
| \`qa-use browser screenshot file.png\` | Save to custom path |
|
|
224
|
+
| \`qa-use browser screenshot --base64\` | Output base64 to stdout |
|
|
225
|
+
| \`qa-use browser evaluate <expression>\` | Execute JavaScript in browser context |
|
|
226
|
+
|
|
227
|
+
The snapshot-diff feature automatically displays DOM changes after each browser action:
|
|
228
|
+
- **Added elements**: Shown with \`+\` prefix and green color — these refs are immediately usable
|
|
229
|
+
- **Modified elements**: Shown with \`~\` prefix and yellow color, including attribute changes (\`+attrs: checked\`)
|
|
230
|
+
- **Removed elements**: Shown with \`-\` prefix and red color — do NOT use these refs
|
|
231
|
+
|
|
232
|
+
**Downloads:** When an action triggers a file download (e.g., clicking a download link), the response includes download info: filename, size, and a presigned URL. Use \`qa-use browser downloads\` to list all downloads or \`--save <dir>\` to save them locally.
|
|
233
|
+
|
|
234
|
+
Use diff output to interact with newly appeared elements directly, without running a full \`snapshot\` first.
|
|
235
|
+
|
|
236
|
+
### Test Operations
|
|
237
|
+
|
|
238
|
+
| Command | Description |
|
|
239
|
+
|---------|-------------|
|
|
240
|
+
| \`qa-use test run <name>\` | Run test by name |
|
|
241
|
+
| \`qa-use test run --all\` | Run all tests |
|
|
242
|
+
| \`qa-use test run <name> --tunnel\` | Run with local browser tunnel |
|
|
243
|
+
| \`qa-use test run <name> --autofix\` | Enable AI self-healing |
|
|
244
|
+
| \`qa-use test run <name> --update-local\` | Persist AI fixes to file |
|
|
245
|
+
| \`qa-use test run <name> --download\` | Download assets to \`/tmp/qa-use/downloads/\` |
|
|
246
|
+
| \`qa-use test run <name> --var key=value\` | Override variable |
|
|
247
|
+
| \`qa-use test validate <name>\` | Validate test syntax |
|
|
248
|
+
| \`qa-use test list\` | List available tests |
|
|
249
|
+
| \`qa-use test info <name>\` | Show test details (steps, tags, description) |
|
|
250
|
+
| \`qa-use test info --id <uuid>\` | Show cloud test details by ID |
|
|
251
|
+
| \`qa-use test runs [name]\` | List test run history |
|
|
252
|
+
| \`qa-use test runs --id <uuid>\` | Filter runs by test ID |
|
|
253
|
+
| \`qa-use test runs --status failed\` | Filter runs by status |
|
|
254
|
+
| \`qa-use test init\` | Initialize test directory |
|
|
255
|
+
| \`qa-use test sync pull\` | Pull tests from cloud |
|
|
256
|
+
| \`qa-use test sync push --all\` | Push all local tests to cloud |
|
|
257
|
+
| \`qa-use test sync push --id <uuid>\` | Push specific test |
|
|
258
|
+
| \`qa-use test sync push --force\` | Push tests, overwriting conflicts |
|
|
259
|
+
| \`qa-use test diff <file>\` | Compare local vs cloud test |
|
|
260
|
+
| \`qa-use test schema [path]\` | View test definition schema |
|
|
261
|
+
|
|
262
|
+
### API Operations (Dynamic OpenAPI)
|
|
263
|
+
|
|
264
|
+
\`qa-use api\` dynamically discovers operations from \`/api/v1/openapi.json\` and caches metadata locally for offline fallback.
|
|
265
|
+
|
|
266
|
+
| Command | Description |
|
|
267
|
+
|---------|-------------|
|
|
268
|
+
| \`qa-use api ls\` | List available \`/api/v1/*\` routes from OpenAPI |
|
|
269
|
+
| \`qa-use api ls --refresh\` | Force refresh OpenAPI cache |
|
|
270
|
+
| \`qa-use api ls --offline\` | Use cached OpenAPI metadata only |
|
|
271
|
+
| \`qa-use api /api/v1/tests\` | Call endpoint (method inferred when possible) |
|
|
272
|
+
| \`qa-use api -X GET /api/v1/test-runs -f limit=5\` | GET with query fields |
|
|
273
|
+
| \`qa-use api -X POST /api/v1/tests-actions/run --input body.json\` | POST with JSON body file |
|
|
274
|
+
| \`qa-use api -X GET /api/v1/test-runs/<id>\` | Fetch detail endpoint by ID |
|
|
275
|
+
|
|
276
|
+
**No Plugin Shortcut** - Use CLI commands directly.
|
|
277
|
+
|
|
278
|
+
### Logs & Debugging
|
|
279
|
+
|
|
280
|
+
| Command | Description |
|
|
281
|
+
|---------|-------------|
|
|
282
|
+
| \`qa-use browser logs console\` | View console logs from session |
|
|
283
|
+
| \`qa-use browser logs console -s <id>\` | View logs from specific/closed session |
|
|
284
|
+
| \`qa-use browser logs network\` | View network request logs |
|
|
285
|
+
| \`qa-use browser logs network -s <id>\` | View network logs from specific session |
|
|
286
|
+
| \`qa-use browser downloads\` | List downloaded files from session |
|
|
287
|
+
| \`qa-use browser downloads --save <dir>\` | Save downloaded files to local directory |
|
|
288
|
+
| \`qa-use browser downloads --json\` | Output download info as JSON |
|
|
289
|
+
|
|
290
|
+
### Test Generation
|
|
291
|
+
|
|
292
|
+
| Command | Description |
|
|
293
|
+
|---------|-------------|
|
|
294
|
+
| \`qa-use browser generate-test\` | Generate test YAML from recorded session |
|
|
295
|
+
| \`qa-use browser generate-test -s <id>\` | Generate from specific session |
|
|
296
|
+
| \`qa-use browser generate-test -n <name>\` | Specify test name |
|
|
297
|
+
| \`qa-use browser generate-test -o <path>\` | Specify output path |
|
|
298
|
+
| \`qa-use browser get-blocks\` | Get recorded interaction blocks (JSON) |
|
|
299
|
+
|
|
300
|
+
### Waiting
|
|
301
|
+
|
|
302
|
+
| Command | Description |
|
|
303
|
+
|---------|-------------|
|
|
304
|
+
| \`qa-use browser wait <ms>\` | Fixed wait |
|
|
305
|
+
| \`qa-use browser wait-for-selector ".class"\` | Wait for selector |
|
|
306
|
+
| \`qa-use browser wait-for-load\` | Wait for page load |
|
|
307
|
+
|
|
308
|
+
### Variable Overrides
|
|
309
|
+
|
|
310
|
+
Use \`--var\` to override app config variables at runtime. Common variables:
|
|
311
|
+
|
|
312
|
+
| Variable | Description |
|
|
313
|
+
|----------|-------------|
|
|
314
|
+
| \`base_url\` | Base URL for the app (e.g., preview deployment URL) |
|
|
315
|
+
| \`login_url\` | Login page URL |
|
|
316
|
+
| \`login_username\` | Username/email for authentication |
|
|
317
|
+
| \`login_password\` | Password for authentication |
|
|
318
|
+
|
|
319
|
+
Example with ephemeral preview URL:
|
|
320
|
+
\`\`\`bash
|
|
321
|
+
qa-use browser create --after-test-id <login-test-uuid> \\
|
|
322
|
+
--var base_url=https://preview-123.example.com \\
|
|
323
|
+
--var login_url=https://preview-123.example.com/auth/login
|
|
324
|
+
\`\`\`
|
|
325
|
+
|
|
326
|
+
## Common Patterns
|
|
327
|
+
|
|
328
|
+
### Pattern 1: Feature Verification
|
|
329
|
+
|
|
330
|
+
**CLI Workflow:**
|
|
331
|
+
\`\`\`bash
|
|
332
|
+
# 1. Search for existing test
|
|
333
|
+
qa-use test list | grep "login"
|
|
334
|
+
|
|
335
|
+
# 2. Run test with autofix
|
|
336
|
+
qa-use test run login --autofix
|
|
337
|
+
|
|
338
|
+
# 3. Debug failures
|
|
339
|
+
qa-use browser logs console
|
|
340
|
+
\`\`\`
|
|
341
|
+
|
|
342
|
+
**Plugin Shortcut:**
|
|
343
|
+
\`\`\`
|
|
344
|
+
/qa-use:verify "login works with valid credentials"
|
|
345
|
+
\`\`\`
|
|
346
|
+
(Wraps the above CLI workflow with AI-powered test discovery and analysis)
|
|
347
|
+
|
|
348
|
+
### Pattern 2: Record & Generate Test
|
|
349
|
+
|
|
350
|
+
**CLI Workflow:**
|
|
351
|
+
\`\`\`bash
|
|
352
|
+
# 1. Create session
|
|
353
|
+
qa-use browser create --tunnel --no-headless
|
|
354
|
+
|
|
355
|
+
# 2. Navigate and interact
|
|
356
|
+
qa-use browser goto https://example.com
|
|
357
|
+
qa-use browser snapshot
|
|
358
|
+
qa-use browser click e1
|
|
359
|
+
qa-use browser fill e5 "test"
|
|
360
|
+
|
|
361
|
+
# 3. Generate test from blocks
|
|
362
|
+
qa-use browser get-blocks
|
|
363
|
+
qa-use browser generate-test -n "my_test"
|
|
364
|
+
|
|
365
|
+
# 4. Run test
|
|
366
|
+
qa-use test run my_test
|
|
367
|
+
\`\`\`
|
|
368
|
+
|
|
369
|
+
**Plugin Shortcut:**
|
|
370
|
+
\`\`\`
|
|
371
|
+
/qa-use:record start my_test
|
|
372
|
+
# ... perform interactions ...
|
|
373
|
+
/qa-use:record stop
|
|
374
|
+
\`\`\`
|
|
375
|
+
|
|
376
|
+
### Pattern 3: Authenticated Exploration
|
|
377
|
+
|
|
378
|
+
**CLI Workflow:**
|
|
379
|
+
\`\`\`bash
|
|
380
|
+
# Create session that runs login test first
|
|
381
|
+
qa-use browser create --after-test-id <login-test-uuid>
|
|
382
|
+
|
|
383
|
+
# Session now authenticated, explore
|
|
384
|
+
qa-use browser goto /dashboard
|
|
385
|
+
qa-use browser snapshot
|
|
386
|
+
\`\`\`
|
|
387
|
+
|
|
388
|
+
**Plugin Shortcut:**
|
|
389
|
+
\`\`\`
|
|
390
|
+
/qa-use:explore /dashboard
|
|
391
|
+
\`\`\`
|
|
392
|
+
(Automatically handles auth detection and session creation)
|
|
393
|
+
|
|
394
|
+
### Pattern 4: Edit Existing Test
|
|
395
|
+
|
|
396
|
+
**CLI Workflow:**
|
|
397
|
+
\`\`\`bash
|
|
398
|
+
# 1. Open test file in editor
|
|
399
|
+
vim qa-tests/login.yaml
|
|
400
|
+
|
|
401
|
+
# 2. Validate syntax
|
|
402
|
+
qa-use test validate login
|
|
403
|
+
|
|
404
|
+
# 3. Run to verify
|
|
405
|
+
qa-use test run login
|
|
406
|
+
\`\`\`
|
|
407
|
+
|
|
408
|
+
**Plugin Shortcut:**
|
|
409
|
+
\`\`\`
|
|
410
|
+
/qa-use:record edit login
|
|
411
|
+
\`\`\`
|
|
412
|
+
(AI-assisted editing with validation)
|
|
413
|
+
|
|
414
|
+
### Pattern 5: Using Snapshot Diff to Avoid Unnecessary Snapshots
|
|
415
|
+
|
|
416
|
+
**CLI Workflow:**
|
|
417
|
+
\`\`\`bash
|
|
418
|
+
# Create session and navigate
|
|
419
|
+
qa-use browser create --tunnel --no-headless
|
|
420
|
+
qa-use browser goto https://evals.desplega.ai/checkboxes
|
|
421
|
+
|
|
422
|
+
# goto shows diff — initial page load shows all elements:
|
|
423
|
+
# Changes: 45 elements added
|
|
424
|
+
# + [e18] checkbox "I agree to the terms and conditions"
|
|
425
|
+
# + [e19] generic "I agree to the terms and conditions"
|
|
426
|
+
|
|
427
|
+
# ✅ Use ref from diff directly — no snapshot needed!
|
|
428
|
+
qa-use browser click e18
|
|
429
|
+
|
|
430
|
+
# Diff shows what changed:
|
|
431
|
+
# Changes: 5 elements added, 1 element modified
|
|
432
|
+
# + [e54] generic "Thanks for agreeing!"
|
|
433
|
+
# + [e55] link "Terms and Conditions"
|
|
434
|
+
# ~ [e18] checkbox "I agree to the terms and conditions"
|
|
435
|
+
# +attrs: active, checked
|
|
436
|
+
|
|
437
|
+
# ✅ Can click e55 directly from diff output — no snapshot needed!
|
|
438
|
+
qa-use browser click e55
|
|
439
|
+
|
|
440
|
+
# ❌ Need to find an element NOT in the diff? Now run snapshot:
|
|
441
|
+
qa-use browser snapshot
|
|
442
|
+
\`\`\`
|
|
443
|
+
|
|
444
|
+
**Key principle:** Use diff output as your primary source of element refs after actions. Only fall back to \`snapshot\` when you need to find elements that weren't in the diff.
|
|
445
|
+
|
|
446
|
+
**Benefits:**
|
|
447
|
+
- Fewer API calls = faster automation
|
|
448
|
+
- Diff refs are always fresh (just returned from the server)
|
|
449
|
+
- Instantly see what changed (new elements, attribute changes, removals)
|
|
450
|
+
|
|
451
|
+
**No Plugin Shortcut** - Automatic feature in all browser commands
|
|
452
|
+
|
|
453
|
+
## CI/CD Integration
|
|
454
|
+
|
|
455
|
+
### Running Tests in CI
|
|
456
|
+
|
|
457
|
+
**Environment Variables:**
|
|
458
|
+
\`\`\`bash
|
|
459
|
+
export QA_USE_API_KEY="your-api-key"
|
|
460
|
+
export QA_USE_REGION="us" # Optional: "us" or "auto"
|
|
461
|
+
\`\`\`
|
|
462
|
+
|
|
463
|
+
**Basic Test Execution:**
|
|
464
|
+
\`\`\`bash
|
|
465
|
+
# Run all tests
|
|
466
|
+
qa-use test run --all
|
|
467
|
+
|
|
468
|
+
# Run specific tag
|
|
469
|
+
qa-use test run --tag smoke
|
|
470
|
+
|
|
471
|
+
# Exit codes: 0 = pass, 1 = fail
|
|
472
|
+
\`\`\`
|
|
473
|
+
|
|
474
|
+
### GitHub Actions Example
|
|
475
|
+
|
|
476
|
+
\`\`\`yaml
|
|
477
|
+
name: QA Tests
|
|
478
|
+
on: [push, pull_request]
|
|
479
|
+
|
|
480
|
+
jobs:
|
|
481
|
+
test:
|
|
482
|
+
runs-on: ubuntu-latest
|
|
483
|
+
steps:
|
|
484
|
+
- uses: actions/checkout@v3
|
|
485
|
+
- uses: actions/setup-node@v3
|
|
486
|
+
with:
|
|
487
|
+
node-version: '20'
|
|
488
|
+
- name: Install qa-use
|
|
489
|
+
run: npm install -g @desplega.ai/qa-use
|
|
490
|
+
- name: Run tests
|
|
491
|
+
run: qa-use test run --all
|
|
492
|
+
env:
|
|
493
|
+
QA_USE_API_KEY: \${{ secrets.QA_USE_API_KEY }}
|
|
494
|
+
\`\`\`
|
|
495
|
+
|
|
496
|
+
### Test Artifacts
|
|
497
|
+
|
|
498
|
+
**Screenshots:**
|
|
499
|
+
- Automatically saved on failure
|
|
500
|
+
- Location: \`/tmp/qa-use/downloads/\` (local) or cloud (remote)
|
|
501
|
+
|
|
502
|
+
**Logs:**
|
|
503
|
+
- Console logs: \`qa-use browser logs console -s <session-id>\`
|
|
504
|
+
- Network logs: \`qa-use browser logs network -s <session-id>\`
|
|
505
|
+
|
|
506
|
+
## Advanced Topics
|
|
507
|
+
|
|
508
|
+
### Localhost Testing (Tunnel Mode)
|
|
509
|
+
|
|
510
|
+
**When to use tunnel mode:**
|
|
511
|
+
|
|
512
|
+
\`\`\`
|
|
513
|
+
Testing localhost (http://localhost:3000)?
|
|
514
|
+
├─ YES → Use --tunnel
|
|
515
|
+
│ └─ qa-use browser create --tunnel [--no-headless]
|
|
516
|
+
│ (Starts local Playwright, creates localtunnel, keeps running)
|
|
517
|
+
│
|
|
518
|
+
└─ NO (Public URL) → Use remote browser (default)
|
|
519
|
+
└─ qa-use browser create
|
|
520
|
+
(Uses desplega.ai cloud browser via WebSocket)
|
|
521
|
+
\`\`\`
|
|
522
|
+
|
|
523
|
+
**The \`--tunnel\` flag is a binary choice:**
|
|
524
|
+
- **Local tunnel mode**: Playwright on your machine + localtunnel
|
|
525
|
+
- **Remote mode**: WebSocket URL to cloud-hosted browser
|
|
526
|
+
|
|
527
|
+
**For test execution:**
|
|
528
|
+
\`\`\`bash
|
|
529
|
+
# Local app
|
|
530
|
+
qa-use test run my_test --tunnel [--headful]
|
|
531
|
+
|
|
532
|
+
# Public app
|
|
533
|
+
qa-use test run my_test
|
|
534
|
+
\`\`\`
|
|
535
|
+
|
|
536
|
+
**Plugin shortcuts handle tunnel detection automatically:**
|
|
537
|
+
\`\`\`
|
|
538
|
+
/qa-use:explore http://localhost:3000
|
|
539
|
+
/qa-use:record start local_test
|
|
540
|
+
\`\`\`
|
|
541
|
+
|
|
542
|
+
See [references/localhost-testing.md](references/localhost-testing.md) for troubleshooting.
|
|
543
|
+
|
|
544
|
+
### Session Persistence
|
|
545
|
+
|
|
546
|
+
Sessions are stored in \`~/.qa-use.json\` and have:
|
|
547
|
+
- **TTL**: 30 minutes (default)
|
|
548
|
+
- **Auto-resolve**: One active session = no \`-s\` flag needed
|
|
549
|
+
- **Cleanup**: Automatic on timeout or explicit \`browser close\`
|
|
550
|
+
|
|
551
|
+
### Block Limitations
|
|
552
|
+
|
|
553
|
+
**What's captured:**
|
|
554
|
+
- goto, click, fill, type, check, uncheck, select, hover
|
|
555
|
+
- scroll, scroll-into-view, drag, upload, press
|
|
556
|
+
|
|
557
|
+
**What's NOT captured:**
|
|
558
|
+
- Assertions (must be added manually)
|
|
559
|
+
- Waits (inferred from timing, may need adjustment)
|
|
560
|
+
- Complex interactions (multi-drag, hover sequences)
|
|
561
|
+
|
|
562
|
+
**Manual editing:** Edit generated YAML to add assertions and refine selectors.
|
|
563
|
+
|
|
564
|
+
### WebSocket Sessions
|
|
565
|
+
|
|
566
|
+
**Sharing sessions across processes:**
|
|
567
|
+
\`\`\`bash
|
|
568
|
+
# Process 1: Create session
|
|
569
|
+
qa-use browser create --tunnel
|
|
570
|
+
# Output: ws://localhost:12345/browser/abc123
|
|
571
|
+
|
|
572
|
+
# Process 2: Connect to session
|
|
573
|
+
qa-use browser goto https://example.com --ws-url ws://localhost:12345/browser/abc123
|
|
574
|
+
\`\`\`
|
|
575
|
+
|
|
576
|
+
## Deep-Dive References
|
|
577
|
+
|
|
578
|
+
| Document | Description |
|
|
579
|
+
|----------|-------------|
|
|
580
|
+
| [browser-commands.md](references/browser-commands.md) | Complete browser CLI reference with all flags |
|
|
581
|
+
| [test-format.md](references/test-format.md) | Full test YAML specification |
|
|
582
|
+
| [localhost-testing.md](references/localhost-testing.md) | Tunnel setup for local development |
|
|
583
|
+
| [failure-debugging.md](references/failure-debugging.md) | Failure classification and diagnostics |
|
|
584
|
+
| [ci.md](references/ci.md) | CI/CD integration patterns and examples |
|
|
585
|
+
|
|
586
|
+
## Templates
|
|
587
|
+
|
|
588
|
+
| Template | Description |
|
|
589
|
+
|----------|-------------|
|
|
590
|
+
| [basic-test.yaml](templates/basic-test.yaml) | Simple navigation and assertion |
|
|
591
|
+
| [auth-flow.yaml](templates/auth-flow.yaml) | Login flow with credentials |
|
|
592
|
+
| [form-test.yaml](templates/form-test.yaml) | Form submission with validation |
|
|
593
|
+
|
|
594
|
+
## Test Format Overview
|
|
595
|
+
|
|
596
|
+
\`\`\`yaml
|
|
597
|
+
name: Login Test
|
|
598
|
+
description: Validates login functionality with valid credentials
|
|
599
|
+
tags:
|
|
600
|
+
- smoke
|
|
601
|
+
- auth
|
|
602
|
+
app_config: <app-config-id>
|
|
603
|
+
variables:
|
|
604
|
+
email: test@example.com
|
|
605
|
+
password: secret123
|
|
606
|
+
depends_on: setup-test # Optional
|
|
607
|
+
steps:
|
|
608
|
+
- action: goto
|
|
609
|
+
url: /login
|
|
610
|
+
- action: fill
|
|
611
|
+
target: email input
|
|
612
|
+
value: $email
|
|
613
|
+
- action: click
|
|
614
|
+
target: login button
|
|
615
|
+
- action: to_be_visible
|
|
616
|
+
target: dashboard
|
|
617
|
+
\`\`\`
|
|
618
|
+
|
|
619
|
+
See [references/test-format.md](references/test-format.md) for complete specification.
|
|
620
|
+
|
|
621
|
+
## Common Mistakes
|
|
622
|
+
|
|
623
|
+
| ❌ Wrong | ✅ Correct |
|
|
624
|
+
|---------|-----------|
|
|
625
|
+
| \`browser navigate <url>\` | \`browser goto <url>\` |
|
|
626
|
+
| \`browser destroy\` | \`browser close\` |
|
|
627
|
+
| \`browser close <session-id>\` | \`browser close\` |
|
|
628
|
+
| Guessing element refs | Use refs from diff output or \`snapshot\` |
|
|
629
|
+
| Running \`snapshot\` after every action | Use diff output; only \`snapshot\` when needed |
|
|
630
|
+
| Testing localhost without \`--tunnel\` | Use \`--tunnel\` flag |
|
|
631
|
+
| \`test sync --pull\` | \`test sync pull\` (subcommand, not flag) |
|
|
632
|
+
| \`test sync --push\` | \`test sync push\` (subcommand, not flag) |
|
|
633
|
+
|
|
634
|
+
## npx Alternative
|
|
635
|
+
|
|
636
|
+
All commands use \`qa-use\` assuming global install. For one-off use:
|
|
637
|
+
\`\`\`bash
|
|
638
|
+
npx @desplega.ai/qa-use browser <command>
|
|
639
|
+
\`\`\`
|
|
640
|
+
`;
|
|
641
|
+
export const REFERENCE_DOCS = {
|
|
642
|
+
'browser-commands': {
|
|
643
|
+
title: 'Browser Commands Reference',
|
|
644
|
+
content: `# Browser Commands Reference
|
|
645
|
+
|
|
646
|
+
Complete reference for \`qa-use browser\` CLI commands.
|
|
647
|
+
|
|
648
|
+
## Session Management
|
|
649
|
+
|
|
650
|
+
### create
|
|
651
|
+
|
|
652
|
+
Create a new browser session.
|
|
653
|
+
|
|
654
|
+
\`\`\`bash
|
|
655
|
+
qa-use browser create [options]
|
|
656
|
+
\`\`\`
|
|
657
|
+
|
|
658
|
+
| Flag | Description |
|
|
659
|
+
|------|-------------|
|
|
660
|
+
| \`--viewport <size>\` | Viewport size: \`desktop\` (1280x720), \`tablet\` (768x1024), \`mobile\` (375x667) |
|
|
661
|
+
| \`--tunnel\` | Run local browser with API tunnel (for localhost testing) |
|
|
662
|
+
| \`--headless\` | Run in headless mode (default with \`--tunnel\`) |
|
|
663
|
+
| \`--no-headless\` | Show browser window (use with \`--tunnel\` for debugging) |
|
|
664
|
+
| \`--ws-url <url>\` | Connect to existing WebSocket browser endpoint |
|
|
665
|
+
| \`--after-test-id <uuid>\` | Run a test before session becomes interactive (start after login, etc.) |
|
|
666
|
+
|
|
667
|
+
**Examples:**
|
|
668
|
+
\`\`\`bash
|
|
669
|
+
qa-use browser create # Remote browser, default viewport
|
|
670
|
+
qa-use browser create --viewport mobile # Remote browser, mobile viewport
|
|
671
|
+
qa-use browser create --tunnel # Local headless browser with tunnel
|
|
672
|
+
qa-use browser create --tunnel --no-headless # Local visible browser for debugging
|
|
673
|
+
qa-use browser create --ws-url wss://... # Connect to existing browser
|
|
674
|
+
qa-use browser create --after-test-id <uuid> # Start session after running a test
|
|
675
|
+
\`\`\`
|
|
676
|
+
|
|
677
|
+
**Starting after login (--after-test-id):**
|
|
678
|
+
|
|
679
|
+
The \`--after-test-id\` flag runs an existing test before the session becomes interactive. This is extremely useful for:
|
|
680
|
+
- **Bypassing login walls** - use a test that logs in, then start exploring from the authenticated state
|
|
681
|
+
- **Starting from a specific page state** - run a test that navigates to a complex form, then continue manually
|
|
682
|
+
- **Resuming from checkpoints** - save common setup steps as a test, reuse across explorations
|
|
683
|
+
|
|
684
|
+
\`\`\`bash
|
|
685
|
+
# First, create a login test and get its ID from the test listing
|
|
686
|
+
qa-use test run --list
|
|
687
|
+
|
|
688
|
+
# Then create a session that starts after login
|
|
689
|
+
qa-use browser create --after-test-id 4292938b-338d-4c1c-952e-6bcdf3f7731a
|
|
690
|
+
|
|
691
|
+
# Session is now logged in and ready for exploration
|
|
692
|
+
qa-use browser snapshot
|
|
693
|
+
\`\`\`
|
|
694
|
+
|
|
695
|
+
**Error handling for --after-test-id:**
|
|
696
|
+
- If test not found: "Test not found" (exit 1)
|
|
697
|
+
- If test belongs to different org: "Test belongs to different organization" (exit 1)
|
|
698
|
+
- If test fails: Session status becomes "failed" with error message displayed
|
|
699
|
+
|
|
700
|
+
**Session persistence:** Sessions are stored in \`~/.qa-use.json\`. If only one active session exists, it's used automatically for all commands.
|
|
701
|
+
|
|
702
|
+
### list
|
|
703
|
+
|
|
704
|
+
List all active browser sessions.
|
|
705
|
+
|
|
706
|
+
\`\`\`bash
|
|
707
|
+
qa-use browser list
|
|
708
|
+
\`\`\`
|
|
709
|
+
|
|
710
|
+
Shows session IDs, creation time, and status.
|
|
711
|
+
|
|
712
|
+
### status
|
|
713
|
+
|
|
714
|
+
Show detailed status of current session.
|
|
715
|
+
|
|
716
|
+
\`\`\`bash
|
|
717
|
+
qa-use browser status
|
|
718
|
+
qa-use browser -s <session-id> status
|
|
719
|
+
\`\`\`
|
|
720
|
+
|
|
721
|
+
**Output includes:**
|
|
722
|
+
- Session ID
|
|
723
|
+
- Current URL
|
|
724
|
+
- Viewport size
|
|
725
|
+
- \`app_url\` - Web UI for viewing the session
|
|
726
|
+
- \`recording_url\` - URL to download session recording
|
|
727
|
+
- \`har_url\` - URL to download HAR file (network logs)
|
|
728
|
+
- Creation time and deadline
|
|
729
|
+
|
|
730
|
+
### close
|
|
731
|
+
|
|
732
|
+
Close the active browser session.
|
|
733
|
+
|
|
734
|
+
\`\`\`bash
|
|
735
|
+
qa-use browser close
|
|
736
|
+
\`\`\`
|
|
737
|
+
|
|
738
|
+
**Note:** Takes no arguments. Closes the currently active session. Use \`browser list\` first if you have multiple sessions and need to switch.
|
|
739
|
+
|
|
740
|
+
## Navigation
|
|
741
|
+
|
|
742
|
+
### goto
|
|
743
|
+
|
|
744
|
+
Navigate to a URL.
|
|
745
|
+
|
|
746
|
+
\`\`\`bash
|
|
747
|
+
qa-use browser goto <url>
|
|
748
|
+
\`\`\`
|
|
749
|
+
|
|
750
|
+
URL can be absolute (\`https://example.com\`) or relative (\`/login\`).
|
|
751
|
+
|
|
752
|
+
### back / forward / reload
|
|
753
|
+
|
|
754
|
+
History navigation.
|
|
755
|
+
|
|
756
|
+
\`\`\`bash
|
|
757
|
+
qa-use browser back
|
|
758
|
+
qa-use browser forward
|
|
759
|
+
qa-use browser reload
|
|
760
|
+
\`\`\`
|
|
761
|
+
|
|
762
|
+
## Element Targeting
|
|
763
|
+
|
|
764
|
+
### snapshot
|
|
765
|
+
|
|
766
|
+
Get the page's ARIA accessibility tree with element refs.
|
|
767
|
+
|
|
768
|
+
\`\`\`bash
|
|
769
|
+
qa-use browser snapshot [options]
|
|
770
|
+
\`\`\`
|
|
771
|
+
|
|
772
|
+
| Flag | Description |
|
|
773
|
+
|------|-------------|
|
|
774
|
+
| \`-i, --interactive\` | Only include interactive elements (buttons, inputs, links) |
|
|
775
|
+
| \`-c, --compact\` | Remove empty structural elements |
|
|
776
|
+
| \`-d, --max-depth <n>\` | Limit tree depth (1-20, where 1 = top level only) |
|
|
777
|
+
| \`--scope <selector>\` | CSS selector to scope snapshot (e.g., \`#main\`, \`.form\`) |
|
|
778
|
+
| \`--json\` | Output raw JSON including filter_stats |
|
|
779
|
+
|
|
780
|
+
**Output format:**
|
|
781
|
+
\`\`\`
|
|
782
|
+
- heading "Page Title" [level=1] [ref=e2]
|
|
783
|
+
- button "Click Me" [ref=e3]
|
|
784
|
+
- textbox "Email" [ref=e4]
|
|
785
|
+
- link "Sign Up" [ref=e5]
|
|
786
|
+
\`\`\`
|
|
787
|
+
|
|
788
|
+
**Filtering examples:**
|
|
789
|
+
\`\`\`bash
|
|
790
|
+
# Get only interactive elements (great for reducing token count)
|
|
791
|
+
qa-use browser snapshot --interactive
|
|
792
|
+
|
|
793
|
+
# Combine filters for maximum reduction
|
|
794
|
+
qa-use browser snapshot --interactive --compact --max-depth 3
|
|
795
|
+
|
|
796
|
+
# Scope to specific section
|
|
797
|
+
qa-use browser snapshot --scope "#main-content"
|
|
798
|
+
\`\`\`
|
|
799
|
+
|
|
800
|
+
**Typical reductions:**
|
|
801
|
+
- \`--max-depth 3\`: ~98% reduction
|
|
802
|
+
- \`--interactive\`: 0-80% depending on page
|
|
803
|
+
- Combined \`--interactive --max-depth 4\`: ~95% reduction
|
|
804
|
+
|
|
805
|
+
Use the \`[ref=eN]\` values in interaction commands.
|
|
806
|
+
|
|
807
|
+
**Critical workflow:** Run \`snapshot\` before your first interaction on a new page. After that, use the snapshot diff output from actions to get fresh refs — only run \`snapshot\` again when you need elements not shown in the diff. Refs are session-specific and change between page loads.
|
|
808
|
+
|
|
809
|
+
## Interactions
|
|
810
|
+
|
|
811
|
+
### click
|
|
812
|
+
|
|
813
|
+
Click an element.
|
|
814
|
+
|
|
815
|
+
\`\`\`bash
|
|
816
|
+
qa-use browser click <ref>
|
|
817
|
+
qa-use browser click --text "Button label"
|
|
818
|
+
\`\`\`
|
|
819
|
+
|
|
820
|
+
| Argument | Description |
|
|
821
|
+
|----------|-------------|
|
|
822
|
+
| \`<ref>\` | Element ref from snapshot (e.g., \`e3\`) |
|
|
823
|
+
| \`--text\` | Semantic description for AI selection |
|
|
824
|
+
|
|
825
|
+
### fill
|
|
826
|
+
|
|
827
|
+
Fill an input field (clears existing content).
|
|
828
|
+
|
|
829
|
+
\`\`\`bash
|
|
830
|
+
qa-use browser fill <ref> "value"
|
|
831
|
+
qa-use browser fill --text "Email field" "user@example.com"
|
|
832
|
+
\`\`\`
|
|
833
|
+
|
|
834
|
+
### type
|
|
835
|
+
|
|
836
|
+
Type text with keystroke delays (useful for autocomplete).
|
|
837
|
+
|
|
838
|
+
\`\`\`bash
|
|
839
|
+
qa-use browser type <ref> "text"
|
|
840
|
+
\`\`\`
|
|
841
|
+
|
|
842
|
+
### press
|
|
843
|
+
|
|
844
|
+
Press a keyboard key.
|
|
845
|
+
|
|
846
|
+
\`\`\`bash
|
|
847
|
+
qa-use browser press Enter
|
|
848
|
+
qa-use browser press Tab
|
|
849
|
+
qa-use browser press Escape
|
|
850
|
+
\`\`\`
|
|
851
|
+
|
|
852
|
+
### check / uncheck
|
|
853
|
+
|
|
854
|
+
Toggle checkboxes.
|
|
855
|
+
|
|
856
|
+
\`\`\`bash
|
|
857
|
+
qa-use browser check <ref>
|
|
858
|
+
qa-use browser uncheck <ref>
|
|
859
|
+
\`\`\`
|
|
860
|
+
|
|
861
|
+
### select
|
|
862
|
+
|
|
863
|
+
Select dropdown option by value or label.
|
|
864
|
+
|
|
865
|
+
\`\`\`bash
|
|
866
|
+
qa-use browser select <ref> "option value"
|
|
867
|
+
\`\`\`
|
|
868
|
+
|
|
869
|
+
### hover
|
|
870
|
+
|
|
871
|
+
Hover over an element.
|
|
872
|
+
|
|
873
|
+
\`\`\`bash
|
|
874
|
+
qa-use browser hover <ref>
|
|
875
|
+
\`\`\`
|
|
876
|
+
|
|
877
|
+
### scroll
|
|
878
|
+
|
|
879
|
+
Scroll the page or viewport.
|
|
880
|
+
|
|
881
|
+
\`\`\`bash
|
|
882
|
+
qa-use browser scroll down 500 # Scroll down 500px
|
|
883
|
+
qa-use browser scroll up 300 # Scroll up 300px
|
|
884
|
+
qa-use browser scroll-into-view <ref> # Scroll element into viewport
|
|
885
|
+
\`\`\`
|
|
886
|
+
|
|
887
|
+
### drag
|
|
888
|
+
|
|
889
|
+
Drag an element to a target element.
|
|
890
|
+
|
|
891
|
+
\`\`\`bash
|
|
892
|
+
qa-use browser drag <ref> --target <target-ref>
|
|
893
|
+
qa-use browser drag <ref> --target-selector ".drop-zone"
|
|
894
|
+
qa-use browser drag --text "Draggable item" --target <target-ref>
|
|
895
|
+
\`\`\`
|
|
896
|
+
|
|
897
|
+
| Argument | Description |
|
|
898
|
+
|----------|-------------|
|
|
899
|
+
| \`<ref>\` | Source element ref from snapshot |
|
|
900
|
+
| \`--text\` | Semantic source description for AI selection |
|
|
901
|
+
| \`--target <ref>\` | Target element ref |
|
|
902
|
+
| \`--target-selector <sel>\` | Target CSS selector |
|
|
903
|
+
|
|
904
|
+
**Examples:**
|
|
905
|
+
\`\`\`bash
|
|
906
|
+
qa-use browser drag e5 --target e10 # Drag by ref to ref
|
|
907
|
+
qa-use browser drag e5 --target-selector ".canvas" # Drag to CSS selector
|
|
908
|
+
qa-use browser drag --text "Process node" --target e10 # Drag by text
|
|
909
|
+
\`\`\`
|
|
910
|
+
|
|
911
|
+
**Note:** The browser CLI drag command uses element refs from snapshots. This is different from the test YAML format which uses locator chains. See test-format.md for YAML test syntax.
|
|
912
|
+
|
|
913
|
+
### mfa-totp
|
|
914
|
+
|
|
915
|
+
Generate TOTP code and optionally fill into an input field.
|
|
916
|
+
|
|
917
|
+
\`\`\`bash
|
|
918
|
+
qa-use browser mfa-totp <secret> # Generate only
|
|
919
|
+
qa-use browser mfa-totp <ref> <secret> # Generate and fill by ref
|
|
920
|
+
qa-use browser mfa-totp --text "OTP input" <secret> # Generate and fill by text
|
|
921
|
+
\`\`\`
|
|
922
|
+
|
|
923
|
+
| Argument | Description |
|
|
924
|
+
|----------|-------------|
|
|
925
|
+
| \`<secret>\` | TOTP secret (base32 encoded) |
|
|
926
|
+
| \`<ref>\` | Element ref to fill (optional) |
|
|
927
|
+
| \`--text\` | Semantic element description for AI selection |
|
|
928
|
+
|
|
929
|
+
**Examples:**
|
|
930
|
+
\`\`\`bash
|
|
931
|
+
qa-use browser mfa-totp JBSWY3DPEHPK3PXP # Generate code only
|
|
932
|
+
qa-use browser mfa-totp e15 JBSWY3DPEHPK3PXP # Fill into element e15
|
|
933
|
+
qa-use browser mfa-totp --text "verification code" JBSWY3DPEHPK3PXP
|
|
934
|
+
\`\`\`
|
|
935
|
+
|
|
936
|
+
### upload
|
|
937
|
+
|
|
938
|
+
Upload file(s) to a file input element.
|
|
939
|
+
|
|
940
|
+
\`\`\`bash
|
|
941
|
+
qa-use browser upload <ref> <file>...
|
|
942
|
+
qa-use browser upload --text "Choose file" <file>...
|
|
943
|
+
\`\`\`
|
|
944
|
+
|
|
945
|
+
| Argument | Description |
|
|
946
|
+
|----------|-------------|
|
|
947
|
+
| \`<ref>\` | File input element ref from snapshot |
|
|
948
|
+
| \`--text\` | Semantic element description for AI selection |
|
|
949
|
+
| \`<file>...\` | One or more file paths to upload |
|
|
950
|
+
|
|
951
|
+
**Examples:**
|
|
952
|
+
\`\`\`bash
|
|
953
|
+
qa-use browser upload e8 /tmp/document.pdf # Single file
|
|
954
|
+
qa-use browser upload e8 /tmp/file1.pdf /tmp/file2.pdf # Multiple files
|
|
955
|
+
qa-use browser upload --text "Upload attachment" /tmp/doc.pdf # By text
|
|
956
|
+
\`\`\`
|
|
957
|
+
|
|
958
|
+
**Upload encoding:** Files are read locally and sent as base64-encoded data. This works in both remote and tunnel modes — no need for the browser to have direct access to the file system.
|
|
959
|
+
|
|
960
|
+
## Downloads
|
|
961
|
+
|
|
962
|
+
### downloads
|
|
963
|
+
|
|
964
|
+
List or save files downloaded during the browser session.
|
|
965
|
+
|
|
966
|
+
\`\`\`bash
|
|
967
|
+
qa-use browser downloads # List downloads
|
|
968
|
+
qa-use browser downloads --json # Output as JSON
|
|
969
|
+
qa-use browser downloads --save /tmp/dl # Save files to directory
|
|
970
|
+
qa-use browser downloads -s <id> # Downloads from specific/closed session
|
|
971
|
+
\`\`\`
|
|
972
|
+
|
|
973
|
+
| Flag | Description |
|
|
974
|
+
|------|-------------|
|
|
975
|
+
| \`--json\` | Output raw JSON with URLs and metadata |
|
|
976
|
+
| \`--save <dir>\` | Download files to local directory |
|
|
977
|
+
| \`-s, --session-id <id>\` | Specify session (default: auto-resolved) |
|
|
978
|
+
|
|
979
|
+
**Download detection:** When any browser action triggers a file download (e.g., clicking a download link), the action response automatically includes download info (filename, size, presigned URL). The \`downloads\` command retrieves the full list.
|
|
980
|
+
|
|
981
|
+
## Inspection
|
|
982
|
+
|
|
983
|
+
### url
|
|
984
|
+
|
|
985
|
+
Get current page URL.
|
|
986
|
+
|
|
987
|
+
\`\`\`bash
|
|
988
|
+
qa-use browser url
|
|
989
|
+
\`\`\`
|
|
990
|
+
|
|
991
|
+
### screenshot
|
|
992
|
+
|
|
993
|
+
Capture a screenshot.
|
|
994
|
+
|
|
995
|
+
\`\`\`bash
|
|
996
|
+
qa-use browser screenshot # Saves as screenshot.png
|
|
997
|
+
qa-use browser screenshot myfile.png # Custom filename
|
|
998
|
+
qa-use browser screenshot /path/to/file.png # Custom path
|
|
999
|
+
qa-use browser screenshot --base64 # Output base64 to stdout
|
|
1000
|
+
\`\`\`
|
|
1001
|
+
|
|
1002
|
+
**Note:** Path is a positional argument, not a flag. Do NOT use \`--output\` or \`--path\`.
|
|
1003
|
+
|
|
1004
|
+
### get-blocks
|
|
1005
|
+
|
|
1006
|
+
Get recorded interaction blocks from the session.
|
|
1007
|
+
|
|
1008
|
+
\`\`\`bash
|
|
1009
|
+
qa-use browser get-blocks
|
|
1010
|
+
\`\`\`
|
|
1011
|
+
|
|
1012
|
+
Returns structured data of interactions performed during the session.
|
|
1013
|
+
|
|
1014
|
+
## Logs
|
|
1015
|
+
|
|
1016
|
+
### logs console
|
|
1017
|
+
|
|
1018
|
+
View browser console logs.
|
|
1019
|
+
|
|
1020
|
+
\`\`\`bash
|
|
1021
|
+
qa-use browser logs console # Current session
|
|
1022
|
+
qa-use browser logs console -s <id> # Specific or closed session
|
|
1023
|
+
\`\`\`
|
|
1024
|
+
|
|
1025
|
+
Shows console.log, console.error, and other console output from the page.
|
|
1026
|
+
|
|
1027
|
+
### logs network
|
|
1028
|
+
|
|
1029
|
+
View network request logs.
|
|
1030
|
+
|
|
1031
|
+
\`\`\`bash
|
|
1032
|
+
qa-use browser logs network # Current session
|
|
1033
|
+
qa-use browser logs network -s <id> # Specific or closed session
|
|
1034
|
+
\`\`\`
|
|
1035
|
+
|
|
1036
|
+
Shows HTTP requests, responses, and timing information.
|
|
1037
|
+
|
|
1038
|
+
## Test Generation
|
|
1039
|
+
|
|
1040
|
+
### generate-test
|
|
1041
|
+
|
|
1042
|
+
Generate a test YAML file from recorded session interactions.
|
|
1043
|
+
|
|
1044
|
+
\`\`\`bash
|
|
1045
|
+
qa-use browser generate-test # Current session
|
|
1046
|
+
qa-use browser generate-test -s <id> # Specific session
|
|
1047
|
+
qa-use browser generate-test --output my-test.yaml # Custom output path
|
|
1048
|
+
\`\`\`
|
|
1049
|
+
|
|
1050
|
+
Creates a test definition based on the interactions performed during the session.
|
|
1051
|
+
|
|
1052
|
+
## Waiting
|
|
1053
|
+
|
|
1054
|
+
### wait
|
|
1055
|
+
|
|
1056
|
+
Fixed time wait.
|
|
1057
|
+
|
|
1058
|
+
\`\`\`bash
|
|
1059
|
+
qa-use browser wait 2000 # Wait 2 seconds
|
|
1060
|
+
\`\`\`
|
|
1061
|
+
|
|
1062
|
+
### wait-for-selector
|
|
1063
|
+
|
|
1064
|
+
Wait for an element to appear.
|
|
1065
|
+
|
|
1066
|
+
\`\`\`bash
|
|
1067
|
+
qa-use browser wait-for-selector ".content"
|
|
1068
|
+
qa-use browser wait-for-selector ".modal" --state visible
|
|
1069
|
+
qa-use browser wait-for-selector ".loading" --state hidden
|
|
1070
|
+
\`\`\`
|
|
1071
|
+
|
|
1072
|
+
| Flag | Description |
|
|
1073
|
+
|------|-------------|
|
|
1074
|
+
| \`--state\` | Wait for state: \`visible\`, \`hidden\`, \`attached\`, \`detached\` |
|
|
1075
|
+
| \`--timeout\` | Max wait time in ms (default: 30000) |
|
|
1076
|
+
|
|
1077
|
+
### wait-for-load
|
|
1078
|
+
|
|
1079
|
+
Wait for page load state.
|
|
1080
|
+
|
|
1081
|
+
\`\`\`bash
|
|
1082
|
+
qa-use browser wait-for-load
|
|
1083
|
+
qa-use browser wait-for-load --state networkidle
|
|
1084
|
+
qa-use browser wait-for-load --state domcontentloaded
|
|
1085
|
+
\`\`\`
|
|
1086
|
+
|
|
1087
|
+
| State | Description |
|
|
1088
|
+
|-------|-------------|
|
|
1089
|
+
| \`load\` | Wait for load event (default) |
|
|
1090
|
+
| \`domcontentloaded\` | Wait for DOMContentLoaded |
|
|
1091
|
+
| \`networkidle\` | Wait for no network activity |
|
|
1092
|
+
|
|
1093
|
+
## Session Flag Position
|
|
1094
|
+
|
|
1095
|
+
When working with multiple sessions, use \`-s <id>\` BEFORE the command:
|
|
1096
|
+
|
|
1097
|
+
\`\`\`bash
|
|
1098
|
+
qa-use browser -s abc123 goto https://example.com # ✅ Correct
|
|
1099
|
+
qa-use browser goto -s abc123 https://example.com # ❌ Wrong
|
|
1100
|
+
qa-use browser goto https://example.com -s abc123 # ❌ Wrong
|
|
1101
|
+
\`\`\`
|
|
1102
|
+
|
|
1103
|
+
## Interactive Mode
|
|
1104
|
+
|
|
1105
|
+
For extended multi-command sessions:
|
|
1106
|
+
|
|
1107
|
+
\`\`\`bash
|
|
1108
|
+
qa-use browser run
|
|
1109
|
+
qa-use browser run --after-test-id <uuid> # Start REPL from post-test state
|
|
1110
|
+
\`\`\`
|
|
1111
|
+
|
|
1112
|
+
Opens interactive REPL for browser commands. Use \`--after-test-id\` to start the REPL in an authenticated or pre-configured state.
|
|
1113
|
+
|
|
1114
|
+
## Local Browser with Tunnel
|
|
1115
|
+
|
|
1116
|
+
The \`--tunnel\` flag starts a real browser on your machine with a tunnel for API control:
|
|
1117
|
+
|
|
1118
|
+
1. **Browser runs locally** - you can see it (with \`--no-headless\`)
|
|
1119
|
+
2. **API controls via tunnel** - cloud API sends commands through the tunnel
|
|
1120
|
+
3. **Auto-cleanup** - session closes when you press Ctrl+C or run \`browser close\`
|
|
1121
|
+
|
|
1122
|
+
**Use cases:**
|
|
1123
|
+
- Debugging tests visually
|
|
1124
|
+
- Testing localhost URLs
|
|
1125
|
+
- Developing tests interactively
|
|
1126
|
+
|
|
1127
|
+
\`\`\`bash
|
|
1128
|
+
# Start visible local browser
|
|
1129
|
+
qa-use browser create --tunnel --no-headless
|
|
1130
|
+
|
|
1131
|
+
# Now interact normally
|
|
1132
|
+
qa-use browser goto http://localhost:3000
|
|
1133
|
+
qa-use browser snapshot
|
|
1134
|
+
qa-use browser click e3
|
|
1135
|
+
|
|
1136
|
+
# Watch the browser respond in real-time
|
|
1137
|
+
\`\`\`
|
|
1138
|
+
`,
|
|
1139
|
+
},
|
|
1140
|
+
ci: {
|
|
1141
|
+
title: 'CI Integration Guide',
|
|
1142
|
+
content: `# CI Integration Guide
|
|
1143
|
+
|
|
1144
|
+
Run qa-use verification in GitHub Actions and other CI environments.
|
|
1145
|
+
|
|
1146
|
+
## GitHub Actions Setup
|
|
1147
|
+
|
|
1148
|
+
### Basic Workflow
|
|
1149
|
+
|
|
1150
|
+
\`\`\`yaml
|
|
1151
|
+
# .github/workflows/pr-verify.yml
|
|
1152
|
+
name: PR Verification
|
|
1153
|
+
|
|
1154
|
+
on:
|
|
1155
|
+
pull_request:
|
|
1156
|
+
types: [opened, synchronize, reopened]
|
|
1157
|
+
|
|
1158
|
+
jobs:
|
|
1159
|
+
verify-pr:
|
|
1160
|
+
runs-on: ubuntu-latest
|
|
1161
|
+
# Optional: only run on PRs with frontend changes
|
|
1162
|
+
# if: contains(github.event.pull_request.labels.*.name, 'frontend')
|
|
1163
|
+
|
|
1164
|
+
steps:
|
|
1165
|
+
- name: Checkout repository
|
|
1166
|
+
uses: actions/checkout@v4
|
|
1167
|
+
with:
|
|
1168
|
+
fetch-depth: 0 # Full history for diff analysis
|
|
1169
|
+
|
|
1170
|
+
- name: Setup Node.js
|
|
1171
|
+
uses: actions/setup-node@v4
|
|
1172
|
+
with:
|
|
1173
|
+
node-version: '20'
|
|
1174
|
+
|
|
1175
|
+
- name: Install Claude Code CLI
|
|
1176
|
+
run: |
|
|
1177
|
+
curl -fsSL https://claude.ai/install.sh | bash
|
|
1178
|
+
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
|
1179
|
+
|
|
1180
|
+
- name: Install qa-use plugin and CLI
|
|
1181
|
+
run: |
|
|
1182
|
+
claude mcp add-from-marketplace qa-use
|
|
1183
|
+
npm install -g @desplega.ai/qa-use
|
|
1184
|
+
|
|
1185
|
+
- name: Run PR Verification
|
|
1186
|
+
env:
|
|
1187
|
+
CLAUDE_CODE_OAUTH_TOKEN: \${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
1188
|
+
QA_USE_API_KEY: \${{ secrets.QA_USE_API_KEY }}
|
|
1189
|
+
GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
|
|
1190
|
+
CI: true
|
|
1191
|
+
run: |
|
|
1192
|
+
# Run Claude Code with the verify-pr command
|
|
1193
|
+
claude --print "/qa-use:verify-pr #\${{ github.event.pull_request.number }}"
|
|
1194
|
+
|
|
1195
|
+
- name: Post Report to PR
|
|
1196
|
+
if: always() # Post even if verification had warnings
|
|
1197
|
+
env:
|
|
1198
|
+
GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
|
|
1199
|
+
run: |
|
|
1200
|
+
if [ -f /tmp/pr-verify-report-\${{ github.event.pull_request.number }}.md ]; then
|
|
1201
|
+
gh pr comment \${{ github.event.pull_request.number }} \\
|
|
1202
|
+
--body-file /tmp/pr-verify-report-\${{ github.event.pull_request.number }}.md
|
|
1203
|
+
fi
|
|
1204
|
+
\`\`\`
|
|
1205
|
+
|
|
1206
|
+
### With Preview Deployment (Vercel/Netlify)
|
|
1207
|
+
|
|
1208
|
+
\`\`\`yaml
|
|
1209
|
+
# .github/workflows/pr-verify.yml
|
|
1210
|
+
name: PR Verification
|
|
1211
|
+
|
|
1212
|
+
on:
|
|
1213
|
+
pull_request:
|
|
1214
|
+
branches:
|
|
1215
|
+
- main
|
|
1216
|
+
types: [opened, synchronize, reopened, ready_for_review]
|
|
1217
|
+
workflow_dispatch:
|
|
1218
|
+
inputs:
|
|
1219
|
+
pr_number:
|
|
1220
|
+
description: "PR number to verify"
|
|
1221
|
+
required: true
|
|
1222
|
+
type: number
|
|
1223
|
+
|
|
1224
|
+
concurrency:
|
|
1225
|
+
group: pr-verify-\${{ github.event.pull_request.number || inputs.pr_number }}
|
|
1226
|
+
cancel-in-progress: true
|
|
1227
|
+
|
|
1228
|
+
jobs:
|
|
1229
|
+
verify-pr:
|
|
1230
|
+
if: github.event_name == 'workflow_dispatch' || github.event.pull_request.draft == false
|
|
1231
|
+
runs-on: ubuntu-latest
|
|
1232
|
+
permissions:
|
|
1233
|
+
contents: read
|
|
1234
|
+
deployments: read
|
|
1235
|
+
pull-requests: write
|
|
1236
|
+
statuses: read
|
|
1237
|
+
|
|
1238
|
+
steps:
|
|
1239
|
+
- name: Checkout repository
|
|
1240
|
+
uses: actions/checkout@v4
|
|
1241
|
+
with:
|
|
1242
|
+
fetch-depth: 0 # Full history for diff analysis
|
|
1243
|
+
|
|
1244
|
+
- name: Check PR approval status
|
|
1245
|
+
id: approval
|
|
1246
|
+
env:
|
|
1247
|
+
GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
|
|
1248
|
+
run: |
|
|
1249
|
+
# REVIEW_DECISION=$(gh pr view \${{ github.event.pull_request.number || inputs.pr_number }} --json reviewDecision -q '.reviewDecision')
|
|
1250
|
+
# echo "Review decision: $REVIEW_DECISION"
|
|
1251
|
+
# if [ "$REVIEW_DECISION" != "APPROVED" ]; then
|
|
1252
|
+
# echo "PR is not approved yet. Skipping verification."
|
|
1253
|
+
# echo "approved=false" >> $GITHUB_OUTPUT
|
|
1254
|
+
# else
|
|
1255
|
+
# echo "approved=true" >> $GITHUB_OUTPUT
|
|
1256
|
+
# fi
|
|
1257
|
+
# For demonstration purposes, we will assume all PRs are approved.
|
|
1258
|
+
echo "approved=true" >> $GITHUB_OUTPUT
|
|
1259
|
+
|
|
1260
|
+
- name: Setup Node.js
|
|
1261
|
+
if: steps.approval.outputs.approved == 'true'
|
|
1262
|
+
uses: actions/setup-node@v4
|
|
1263
|
+
with:
|
|
1264
|
+
node-version: "20"
|
|
1265
|
+
|
|
1266
|
+
- name: Install Claude Code CLI
|
|
1267
|
+
if: steps.approval.outputs.approved == 'true'
|
|
1268
|
+
run: |
|
|
1269
|
+
curl -fsSL https://claude.ai/install.sh | bash
|
|
1270
|
+
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
|
1271
|
+
|
|
1272
|
+
- name: Verify Claude CLI Installation
|
|
1273
|
+
if: steps.approval.outputs.approved == 'true'
|
|
1274
|
+
run: |
|
|
1275
|
+
claude --version || (echo "Claude CLI installation failed" && exit 1)
|
|
1276
|
+
|
|
1277
|
+
- name: Install qa-use plugin and CLI
|
|
1278
|
+
if: steps.approval.outputs.approved == 'true'
|
|
1279
|
+
run: |
|
|
1280
|
+
claude plugin marketplace add desplega-ai/qa-use
|
|
1281
|
+
claude plugin install qa-use@desplega.ai
|
|
1282
|
+
npm install -g @desplega.ai/qa-use
|
|
1283
|
+
|
|
1284
|
+
- name: Wait for Vercel Preview
|
|
1285
|
+
if: steps.approval.outputs.approved == 'true'
|
|
1286
|
+
uses: patrickedqvist/wait-for-vercel-preview@v1.3.1
|
|
1287
|
+
id: vercel
|
|
1288
|
+
with:
|
|
1289
|
+
token: \${{ secrets.GITHUB_TOKEN }}
|
|
1290
|
+
max_timeout: 300
|
|
1291
|
+
|
|
1292
|
+
- name: Run PR Verification
|
|
1293
|
+
if: steps.approval.outputs.approved == 'true'
|
|
1294
|
+
env:
|
|
1295
|
+
CLAUDE_CODE_OAUTH_TOKEN: \${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
1296
|
+
QA_USE_API_KEY: \${{ secrets.QA_USE_API_KEY }}
|
|
1297
|
+
GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
|
|
1298
|
+
CI: true
|
|
1299
|
+
run: |
|
|
1300
|
+
# Run Claude Code with the verify-pr command using Vercel preview URL
|
|
1301
|
+
claude --print --verbose --dangerously-skip-permissions --output-format stream-json --model haiku "/qa-use:verify-pr #\${{ github.event.pull_request.number || inputs.pr_number }} --base-url \${{ steps.vercel.outputs.url }}" 2>&1 | jq -c 'select(.type == "assistant" or .type == "tool_use" or .type == "result")'
|
|
1302
|
+
|
|
1303
|
+
- name: Post Report to PR
|
|
1304
|
+
if: always() && steps.approval.outputs.approved == 'true'
|
|
1305
|
+
env:
|
|
1306
|
+
GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
|
|
1307
|
+
run: |
|
|
1308
|
+
if [ -f /tmp/pr-verify-report-\${{ github.event.pull_request.number || inputs.pr_number }}.md ]; then
|
|
1309
|
+
gh pr comment \${{ github.event.pull_request.number || inputs.pr_number }} \\
|
|
1310
|
+
--body-file /tmp/pr-verify-report-\${{ github.event.pull_request.number || inputs.pr_number }}.md
|
|
1311
|
+
fi
|
|
1312
|
+
|
|
1313
|
+
- name: Upload Verification Artifacts
|
|
1314
|
+
if: always() && steps.approval.outputs.approved == 'true'
|
|
1315
|
+
uses: actions/upload-artifact@v4
|
|
1316
|
+
with:
|
|
1317
|
+
name: pr-verification-\${{ github.event.pull_request.number || inputs.pr_number }}
|
|
1318
|
+
path: |
|
|
1319
|
+
/tmp/pr-verify-*.png
|
|
1320
|
+
/tmp/pr-verify-*.json
|
|
1321
|
+
/tmp/pr-verify-*.jsonl
|
|
1322
|
+
/tmp/pr-verify-*.log
|
|
1323
|
+
/tmp/pr-verify-report-*.md
|
|
1324
|
+
\`\`\`
|
|
1325
|
+
|
|
1326
|
+
### Netlify Preview Deployment
|
|
1327
|
+
|
|
1328
|
+
\`\`\`yaml
|
|
1329
|
+
# Wait for Netlify preview deployment
|
|
1330
|
+
- name: Wait for Netlify Preview
|
|
1331
|
+
uses: jlevy-io/wait-for-netlify-deploy-with-headers@v1.0.1
|
|
1332
|
+
id: netlify
|
|
1333
|
+
with:
|
|
1334
|
+
site_name: 'your-netlify-site-name'
|
|
1335
|
+
max_timeout: 300
|
|
1336
|
+
|
|
1337
|
+
- name: Run PR Verification
|
|
1338
|
+
env:
|
|
1339
|
+
CLAUDE_CODE_OAUTH_TOKEN: \${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
1340
|
+
QA_USE_API_KEY: \${{ secrets.QA_USE_API_KEY }}
|
|
1341
|
+
GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
|
|
1342
|
+
CI: true
|
|
1343
|
+
run: |
|
|
1344
|
+
claude --print "/qa-use:verify-pr #\${{ github.event.pull_request.number }} --base-url \${{ steps.netlify.outputs.url }}"
|
|
1345
|
+
\`\`\`
|
|
1346
|
+
|
|
1347
|
+
## Variable Overrides
|
|
1348
|
+
|
|
1349
|
+
When running tests against preview deployments, you can override app config variables using \`--var\`:
|
|
1350
|
+
|
|
1351
|
+
\`\`\`bash
|
|
1352
|
+
qa-use browser create --after-test-id <login-test-uuid> \\
|
|
1353
|
+
--var base_url=https://preview-123.example.com \\
|
|
1354
|
+
--var login_url=https://preview-123.example.com/auth/login
|
|
1355
|
+
\`\`\`
|
|
1356
|
+
|
|
1357
|
+
Common app config variables:
|
|
1358
|
+
|
|
1359
|
+
| Variable | Description |
|
|
1360
|
+
|----------|-------------|
|
|
1361
|
+
| \`base_url\` | Base URL for the app (e.g., preview deployment) |
|
|
1362
|
+
| \`login_url\` | Login page URL |
|
|
1363
|
+
| \`login_username\` | Username/email for authentication |
|
|
1364
|
+
| \`login_password\` | Password for authentication |
|
|
1365
|
+
|
|
1366
|
+
The \`/qa-use:verify-pr\` command handles this automatically when you pass \`--base-url\`.
|
|
1367
|
+
|
|
1368
|
+
## Pre-installed Tools on GitHub Runners
|
|
1369
|
+
|
|
1370
|
+
GitHub-hosted runners include:
|
|
1371
|
+
|
|
1372
|
+
| Tool | Status | Notes |
|
|
1373
|
+
|------|--------|-------|
|
|
1374
|
+
| \`gh\` CLI | Pre-installed | Auto-authenticated via \`GITHUB_TOKEN\` |
|
|
1375
|
+
| Node.js | Available | Pin version for consistency |
|
|
1376
|
+
| git | Pre-installed | Full functionality |
|
|
1377
|
+
| curl | Pre-installed | For fallback API calls |
|
|
1378
|
+
|
|
1379
|
+
## Required Secrets
|
|
1380
|
+
|
|
1381
|
+
| Secret | Description | How to Get |
|
|
1382
|
+
|--------|-------------|------------|
|
|
1383
|
+
| \`CLAUDE_CODE_OAUTH_TOKEN\` | OAuth token for Claude Code authentication | Run \`claude setup-token\` locally (see below) |
|
|
1384
|
+
| \`QA_USE_API_KEY\` | qa-use/desplega.ai API key | From [desplega.ai dashboard](https://desplega.ai) |
|
|
1385
|
+
| \`GITHUB_TOKEN\` | Auto-provided by GitHub Actions | No setup needed (automatic) |
|
|
1386
|
+
|
|
1387
|
+
### Getting CLAUDE_CODE_OAUTH_TOKEN
|
|
1388
|
+
|
|
1389
|
+
Run locally to generate and retrieve your OAuth token:
|
|
1390
|
+
|
|
1391
|
+
\`\`\`bash
|
|
1392
|
+
# This will authenticate and store the token locally
|
|
1393
|
+
claude setup-token
|
|
1394
|
+
|
|
1395
|
+
# The token is stored in ~/.claude/.credentials.json
|
|
1396
|
+
# Copy the token value and add it as a GitHub secret
|
|
1397
|
+
\`\`\`
|
|
1398
|
+
|
|
1399
|
+
Claude Code automatically picks up \`CLAUDE_CODE_OAUTH_TOKEN\` from the environment when running in CI.
|
|
1400
|
+
|
|
1401
|
+
## Headless/Autonomous Mode
|
|
1402
|
+
|
|
1403
|
+
When \`CI=true\` or \`GITHUB_ACTIONS=true\` is set, the verify-pr command operates in fully autonomous mode:
|
|
1404
|
+
|
|
1405
|
+
| Behavior | Description |
|
|
1406
|
+
|----------|-------------|
|
|
1407
|
+
| No user prompts | Makes autonomous decisions with sensible defaults |
|
|
1408
|
+
| Auto-select first match | When multiple options exist (e.g., login tests) |
|
|
1409
|
+
| Continue on soft failures | Reports issues but doesn't block execution |
|
|
1410
|
+
| Fail fast on hard failures | Missing API key, no PR context, etc. |
|
|
1411
|
+
|
|
1412
|
+
## Exit Codes
|
|
1413
|
+
|
|
1414
|
+
| Code | Meaning |
|
|
1415
|
+
|------|---------|
|
|
1416
|
+
| 0 | Verification completed (even with warnings/partial results) |
|
|
1417
|
+
| 1 | Hard failure (no PR context, API key missing, session creation failed) |
|
|
1418
|
+
|
|
1419
|
+
The report is always generated regardless of exit code, allowing PR comments to be posted even on partial failures.
|
|
1420
|
+
|
|
1421
|
+
## Filtering by Label
|
|
1422
|
+
|
|
1423
|
+
To only run verification on PRs with specific labels:
|
|
1424
|
+
|
|
1425
|
+
\`\`\`yaml
|
|
1426
|
+
jobs:
|
|
1427
|
+
verify-pr:
|
|
1428
|
+
runs-on: ubuntu-latest
|
|
1429
|
+
if: contains(github.event.pull_request.labels.*.name, 'needs-verification')
|
|
1430
|
+
\`\`\`
|
|
1431
|
+
|
|
1432
|
+
Or to only run on frontend changes:
|
|
1433
|
+
|
|
1434
|
+
\`\`\`yaml
|
|
1435
|
+
on:
|
|
1436
|
+
pull_request:
|
|
1437
|
+
paths:
|
|
1438
|
+
- 'src/**/*.tsx'
|
|
1439
|
+
- 'src/**/*.jsx'
|
|
1440
|
+
- 'src/**/*.ts'
|
|
1441
|
+
- 'src/**/*.js'
|
|
1442
|
+
- 'src/**/*.vue'
|
|
1443
|
+
- 'src/**/*.svelte'
|
|
1444
|
+
\`\`\`
|
|
1445
|
+
|
|
1446
|
+
## Debugging
|
|
1447
|
+
|
|
1448
|
+
### View Raw Output
|
|
1449
|
+
|
|
1450
|
+
The command outputs a markdown report to stdout. To see raw output:
|
|
1451
|
+
|
|
1452
|
+
\`\`\`yaml
|
|
1453
|
+
- name: Run PR Verification
|
|
1454
|
+
run: |
|
|
1455
|
+
claude --print "/qa-use:verify-pr #\${{ github.event.pull_request.number }}" 2>&1 | tee /tmp/verification-output.txt
|
|
1456
|
+
\`\`\`
|
|
1457
|
+
|
|
1458
|
+
### Check Session Artifacts
|
|
1459
|
+
|
|
1460
|
+
After verification, session artifacts are available:
|
|
1461
|
+
|
|
1462
|
+
\`\`\`yaml
|
|
1463
|
+
- name: Upload Verification Artifacts
|
|
1464
|
+
uses: actions/upload-artifact@v4
|
|
1465
|
+
if: always()
|
|
1466
|
+
with:
|
|
1467
|
+
name: pr-verification-\${{ github.event.pull_request.number }}
|
|
1468
|
+
path: |
|
|
1469
|
+
/tmp/pr-verify-*.png
|
|
1470
|
+
/tmp/pr-verify-*.json
|
|
1471
|
+
/tmp/pr-verify-report-*.md
|
|
1472
|
+
\`\`\`
|
|
1473
|
+
|
|
1474
|
+
### Common Issues
|
|
1475
|
+
|
|
1476
|
+
| Issue | Solution |
|
|
1477
|
+
|-------|----------|
|
|
1478
|
+
| "API key not configured" | Ensure \`QA_USE_API_KEY\` secret is set |
|
|
1479
|
+
| "No login test found" | Either upload a login test or the command will proceed without auth |
|
|
1480
|
+
| "Session creation failed" | Check if \`QA_USE_API_KEY\` is valid and not expired |
|
|
1481
|
+
| "gh: command not found" | \`gh\` should be pre-installed; ensure checkout step runs first |
|
|
1482
|
+
`,
|
|
1483
|
+
},
|
|
1484
|
+
'failure-debugging': {
|
|
1485
|
+
title: 'Failure Debugging',
|
|
1486
|
+
content: `# Failure Debugging
|
|
1487
|
+
|
|
1488
|
+
Guide for analyzing E2E test failures and determining root causes.
|
|
1489
|
+
|
|
1490
|
+
## Failure Classification
|
|
1491
|
+
|
|
1492
|
+
Every test failure falls into one of three categories:
|
|
1493
|
+
|
|
1494
|
+
| Category | Meaning | Who Fixes |
|
|
1495
|
+
|----------|---------|-----------|
|
|
1496
|
+
| **CODE BUG** | Feature doesn't work | Developer (fix application code) |
|
|
1497
|
+
| **TEST BUG** | Test is outdated | Developer/QA (update test) |
|
|
1498
|
+
| **ENVIRONMENT** | External issue | Ops (fix infrastructure) |
|
|
1499
|
+
|
|
1500
|
+
Getting the classification right determines the correct fix approach.
|
|
1501
|
+
|
|
1502
|
+
## CODE BUG
|
|
1503
|
+
|
|
1504
|
+
**The feature doesn't work as expected. The application code is broken.**
|
|
1505
|
+
|
|
1506
|
+
### Indicators
|
|
1507
|
+
|
|
1508
|
+
- Expected behavior doesn't happen (redirect doesn't occur, data isn't saved)
|
|
1509
|
+
- JavaScript errors in browser console
|
|
1510
|
+
- API calls returning error responses (4xx, 5xx)
|
|
1511
|
+
- Application crashes or shows error pages
|
|
1512
|
+
- Form submission has no effect
|
|
1513
|
+
- Data not persisting
|
|
1514
|
+
|
|
1515
|
+
### Diagnostic Questions
|
|
1516
|
+
|
|
1517
|
+
1. Does the feature work when tested manually in a browser?
|
|
1518
|
+
2. Are there related recent code changes?
|
|
1519
|
+
3. Is the backend API responding correctly?
|
|
1520
|
+
4. Are there JavaScript errors in the console? (\`qa-use browser logs console\`)
|
|
1521
|
+
5. Are API requests failing? (\`qa-use browser logs network\`)
|
|
1522
|
+
|
|
1523
|
+
### Investigation Steps
|
|
1524
|
+
|
|
1525
|
+
\`\`\`bash
|
|
1526
|
+
# 1. Get console logs
|
|
1527
|
+
qa-use browser logs console -s <session-id>
|
|
1528
|
+
|
|
1529
|
+
# 2. Get network logs
|
|
1530
|
+
qa-use browser logs network -s <session-id>
|
|
1531
|
+
|
|
1532
|
+
# 3. Check for errors
|
|
1533
|
+
# Look for: console.error, failed requests, 4xx/5xx responses
|
|
1534
|
+
\`\`\`
|
|
1535
|
+
|
|
1536
|
+
### Suggested Actions
|
|
1537
|
+
|
|
1538
|
+
- **Locate relevant code:**
|
|
1539
|
+
- URL \`/login\` → look for \`pages/login\`, \`routes/login\`, \`auth/\`
|
|
1540
|
+
- Component "dashboard" → look for \`Dashboard.tsx\`, \`components/dashboard\`
|
|
1541
|
+
- Form submission → look for \`handleSubmit\`, form handlers, API calls
|
|
1542
|
+
|
|
1543
|
+
- **Check recent changes:**
|
|
1544
|
+
\`\`\`bash
|
|
1545
|
+
git log --oneline -20 -- src/
|
|
1546
|
+
git diff HEAD~5 -- src/auth/
|
|
1547
|
+
\`\`\`
|
|
1548
|
+
|
|
1549
|
+
- **Debug manually** - reproduce the issue in a browser with DevTools open
|
|
1550
|
+
|
|
1551
|
+
## TEST BUG
|
|
1552
|
+
|
|
1553
|
+
**The test definition is outdated or incorrect. The feature works, but the test doesn't match it.**
|
|
1554
|
+
|
|
1555
|
+
### Indicators
|
|
1556
|
+
|
|
1557
|
+
- Element selector/target no longer matches
|
|
1558
|
+
- Timing issues (element appears with different delay)
|
|
1559
|
+
- Expected value changed (button text "Submit" → "Sign In")
|
|
1560
|
+
- Test assumes old workflow that was redesigned
|
|
1561
|
+
- Assertion expects outdated content
|
|
1562
|
+
|
|
1563
|
+
### Diagnostic Questions
|
|
1564
|
+
|
|
1565
|
+
1. Has the UI changed recently (button text, layout, element attributes)?
|
|
1566
|
+
2. Is this a timing/race condition issue?
|
|
1567
|
+
3. Does the test pass with \`--autofix\`?
|
|
1568
|
+
4. Did someone refactor the component without updating tests?
|
|
1569
|
+
|
|
1570
|
+
### Investigation Steps
|
|
1571
|
+
|
|
1572
|
+
\`\`\`bash
|
|
1573
|
+
# 1. Run with autofix to see if AI can fix it
|
|
1574
|
+
qa-use test run my-test --autofix
|
|
1575
|
+
|
|
1576
|
+
# 2. If autofix works, persist the fix
|
|
1577
|
+
qa-use test run my-test --autofix --update-local
|
|
1578
|
+
|
|
1579
|
+
# 3. Check what changed
|
|
1580
|
+
git diff qa-tests/my-test.yaml
|
|
1581
|
+
\`\`\`
|
|
1582
|
+
|
|
1583
|
+
### Suggested Actions
|
|
1584
|
+
|
|
1585
|
+
- **Update target description** to match current UI
|
|
1586
|
+
- **Add wait steps** for timing issues
|
|
1587
|
+
- **Run with \`--autofix --update-local\`** to let AI fix and persist
|
|
1588
|
+
- **Review the diff** to understand what changed
|
|
1589
|
+
|
|
1590
|
+
### Common Test Bug Patterns
|
|
1591
|
+
|
|
1592
|
+
| Symptom | Likely Cause | Fix |
|
|
1593
|
+
|---------|--------------|-----|
|
|
1594
|
+
| "Element not found: submit button" | Button text changed | Update target to new text |
|
|
1595
|
+
| "Timeout waiting for dashboard" | Slower load time | Add \`wait\` or increase timeout |
|
|
1596
|
+
| "Expected 'Welcome' but got 'Hello'" | Copy changed | Update assertion value |
|
|
1597
|
+
| "Element not interactable" | Overlay blocking | Add wait for overlay to close |
|
|
1598
|
+
|
|
1599
|
+
## ENVIRONMENT
|
|
1600
|
+
|
|
1601
|
+
**External factors are causing the failure. The code and test are correct.**
|
|
1602
|
+
|
|
1603
|
+
### Indicators
|
|
1604
|
+
|
|
1605
|
+
- Network timeouts or connection errors
|
|
1606
|
+
- Authentication failures (session expired, invalid credentials)
|
|
1607
|
+
- Missing test data (database not seeded, user doesn't exist)
|
|
1608
|
+
- Service unavailable (third-party API down)
|
|
1609
|
+
- Rate limiting errors
|
|
1610
|
+
- SSL/TLS certificate errors
|
|
1611
|
+
|
|
1612
|
+
### Diagnostic Questions
|
|
1613
|
+
|
|
1614
|
+
1. Does the app work when accessed manually?
|
|
1615
|
+
2. Are API credentials valid and not expired?
|
|
1616
|
+
3. Is test data in the expected state?
|
|
1617
|
+
4. Are external services (APIs, databases) accessible?
|
|
1618
|
+
5. Is this a transient network issue?
|
|
1619
|
+
|
|
1620
|
+
### Investigation Steps
|
|
1621
|
+
|
|
1622
|
+
\`\`\`bash
|
|
1623
|
+
# 1. Check if app is accessible
|
|
1624
|
+
curl https://your-app.com/health
|
|
1625
|
+
|
|
1626
|
+
# 2. Check network logs for failed requests
|
|
1627
|
+
qa-use browser logs network -s <session-id>
|
|
1628
|
+
|
|
1629
|
+
# 3. Verify credentials haven't expired
|
|
1630
|
+
# Check .qa-use-tests.json or environment variables
|
|
1631
|
+
\`\`\`
|
|
1632
|
+
|
|
1633
|
+
### Suggested Actions
|
|
1634
|
+
|
|
1635
|
+
- **Retry the test** - transient issues often resolve themselves
|
|
1636
|
+
- **Refresh credentials** - update expired API keys or tokens
|
|
1637
|
+
- **Reset test data** - re-seed database, recreate test user
|
|
1638
|
+
- **Check service status** - verify third-party services are up
|
|
1639
|
+
- **Wait and retry** - for rate limiting, wait before retrying
|
|
1640
|
+
|
|
1641
|
+
## Debugging Workflow
|
|
1642
|
+
|
|
1643
|
+
\`\`\`
|
|
1644
|
+
Test Failed
|
|
1645
|
+
│
|
|
1646
|
+
▼
|
|
1647
|
+
┌──────────────────────────────────────┐
|
|
1648
|
+
│ 1. Get session logs │
|
|
1649
|
+
│ qa-use browser logs console -s ID │
|
|
1650
|
+
│ qa-use browser logs network -s ID │
|
|
1651
|
+
└──────────────────┬───────────────────┘
|
|
1652
|
+
│
|
|
1653
|
+
▼
|
|
1654
|
+
┌──────────────────────────────────────┐
|
|
1655
|
+
│ 2. Check for JS errors or API fails │
|
|
1656
|
+
│ - Console errors = CODE BUG │
|
|
1657
|
+
│ - 4xx/5xx responses = CODE BUG │
|
|
1658
|
+
│ - Network timeout = ENVIRONMENT │
|
|
1659
|
+
└──────────────────┬───────────────────┘
|
|
1660
|
+
│
|
|
1661
|
+
▼
|
|
1662
|
+
┌──────────────────────────────────────┐
|
|
1663
|
+
│ 3. Try --autofix │
|
|
1664
|
+
│ qa-use test run name --autofix │
|
|
1665
|
+
│ - Works = TEST BUG, use │
|
|
1666
|
+
│ --update-local to persist │
|
|
1667
|
+
│ - Still fails = probably CODE BUG │
|
|
1668
|
+
└──────────────────┬───────────────────┘
|
|
1669
|
+
│
|
|
1670
|
+
▼
|
|
1671
|
+
┌──────────────────────────────────────┐
|
|
1672
|
+
│ 4. Manual verification │
|
|
1673
|
+
│ - Open app in browser │
|
|
1674
|
+
│ - Try the same flow manually │
|
|
1675
|
+
│ - Works manually = TEST BUG │
|
|
1676
|
+
│ - Fails manually = CODE BUG │
|
|
1677
|
+
└──────────────────────────────────────┘
|
|
1678
|
+
\`\`\`
|
|
1679
|
+
|
|
1680
|
+
## Error Message Reference
|
|
1681
|
+
|
|
1682
|
+
| Error Message | Category | Likely Fix |
|
|
1683
|
+
|---------------|----------|------------|
|
|
1684
|
+
| "Element not found: ..." | TEST BUG | Update target description |
|
|
1685
|
+
| "Timeout waiting for ..." | TEST BUG/ENV | Add wait or check service |
|
|
1686
|
+
| "Expected ... but got ..." | TEST BUG/CODE | Verify expected value |
|
|
1687
|
+
| "Navigation to ... failed" | TEST BUG/CODE | Check URL and redirects |
|
|
1688
|
+
| "Element not interactable" | TEST BUG | Wait for overlays |
|
|
1689
|
+
| "Network request failed" | ENVIRONMENT | Check service health |
|
|
1690
|
+
| "Unauthorized" / "401" | ENVIRONMENT | Refresh credentials |
|
|
1691
|
+
| "Internal Server Error" / "500" | CODE BUG | Check server logs |
|
|
1692
|
+
| "Not Found" / "404" | CODE BUG | Check routing |
|
|
1693
|
+
| "TypeError: Cannot read ..." | CODE BUG | Fix JavaScript error |
|
|
1694
|
+
|
|
1695
|
+
## Using AI Self-Healing
|
|
1696
|
+
|
|
1697
|
+
The \`--autofix\` flag enables AI-powered test repair:
|
|
1698
|
+
|
|
1699
|
+
\`\`\`bash
|
|
1700
|
+
# Try autofix
|
|
1701
|
+
qa-use test run my-test --autofix
|
|
1702
|
+
|
|
1703
|
+
# If it works, persist the changes
|
|
1704
|
+
qa-use test run my-test --autofix --update-local
|
|
1705
|
+
|
|
1706
|
+
# Review what changed
|
|
1707
|
+
git diff qa-tests/my-test.yaml
|
|
1708
|
+
\`\`\`
|
|
1709
|
+
|
|
1710
|
+
**What autofix can fix:**
|
|
1711
|
+
- Selector/target changes
|
|
1712
|
+
- Timing issues (adds waits)
|
|
1713
|
+
- Minor assertion value changes
|
|
1714
|
+
|
|
1715
|
+
**What autofix cannot fix:**
|
|
1716
|
+
- Broken application code
|
|
1717
|
+
- Major workflow changes
|
|
1718
|
+
- Missing features
|
|
1719
|
+
- Authentication issues
|
|
1720
|
+
`,
|
|
1721
|
+
},
|
|
1722
|
+
'localhost-testing': {
|
|
1723
|
+
title: 'Localhost Testing',
|
|
1724
|
+
content: `# Localhost Testing
|
|
1725
|
+
|
|
1726
|
+
Testing applications running on \`localhost\` requires a tunnel because the cloud-hosted browser cannot access your local machine.
|
|
1727
|
+
|
|
1728
|
+
## Why Tunnels Are Needed
|
|
1729
|
+
|
|
1730
|
+
\`\`\`
|
|
1731
|
+
Your Machine Cloud
|
|
1732
|
+
┌─────────────────┐ ┌─────────────────┐
|
|
1733
|
+
│ localhost:3000 │ ✗ │ Cloud Browser │
|
|
1734
|
+
│ (your app) │ ◄──────────│ (qa-use API) │
|
|
1735
|
+
└─────────────────┘ └─────────────────┘
|
|
1736
|
+
|
|
1737
|
+
Without tunnel: Cloud cannot reach localhost
|
|
1738
|
+
\`\`\`
|
|
1739
|
+
|
|
1740
|
+
\`\`\`
|
|
1741
|
+
Your Machine Cloud
|
|
1742
|
+
┌─────────────────┐ ┌─────────────────┐
|
|
1743
|
+
│ localhost:3000 │ │ Cloud Browser │
|
|
1744
|
+
│ (your app) │ │ (qa-use API) │
|
|
1745
|
+
└────────┬────────┘ └────────┬────────┘
|
|
1746
|
+
│ │
|
|
1747
|
+
└──────────┐ ┌──────────────┘
|
|
1748
|
+
│ │
|
|
1749
|
+
┌─────▼────▼─────┐
|
|
1750
|
+
│ Local Browser │
|
|
1751
|
+
│ + Tunnel │
|
|
1752
|
+
└────────────────┘
|
|
1753
|
+
|
|
1754
|
+
With tunnel: Local browser accesses localhost,
|
|
1755
|
+
API controls browser through tunnel
|
|
1756
|
+
\`\`\`
|
|
1757
|
+
|
|
1758
|
+
## Using \`--tunnel\` Flag
|
|
1759
|
+
|
|
1760
|
+
The simplest approach - add \`--tunnel\` to your test run command:
|
|
1761
|
+
|
|
1762
|
+
\`\`\`bash
|
|
1763
|
+
qa-use test run my-test --tunnel
|
|
1764
|
+
\`\`\`
|
|
1765
|
+
|
|
1766
|
+
This:
|
|
1767
|
+
1. Starts a local headless browser
|
|
1768
|
+
2. Creates a tunnel for API control
|
|
1769
|
+
3. Runs the test
|
|
1770
|
+
4. Cleans up automatically
|
|
1771
|
+
|
|
1772
|
+
### With Visible Browser
|
|
1773
|
+
|
|
1774
|
+
For debugging, add \`--headful\`:
|
|
1775
|
+
|
|
1776
|
+
\`\`\`bash
|
|
1777
|
+
qa-use test run my-test --tunnel --headful
|
|
1778
|
+
\`\`\`
|
|
1779
|
+
|
|
1780
|
+
## Persistent Tunnel Session
|
|
1781
|
+
|
|
1782
|
+
For running multiple tests or interactive development, create a persistent tunnel session:
|
|
1783
|
+
|
|
1784
|
+
### Terminal 1: Start Tunnel
|
|
1785
|
+
|
|
1786
|
+
\`\`\`bash
|
|
1787
|
+
qa-use browser create --tunnel --no-headless
|
|
1788
|
+
\`\`\`
|
|
1789
|
+
|
|
1790
|
+
Output:
|
|
1791
|
+
\`\`\`
|
|
1792
|
+
Session created: abc123
|
|
1793
|
+
WebSocket URL: wss://tunnel.desplega.ai/abc123
|
|
1794
|
+
Tunnel active. Press Ctrl+C to stop.
|
|
1795
|
+
\`\`\`
|
|
1796
|
+
|
|
1797
|
+
### Terminal 2: Run Tests
|
|
1798
|
+
|
|
1799
|
+
\`\`\`bash
|
|
1800
|
+
# Run test against the tunneled browser
|
|
1801
|
+
qa-use test run my-test --ws-url wss://tunnel.desplega.ai/abc123
|
|
1802
|
+
|
|
1803
|
+
# Or run multiple tests
|
|
1804
|
+
qa-use test run login --ws-url wss://tunnel.desplega.ai/abc123
|
|
1805
|
+
qa-use test run checkout --ws-url wss://tunnel.desplega.ai/abc123
|
|
1806
|
+
\`\`\`
|
|
1807
|
+
|
|
1808
|
+
### Benefits
|
|
1809
|
+
|
|
1810
|
+
- **Reuse browser session** - no startup time between tests
|
|
1811
|
+
- **Watch execution** - see what's happening in real-time
|
|
1812
|
+
- **Debug interactively** - use browser commands between test runs
|
|
1813
|
+
- **Inspect state** - check page state after failures
|
|
1814
|
+
|
|
1815
|
+
## Browser Session Commands with Tunnel
|
|
1816
|
+
|
|
1817
|
+
You can also use browser commands directly for exploration:
|
|
1818
|
+
|
|
1819
|
+
\`\`\`bash
|
|
1820
|
+
# Create tunneled session
|
|
1821
|
+
qa-use browser create --tunnel --no-headless
|
|
1822
|
+
|
|
1823
|
+
# Navigate to your local app
|
|
1824
|
+
qa-use browser goto http://localhost:3000
|
|
1825
|
+
|
|
1826
|
+
# Explore
|
|
1827
|
+
qa-use browser snapshot
|
|
1828
|
+
qa-use browser click e3
|
|
1829
|
+
qa-use browser screenshot
|
|
1830
|
+
|
|
1831
|
+
# Close when done
|
|
1832
|
+
qa-use browser close
|
|
1833
|
+
\`\`\`
|
|
1834
|
+
|
|
1835
|
+
## Environment-Specific URLs
|
|
1836
|
+
|
|
1837
|
+
If your app runs on different ports in different environments, use variables:
|
|
1838
|
+
|
|
1839
|
+
\`\`\`yaml
|
|
1840
|
+
# test.yaml
|
|
1841
|
+
name: Local Test
|
|
1842
|
+
app_config: my-app
|
|
1843
|
+
variables:
|
|
1844
|
+
base_url: http://localhost:3000
|
|
1845
|
+
steps:
|
|
1846
|
+
- action: goto
|
|
1847
|
+
url: $base_url/login
|
|
1848
|
+
\`\`\`
|
|
1849
|
+
|
|
1850
|
+
Override at runtime:
|
|
1851
|
+
|
|
1852
|
+
\`\`\`bash
|
|
1853
|
+
# Local development
|
|
1854
|
+
qa-use test run my-test --tunnel --var base_url=http://localhost:3000
|
|
1855
|
+
|
|
1856
|
+
# Staging
|
|
1857
|
+
qa-use test run my-test --var base_url=https://staging.example.com
|
|
1858
|
+
\`\`\`
|
|
1859
|
+
|
|
1860
|
+
## Common Issues
|
|
1861
|
+
|
|
1862
|
+
### "Connection refused" / "Network error"
|
|
1863
|
+
|
|
1864
|
+
Your local server isn't running or is on a different port.
|
|
1865
|
+
|
|
1866
|
+
**Fix:** Verify your app is running:
|
|
1867
|
+
\`\`\`bash
|
|
1868
|
+
curl http://localhost:3000
|
|
1869
|
+
\`\`\`
|
|
1870
|
+
|
|
1871
|
+
### Tunnel disconnects
|
|
1872
|
+
|
|
1873
|
+
The tunnel process was interrupted.
|
|
1874
|
+
|
|
1875
|
+
**Fix:** Restart the tunnel:
|
|
1876
|
+
\`\`\`bash
|
|
1877
|
+
qa-use browser create --tunnel
|
|
1878
|
+
\`\`\`
|
|
1879
|
+
|
|
1880
|
+
### "localhost" resolved differently
|
|
1881
|
+
|
|
1882
|
+
Some setups resolve \`localhost\` differently than \`127.0.0.1\`.
|
|
1883
|
+
|
|
1884
|
+
**Fix:** Try the explicit IP:
|
|
1885
|
+
\`\`\`bash
|
|
1886
|
+
qa-use browser goto http://127.0.0.1:3000
|
|
1887
|
+
\`\`\`
|
|
1888
|
+
|
|
1889
|
+
### HTTPS localhost with self-signed cert
|
|
1890
|
+
|
|
1891
|
+
Local HTTPS with self-signed certificates may fail.
|
|
1892
|
+
|
|
1893
|
+
**Fix:** Use HTTP for local testing, or configure your browser to accept the cert:
|
|
1894
|
+
\`\`\`bash
|
|
1895
|
+
# Use HTTP locally
|
|
1896
|
+
qa-use browser goto http://localhost:3000
|
|
1897
|
+
|
|
1898
|
+
# Test HTTPS only in staging/prod environments
|
|
1899
|
+
\`\`\`
|
|
1900
|
+
|
|
1901
|
+
## Best Practices
|
|
1902
|
+
|
|
1903
|
+
1. **Use \`--tunnel\` for all localhost tests** - Don't forget, or tests will fail with confusing network errors
|
|
1904
|
+
|
|
1905
|
+
2. **Keep tunnel running during development** - Create once, run many tests
|
|
1906
|
+
|
|
1907
|
+
3. **Use \`--no-headless\` for debugging** - Watch what's happening
|
|
1908
|
+
|
|
1909
|
+
4. **Save WebSocket URL** - Copy it from tunnel output for reuse in \`--ws-url\`
|
|
1910
|
+
|
|
1911
|
+
5. **Clean up sessions** - Run \`qa-use browser close\` when done to free resources
|
|
1912
|
+
`,
|
|
1913
|
+
},
|
|
1914
|
+
'test-format': {
|
|
1915
|
+
title: 'Test Format Reference',
|
|
1916
|
+
content: `# Test Format Reference
|
|
1917
|
+
|
|
1918
|
+
Complete specification for qa-use test YAML files.
|
|
1919
|
+
|
|
1920
|
+
## Basic Structure
|
|
1921
|
+
|
|
1922
|
+
\`\`\`yaml
|
|
1923
|
+
name: Test Name
|
|
1924
|
+
description: Optional description of what this test verifies
|
|
1925
|
+
tags:
|
|
1926
|
+
- smoke
|
|
1927
|
+
- auth
|
|
1928
|
+
app_config: <app-config-id>
|
|
1929
|
+
variables:
|
|
1930
|
+
key: value
|
|
1931
|
+
depends_on: optional-prerequisite-test
|
|
1932
|
+
steps:
|
|
1933
|
+
- action: goto
|
|
1934
|
+
url: /path
|
|
1935
|
+
\`\`\`
|
|
1936
|
+
|
|
1937
|
+
## Required Fields
|
|
1938
|
+
|
|
1939
|
+
| Field | Description |
|
|
1940
|
+
|-------|-------------|
|
|
1941
|
+
| \`name\` | Human-readable test name |
|
|
1942
|
+
| \`app_config\` | App configuration ID from desplega.ai (or use default from \`.qa-use-tests.json\`) |
|
|
1943
|
+
| \`steps\` | Array of test steps |
|
|
1944
|
+
|
|
1945
|
+
## Optional Fields
|
|
1946
|
+
|
|
1947
|
+
| Field | Description |
|
|
1948
|
+
|-------|-------------|
|
|
1949
|
+
| \`description\` | What this test verifies |
|
|
1950
|
+
| \`tags\` | Array of strings for categorization (e.g., \`smoke\`, \`auth\`, \`critical\`) |
|
|
1951
|
+
| \`variables\` | Key-value pairs for parameterization |
|
|
1952
|
+
| \`depends_on\` | Name of test that must run first |
|
|
1953
|
+
|
|
1954
|
+
## Variables
|
|
1955
|
+
|
|
1956
|
+
Define variables at the top level:
|
|
1957
|
+
|
|
1958
|
+
\`\`\`yaml
|
|
1959
|
+
variables:
|
|
1960
|
+
email: test@example.com
|
|
1961
|
+
password: secret123
|
|
1962
|
+
base_path: /app
|
|
1963
|
+
\`\`\`
|
|
1964
|
+
|
|
1965
|
+
Reference with \`$\` prefix:
|
|
1966
|
+
|
|
1967
|
+
\`\`\`yaml
|
|
1968
|
+
steps:
|
|
1969
|
+
- action: fill
|
|
1970
|
+
target: email input
|
|
1971
|
+
value: $email
|
|
1972
|
+
- action: goto
|
|
1973
|
+
url: $base_path/dashboard
|
|
1974
|
+
\`\`\`
|
|
1975
|
+
|
|
1976
|
+
Variables can be overridden at runtime:
|
|
1977
|
+
|
|
1978
|
+
\`\`\`bash
|
|
1979
|
+
qa-use test run my-test --var email=other@example.com
|
|
1980
|
+
\`\`\`
|
|
1981
|
+
|
|
1982
|
+
## Dependencies
|
|
1983
|
+
|
|
1984
|
+
Run prerequisite tests first:
|
|
1985
|
+
|
|
1986
|
+
\`\`\`yaml
|
|
1987
|
+
name: Checkout Test
|
|
1988
|
+
depends_on: login-test
|
|
1989
|
+
steps:
|
|
1990
|
+
- action: goto
|
|
1991
|
+
url: /checkout
|
|
1992
|
+
\`\`\`
|
|
1993
|
+
|
|
1994
|
+
Dependencies are resolved recursively. If \`checkout-test\` depends on \`login-test\`, and \`login-test\` depends on \`setup-test\`, all three run in order.
|
|
1995
|
+
|
|
1996
|
+
## Step Format
|
|
1997
|
+
|
|
1998
|
+
Each step has an \`action\` and action-specific fields:
|
|
1999
|
+
|
|
2000
|
+
\`\`\`yaml
|
|
2001
|
+
- action: <action-type>
|
|
2002
|
+
target: <element description> # For interactions
|
|
2003
|
+
value: <value> # For fill, type, assertions
|
|
2004
|
+
url: <path> # For navigation
|
|
2005
|
+
\`\`\`
|
|
2006
|
+
|
|
2007
|
+
## Available Actions
|
|
2008
|
+
|
|
2009
|
+
### Navigation
|
|
2010
|
+
|
|
2011
|
+
| Action | Fields | Description |
|
|
2012
|
+
|--------|--------|-------------|
|
|
2013
|
+
| \`goto\` | \`url\` | Navigate to URL (absolute or relative) |
|
|
2014
|
+
| \`back\` | - | Browser back |
|
|
2015
|
+
| \`forward\` | - | Browser forward |
|
|
2016
|
+
| \`reload\` | - | Reload page |
|
|
2017
|
+
|
|
2018
|
+
\`\`\`yaml
|
|
2019
|
+
- action: goto
|
|
2020
|
+
url: /login
|
|
2021
|
+
|
|
2022
|
+
- action: goto
|
|
2023
|
+
url: https://example.com/page
|
|
2024
|
+
\`\`\`
|
|
2025
|
+
|
|
2026
|
+
### Interactions
|
|
2027
|
+
|
|
2028
|
+
| Action | Fields | Description |
|
|
2029
|
+
|--------|--------|-------------|
|
|
2030
|
+
| \`click\` | \`target\` | Click element |
|
|
2031
|
+
| \`fill\` | \`target\`, \`value\` | Fill input (clears first) |
|
|
2032
|
+
| \`type\` | \`target\`, \`value\` | Type with delays |
|
|
2033
|
+
| \`press\` | \`value\` | Press keyboard key |
|
|
2034
|
+
| \`check\` | \`target\` | Check checkbox |
|
|
2035
|
+
| \`uncheck\` | \`target\` | Uncheck checkbox |
|
|
2036
|
+
| \`select\` | \`target\`, \`value\` | Select dropdown option |
|
|
2037
|
+
| \`hover\` | \`target\` | Hover over element |
|
|
2038
|
+
| \`scroll\` | \`target\` or direction | Scroll page or element |
|
|
2039
|
+
| \`mfa_totp\` | \`target\` (optional), \`secret\` | Generate TOTP and optionally fill |
|
|
2040
|
+
| \`set_input_files\` | \`target\`, \`files\` | Upload files to input |
|
|
2041
|
+
|
|
2042
|
+
\`\`\`yaml
|
|
2043
|
+
- action: click
|
|
2044
|
+
target: submit button
|
|
2045
|
+
|
|
2046
|
+
- action: fill
|
|
2047
|
+
target: email input
|
|
2048
|
+
value: $email
|
|
2049
|
+
|
|
2050
|
+
- action: type
|
|
2051
|
+
target: search box
|
|
2052
|
+
value: search query
|
|
2053
|
+
|
|
2054
|
+
- action: press
|
|
2055
|
+
value: Enter
|
|
2056
|
+
|
|
2057
|
+
- action: select
|
|
2058
|
+
target: country dropdown
|
|
2059
|
+
value: United States
|
|
2060
|
+
|
|
2061
|
+
- action: mfa_totp
|
|
2062
|
+
target: OTP input field
|
|
2063
|
+
secret: $totp_secret
|
|
2064
|
+
|
|
2065
|
+
- action: set_input_files
|
|
2066
|
+
target: file upload button
|
|
2067
|
+
files:
|
|
2068
|
+
- /path/to/file1.pdf
|
|
2069
|
+
- /path/to/file2.pdf
|
|
2070
|
+
\`\`\`
|
|
2071
|
+
|
|
2072
|
+
### Assertions
|
|
2073
|
+
|
|
2074
|
+
| Action | Fields | Description |
|
|
2075
|
+
|--------|--------|-------------|
|
|
2076
|
+
| \`to_be_visible\` | \`target\` | Assert element is visible |
|
|
2077
|
+
| \`to_be_hidden\` | \`target\` | Assert element is hidden |
|
|
2078
|
+
| \`to_have_text\` | \`target\`, \`value\` | Assert element has text |
|
|
2079
|
+
| \`to_have_value\` | \`target\`, \`value\` | Assert input has value |
|
|
2080
|
+
| \`to_be_checked\` | \`target\` | Assert checkbox is checked |
|
|
2081
|
+
| \`to_be_unchecked\` | \`target\` | Assert checkbox is unchecked |
|
|
2082
|
+
|
|
2083
|
+
\`\`\`yaml
|
|
2084
|
+
- action: to_be_visible
|
|
2085
|
+
target: success message
|
|
2086
|
+
|
|
2087
|
+
- action: to_have_text
|
|
2088
|
+
target: page heading
|
|
2089
|
+
value: Welcome
|
|
2090
|
+
|
|
2091
|
+
- action: to_be_checked
|
|
2092
|
+
target: remember me checkbox
|
|
2093
|
+
\`\`\`
|
|
2094
|
+
|
|
2095
|
+
### Waiting
|
|
2096
|
+
|
|
2097
|
+
| Action | Fields | Description |
|
|
2098
|
+
|--------|--------|-------------|
|
|
2099
|
+
| \`wait\` | \`value\` | Wait fixed time (ms) |
|
|
2100
|
+
| \`wait_for_url\` | \`url\` | Wait for URL to match |
|
|
2101
|
+
| \`wait_for_selector\` | \`target\`, \`state\` | Wait for element state |
|
|
2102
|
+
|
|
2103
|
+
\`\`\`yaml
|
|
2104
|
+
- action: wait
|
|
2105
|
+
value: 2000
|
|
2106
|
+
|
|
2107
|
+
- action: wait_for_url
|
|
2108
|
+
url: /dashboard
|
|
2109
|
+
|
|
2110
|
+
- action: wait_for_selector
|
|
2111
|
+
target: .modal
|
|
2112
|
+
state: hidden
|
|
2113
|
+
\`\`\`
|
|
2114
|
+
|
|
2115
|
+
### AI-Powered Actions
|
|
2116
|
+
|
|
2117
|
+
Use when human-readable selectors are insufficient:
|
|
2118
|
+
|
|
2119
|
+
| Action | Fields | Description |
|
|
2120
|
+
|--------|--------|-------------|
|
|
2121
|
+
| \`ai_action\` | \`value\` | AI performs action from description |
|
|
2122
|
+
| \`ai_assertion\` | \`value\` | AI verifies condition from description |
|
|
2123
|
+
|
|
2124
|
+
\`\`\`yaml
|
|
2125
|
+
- action: ai_action
|
|
2126
|
+
value: scroll to the pricing section
|
|
2127
|
+
|
|
2128
|
+
- action: ai_action
|
|
2129
|
+
value: dismiss the cookie banner if present
|
|
2130
|
+
|
|
2131
|
+
- action: ai_assertion
|
|
2132
|
+
value: verify the cart shows exactly 3 items
|
|
2133
|
+
|
|
2134
|
+
- action: ai_assertion
|
|
2135
|
+
value: confirm the total price is greater than $50
|
|
2136
|
+
\`\`\`
|
|
2137
|
+
|
|
2138
|
+
AI actions are more flexible but slower and less deterministic. Prefer explicit actions when possible.
|
|
2139
|
+
|
|
2140
|
+
### Extended Step Format
|
|
2141
|
+
|
|
2142
|
+
For actions not available in simple format (like drag operations), use the extended format:
|
|
2143
|
+
|
|
2144
|
+
| Action | Description |
|
|
2145
|
+
|--------|-------------|
|
|
2146
|
+
| \`drag_and_drop\` | Drag source element to target |
|
|
2147
|
+
| \`relative_drag_and_drop\` | Drag with relative positioning |
|
|
2148
|
+
| \`mfa_totp\` | Generate and enter TOTP code |
|
|
2149
|
+
| \`set_input_files\` | Upload files |
|
|
2150
|
+
|
|
2151
|
+
#### Drag and Drop Example
|
|
2152
|
+
|
|
2153
|
+
\`\`\`yaml
|
|
2154
|
+
- type: extended
|
|
2155
|
+
name: Drag item to drop zone
|
|
2156
|
+
action:
|
|
2157
|
+
action: drag_and_drop
|
|
2158
|
+
value:
|
|
2159
|
+
target_locator: "#drop-zone" # Playwright locator string
|
|
2160
|
+
locator:
|
|
2161
|
+
chain:
|
|
2162
|
+
- method: get_by_text
|
|
2163
|
+
args: ["draggable item"]
|
|
2164
|
+
\`\`\`
|
|
2165
|
+
|
|
2166
|
+
The \`target_locator\` must be a valid Playwright locator string:
|
|
2167
|
+
- \`"#drop-zone"\` - CSS ID selector
|
|
2168
|
+
- \`".drop-area"\` - CSS class selector
|
|
2169
|
+
- \`"text=Drop here"\` - Text selector
|
|
2170
|
+
- \`"[data-testid='target']"\` - Attribute selector
|
|
2171
|
+
|
|
2172
|
+
#### TOTP Example
|
|
2173
|
+
|
|
2174
|
+
\`\`\`yaml
|
|
2175
|
+
- type: extended
|
|
2176
|
+
name: Enter MFA code
|
|
2177
|
+
action:
|
|
2178
|
+
action: mfa_totp
|
|
2179
|
+
value:
|
|
2180
|
+
target_locator: "#otp-input"
|
|
2181
|
+
locator:
|
|
2182
|
+
chain:
|
|
2183
|
+
- method: get_by_label
|
|
2184
|
+
args: ["Enter your code"]
|
|
2185
|
+
\`\`\`
|
|
2186
|
+
|
|
2187
|
+
**Tip:** Use \`qa-use test schema\` to explore all available actions and their schemas.
|
|
2188
|
+
|
|
2189
|
+
## Target Descriptions
|
|
2190
|
+
|
|
2191
|
+
The \`target\` field uses natural language descriptions:
|
|
2192
|
+
|
|
2193
|
+
\`\`\`yaml
|
|
2194
|
+
# Good - specific and unambiguous
|
|
2195
|
+
target: submit button in the login form
|
|
2196
|
+
target: email input field
|
|
2197
|
+
target: first product card
|
|
2198
|
+
target: navigation menu item labeled "Settings"
|
|
2199
|
+
|
|
2200
|
+
# Avoid - too generic
|
|
2201
|
+
target: button
|
|
2202
|
+
target: input
|
|
2203
|
+
target: link
|
|
2204
|
+
\`\`\`
|
|
2205
|
+
|
|
2206
|
+
The AI matches your description against the page's ARIA accessibility tree. Be specific enough to uniquely identify the element.
|
|
2207
|
+
|
|
2208
|
+
## Complete Example
|
|
2209
|
+
|
|
2210
|
+
\`\`\`yaml
|
|
2211
|
+
name: User Registration
|
|
2212
|
+
description: Tests the full user registration flow
|
|
2213
|
+
tags:
|
|
2214
|
+
- smoke
|
|
2215
|
+
- registration
|
|
2216
|
+
- critical
|
|
2217
|
+
app_config: my-app-config-id
|
|
2218
|
+
variables:
|
|
2219
|
+
email: newuser@example.com
|
|
2220
|
+
password: SecurePass123!
|
|
2221
|
+
name: Test User
|
|
2222
|
+
depends_on: clear-test-data
|
|
2223
|
+
|
|
2224
|
+
steps:
|
|
2225
|
+
# Navigate to registration
|
|
2226
|
+
- action: goto
|
|
2227
|
+
url: /register
|
|
2228
|
+
|
|
2229
|
+
# Fill registration form
|
|
2230
|
+
- action: fill
|
|
2231
|
+
target: name input
|
|
2232
|
+
value: $name
|
|
2233
|
+
|
|
2234
|
+
- action: fill
|
|
2235
|
+
target: email input
|
|
2236
|
+
value: $email
|
|
2237
|
+
|
|
2238
|
+
- action: fill
|
|
2239
|
+
target: password input
|
|
2240
|
+
value: $password
|
|
2241
|
+
|
|
2242
|
+
- action: fill
|
|
2243
|
+
target: confirm password input
|
|
2244
|
+
value: $password
|
|
2245
|
+
|
|
2246
|
+
# Accept terms
|
|
2247
|
+
- action: check
|
|
2248
|
+
target: terms and conditions checkbox
|
|
2249
|
+
|
|
2250
|
+
# Submit
|
|
2251
|
+
- action: click
|
|
2252
|
+
target: create account button
|
|
2253
|
+
|
|
2254
|
+
# Wait for redirect
|
|
2255
|
+
- action: wait_for_url
|
|
2256
|
+
url: /welcome
|
|
2257
|
+
|
|
2258
|
+
# Verify success
|
|
2259
|
+
- action: to_be_visible
|
|
2260
|
+
target: welcome message
|
|
2261
|
+
|
|
2262
|
+
- action: to_have_text
|
|
2263
|
+
target: user greeting
|
|
2264
|
+
value: Hello, Test User
|
|
2265
|
+
\`\`\`
|
|
2266
|
+
|
|
2267
|
+
## File Location
|
|
2268
|
+
|
|
2269
|
+
Tests should be placed in the test directory (default: \`qa-tests/\`):
|
|
2270
|
+
|
|
2271
|
+
\`\`\`
|
|
2272
|
+
qa-tests/
|
|
2273
|
+
├── login.yaml
|
|
2274
|
+
├── registration.yaml
|
|
2275
|
+
├── checkout.yaml
|
|
2276
|
+
└── setup/
|
|
2277
|
+
└── seed-data.yaml
|
|
2278
|
+
\`\`\`
|
|
2279
|
+
|
|
2280
|
+
Configure the test directory in \`.qa-use-tests.json\`:
|
|
2281
|
+
|
|
2282
|
+
\`\`\`json
|
|
2283
|
+
{
|
|
2284
|
+
"test_directory": "./qa-tests"
|
|
2285
|
+
}
|
|
2286
|
+
\`\`\`
|
|
2287
|
+
`,
|
|
2288
|
+
},
|
|
2289
|
+
};
|
|
2290
|
+
export const TEMPLATES = {
|
|
2291
|
+
'auth-flow': {
|
|
2292
|
+
title: 'Auth Flow Template',
|
|
2293
|
+
content: `# Authentication Flow Template
|
|
2294
|
+
# Login with credentials and verify dashboard access
|
|
2295
|
+
|
|
2296
|
+
name: Authentication Flow
|
|
2297
|
+
description: Login with credentials and verify successful authentication
|
|
2298
|
+
|
|
2299
|
+
# Replace with your app config ID from desplega.ai
|
|
2300
|
+
app_config: $APP_CONFIG_ID
|
|
2301
|
+
|
|
2302
|
+
# Variables for credentials
|
|
2303
|
+
# Override at runtime: qa-use test run auth-flow --var email=real@example.com
|
|
2304
|
+
variables:
|
|
2305
|
+
email: test@example.com
|
|
2306
|
+
password: "********"
|
|
2307
|
+
|
|
2308
|
+
steps:
|
|
2309
|
+
# Navigate to login page
|
|
2310
|
+
- action: goto
|
|
2311
|
+
url: /login
|
|
2312
|
+
|
|
2313
|
+
# Fill login form
|
|
2314
|
+
- action: fill
|
|
2315
|
+
target: email input
|
|
2316
|
+
value: $email
|
|
2317
|
+
|
|
2318
|
+
- action: fill
|
|
2319
|
+
target: password input
|
|
2320
|
+
value: $password
|
|
2321
|
+
|
|
2322
|
+
# Submit the form
|
|
2323
|
+
- action: click
|
|
2324
|
+
target: sign in button
|
|
2325
|
+
|
|
2326
|
+
# Wait for successful redirect
|
|
2327
|
+
- action: wait_for_url
|
|
2328
|
+
url: /dashboard
|
|
2329
|
+
|
|
2330
|
+
# Verify dashboard is visible
|
|
2331
|
+
- action: to_be_visible
|
|
2332
|
+
target: dashboard content
|
|
2333
|
+
|
|
2334
|
+
# Optional: verify user greeting
|
|
2335
|
+
# - action: to_be_visible
|
|
2336
|
+
# target: welcome message
|
|
2337
|
+
`,
|
|
2338
|
+
},
|
|
2339
|
+
'basic-test': {
|
|
2340
|
+
title: 'Basic Test Template',
|
|
2341
|
+
content: `# Basic Test Template
|
|
2342
|
+
# A simple navigation and assertion test
|
|
2343
|
+
|
|
2344
|
+
name: Basic Test
|
|
2345
|
+
description: Navigate to a page and verify an element is visible
|
|
2346
|
+
|
|
2347
|
+
# Replace with your app config ID from desplega.ai
|
|
2348
|
+
# Or set default_app_config_id in .qa-use-tests.json
|
|
2349
|
+
app_config: $APP_CONFIG_ID
|
|
2350
|
+
|
|
2351
|
+
steps:
|
|
2352
|
+
# Navigate to the starting page
|
|
2353
|
+
- action: goto
|
|
2354
|
+
url: /
|
|
2355
|
+
|
|
2356
|
+
# Verify the main content is visible
|
|
2357
|
+
- action: to_be_visible
|
|
2358
|
+
target: main content area
|
|
2359
|
+
|
|
2360
|
+
# Optional: verify page heading
|
|
2361
|
+
# - action: to_have_text
|
|
2362
|
+
# target: page heading
|
|
2363
|
+
# value: Welcome
|
|
2364
|
+
`,
|
|
2365
|
+
},
|
|
2366
|
+
'form-test': {
|
|
2367
|
+
title: 'Form Test Template',
|
|
2368
|
+
content: `# Form Submission Template
|
|
2369
|
+
# Fill out a form and verify successful submission
|
|
2370
|
+
|
|
2371
|
+
name: Form Submission
|
|
2372
|
+
description: Fill a contact form and verify submission success
|
|
2373
|
+
|
|
2374
|
+
# Replace with your app config ID from desplega.ai
|
|
2375
|
+
app_config: $APP_CONFIG_ID
|
|
2376
|
+
|
|
2377
|
+
# Variables for form data
|
|
2378
|
+
variables:
|
|
2379
|
+
name: Test User
|
|
2380
|
+
email: test@example.com
|
|
2381
|
+
message: This is a test message from automated testing.
|
|
2382
|
+
|
|
2383
|
+
steps:
|
|
2384
|
+
# Navigate to the form page
|
|
2385
|
+
- action: goto
|
|
2386
|
+
url: /contact
|
|
2387
|
+
|
|
2388
|
+
# Fill form fields
|
|
2389
|
+
- action: fill
|
|
2390
|
+
target: name input
|
|
2391
|
+
value: $name
|
|
2392
|
+
|
|
2393
|
+
- action: fill
|
|
2394
|
+
target: email input
|
|
2395
|
+
value: $email
|
|
2396
|
+
|
|
2397
|
+
- action: fill
|
|
2398
|
+
target: message textarea
|
|
2399
|
+
value: $message
|
|
2400
|
+
|
|
2401
|
+
# Optional: handle checkbox/consent
|
|
2402
|
+
# - action: check
|
|
2403
|
+
# target: consent checkbox
|
|
2404
|
+
|
|
2405
|
+
# Submit the form
|
|
2406
|
+
- action: click
|
|
2407
|
+
target: submit button
|
|
2408
|
+
|
|
2409
|
+
# Verify success
|
|
2410
|
+
- action: to_be_visible
|
|
2411
|
+
target: success message
|
|
2412
|
+
|
|
2413
|
+
# Optional: verify specific success text
|
|
2414
|
+
# - action: to_have_text
|
|
2415
|
+
# target: confirmation message
|
|
2416
|
+
# value: Thank you for your message
|
|
2417
|
+
`,
|
|
2418
|
+
},
|
|
2419
|
+
};
|
|
2420
|
+
//# sourceMappingURL=docs-content.js.map
|