testdriverai 7.3.32 → 7.3.34
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/.github/copilot-instructions.md +641 -0
- package/.github/skills/testdriver:assert/SKILL.md +31 -0
- package/.github/skills/testdriver:aws-setup/SKILL.md +1 -68
- package/.github/skills/testdriver:client/SKILL.md +33 -0
- package/.github/skills/testdriver:debugging-with-screenshots/SKILL.md +175 -45
- package/.github/skills/testdriver:find/SKILL.md +87 -0
- package/.github/skills/testdriver:parse/SKILL.md +124 -6
- package/.github/skills/testdriver:quickstart/SKILL.md +2 -17
- package/.github/skills/testdriver:reusable-code/SKILL.md +9 -0
- package/.github/skills/testdriver:running-tests/SKILL.md +4 -0
- package/.github/skills/testdriver:screenshot/SKILL.md +84 -3
- package/.github/skills/testdriver:scroll/SKILL.md +36 -0
- package/.github/skills/testdriver:testdriver/SKILL.md +194 -86
- package/CHANGELOG.md +8 -0
- package/docs/_data/examples-manifest.json +72 -64
- package/docs/v7/examples/ai.mdx +1 -1
- package/docs/v7/examples/assert.mdx +1 -1
- package/docs/v7/examples/chrome-extension.mdx +1 -1
- package/docs/v7/examples/drag-and-drop.mdx +1 -1
- package/docs/v7/examples/element-not-found.mdx +1 -1
- package/docs/v7/examples/hover-image.mdx +1 -1
- package/docs/v7/examples/hover-text.mdx +1 -1
- package/docs/v7/examples/installer.mdx +1 -1
- package/docs/v7/examples/launch-vscode-linux.mdx +1 -1
- package/docs/v7/examples/match-image.mdx +1 -1
- package/docs/v7/examples/press-keys.mdx +1 -1
- package/docs/v7/examples/scroll-keyboard.mdx +1 -1
- package/docs/v7/examples/scroll-until-image.mdx +1 -1
- package/docs/v7/examples/scroll-until-text.mdx +1 -1
- package/docs/v7/examples/scroll.mdx +1 -1
- package/docs/v7/examples/type.mdx +1 -1
- package/docs/v7/examples/windows-installer.mdx +1 -1
- package/package.json +1 -2
- package/sdk.js +1 -1
|
@@ -34,10 +34,46 @@ Use this agent when the user asks to:
|
|
|
34
34
|
4. **⚠️ WRITE CODE IMMEDIATELY**: After EVERY successful action, append the generated code to the test file RIGHT AWAY. Do NOT wait until the end.
|
|
35
35
|
5. **Verify Actions**: Use `check` after actions to verify they succeeded (for YOUR understanding only).
|
|
36
36
|
6. **Add Assertions**: Use `assert` for test conditions that should be in the final test file.
|
|
37
|
-
7. **⚠️ RUN THE TEST YOURSELF**: Use `vitest run <testFile> --reporter=dot` to run the test - do NOT tell the user to run it. Iterate until it passes.
|
|
37
|
+
7. **⚠️ RUN THE TEST YOURSELF**: Use `vitest run <testFile> --reporter=dot` to run the test - do NOT tell the user to run it. Iterate until it passes. **NEVER use `npx vitest`** - always use `vitest` directly.
|
|
38
|
+
8. **⚠️ SHARE THE TEST REPORT**: After EVERY test run, find the `TESTDRIVER_RUN_URL` in the output (e.g., `TESTDRIVER_RUN_URL=https://console.testdriver.ai/runs/...`) and share it with the user so they can view the recording and results.
|
|
38
39
|
|
|
39
40
|
## Prerequisites
|
|
40
41
|
|
|
42
|
+
### Quick Start - Creating Your First TestDriver Test
|
|
43
|
+
|
|
44
|
+
**For new projects, use the `init` command to automatically set up everything:**
|
|
45
|
+
|
|
46
|
+
**CLI:**
|
|
47
|
+
```bash
|
|
48
|
+
npx testdriverai init
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**MCP (via this agent):**
|
|
52
|
+
```
|
|
53
|
+
// apiKey is optional - if not provided, user adds it to .env manually after init
|
|
54
|
+
init({ directory: "." })
|
|
55
|
+
|
|
56
|
+
// Or with API key if available (though MCP typically won't have access to it)
|
|
57
|
+
init({ directory: ".", apiKey: "your_api_key" })
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Note:** The `apiKey` parameter is optional. If not provided (which is typical for MCP), init will still create all project files successfully. The user can manually add `TD_API_KEY=...` to the `.env` file afterward.
|
|
61
|
+
|
|
62
|
+
The `init` command creates:
|
|
63
|
+
- ✅ `package.json` with proper dependencies
|
|
64
|
+
- ✅ Example test files (`tests/example.test.js`, `tests/login.js`)
|
|
65
|
+
- ✅ `vitest.config.js` with correct timeouts
|
|
66
|
+
- ✅ `.gitignore` with `.env`
|
|
67
|
+
- ✅ GitHub Actions workflow (`.github/workflows/testdriver.yml`)
|
|
68
|
+
- ✅ VSCode MCP config (`.vscode/mcp.json`)
|
|
69
|
+
- ✅ TestDriver skills and agents in `.github/`
|
|
70
|
+
- ✅ `.env` file (user adds API key manually if not provided to init)
|
|
71
|
+
|
|
72
|
+
**After running init:**
|
|
73
|
+
1. User adds their API key to `.env`: `TD_API_KEY=...`
|
|
74
|
+
2. Test the setup: `vitest run`
|
|
75
|
+
3. Start building custom tests using the examples as templates
|
|
76
|
+
|
|
41
77
|
### API Key Setup
|
|
42
78
|
|
|
43
79
|
The user **must** have a TestDriver API key set in their environment:
|
|
@@ -49,14 +85,12 @@ TD_API_KEY=your_api_key_here
|
|
|
49
85
|
|
|
50
86
|
Get your API key at: **https://console.testdriver.ai/team**
|
|
51
87
|
|
|
52
|
-
### Installation
|
|
88
|
+
### Manual Installation
|
|
53
89
|
|
|
54
|
-
|
|
90
|
+
If not using `init`, install TestDriver:
|
|
55
91
|
|
|
56
92
|
```bash
|
|
57
|
-
npm install --save-dev testdriverai
|
|
58
|
-
# or
|
|
59
|
-
npx testdriverai@beta init
|
|
93
|
+
npm install --save-dev testdriverai
|
|
60
94
|
```
|
|
61
95
|
|
|
62
96
|
### Test Runner
|
|
@@ -96,29 +130,32 @@ import { TestDriver } from "testdriverai/vitest/hooks";
|
|
|
96
130
|
|
|
97
131
|
describe("My Test Suite", () => {
|
|
98
132
|
it("should do something", async (context) => {
|
|
99
|
-
// Initialize TestDriver
|
|
133
|
+
// Initialize TestDriver - screenshots are captured automatically before/after each command
|
|
100
134
|
const testdriver = TestDriver(context);
|
|
101
135
|
|
|
102
136
|
// Start with provision - this launches the sandbox and browser
|
|
103
137
|
await testdriver.provision.chrome({
|
|
104
138
|
url: "https://example.com",
|
|
105
139
|
});
|
|
106
|
-
await testdriver.screenshot(); // Capture initial page state
|
|
107
140
|
|
|
108
141
|
// Find elements and interact
|
|
142
|
+
// Note: Screenshots are automatically captured before/after find() and click()
|
|
109
143
|
const button = await testdriver.find("Sign In button");
|
|
110
|
-
await testdriver.screenshot(); // Capture before click
|
|
111
144
|
await button.click();
|
|
112
|
-
await testdriver.
|
|
145
|
+
await testdriver.wait(2000); // Wait for state change
|
|
113
146
|
|
|
114
147
|
// Assert using natural language
|
|
115
|
-
|
|
148
|
+
// Screenshots are automatically captured before/after assert()
|
|
116
149
|
const result = await testdriver.assert("the dashboard is visible");
|
|
117
150
|
expect(result).toBeTruthy();
|
|
118
151
|
});
|
|
119
152
|
});
|
|
120
153
|
```
|
|
121
154
|
|
|
155
|
+
<Note>
|
|
156
|
+
**Automatic Screenshots**: TestDriver captures screenshots before and after every command by default. Screenshots are saved with descriptive names like `001-click-before-L42-submit-button.png` that include the line number from your test file.
|
|
157
|
+
</Note>
|
|
158
|
+
|
|
122
159
|
## Provisioning Options
|
|
123
160
|
|
|
124
161
|
Most tests start with `testdriver.provision`.
|
|
@@ -176,38 +213,22 @@ await element.mouseUp(); // release mouse
|
|
|
176
213
|
element.found(); // check if found (boolean)
|
|
177
214
|
```
|
|
178
215
|
|
|
179
|
-
### Screenshots
|
|
216
|
+
### Automatic Screenshots (Enabled by Default)
|
|
180
217
|
|
|
181
|
-
**
|
|
218
|
+
TestDriver **automatically captures screenshots before and after every command** by default. This creates a complete visual timeline without any additional code. Screenshots are named with the line number from your test file, making it easy to trace issues:
|
|
182
219
|
|
|
183
|
-
```javascript
|
|
184
|
-
// Capture a screenshot - saved to .testdriver/screenshots/<test-file>/
|
|
185
|
-
const screenshotPath = await testdriver.screenshot();
|
|
186
|
-
console.log("Screenshot saved to:", screenshotPath);
|
|
187
|
-
|
|
188
|
-
// Include mouse cursor in screenshot
|
|
189
|
-
await testdriver.screenshot(1, false, true);
|
|
190
220
|
```
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
-
|
|
194
|
-
-
|
|
195
|
-
-
|
|
196
|
-
-
|
|
197
|
-
-
|
|
198
|
-
- When debugging a flaky or failing test
|
|
199
|
-
|
|
200
|
-
**Screenshot file organization:**
|
|
201
|
-
|
|
202
|
-
```
|
|
203
|
-
.testdriver/
|
|
204
|
-
screenshots/
|
|
205
|
-
login.test/ # Folder per test file
|
|
206
|
-
screenshot-1737633600000.png
|
|
207
|
-
checkout.test/
|
|
208
|
-
screenshot-1737633700000.png
|
|
221
|
+
.testdriver/screenshots/login.test/
|
|
222
|
+
001-find-before-L15-email-input.png
|
|
223
|
+
002-find-after-L15-email-input.png
|
|
224
|
+
003-click-before-L16-email-input.png
|
|
225
|
+
004-click-after-L16-email-input.png
|
|
226
|
+
005-type-before-L17-userexamplecom.png
|
|
227
|
+
006-type-after-L17-userexamplecom.png
|
|
209
228
|
```
|
|
210
229
|
|
|
230
|
+
**Filename format:** `<seq>-<action>-<phase>-L<line>-<description>.png`
|
|
231
|
+
|
|
211
232
|
> **Note:** The screenshot folder for each test file is automatically cleared when the test starts.
|
|
212
233
|
|
|
213
234
|
## Best Workflow: MCP Tools
|
|
@@ -224,7 +245,7 @@ await testdriver.screenshot(1, false, true);
|
|
|
224
245
|
|
|
225
246
|
**Every MCP tool response includes "ACTION REQUIRED: Append this code..." - you MUST write that code to the test file IMMEDIATELY before proceeding to the next action.**
|
|
226
247
|
|
|
227
|
-
**When ready to validate, RUN THE TEST YOURSELF using `vitest run`. Do NOT tell the user to run it
|
|
248
|
+
**When ready to validate, RUN THE TEST YOURSELF using `vitest run`. Do NOT tell the user to run it. NEVER use `npx vitest`.**
|
|
228
249
|
|
|
229
250
|
### Step 1: Start a Session
|
|
230
251
|
|
|
@@ -234,29 +255,30 @@ session_start({ type: "chrome", url: "https://your-app.com/login", testFile: "te
|
|
|
234
255
|
→ Response includes: "ACTION REQUIRED: Append this code..."
|
|
235
256
|
→ ⚠️ IMMEDIATELY write to tests/login.test.mjs:
|
|
236
257
|
await testdriver.provision.chrome({ url: "https://your-app.com/login" });
|
|
237
|
-
await testdriver.screenshot(); // Capture initial page state
|
|
238
258
|
```
|
|
239
259
|
|
|
240
260
|
This provisions a sandbox with Chrome and navigates to your URL. You'll see a screenshot of the initial page.
|
|
241
261
|
|
|
262
|
+
> **Note**: Screenshots are captured automatically before/after each command. The generated code no longer includes manual `screenshot()` calls.
|
|
263
|
+
|
|
242
264
|
### Step 2: Interact with the App
|
|
243
265
|
|
|
244
|
-
Find elements and interact with them. **Write code to file after EACH action
|
|
266
|
+
Find elements and interact with them. **Write code to file after EACH action:**
|
|
245
267
|
|
|
246
268
|
```
|
|
247
269
|
find_and_click({ description: "email input field" })
|
|
248
270
|
→ Returns: screenshot with element highlighted
|
|
249
271
|
→ ⚠️ IMMEDIATELY append to test file:
|
|
250
272
|
await testdriver.find("email input field").click();
|
|
251
|
-
await testdriver.screenshot(); // Capture after click
|
|
252
273
|
|
|
253
274
|
type({ text: "user@example.com" })
|
|
254
275
|
→ Returns: screenshot showing typed text
|
|
255
276
|
→ ⚠️ IMMEDIATELY append to test file:
|
|
256
277
|
await testdriver.type("user@example.com");
|
|
257
|
-
await testdriver.screenshot(); // Capture after typing
|
|
258
278
|
```
|
|
259
279
|
|
|
280
|
+
> **Note**: Screenshots are automatically captured before/after each command. Each screenshot filename includes the line number (e.g., `001-click-before-L42-email-input.png`).
|
|
281
|
+
|
|
260
282
|
### Step 3: Verify Actions Succeeded (For Your Understanding)
|
|
261
283
|
|
|
262
284
|
After actions, use `check` to verify they worked. This is for YOUR understanding - does NOT generate code:
|
|
@@ -274,14 +296,13 @@ Use `assert` for pass/fail conditions. This DOES generate code for the test file
|
|
|
274
296
|
assert({ assertion: "the dashboard is visible" })
|
|
275
297
|
→ Returns: pass/fail with screenshot
|
|
276
298
|
→ ⚠️ IMMEDIATELY append to test file:
|
|
277
|
-
await testdriver.screenshot(); // Capture before assertion
|
|
278
299
|
const assertResult = await testdriver.assert("the dashboard is visible");
|
|
279
300
|
expect(assertResult).toBeTruthy();
|
|
280
301
|
```
|
|
281
302
|
|
|
282
303
|
### Step 5: Run the Test Yourself
|
|
283
304
|
|
|
284
|
-
**⚠️ YOU must run the test - do NOT tell the user to run it:**
|
|
305
|
+
**⚠️ YOU must run the test - do NOT tell the user to run it. NEVER use `npx vitest` - always use `vitest` directly:**
|
|
285
306
|
|
|
286
307
|
```bash
|
|
287
308
|
vitest run tests/login.test.mjs --reporter=dot
|
|
@@ -291,7 +312,7 @@ vitest run tests/login.test.mjs --reporter=dot
|
|
|
291
312
|
|
|
292
313
|
Analyze the output, fix any issues, and iterate until the test passes.
|
|
293
314
|
|
|
294
|
-
**⚠️ ALWAYS share the test report link with the user.** After each test run, look for
|
|
315
|
+
**⚠️ ALWAYS share the test report link with the user.** After each test run, look for `TESTDRIVER_RUN_URL` in the test output (e.g., `TESTDRIVER_RUN_URL=https://console.testdriver.ai/runs/...`) and share it with the user so they can view the recording and results. This is CRITICAL - users need to see the visual recording to understand test behavior.
|
|
295
316
|
|
|
296
317
|
### MCP Tools Reference
|
|
297
318
|
|
|
@@ -310,28 +331,97 @@ Analyze the output, fix any issues, and iterate until the test passes.
|
|
|
310
331
|
| `assert` | AI-powered boolean assertion - GENERATES CODE for test files |
|
|
311
332
|
| `exec` | Execute JavaScript, shell, or PowerShell in sandbox |
|
|
312
333
|
| `screenshot` | Capture screenshot - **only use when user explicitly asks** |
|
|
313
|
-
| `list_local_screenshots` | List screenshots
|
|
334
|
+
| `list_local_screenshots` | List/filter screenshots by line, action, phase, regex, etc. |
|
|
314
335
|
| `view_local_screenshot` | View a local screenshot (returns image to AI + displays to user) |
|
|
315
336
|
|
|
316
337
|
### Debugging with Local Screenshots
|
|
317
338
|
|
|
318
|
-
After test runs (successful or failed), you can view saved screenshots to understand test behavior
|
|
339
|
+
After test runs (successful or failed), you can view saved screenshots to understand test behavior.
|
|
319
340
|
|
|
320
|
-
**
|
|
341
|
+
**Screenshot filename format:** `<seq>-<action>-<phase>-L<line>-<description>.png`
|
|
342
|
+
Example: `001-click-before-L42-submit-button.png`
|
|
343
|
+
|
|
344
|
+
**1. List all screenshots from a test:**
|
|
321
345
|
|
|
322
346
|
```
|
|
323
347
|
list_local_screenshots({ directory: "login.test" })
|
|
324
348
|
```
|
|
325
349
|
|
|
326
|
-
|
|
350
|
+
**2. Filter by line number (find what happened at a specific line):**
|
|
351
|
+
|
|
352
|
+
```
|
|
353
|
+
// Find screenshots from line 42
|
|
354
|
+
list_local_screenshots({ line: 42 })
|
|
355
|
+
|
|
356
|
+
// Find screenshots from lines 10-20
|
|
357
|
+
list_local_screenshots({ lineRange: { start: 10, end: 20 } })
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
**3. Filter by action type:**
|
|
361
|
+
|
|
362
|
+
```
|
|
363
|
+
// Find all click screenshots
|
|
364
|
+
list_local_screenshots({ action: "click" })
|
|
365
|
+
|
|
366
|
+
// Find all assertions
|
|
367
|
+
list_local_screenshots({ action: "assert" })
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
**4. Filter by phase (before/after):**
|
|
371
|
+
|
|
372
|
+
```
|
|
373
|
+
// See state BEFORE actions (useful for debugging what was visible)
|
|
374
|
+
list_local_screenshots({ phase: "before" })
|
|
375
|
+
|
|
376
|
+
// See state AFTER actions (useful for verifying results)
|
|
377
|
+
list_local_screenshots({ phase: "after" })
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
**5. Filter by regex pattern:**
|
|
381
|
+
|
|
382
|
+
```
|
|
383
|
+
// Find screenshots related to login
|
|
384
|
+
list_local_screenshots({ pattern: "login|signin" })
|
|
385
|
+
|
|
386
|
+
// Find button-related screenshots
|
|
387
|
+
list_local_screenshots({ pattern: "button.*click" })
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
**6. Filter by sequence number:**
|
|
327
391
|
|
|
328
|
-
|
|
392
|
+
```
|
|
393
|
+
// Find screenshots 1-5 (first 5 actions)
|
|
394
|
+
list_local_screenshots({ sequenceRange: { start: 1, end: 5 } })
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
**7. Sort results:**
|
|
329
398
|
|
|
330
399
|
```
|
|
331
|
-
|
|
400
|
+
// Sort by execution order (useful for understanding flow)
|
|
401
|
+
list_local_screenshots({ sortBy: "sequence" })
|
|
402
|
+
|
|
403
|
+
// Sort by line number (useful for tracing back to code)
|
|
404
|
+
list_local_screenshots({ sortBy: "line" })
|
|
405
|
+
|
|
406
|
+
// Sort by modified time (default - newest first)
|
|
407
|
+
list_local_screenshots({ sortBy: "modified" })
|
|
332
408
|
```
|
|
333
409
|
|
|
334
|
-
|
|
410
|
+
**8. Combine filters:**
|
|
411
|
+
|
|
412
|
+
```
|
|
413
|
+
// Find click screenshots at line 42
|
|
414
|
+
list_local_screenshots({ directory: "checkout.test", line: 42, action: "click" })
|
|
415
|
+
|
|
416
|
+
// Find all "before" screenshots in lines 10-30
|
|
417
|
+
list_local_screenshots({ lineRange: { start: 10, end: 30 }, phase: "before" })
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
**9. View a screenshot:**
|
|
421
|
+
|
|
422
|
+
```
|
|
423
|
+
view_local_screenshot({ path: ".testdriver/screenshots/login.test/001-click-before-L42-submit-button.png" })
|
|
424
|
+
```
|
|
335
425
|
|
|
336
426
|
**When to use screenshot viewing:**
|
|
337
427
|
|
|
@@ -340,23 +430,24 @@ This displays the screenshot to both you (the AI) and the user via MCP App.
|
|
|
340
430
|
- **Comparing test runs** - View screenshots from multiple runs to identify flaky behavior
|
|
341
431
|
- **Verifying test logic** - Before running a test, view screenshots from previous runs to understand the UI flow
|
|
342
432
|
|
|
343
|
-
**
|
|
433
|
+
**Debugging workflow example:**
|
|
344
434
|
|
|
345
435
|
```
|
|
346
|
-
# Test failed, let's
|
|
347
|
-
list_local_screenshots({
|
|
436
|
+
# Test failed at line 42, let's see what happened
|
|
437
|
+
list_local_screenshots({ line: 42 })
|
|
348
438
|
|
|
349
|
-
# View the
|
|
350
|
-
view_local_screenshot({ path: ".testdriver/screenshots/checkout.test/
|
|
351
|
-
view_local_screenshot({ path: ".testdriver/screenshots/checkout.test/
|
|
439
|
+
# View the before/after state at that line
|
|
440
|
+
view_local_screenshot({ path: ".testdriver/screenshots/checkout.test/005-click-before-L42-submit-button.png" })
|
|
441
|
+
view_local_screenshot({ path: ".testdriver/screenshots/checkout.test/006-click-after-L42-submit-button.png" })
|
|
352
442
|
|
|
353
|
-
#
|
|
443
|
+
# Check what the screen looked like before the failing action
|
|
444
|
+
list_local_screenshots({ directory: "checkout.test", phase: "before", limit: 10 })
|
|
354
445
|
```
|
|
355
446
|
|
|
356
447
|
### Tips for MCP Workflow
|
|
357
448
|
|
|
358
449
|
1. **⚠️ Write code IMMEDIATELY** - After EVERY action, append generated code to test file RIGHT AWAY
|
|
359
|
-
2. **⚠️ Run tests YOURSELF** - Use `vitest run` - do NOT tell user to run tests
|
|
450
|
+
2. **⚠️ Run tests YOURSELF** - Use `vitest run` (NEVER `npx vitest`) - do NOT tell user to run tests
|
|
360
451
|
3. **⚠️ Add screenshots liberally** - Include `await testdriver.screenshot()` after every significant action for debugging
|
|
361
452
|
4. **⚠️ Use screenshot viewing for debugging** - When tests fail, use `list_local_screenshots` and `view_local_screenshot` to understand what went wrong
|
|
362
453
|
5. **Work incrementally** - Don't try to build the entire test at once
|
|
@@ -375,27 +466,28 @@ view_local_screenshot({ path: ".testdriver/screenshots/checkout.test/before-asse
|
|
|
375
466
|
|
|
376
467
|
```javascript
|
|
377
468
|
// Development workflow example
|
|
469
|
+
// Note: Screenshots are automatically captured before/after each command!
|
|
378
470
|
it("should incrementally build test", async (context) => {
|
|
379
471
|
const testdriver = TestDriver(context);
|
|
380
472
|
await testdriver.provision.chrome({ url: "https://example.com" });
|
|
381
|
-
|
|
473
|
+
// Automatic screenshot: 001-provision-after-L3-chrome.png
|
|
382
474
|
|
|
383
475
|
// Step 1: Find and inspect
|
|
384
476
|
const element = await testdriver.find("Some button");
|
|
385
477
|
console.log("Element found:", element.found());
|
|
386
478
|
console.log("Coordinates:", element.x, element.y);
|
|
387
479
|
console.log("Confidence:", element.confidence);
|
|
388
|
-
|
|
480
|
+
// Automatic screenshot: 002-find-after-L7-some-button.png
|
|
389
481
|
|
|
390
482
|
// Step 2: Interact
|
|
391
483
|
await element.click();
|
|
392
|
-
|
|
484
|
+
// Automatic screenshot: 003-click-after-L13-element.png
|
|
393
485
|
|
|
394
|
-
// Step 3: Assert
|
|
395
|
-
await testdriver.screenshot(); // Capture before assertion
|
|
486
|
+
// Step 3: Assert
|
|
396
487
|
const result = await testdriver.assert("Something happened");
|
|
397
488
|
console.log("Assertion result:", result);
|
|
398
489
|
expect(result).toBeTruthy();
|
|
490
|
+
// Automatic screenshot: 004-assert-after-L17-something-happened.png
|
|
399
491
|
|
|
400
492
|
// Then add more steps...
|
|
401
493
|
});
|
|
@@ -413,6 +505,7 @@ const testdriver = TestDriver(context, {
|
|
|
413
505
|
resolution: "1366x768", // Sandbox resolution
|
|
414
506
|
cache: true, // Enable element caching (default: true)
|
|
415
507
|
cacheKey: "my-test", // Cache key for element finding
|
|
508
|
+
autoScreenshots: true, // Capture screenshots before/after each command (default: true)
|
|
416
509
|
});
|
|
417
510
|
```
|
|
418
511
|
|
|
@@ -453,10 +546,23 @@ await element.click();
|
|
|
453
546
|
|
|
454
547
|
### Scrolling
|
|
455
548
|
|
|
549
|
+
**⚠️ Important: Ensure proper focus before scrolling**
|
|
550
|
+
|
|
551
|
+
Scrolling requires the page or frame to be focused, not an input field or other interactive element. If an input is focused, scroll commands may not work as expected.
|
|
552
|
+
|
|
456
553
|
```javascript
|
|
554
|
+
// If you've been typing in an input, click elsewhere first
|
|
555
|
+
await testdriver.find("page background").click();
|
|
556
|
+
// Or press Escape to unfocus
|
|
557
|
+
await testdriver.pressKeys(["escape"]);
|
|
558
|
+
|
|
559
|
+
// Now scroll
|
|
457
560
|
await testdriver.scroll("down");
|
|
458
561
|
await testdriver.scrollUntilText("Footer text");
|
|
459
562
|
await testdriver.scrollUntilImage("Product image at bottom");
|
|
563
|
+
|
|
564
|
+
// If scroll is not working, try using Page Down key directly
|
|
565
|
+
await testdriver.pressKeys(["pagedown"]);
|
|
460
566
|
```
|
|
461
567
|
|
|
462
568
|
### Executing Code in Sandbox
|
|
@@ -474,35 +580,37 @@ const date = await testdriver.exec("pwsh", "Get-Date", 5000);
|
|
|
474
580
|
|
|
475
581
|
### Capturing Screenshots
|
|
476
582
|
|
|
477
|
-
**
|
|
583
|
+
**Screenshots are captured automatically** before and after each SDK command (click, type, find, assert, etc.). Each screenshot filename includes:
|
|
584
|
+
- Sequential number for chronological ordering
|
|
585
|
+
- Action name (e.g., `click`, `find`, `assert`)
|
|
586
|
+
- Phase (`before` or `after`)
|
|
587
|
+
- Line number from your test file
|
|
588
|
+
- Description from the command
|
|
478
589
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
590
|
+
Example filenames:
|
|
591
|
+
- `001-provision-after-L8-chrome.png`
|
|
592
|
+
- `002-find-before-L12-login-button.png`
|
|
593
|
+
- `003-click-after-L12-element.png`
|
|
482
594
|
|
|
483
|
-
|
|
484
|
-
await testdriver.screenshot(1, false, true);
|
|
485
|
-
|
|
486
|
-
// Recommended pattern: screenshot after every significant action
|
|
487
|
-
await testdriver.provision.chrome({ url: "https://example.com" });
|
|
488
|
-
await testdriver.screenshot(); // After page load
|
|
595
|
+
Screenshots are saved to `.testdriver/screenshots/<test-file>/`.
|
|
489
596
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
await testdriver.screenshot(); // After typing
|
|
597
|
+
To disable automatic screenshots:
|
|
598
|
+
```javascript
|
|
599
|
+
const testdriver = TestDriver(context, { autoScreenshots: false });
|
|
600
|
+
```
|
|
495
601
|
|
|
496
|
-
|
|
497
|
-
|
|
602
|
+
For manual screenshots (e.g., with mouse cursor visible):
|
|
603
|
+
```javascript
|
|
604
|
+
await testdriver.screenshot(1, false, true);
|
|
498
605
|
```
|
|
499
606
|
|
|
500
607
|
## Tips for Agents
|
|
501
608
|
|
|
502
609
|
1. **⚠️ WRITE CODE IMMEDIATELY** - After EVERY successful MCP action, append the generated code to the test file RIGHT AWAY. Do NOT wait until the session ends.
|
|
503
|
-
2. **⚠️ RUN TESTS YOURSELF** - Do NOT tell the user to run tests. YOU must run the tests using `vitest run <testFile> --reporter=dot
|
|
504
|
-
3. **⚠️
|
|
505
|
-
|
|
610
|
+
2. **⚠️ RUN TESTS YOURSELF** - Do NOT tell the user to run tests. YOU must run the tests using `vitest run <testFile> --reporter=dot` (NEVER use `npx vitest` - it breaks the reporter). Always use `--reporter=dot` for cleaner output. Analyze the output and iterate until the test passes.
|
|
611
|
+
3. **⚠️ SHARE THE TEST REPORT URL** - After EVERY test run, find `TESTDRIVER_RUN_URL=https://console.testdriver.ai/runs/...` in the output and share it with the user. This is CRITICAL - users need to view the recording to understand what happened.
|
|
612
|
+
3. **Screenshots are automatic** - TestDriver captures screenshots before/after every command by default. Each screenshot filename includes the line number (e.g., `001-click-before-L42-submit-button.png`) making it easy to trace issues.
|
|
613
|
+
4. **⚠️ USE SCREENSHOT VIEWING FOR DEBUGGING** - When tests fail, use `list_local_screenshots` and `view_local_screenshot` MCP commands to see exactly what the UI looked like. The filenames tell you which line of code triggered each screenshot.
|
|
506
614
|
5. **⚠️ NEVER USE `.wait()`** - Do NOT use any `.wait()` method. Instead, use `find()` with a `timeout` option to poll for elements, or use `assert()` / `check()` to verify state. Explicit waits are flaky and slow.
|
|
507
615
|
6. **Use MCP tools for development** - Build tests interactively with visual feedback
|
|
508
616
|
7. **Always check `sdk.d.ts`** for method signatures and types when debugging generated tests
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## [7.3.34](https://github.com/testdriverai/testdriverai/compare/v7.3.33...v7.3.34) (2026-02-24)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
## [7.3.33](https://github.com/testdriverai/testdriverai/compare/v7.3.32...v7.3.33) (2026-02-24)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
1
9
|
## [7.3.32](https://github.com/testdriverai/testdriverai/compare/v7.3.31...v7.3.32) (2026-02-20)
|
|
2
10
|
|
|
3
11
|
|