@testdriverai/agent 7.11.229-test → 7.11.231-test
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/docs/_data/examples-manifest.json +16 -16
- package/docs/_scripts/generate-examples.js +38 -45
- package/docs/agent.mdx +174 -93
- package/docs/assert.mdx +73 -269
- package/docs/aws-setup.mdx +196 -314
- package/docs/bring-your-own-machine.mdx +139 -206
- package/docs/cache.mdx +144 -151
- package/docs/caching.mdx +99 -89
- package/docs/captcha.mdx +126 -111
- package/docs/ci-cd.mdx +154 -543
- package/docs/click.mdx +74 -229
- package/docs/client.mdx +177 -231
- package/docs/copilot/auto-healing.mdx +86 -370
- package/docs/copilot/running-tests.mdx +121 -930
- package/docs/customizing-devices.mdx +74 -251
- package/docs/dashcam.mdx +72 -405
- package/docs/debugging-with-screenshots.mdx +105 -371
- package/docs/docs.json +75 -18
- package/docs/double-click.mdx +48 -68
- package/docs/errors.mdx +102 -176
- package/docs/events.mdx +170 -327
- package/docs/examples/{hover-text-with-description.mdx → add-to-cart.mdx} +30 -35
- package/docs/examples/assert.mdx +28 -41
- package/docs/examples/click-button.mdx +71 -0
- package/docs/examples/{hover-image.mdx → click-icon.mdx} +32 -28
- package/docs/examples/element-not-found.mdx +27 -26
- package/docs/examples/findall-coffee-icons.mdx +28 -32
- package/docs/examples/installer.mdx +61 -25
- package/docs/examples/launch-vscode-linux.mdx +28 -51
- package/docs/examples/navigate-and-scroll.mdx +82 -0
- package/docs/examples/parse.mdx +24 -28
- package/docs/examples/press-keys.mdx +28 -25
- package/docs/examples/scroll.mdx +25 -27
- package/docs/examples/type.mdx +26 -21
- package/docs/exec.mdx +92 -256
- package/docs/extract.mdx +69 -170
- package/docs/find.mdx +140 -736
- package/docs/focus-application.mdx +69 -246
- package/docs/generating-tests.mdx +103 -137
- package/docs/guide/best-practices-polling.mdx +65 -141
- package/docs/hosted.mdx +80 -144
- package/docs/hover.mdx +62 -235
- package/docs/locating-elements.mdx +74 -369
- package/docs/making-assertions.mdx +116 -74
- package/docs/mcp-setup.mdx +80 -63
- package/docs/mouse-down.mdx +48 -125
- package/docs/mouse-up.mdx +47 -129
- package/docs/options.mdx +75 -48
- package/docs/parse.mdx +95 -184
- package/docs/performing-actions.mdx +104 -94
- package/docs/press-keys.mdx +59 -299
- package/docs/provision.mdx +137 -182
- package/docs/quickstart-claude.mdx +85 -0
- package/docs/quickstart-github.mdx +62 -32
- package/docs/quickstart-manual.mdx +60 -33
- package/docs/quickstart-vscode.mdx +97 -0
- package/docs/quickstart.mdx +25 -9
- package/docs/redraw.mdx +101 -165
- package/docs/reusable-code.mdx +97 -200
- package/docs/right-click.mdx +47 -89
- package/docs/screenshot.mdx +47 -201
- package/docs/screenshots.mdx +87 -137
- package/docs/scroll.mdx +71 -154
- package/docs/secrets.mdx +96 -91
- package/docs/self-hosted.mdx +83 -142
- package/docs/snippets/enterprise.mdx +15 -0
- package/docs/styles.css +68 -0
- package/docs/test-results-json.mdx +167 -204
- package/docs/type.mdx +56 -304
- package/docs/variables.mdx +121 -81
- package/docs/wait.mdx +33 -31
- package/docs/what-is-testdriver.mdx +80 -32
- package/examples/{hover-text-with-description.test.mjs → add-to-cart.test.mjs} +4 -5
- package/examples/assert.test.mjs +3 -20
- package/examples/{hover-text.test.mjs → click-button.test.mjs} +3 -4
- package/examples/{hover-image.test.mjs → click-icon.test.mjs} +5 -6
- package/examples/element-not-found.test.mjs +3 -5
- package/examples/findall-coffee-icons.test.mjs +3 -3
- package/examples/installer.test.mjs +1 -1
- package/examples/launch-vscode-linux.test.mjs +6 -33
- package/examples/{scroll-keyboard.test.mjs → navigate-and-scroll.test.mjs} +4 -5
- package/examples/parse.test.mjs +1 -2
- package/examples/press-keys.test.mjs +4 -4
- package/examples/scroll.test.mjs +3 -6
- package/examples/type.test.mjs +5 -2
- package/lib/provision.js +6 -2
- package/package.json +1 -1
- package/sdk.d.ts +4 -2
- package/sdk.js +1 -1
- package/docs/claude-mcp-plugin.mdx +0 -244
- package/docs/elements.mdx +0 -606
- package/docs/examples/ai.mdx +0 -78
- package/docs/examples/captcha-api.mdx +0 -92
- package/docs/examples/chrome-extension.mdx +0 -156
- package/docs/examples/drag-and-drop.mdx +0 -100
- package/docs/examples/formatted-logging.mdx +0 -74
- package/docs/examples/hover-text.mdx +0 -70
- package/docs/examples/match-image.mdx +0 -97
- package/docs/examples/scroll-keyboard.mdx +0 -80
- package/docs/examples/scroll-until-text.mdx +0 -109
package/docs/screenshot.mdx
CHANGED
|
@@ -1,249 +1,95 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "screenshot()"
|
|
3
3
|
sidebarTitle: "screenshot"
|
|
4
|
-
description: "
|
|
4
|
+
description: "Save a screenshot of the sandbox screen to a PNG file in your project."
|
|
5
5
|
icon: "camera"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Save what the sandbox screen shows right now as a PNG file. Use it to record a checkpoint you want to look at later.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
```javascript
|
|
11
|
+
const screenshotPath = await testdriver.screenshot('cart-before-checkout');
|
|
12
|
+
```
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
**Automatic Screenshots**: TestDriver can capture screenshots automatically before and after each command (click, type, find, and more). It saves them with clear filenames such as `001-click-before-L42-submit-button.png`. The filename includes the line number from your test file. Enable this with `autoScreenshots: true` in your TestDriver options.
|
|
14
|
-
</Note>
|
|
14
|
+
To capture every step without calling it yourself, turn on `autoScreenshots` instead. See [Screenshots](/screenshots).
|
|
15
15
|
|
|
16
|
-
##
|
|
16
|
+
## Signature
|
|
17
17
|
|
|
18
|
-
```
|
|
19
|
-
|
|
18
|
+
```typescript
|
|
19
|
+
testdriver.screenshot(filename?: string): Promise<string>
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
## Parameters
|
|
23
23
|
|
|
24
|
-
<ParamField path="filename" type="string"
|
|
25
|
-
|
|
24
|
+
<ParamField path="filename" type="string">
|
|
25
|
+
The file name. TestDriver adds `.png` if it's missing. Without it, the file is named `screenshot-<timestamp>.png`.
|
|
26
26
|
</ParamField>
|
|
27
27
|
|
|
28
28
|
## Returns
|
|
29
29
|
|
|
30
|
-
`Promise<string
|
|
30
|
+
`Promise<string>`. The absolute path of the saved file.
|
|
31
31
|
|
|
32
|
-
##
|
|
32
|
+
## Where files are saved
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
Screenshots go to `.testdriver/screenshots/<test file>/` in the directory you run tests from. `<test file>` is the test file's name without its last extension, so `tests/login.test.mjs` saves to `.testdriver/screenshots/login.test/`.
|
|
35
35
|
|
|
36
|
-
```
|
|
37
|
-
.testdriver/
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
001-find-before-L15-email-input.png # Auto: before find()
|
|
41
|
-
002-find-after-L15-email-input.png # Auto: after find()
|
|
42
|
-
003-click-before-L16-email-input.png # Auto: before click()
|
|
43
|
-
004-click-after-L16-email-input.png # Auto: after click()
|
|
44
|
-
005-type-before-L17-userexamplecom.png # Auto: before type()
|
|
45
|
-
006-type-after-L17-userexamplecom.png # Auto: after type()
|
|
46
|
-
custom-screenshot.png # Manual: screenshot("custom-screenshot")
|
|
47
|
-
checkout.test/
|
|
48
|
-
001-find-before-L12-checkout-button.png
|
|
49
|
-
...
|
|
36
|
+
```text
|
|
37
|
+
.testdriver/screenshots/login.test/
|
|
38
|
+
cart-before-checkout.png
|
|
39
|
+
screenshot-1729512345678.png
|
|
50
40
|
```
|
|
51
41
|
|
|
52
|
-
|
|
42
|
+
<Warning>
|
|
43
|
+
TestDriver clears each test file's folder at the start of every run. Copy any screenshot you want to keep.
|
|
44
|
+
</Warning>
|
|
53
45
|
|
|
54
|
-
|
|
46
|
+
Add the folder to `.gitignore`:
|
|
55
47
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|-----------|-------------|---------|
|
|
60
|
-
| `seq` | Sequential number (001, 002, ...) | `001` |
|
|
61
|
-
| `action` | Command name | `click`, `type`, `find` |
|
|
62
|
-
| `phase` | Before, after, or error | `before`, `after` |
|
|
63
|
-
| `L<line>` | Line number from test file | `L42` |
|
|
64
|
-
| `description` | Element description or action target | `submit-button` |
|
|
65
|
-
|
|
66
|
-
<Note>
|
|
67
|
-
The screenshot folder for each test file is automatically cleared when the test starts. This ensures you only see screenshots from the most recent test run.
|
|
68
|
-
</Note>
|
|
48
|
+
```text .gitignore
|
|
49
|
+
.testdriver/screenshots/
|
|
50
|
+
```
|
|
69
51
|
|
|
70
52
|
## Examples
|
|
71
53
|
|
|
72
|
-
###
|
|
54
|
+
### Save a named checkpoint
|
|
73
55
|
|
|
74
56
|
```javascript
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
console.log('Screenshot saved to:', screenshotPath);
|
|
57
|
+
await testdriver.find('Checkout button').click();
|
|
58
|
+
await testdriver.screenshot('checkout-page');
|
|
78
59
|
```
|
|
79
60
|
|
|
80
|
-
###
|
|
61
|
+
### Log the path
|
|
81
62
|
|
|
82
63
|
```javascript
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
//
|
|
86
|
-
|
|
87
|
-
await testdriver.screenshot("after-click");
|
|
88
|
-
// Saves to: .testdriver/screenshots/<test>/after-click.png
|
|
64
|
+
const screenshotPath = await testdriver.screenshot();
|
|
65
|
+
console.log(screenshotPath);
|
|
66
|
+
// /Users/you/my-app/.testdriver/screenshots/login.test/screenshot-1729512345678.png
|
|
89
67
|
```
|
|
90
68
|
|
|
91
|
-
|
|
69
|
+
## Complete example
|
|
92
70
|
|
|
93
|
-
```javascript
|
|
94
|
-
import { describe, expect, it } from
|
|
95
|
-
import { TestDriver } from
|
|
71
|
+
```javascript tests/login.test.mjs
|
|
72
|
+
import { describe, expect, it } from 'vitest';
|
|
73
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
96
74
|
|
|
97
|
-
describe(
|
|
98
|
-
it(
|
|
75
|
+
describe('Login', () => {
|
|
76
|
+
it('shows an error for an empty form', async (context) => {
|
|
99
77
|
const testdriver = TestDriver(context);
|
|
100
|
-
|
|
101
|
-
await testdriver.provision.chrome({
|
|
102
|
-
url: 'https://myapp.com/login',
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
// Capture initial state
|
|
106
|
-
await testdriver.screenshot();
|
|
107
|
-
|
|
108
|
-
// Fill in login form
|
|
109
|
-
const emailInput = await testdriver.find("email input");
|
|
110
|
-
await emailInput.click();
|
|
111
|
-
await testdriver.type("user@example.com");
|
|
112
|
-
|
|
113
|
-
// Capture state after typing
|
|
114
|
-
await testdriver.screenshot();
|
|
78
|
+
await testdriver.provision.chrome({ url: 'https://testdriver-sandbox.vercel.app/login' });
|
|
115
79
|
|
|
116
|
-
|
|
117
|
-
await passwordInput.click();
|
|
118
|
-
await testdriver.type("password123");
|
|
80
|
+
await testdriver.screenshot('login-empty');
|
|
119
81
|
|
|
120
|
-
|
|
121
|
-
await testdriver.screenshot();
|
|
82
|
+
await testdriver.find('Sign in button below the password field').click();
|
|
83
|
+
await testdriver.screenshot('login-error');
|
|
122
84
|
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
// Capture after login attempt
|
|
127
|
-
await testdriver.screenshot();
|
|
128
|
-
|
|
129
|
-
const result = await testdriver.assert("dashboard is visible");
|
|
130
|
-
expect(result).toBeTruthy();
|
|
85
|
+
const result = await testdriver.assert('an error says the fields are required');
|
|
86
|
+
expect(result).toBe(true);
|
|
131
87
|
});
|
|
132
88
|
});
|
|
133
89
|
```
|
|
134
90
|
|
|
135
|
-
## Automatic Screenshots
|
|
136
|
-
|
|
137
|
-
By default, TestDriver captures screenshots **automatically** before and after every command. This creates a complete visual timeline of your test execution without any additional code.
|
|
138
|
-
|
|
139
|
-
### Enabling/Disabling
|
|
140
|
-
|
|
141
|
-
```javascript
|
|
142
|
-
// Auto-screenshots enabled by default
|
|
143
|
-
const testdriver = TestDriver(context);
|
|
144
|
-
|
|
145
|
-
// Explicitly disable if needed (not recommended)
|
|
146
|
-
const testdriver = TestDriver(context, {
|
|
147
|
-
autoScreenshots: false
|
|
148
|
-
});
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
### What Gets Captured
|
|
152
|
-
|
|
153
|
-
Automatic screenshots are taken around these commands:
|
|
154
|
-
- `find()` / `findAll()`
|
|
155
|
-
- `click()` / `hover()` / `doubleClick()` / `rightClick()`
|
|
156
|
-
- `type()` / `pressKeys()`
|
|
157
|
-
- `scroll()`
|
|
158
|
-
- `waitForText()` / `waitForImage()`
|
|
159
|
-
- `focusApplication()`
|
|
160
|
-
- `assert()` / `extract()` / `exec()`
|
|
161
|
-
|
|
162
|
-
### Example Output
|
|
163
|
-
|
|
164
|
-
For this test code:
|
|
165
|
-
|
|
166
|
-
```javascript
|
|
167
|
-
// Line 15: Find email input
|
|
168
|
-
const emailInput = await testdriver.find("email input");
|
|
169
|
-
// Line 16: Click it
|
|
170
|
-
await emailInput.click();
|
|
171
|
-
// Line 17: Type email
|
|
172
|
-
await testdriver.type("user@example.com");
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
TestDriver automatically saves:
|
|
176
|
-
|
|
177
|
-
```
|
|
178
|
-
001-find-before-L15-email-input.png
|
|
179
|
-
002-find-after-L15-email-input.png
|
|
180
|
-
003-click-before-L16-email-input.png
|
|
181
|
-
004-click-after-L16-email-input.png
|
|
182
|
-
005-type-before-L17-userexamplecom.png
|
|
183
|
-
006-type-after-L17-userexamplecom.png
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
If an error occurs, the phase will be `error` instead of `after`.
|
|
187
|
-
|
|
188
|
-
## Best Practices
|
|
189
|
-
|
|
190
|
-
<AccordionGroup>
|
|
191
|
-
<Accordion title="Let automatic screenshots do the work">
|
|
192
|
-
With `autoScreenshots: true`, you get comprehensive coverage without adding manual `screenshot()` calls. Only add manual screenshots for specific named checkpoints.
|
|
193
|
-
</Accordion>
|
|
194
|
-
|
|
195
|
-
<Accordion title="Use screenshots for debugging flaky tests">
|
|
196
|
-
When a test fails intermittently, add screenshots at key steps to capture the actual screen state. This helps identify timing issues or unexpected UI states.
|
|
197
|
-
</Accordion>
|
|
198
|
-
|
|
199
|
-
<Accordion title="Capture before assertions">
|
|
200
|
-
Take a screenshot before making assertions. If the assertion fails, you'll have a visual record of what the screen looked like.
|
|
201
|
-
|
|
202
|
-
```javascript
|
|
203
|
-
await testdriver.screenshot();
|
|
204
|
-
const result = await testdriver.assert("checkout button is visible");
|
|
205
|
-
```
|
|
206
|
-
</Accordion>
|
|
207
|
-
|
|
208
|
-
<Accordion title="Add to .gitignore">
|
|
209
|
-
Add `.testdriver/screenshots/` to your `.gitignore` to avoid committing screenshots to version control:
|
|
210
|
-
|
|
211
|
-
```
|
|
212
|
-
# .gitignore
|
|
213
|
-
.testdriver/screenshots/
|
|
214
|
-
```
|
|
215
|
-
</Accordion>
|
|
216
|
-
</AccordionGroup>
|
|
217
|
-
|
|
218
|
-
## Viewing Saved Screenshots
|
|
219
|
-
|
|
220
|
-
After saving screenshots during test execution, you can view them using TestDriver MCP commands. This is especially useful for debugging failed tests or verifying test behavior.
|
|
221
|
-
|
|
222
|
-
### MCP Commands for Screenshot Viewing
|
|
223
|
-
|
|
224
|
-
**List all saved screenshots:**
|
|
225
|
-
|
|
226
|
-
```
|
|
227
|
-
list_local_screenshots()
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
**View a specific screenshot:**
|
|
231
|
-
|
|
232
|
-
```
|
|
233
|
-
view_local_screenshot({ path: "/full/path/to/screenshot.png" })
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
These commands allow you to:
|
|
237
|
-
- View screenshots from failed tests to understand what went wrong
|
|
238
|
-
- Review test execution flow by examining screenshots in chronological order
|
|
239
|
-
- Compare screenshots across test runs to identify flaky behavior
|
|
240
|
-
|
|
241
|
-
<Note>
|
|
242
|
-
For detailed workflows and examples of using these MCP commands for debugging, see the [Debugging with Screenshots](/debugging-with-screenshots) guide.
|
|
243
|
-
</Note>
|
|
244
|
-
|
|
245
91
|
## Related
|
|
246
92
|
|
|
247
|
-
- [
|
|
248
|
-
- [
|
|
249
|
-
- [
|
|
93
|
+
- [Screenshots](/screenshots): capture every step automatically with `autoScreenshots`
|
|
94
|
+
- [Debug a failing test](/debugging-with-screenshots): view saved screenshots from your AI client
|
|
95
|
+
- [Dashcam](/dashcam): watch a video replay of the whole test
|
package/docs/screenshots.mdx
CHANGED
|
@@ -1,186 +1,136 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "
|
|
2
|
+
title: "Save screenshots"
|
|
3
3
|
sidebarTitle: "Screenshots"
|
|
4
|
-
description: "
|
|
4
|
+
description: "Save screenshots of the sandbox by hand or automatically around each command."
|
|
5
5
|
icon: "camera"
|
|
6
6
|
mode: "wide"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
TestDriver can save screenshots of the sandbox to your machine while a test runs.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
- Call [`screenshot()`](/screenshot) to save one at a specific point.
|
|
12
|
+
- Turn on `autoScreenshots` to save one before and after each command, named after the line that ran it.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
Both kinds are saved as PNG files in `.testdriver/screenshots/<test file>/`.
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
## Save a screenshot by hand
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
const path = await testdriver.screenshot();
|
|
19
|
-
console.log('Saved to:', path);
|
|
20
|
-
// .testdriver/screenshots/my-test/screenshot-1719849312345.png
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### Options
|
|
18
|
+
Call `screenshot()` with an optional file name. It resolves to the absolute path of the saved file:
|
|
24
19
|
|
|
25
|
-
```javascript
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
```javascript tests/login.test.mjs
|
|
21
|
+
import { describe, it } from 'vitest';
|
|
22
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
28
23
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
describe('Login', () => {
|
|
25
|
+
it('loads the login page', async (context) => {
|
|
26
|
+
const testdriver = TestDriver(context);
|
|
27
|
+
await testdriver.provision.chrome({ url: 'https://testdriver-sandbox.vercel.app/login' });
|
|
32
28
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
29
|
+
const filePath = await testdriver.screenshot('login-page');
|
|
30
|
+
console.log(filePath);
|
|
31
|
+
// /path/to/project/.testdriver/screenshots/login.test/login-page.png
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
```
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
// → .testdriver/screenshots/my-test/login-page.png
|
|
36
|
+
- TestDriver adds `.png` if the name doesn't end with it.
|
|
37
|
+
- Without a name, the file is called `screenshot-<timestamp>.png`.
|
|
43
38
|
|
|
44
|
-
|
|
45
|
-
await testdriver.screenshot('dashboard-loaded.png');
|
|
46
|
-
// → .testdriver/screenshots/my-test/dashboard-loaded.png
|
|
47
|
-
```
|
|
39
|
+
See [screenshot()](/screenshot) for the full reference.
|
|
48
40
|
|
|
49
|
-
##
|
|
41
|
+
## Save screenshots automatically
|
|
50
42
|
|
|
51
|
-
|
|
43
|
+
Set `autoScreenshots: true` when you create the client:
|
|
52
44
|
|
|
53
45
|
```javascript
|
|
54
|
-
const testdriver =
|
|
55
|
-
autoScreenshots: true,
|
|
56
|
-
});
|
|
46
|
+
const testdriver = TestDriver(context, { autoScreenshots: true });
|
|
57
47
|
```
|
|
58
48
|
|
|
59
|
-
|
|
60
|
-
When `true`, captures a screenshot before and after every SDK command (`click`, `type`, `find`, `scroll`, `hover`, `pressKeys`, `assert`, `exec`, etc.). On error, an error-phase screenshot replaces the after-phase screenshot.
|
|
61
|
-
</ParamField>
|
|
62
|
-
|
|
63
|
-
### Filename Format
|
|
64
|
-
|
|
65
|
-
Auto-screenshots follow this naming convention:
|
|
66
|
-
|
|
67
|
-
```
|
|
68
|
-
<seq>-<action>-<phase>-L<line>-<description>.png
|
|
69
|
-
```
|
|
49
|
+
TestDriver then saves a screenshot before each command and another after it. When a command fails, it saves an `error` screenshot instead of the `after` one. A failed screenshot never fails the command.
|
|
70
50
|
|
|
71
|
-
|
|
72
|
-
|---|---|---|
|
|
73
|
-
| `seq` | 3-digit zero-padded sequence number | `001` |
|
|
74
|
-
| `action` | Command name | `click`, `type`, `find` |
|
|
75
|
-
| `phase` | `before`, `after`, or `error` | `before` |
|
|
76
|
-
| `L<line>` | Source line number from your test file | `L42` |
|
|
77
|
-
| `description` | Sanitized from command arguments (max 30 chars) | `submit-button` |
|
|
51
|
+
Automatic screenshots are off by default because each one is an extra capture from the sandbox.
|
|
78
52
|
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
001-find-before-L15-login-button.png
|
|
82
|
-
002-find-after-L15-login-button.png
|
|
83
|
-
003-click-before-L16-login-button.png
|
|
84
|
-
004-click-after-L16-login-button.png
|
|
85
|
-
005-type-before-L18-username-field.png
|
|
86
|
-
006-type-error-L18-username-field.png
|
|
87
|
-
```
|
|
53
|
+
### Which commands are captured
|
|
88
54
|
|
|
89
|
-
|
|
55
|
+
- `find()` and `findAll()`.
|
|
56
|
+
- Methods you call on the client, such as `testdriver.click()`, `type()`, `pressKeys()`, `scroll()`, `hover()`, `wait()`, `assert()`, `extract()`, `exec()`, and `focusApplication()`.
|
|
90
57
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
| `after` | After successful command | Captures the result of the action |
|
|
95
|
-
| `error` | After failed command | Captures the screen at the point of failure (replaces `after`) |
|
|
58
|
+
<Note>
|
|
59
|
+
Methods you call on an element, such as `element.click()` or `element.hover()`, aren't captured. The `find()` that returned the element is.
|
|
60
|
+
</Note>
|
|
96
61
|
|
|
97
|
-
|
|
62
|
+
### File names
|
|
98
63
|
|
|
99
|
-
|
|
64
|
+
Each automatic screenshot is named:
|
|
100
65
|
|
|
101
|
-
```
|
|
102
|
-
<
|
|
66
|
+
```text
|
|
67
|
+
<sequence>-<command>-<phase>-L<line>-<description>.png
|
|
103
68
|
```
|
|
104
69
|
|
|
105
|
-
|
|
70
|
+
| Part | Meaning | Example |
|
|
71
|
+
| --- | --- | --- |
|
|
72
|
+
| `sequence` | Three-digit counter, in the order screenshots were taken | `001` |
|
|
73
|
+
| `command` | The method that ran | `find`, `type`, `assert` |
|
|
74
|
+
| `phase` | `before`, `after`, or `error` | `before` |
|
|
75
|
+
| `L<line>` | The line in your test file that called the command | `L15` |
|
|
76
|
+
| `description` | Taken from the command's arguments, as below | `email-input` |
|
|
106
77
|
|
|
107
|
-
|
|
78
|
+
The description comes from:
|
|
108
79
|
|
|
109
|
-
The
|
|
80
|
+
- The description passed to `find()` or `findAll()`.
|
|
81
|
+
- The first 20 characters typed by `type()`.
|
|
82
|
+
- The keys passed to `pressKeys()`, joined with `+`.
|
|
83
|
+
- The direction passed to `scroll()`.
|
|
84
|
+
- The first 30 characters of the text passed to `assert()` or `extract()`.
|
|
110
85
|
|
|
111
|
-
|
|
86
|
+
TestDriver lowercases it, drops anything other than letters, digits, spaces, and hyphens, turns spaces into hyphens, and keeps the first 30 characters.
|
|
112
87
|
|
|
113
|
-
|
|
88
|
+
<Warning>
|
|
89
|
+
The description for `type()` uses the typed text even when you pass `secret: true`. Don't turn on `autoScreenshots` for tests that type passwords, or the start of the password ends up in a file name.
|
|
90
|
+
</Warning>
|
|
114
91
|
|
|
115
|
-
|
|
116
|
-
const el = await testdriver.find('submit button');
|
|
92
|
+
### Example
|
|
117
93
|
|
|
118
|
-
|
|
119
|
-
const debugPath = await el.saveDebugScreenshot();
|
|
120
|
-
console.log('Debug screenshot:', debugPath);
|
|
121
|
-
// → ./debug-screenshot-1719849312345.png
|
|
94
|
+
This test:
|
|
122
95
|
|
|
123
|
-
|
|
124
|
-
await
|
|
96
|
+
```javascript
|
|
97
|
+
await testdriver.find('Email input field').click(); // line 15
|
|
98
|
+
await testdriver.type('user@example.com'); // line 16
|
|
99
|
+
await testdriver.assert('the email is filled in'); // line 17
|
|
125
100
|
```
|
|
126
101
|
|
|
127
|
-
|
|
102
|
+
saves:
|
|
128
103
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
beforeAll(async () => {
|
|
139
|
-
testdriver = new TestDriver({
|
|
140
|
-
autoScreenshots: true, // capture every step
|
|
141
|
-
});
|
|
142
|
-
await testdriver.ready();
|
|
143
|
-
await testdriver.provision.chrome({ url: 'https://example.com' });
|
|
144
|
-
});
|
|
104
|
+
```text
|
|
105
|
+
.testdriver/screenshots/login.test/
|
|
106
|
+
001-find-before-L15-email-input-field.png
|
|
107
|
+
002-find-after-L15-email-input-field.png
|
|
108
|
+
003-type-before-L16-userexamplecom.png
|
|
109
|
+
004-type-after-L16-userexamplecom.png
|
|
110
|
+
005-assert-before-L17-the-email-is-filled-in.png
|
|
111
|
+
006-assert-after-L17-the-email-is-filled-in.png
|
|
112
|
+
```
|
|
145
113
|
|
|
146
|
-
|
|
147
|
-
await testdriver.disconnect();
|
|
148
|
-
});
|
|
114
|
+
## Where screenshots are saved
|
|
149
115
|
|
|
150
|
-
|
|
151
|
-
// Auto-screenshots capture before/after each command
|
|
116
|
+
Screenshots go in a folder named after the test file, without its last extension:
|
|
152
117
|
|
|
153
|
-
|
|
154
|
-
|
|
118
|
+
| Test file | Folder |
|
|
119
|
+
| --- | --- |
|
|
120
|
+
| `tests/login.test.mjs` | `.testdriver/screenshots/login.test/` |
|
|
121
|
+
| `tests/checkout.spec.js` | `.testdriver/screenshots/checkout.spec/` |
|
|
155
122
|
|
|
156
|
-
|
|
157
|
-
await username.click();
|
|
158
|
-
await testdriver.type('testuser@example.com');
|
|
123
|
+
The `.testdriver` folder is created in the directory you run the tests from.
|
|
159
124
|
|
|
160
|
-
|
|
125
|
+
TestDriver deletes a test file's screenshot folder when that file's first test connects to a sandbox. Each folder only holds screenshots from the latest run. Tests in the same file running at the same time don't delete each other's screenshots.
|
|
161
126
|
|
|
162
|
-
|
|
163
|
-
await password.click();
|
|
164
|
-
await testdriver.type('password123');
|
|
127
|
+
## Review the screenshots
|
|
165
128
|
|
|
166
|
-
|
|
129
|
+
Open the folder after a run, or ask your AI assistant to find and show screenshots by line number. [Debug a failing test](/debugging-with-screenshots#inspect-screenshots-with-your-ai-assistant) explains how to do that with the TestDriver MCP server.
|
|
167
130
|
|
|
168
|
-
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
```
|
|
131
|
+
## Related
|
|
172
132
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
├── 001-find-before-L18-username-input.png
|
|
178
|
-
├── 002-find-after-L18-username-input.png
|
|
179
|
-
├── 003-click-before-L19-username-input.png
|
|
180
|
-
├── 004-click-after-L19-username-input.png
|
|
181
|
-
├── 005-type-before-L20-testuser-example-com.png
|
|
182
|
-
├── 006-type-after-L20-testuser-example-com.png
|
|
183
|
-
├── after-username-entry.png
|
|
184
|
-
├── 007-find-before-L24-password-input.png
|
|
185
|
-
├── ...
|
|
186
|
-
```
|
|
133
|
+
- [screenshot()](/screenshot): the reference for manual screenshots
|
|
134
|
+
- [Debug a failing test](/debugging-with-screenshots): use replays and screenshots to find out why a test failed
|
|
135
|
+
- [Dashcam](/dashcam): the video recording of each run
|
|
136
|
+
- [Options](/options#preview-and-recording): every client option
|