@questpie/probe 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/agent-browser-Cxuu-Zz0.js +203 -0
  2. package/dist/assert-BLP5_JwC.js +212 -0
  3. package/dist/browser-DoCXU5Bs.js +736 -0
  4. package/dist/check-Cny-3lkZ.js +41 -0
  5. package/dist/cli.d.ts +1 -0
  6. package/dist/cli.js +30 -0
  7. package/dist/codegen-BH3cUNuf.js +61 -0
  8. package/dist/compose-D5a8qHkg.js +233 -0
  9. package/dist/config-BUEMgFYN.js +89 -0
  10. package/dist/duration-D1ya1zLn.js +3 -0
  11. package/dist/duration-DUrbfMLK.js +30 -0
  12. package/dist/health-B36ufFzJ.js +62 -0
  13. package/dist/http-BZouO1Cj.js +187 -0
  14. package/dist/index.d.ts +119 -0
  15. package/dist/index.js +4 -0
  16. package/dist/init-BjTfn_-A.js +92 -0
  17. package/dist/logs-BCgur07G.js +191 -0
  18. package/dist/output-CHUjdVDf.js +38 -0
  19. package/dist/process-manager-CzexpFO4.js +229 -0
  20. package/dist/process-manager-zzltWvZ0.js +4 -0
  21. package/dist/ps-DuHF7vmE.js +39 -0
  22. package/dist/record-C4SmoPsT.js +140 -0
  23. package/dist/recordings-Cb31alos.js +158 -0
  24. package/dist/replay-Dg9PHNrg.js +171 -0
  25. package/dist/reporter-CqWc26OP.js +25 -0
  26. package/dist/restart-By3Edj5X.js +44 -0
  27. package/dist/snapshot-diff-CqXEVTAZ.js +51 -0
  28. package/dist/start-BClY6oJq.js +79 -0
  29. package/dist/state-DRTSIt_r.js +62 -0
  30. package/dist/stop-QAP6gbDe.js +47 -0
  31. package/package.json +72 -0
  32. package/skills/qprobe/SKILL.md +103 -0
  33. package/skills/qprobe/references/browser.md +201 -0
  34. package/skills/qprobe/references/compose.md +128 -0
  35. package/skills/qprobe/references/http.md +151 -0
  36. package/skills/qprobe/references/process.md +114 -0
  37. package/skills/qprobe/references/recording.md +194 -0
  38. package/skills/qprobe-browser/SKILL.md +87 -0
  39. package/skills/qprobe-compose/SKILL.md +81 -0
  40. package/skills/qprobe-http/SKILL.md +67 -0
  41. package/skills/qprobe-process/SKILL.md +58 -0
  42. package/skills/qprobe-recording/SKILL.md +63 -0
  43. package/skills/qprobe-ux/SKILL.md +250 -0
@@ -0,0 +1,194 @@
1
+ # Recording & Replay Reference
2
+
3
+ Record browser interactions → generate Playwright tests → replay without AI tokens.
4
+
5
+ ## Recording
6
+
7
+ ```bash
8
+ qprobe record start "<n>" # begin recording
9
+ # ... perform browser and http actions ...
10
+ qprobe record stop # save + generate Playwright test
11
+ qprobe record cancel # discard without saving
12
+ ```
13
+
14
+ During recording, ALL `qprobe browser` and `qprobe http` commands are automatically captured. Each step records:
15
+
16
+ - Action type (navigate, click, fill, etc.)
17
+ - `@e` ref (short-term, for current session)
18
+ - CSS selector (long-term, resolved from ref, for Playwright replay)
19
+ - Values, URLs, expected states
20
+ - Before/after snapshots (optional)
21
+
22
+ ### Example Recording Session
23
+
24
+ ```bash
25
+ qprobe record start "create-user"
26
+
27
+ qprobe browser open /admin/users
28
+ qprobe browser snapshot -i
29
+ # - link "Add User" [@e3]
30
+ # - table (5 rows) [@e4]
31
+
32
+ qprobe browser click @e3
33
+ qprobe browser wait --url "/admin/users/new"
34
+ qprobe browser snapshot -i
35
+ # - textbox "Name" [@e5]
36
+ # - textbox "Email" [@e6]
37
+ # - select "Role" [@e7]
38
+ # - button "Save" [@e8]
39
+
40
+ qprobe browser fill @e5 "Test User"
41
+ qprobe browser fill @e6 "test@example.com"
42
+ qprobe browser select @e7 "editor"
43
+ qprobe browser click @e8
44
+ qprobe browser wait --url "/admin/users"
45
+ qprobe browser wait --text "Test User"
46
+ qprobe assert text "Test User"
47
+ qprobe assert no-errors
48
+
49
+ qprobe record stop
50
+ # ✅ Recording saved: tests/qprobe/recordings/create-user.json (8 steps)
51
+ # ✅ Playwright test: tests/qprobe/recordings/create-user.spec.ts
52
+ ```
53
+
54
+ ### Generated Playwright Test
55
+
56
+ ```typescript
57
+ // tests/qprobe/recordings/create-user.spec.ts
58
+ import { test, expect } from '@playwright/test'
59
+
60
+ test('create-user', async ({ page }) => {
61
+ await page.goto('/admin/users')
62
+ await page.locator('a:has-text("Add User")').click()
63
+ await page.waitForURL('**/admin/users/new')
64
+ await page.locator('input[name="name"]').fill('Test User')
65
+ await page.locator('input[name="email"]').fill('test@example.com')
66
+ await page.locator('select[name="role"]').selectOption('editor')
67
+ await page.locator('button:has-text("Save")').click()
68
+ await page.waitForURL('**/admin/users')
69
+ await expect(page.locator('body')).toContainText('Test User')
70
+ })
71
+ ```
72
+
73
+ This test runs with **pure Playwright** — no AI, no LLM calls, no tokens.
74
+
75
+ ## Replay
76
+
77
+ ```bash
78
+ qprobe replay "<n>" # run single recording
79
+ qprobe replay --all # run all recordings
80
+ ```
81
+
82
+ | Flag | Description |
83
+ |------|-------------|
84
+ | `--headed` | Show visible browser |
85
+ | `--browser <name>` | `chromium`, `firefox`, `webkit` |
86
+ | `--parallel` | Run tests in parallel |
87
+ | `--report` | Generate HTML report |
88
+ | `--base <url>` | Override baseUrl |
89
+ | `--retries <n>` | Retry count for flaky tests |
90
+ | `--grep "<pattern>"` | Filter tests by name |
91
+
92
+ ### Examples
93
+
94
+ ```bash
95
+ # Run single test
96
+ qprobe replay "create-user"
97
+ # ✅ create-user passed (2.1s)
98
+
99
+ # Run all with visible browser
100
+ qprobe replay --all --headed
101
+
102
+ # Cross-browser
103
+ qprobe replay --all --browser firefox
104
+
105
+ # CI mode with report
106
+ qprobe replay --all --report --retries 2
107
+ # ✅ 5/5 tests passed
108
+ # 📄 Report: tests/qprobe/report/index.html
109
+
110
+ # Against staging
111
+ qprobe replay --all --base https://staging.myapp.com
112
+ ```
113
+
114
+ ## Managing Recordings
115
+
116
+ ```bash
117
+ qprobe recordings list # list all recordings
118
+ # NAME STEPS CREATED
119
+ # login-flow 5 2026-03-24
120
+ # create-user 8 2026-03-24
121
+ # delete-user 4 2026-03-25
122
+
123
+ qprobe recordings show "create-user" # show steps
124
+ # 1. navigate → /admin/users
125
+ # 2. click → a:has-text("Add User")
126
+ # 3. waitForUrl → /admin/users/new
127
+ # 4. fill → input[name="name"] = "Test User"
128
+ # 5. fill → input[name="email"] = "test@example.com"
129
+ # 6. select → select[name="role"] = "editor"
130
+ # 7. click → button:has-text("Save")
131
+ # 8. assert → body contains "Test User"
132
+
133
+ qprobe recordings delete "old-test" # delete recording + spec
134
+
135
+ qprobe recordings export "create-user" # export as standalone Playwright project
136
+ # Exports to: tests/qprobe/export/create-user/
137
+ # Includes: package.json, playwright.config.ts, test file
138
+ # Run with: cd tests/qprobe/export/create-user && npm test
139
+ ```
140
+
141
+ ## Recording Format
142
+
143
+ `tests/qprobe/recordings/create-user.json`:
144
+
145
+ ```json
146
+ {
147
+ "name": "create-user",
148
+ "created": "2026-03-24T14:30:00Z",
149
+ "baseUrl": "http://localhost:3000",
150
+ "steps": [
151
+ {
152
+ "action": "navigate",
153
+ "url": "/admin/users",
154
+ "timestamp": "2026-03-24T14:30:01Z"
155
+ },
156
+ {
157
+ "action": "click",
158
+ "ref": "@e3",
159
+ "selector": "a:has-text(\"Add User\")",
160
+ "timestamp": "2026-03-24T14:30:03Z"
161
+ },
162
+ {
163
+ "action": "fill",
164
+ "ref": "@e5",
165
+ "selector": "input[name=\"name\"]",
166
+ "value": "Test User"
167
+ }
168
+ ]
169
+ }
170
+ ```
171
+
172
+ Key insight: `ref` is for the agent's current session. `selector` is the resolved CSS selector for Playwright. Both are captured during recording so the test works independently.
173
+
174
+ ## File Structure
175
+
176
+ ```
177
+ tests/qprobe/
178
+ ├── recordings/
179
+ │ ├── login-flow.json
180
+ │ ├── login-flow.spec.ts
181
+ │ ├── create-user.json
182
+ │ └── create-user.spec.ts
183
+ ├── snapshots/ # optional a11y snapshots
184
+ └── playwright.config.ts # auto-generated
185
+ ```
186
+
187
+ ## Tips
188
+
189
+ - **Record important flows early** — login, CRUD, critical paths
190
+ - **Replay is free** — zero AI tokens, runs in <5s per test
191
+ - **Run `qprobe replay --all` after every code change** for instant regression
192
+ - **Export recordings** to share with team or run in CI
193
+ - **Edit generated .spec.ts** files to add custom assertions
194
+ - **Use `--retries 2`** for network-dependent tests that may be flaky
@@ -0,0 +1,87 @@
1
+ ---
2
+ name: qprobe-browser
3
+ description: "QUESTPIE Probe browser control. Accessibility tree snapshots with @e refs, click, fill, screenshot, console logs, network monitoring, JS errors, snapshot diffs. Powered by agent-browser. Use when: testing web UI, checking browser console, inspecting network requests, taking screenshots, filling forms, clicking buttons, checking for JS errors. Triggers: 'open the browser', 'check the page', 'click the button', 'fill the form', 'any console errors', 'network tab', 'screenshot', 'what does the page look like'. Use even for 'check if the UI works' or 'test the frontend'."
4
+ ---
5
+
6
+ # qprobe — Browser Control
7
+
8
+ Token-efficient browser automation via accessibility tree snapshots and `@e` refs.
9
+
10
+ **Install:** `npm install -g @questpie/probe`
11
+
12
+ ## Core Workflow
13
+
14
+ ```bash
15
+ qprobe browser open http://localhost:3000/login
16
+ qprobe browser snapshot -i # interactive elements only (~200 tokens)
17
+ # - textbox "Email" [@e1]
18
+ # - textbox "Password" [@e2]
19
+ # - button "Sign In" [@e3]
20
+
21
+ qprobe browser fill @e1 "admin@test.com"
22
+ qprobe browser fill @e2 "password123"
23
+ qprobe browser click @e3
24
+ qprobe browser wait --url "/dashboard"
25
+ qprobe browser snapshot --diff # only what changed
26
+ ```
27
+
28
+ ## Snapshot Flags
29
+
30
+ | Flag | Short | Effect |
31
+ |------|-------|--------|
32
+ | `--interactive` | `-i` | Only buttons, inputs, links (recommended) |
33
+ | `--compact` | `-c` | Remove empty structural elements |
34
+ | `--depth <n>` | `-d` | Limit tree depth |
35
+ | `--selector <css>` | `-s` | Scope to element |
36
+ | `--diff` | | Show changes since last snapshot |
37
+
38
+ **Always use `-i` by default.** Full snapshots waste tokens on decorative elements.
39
+
40
+ ## Interaction (via @e refs or CSS selectors)
41
+
42
+ ```bash
43
+ qprobe browser click @e3
44
+ qprobe browser fill @e1 "text"
45
+ qprobe browser select @e4 "value"
46
+ qprobe browser check @e5
47
+ qprobe browser press Enter
48
+ qprobe browser type "hello"
49
+ qprobe browser hover @e2
50
+ qprobe browser scroll down 500
51
+ ```
52
+
53
+ ## Inspection (NO BROWSER WINDOW NEEDED)
54
+
55
+ ```bash
56
+ qprobe browser console # console messages (log, warn, error)
57
+ qprobe browser console --level error # only errors
58
+ qprobe browser errors # uncaught JS exceptions
59
+ qprobe browser network # HTTP request log
60
+ qprobe browser network --failed # only 4xx/5xx
61
+ qprobe browser eval "document.title" # execute JS
62
+ qprobe browser text "#main" # extract text content
63
+ ```
64
+
65
+ ## Screenshots
66
+
67
+ ```bash
68
+ qprobe browser screenshot # basic
69
+ qprobe browser screenshot --annotate # with @e labels overlaid
70
+ qprobe browser screenshot --full # full page scroll
71
+ ```
72
+
73
+ ## Waiting
74
+
75
+ ```bash
76
+ qprobe browser wait @e1 # element exists
77
+ qprobe browser wait --url "/dashboard" # URL changed
78
+ qprobe browser wait --text "Welcome" # text appeared
79
+ qprobe browser wait --network idle # no pending requests
80
+ ```
81
+
82
+ ## Tips for Agents
83
+
84
+ - `snapshot -i` saves tokens — use it always
85
+ - `snapshot --diff` after actions — see only changes
86
+ - Check `console --level error` and `network --failed` before visual debugging
87
+ - `screenshot --annotate` is useful when you need visual context
@@ -0,0 +1,81 @@
1
+ ---
2
+ name: qprobe-compose
3
+ description: "QUESTPIE Probe compose — multi-service orchestration with dependency graphs. Start DB, server, admin, workers in correct order with health checks. Config via qprobe.config.ts. Use when: starting a full dev stack, managing multiple services, need database + server + frontend running together. Triggers: 'start everything', 'compose up', 'start the stack', 'bring up the dev environment', 'start db and server'. Use when project has multiple services that need to start in order."
4
+ ---
5
+
6
+ # qprobe — Compose
7
+
8
+ Multi-service orchestration with dependency resolution and health checks.
9
+
10
+ **Install:** `npm install -g @questpie/probe`
11
+
12
+ ## Usage
13
+
14
+ ```bash
15
+ qprobe compose up # start all services in dependency order
16
+ qprobe compose down # stop all in reverse order
17
+ qprobe compose restart # restart all
18
+ qprobe compose status # show service states
19
+ ```
20
+
21
+ ## Config (`qprobe.config.ts`)
22
+
23
+ ```typescript
24
+ import { defineConfig } from '@questpie/probe'
25
+
26
+ export default defineConfig({
27
+ services: {
28
+ db: {
29
+ cmd: 'docker compose up postgres',
30
+ ready: 'ready to accept connections',
31
+ },
32
+ server: {
33
+ cmd: 'bun dev',
34
+ ready: 'ready on http://localhost:3000',
35
+ port: 3000,
36
+ health: '/api/health',
37
+ depends: ['db'],
38
+ },
39
+ admin: {
40
+ cmd: 'bun run admin:dev',
41
+ ready: 'ready on http://localhost:3001',
42
+ port: 3001,
43
+ depends: ['server'],
44
+ },
45
+ },
46
+ })
47
+ ```
48
+
49
+ ## What Happens
50
+
51
+ ```bash
52
+ qprobe compose up
53
+ # ⏳ Starting db... ready (2.3s)
54
+ # ⏳ Starting server... ready (4.1s) ← waited for db first
55
+ # ⏳ Starting admin... ready (3.5s) ← waited for server first
56
+ # ✅ All 3 services ready (9.9s)
57
+ ```
58
+
59
+ Dependency graph resolved automatically. Parallel start where possible.
60
+
61
+ ## Flags
62
+
63
+ | Flag | Description |
64
+ |------|-------------|
65
+ | `--only <names>` | Start only these (+ dependencies) |
66
+ | `--skip <names>` | Skip these services |
67
+ | `--no-health` | Don't wait for health checks |
68
+
69
+ ```bash
70
+ qprobe compose up --only server # starts db (dep) + server
71
+ qprobe compose up --skip admin # starts db + server, skips admin
72
+ ```
73
+
74
+ ## Inline (No Config File)
75
+
76
+ ```bash
77
+ qprobe compose up \
78
+ --service "db: docker compose up postgres | ready to accept" \
79
+ --service "server: bun dev | ready on" \
80
+ --depends "server:db"
81
+ ```
@@ -0,0 +1,67 @@
1
+ ---
2
+ name: qprobe-http
3
+ description: "QUESTPIE Probe HTTP requests. Send API requests against running dev servers with auto baseUrl, Bearer auth, status assertions, JQ filtering, verbose mode. Cheaper than browser for API testing. Use when: testing API endpoints, checking server responses, CRUD operations, verifying auth, debugging 500 errors. Triggers: 'call the API', 'test the endpoint', 'POST to /api/users', 'check if the API works', 'what does the server return', 'send a request'. Prefer this over browser for any API-only testing."
4
+ ---
5
+
6
+ # qprobe — HTTP Requests
7
+
8
+ API testing with auto-resolved baseUrl. Cheaper than browser for backend testing.
9
+
10
+ **Install:** `npm install -g @questpie/probe`
11
+
12
+ ## Usage
13
+
14
+ ```bash
15
+ qprobe http <METHOD> <path> [flags]
16
+ ```
17
+
18
+ Path is relative — baseUrl auto-resolved from config or running services.
19
+
20
+ ## Examples
21
+
22
+ ```bash
23
+ # Basic
24
+ qprobe http GET /api/users
25
+ qprobe http GET /api/users/1
26
+
27
+ # POST with body
28
+ qprobe http POST /api/users -d '{"name":"New","email":"new@test.com"}'
29
+
30
+ # Auth
31
+ qprobe http GET /api/admin/stats --token "eyJhbGci..."
32
+ qprobe http GET /api/data -H "X-API-Key: abc123"
33
+
34
+ # Assert status (exit 1 if different)
35
+ qprobe http GET /api/health --status 200
36
+ qprobe http DELETE /api/users/1 --status 204
37
+
38
+ # Filter response
39
+ qprobe http GET /api/users --jq ".[0].name"
40
+ qprobe http GET /api/stats --jq ".revenue.total"
41
+
42
+ # Verbose (show headers)
43
+ qprobe http POST /api/login -d '{"email":"a@b.com","pass":"123"}' -v
44
+
45
+ # Raw output (for piping)
46
+ qprobe http GET /api/users --raw | jq '.[].email'
47
+ ```
48
+
49
+ ## Flags
50
+
51
+ | Flag | Short | Description |
52
+ |------|-------|-------------|
53
+ | `--data <json>` | `-d` | JSON request body |
54
+ | `--header <k:v>` | `-H` | Header (repeatable) |
55
+ | `--token <jwt>` | | Bearer auth shortcut |
56
+ | `--status <code>` | | Assert expected status |
57
+ | `--jq <expr>` | | JQ filter on response |
58
+ | `--raw` | | No formatting (for pipes) |
59
+ | `--verbose` | `-v` | Full request/response headers |
60
+ | `--base <url>` | | Override baseUrl |
61
+
62
+ ## Tips
63
+
64
+ - **Use `qprobe http` instead of browser** for API testing — much cheaper on tokens
65
+ - **`--status` for assertions** — `qprobe http GET /api/health --status 200`
66
+ - **`--jq` for extraction** — `qprobe http GET /api/me --jq ".user.role"`
67
+ - **Chain with login** — extract token, use in subsequent requests
@@ -0,0 +1,58 @@
1
+ ---
2
+ name: qprobe-process
3
+ description: "QUESTPIE Probe process management. Start dev servers with ready-pattern detection, stop, restart, health checks, list running processes. Use when: starting a dev server, checking if server is running, waiting for service to be ready, restarting after code change. Triggers: 'start the server', 'bun dev', 'is it running', 'restart', 'health check', 'wait for ready', 'server crashed'. Use even when user just says 'run it' or 'start it up' in context of a dev project."
4
+ ---
5
+
6
+ # qprobe — Process Management
7
+
8
+ Start dev servers with ready-pattern detection, health checks, and lifecycle management.
9
+
10
+ **Install:** `npm install -g @questpie/probe`
11
+
12
+ ## Commands
13
+
14
+ ```bash
15
+ # Start with ready detection
16
+ qprobe start <n> "<cmd>" --ready "<pattern>" [--port <n>] [--timeout 60s]
17
+
18
+ # Examples
19
+ qprobe start server "bun dev" --ready "ready on" --port 3000
20
+ qprobe start db "docker compose up postgres" --ready "ready to accept"
21
+
22
+ # Lifecycle
23
+ qprobe stop <n|--all>
24
+ qprobe restart <n>
25
+ qprobe ps # list running processes
26
+ qprobe ps --json # machine-readable
27
+
28
+ # Health check — poll URL until 200
29
+ qprobe health http://localhost:3000/api/health --timeout 30s
30
+
31
+ # Read logs
32
+ qprobe logs <n> # last 50 lines
33
+ qprobe logs <n> --follow # tail -f
34
+ qprobe logs <n> --grep "ERROR"
35
+ qprobe logs --all # all processes merged
36
+ ```
37
+
38
+ ## How It Works
39
+
40
+ - Spawns child process as daemon (survives between CLI calls)
41
+ - Pipes stdout/stderr to `tmp/qprobe/logs/<n>.log` (timestamped)
42
+ - Monitors output for `--ready` pattern, returns when matched
43
+ - PID saved to `tmp/qprobe/pids/<n>.pid`
44
+ - `qprobe stop` sends SIGTERM → SIGKILL after 5s
45
+
46
+ ## Common Patterns
47
+
48
+ ```bash
49
+ # Start, wait, test
50
+ qprobe start server "bun dev" --ready "ready on" --port 3000
51
+ qprobe health http://localhost:3000/api/health
52
+ qprobe http GET /api/users
53
+
54
+ # Check what crashed
55
+ qprobe ps
56
+ qprobe logs server --lines 100 --grep "ERROR"
57
+ qprobe restart server
58
+ ```
@@ -0,0 +1,63 @@
1
+ ---
2
+ name: qprobe-recording
3
+ description: "QUESTPIE Probe test recording and replay. Record browser interactions, auto-generate Playwright tests, replay without AI tokens for regression testing. Use when: recording a test flow, creating regression tests, replaying tests, running test suite, checking for regressions after code changes. Triggers: 'record a test', 'save this as a test', 'replay tests', 'run regression', 'check if it still works', 'run all tests'. Use whenever user wants to capture a flow for future verification."
4
+ ---
5
+
6
+ # qprobe — Recording & Replay
7
+
8
+ Record browser flows → generate Playwright tests → replay with zero AI tokens.
9
+
10
+ **Install:** `npm install -g @questpie/probe`
11
+
12
+ ## Record
13
+
14
+ ```bash
15
+ qprobe record start "login-flow"
16
+ # ... do browser actions (they're automatically captured) ...
17
+ qprobe browser open /login
18
+ qprobe browser fill @e1 "admin@test.com"
19
+ qprobe browser fill @e2 "password123"
20
+ qprobe browser click @e3
21
+ qprobe browser wait --url "/dashboard"
22
+ qprobe assert text "Dashboard"
23
+ qprobe record stop
24
+ # ✅ Recording saved: tests/qprobe/recordings/login-flow.json
25
+ # ✅ Playwright test: tests/qprobe/recordings/login-flow.spec.ts
26
+ ```
27
+
28
+ ## Replay (Zero AI Tokens)
29
+
30
+ ```bash
31
+ qprobe replay "login-flow" # run one test
32
+ qprobe replay --all # run all recordings
33
+ qprobe replay --all --headed # visible browser
34
+ qprobe replay --all --browser firefox # cross-browser
35
+ qprobe replay --all --report # HTML report
36
+ qprobe replay --all --retries 2 # retry flaky tests
37
+ qprobe replay --all --base https://staging.myapp.com # against staging
38
+ ```
39
+
40
+ ## Manage Recordings
41
+
42
+ ```bash
43
+ qprobe recordings list # list all
44
+ qprobe recordings show "login-flow" # show steps
45
+ qprobe recordings delete "old-test" # delete
46
+ qprobe recordings export "login-flow" # standalone Playwright project
47
+ ```
48
+
49
+ ## How It Works
50
+
51
+ 1. `record start` activates capture mode
52
+ 2. Every `qprobe browser` command is recorded with both `@e` ref AND CSS selector
53
+ 3. `record stop` saves JSON recording + generates `.spec.ts` Playwright test
54
+ 4. `replay` runs the Playwright test directly — no AI, no LLM, no tokens
55
+ 5. Tests are committed to repo in `tests/qprobe/recordings/`
56
+
57
+ ## Tips
58
+
59
+ - **Record early** — capture login, CRUD, critical paths as you build them
60
+ - **Replay after every change** — `qprobe replay --all` catches regressions instantly
61
+ - **Replay is free** — pure Playwright, runs in <5s per test
62
+ - **Edit `.spec.ts`** to add custom assertions beyond what was recorded
63
+ - **Export for CI** — `qprobe recordings export` creates standalone test project