@testdriverai/mcp 7.10.0-canary.0 → 7.10.1-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/.claude-plugin/marketplace.json +17 -0
- package/agent/index.js +116 -71
- package/agent/interface.js +13 -1
- package/agent/lib/commands.js +35 -15
- package/agent/lib/provision-commands.js +92 -11
- package/agent/lib/sandbox.js +263 -30
- package/agent/lib/sdk.js +16 -12
- package/agent/lib/system.js +107 -31
- package/ai/.claude-plugin/plugin.json +89 -4
- package/ai/agents/testdriver.md +4 -8
- package/ai/skills/testdriver-assert/SKILL.md +0 -1
- package/ai/skills/testdriver-aws-setup/SKILL.md +1 -1
- package/ai/skills/testdriver-caching/SKILL.md +13 -6
- package/ai/skills/testdriver-ci-cd/SKILL.md +57 -14
- package/ai/skills/testdriver-client/SKILL.md +10 -6
- package/ai/skills/testdriver-customizing-devices/SKILL.md +7 -5
- package/ai/skills/testdriver-dashcam/SKILL.md +36 -3
- package/ai/skills/testdriver-debugging-with-screenshots/SKILL.md +28 -4
- package/ai/skills/testdriver-device-config/SKILL.md +5 -5
- package/ai/skills/testdriver-find/SKILL.md +50 -11
- package/ai/skills/testdriver-generating-tests/SKILL.md +163 -8
- package/ai/skills/testdriver-hosted/SKILL.md +1 -1
- package/ai/skills/testdriver-machine-setup/SKILL.md +331 -0
- package/ai/skills/testdriver-making-assertions/SKILL.md +78 -2
- package/ai/skills/testdriver-mcp-workflow/SKILL.md +2 -2
- package/ai/skills/testdriver-parse/SKILL.md +1 -1
- package/ai/skills/testdriver-performing-actions/SKILL.md +97 -3
- package/ai/skills/testdriver-provision/SKILL.md +0 -20
- package/ai/skills/testdriver-quickstart/SKILL.md +299 -21
- package/ai/skills/testdriver-reusable-code/SKILL.md +3 -3
- package/ai/skills/testdriver-running-tests/SKILL.md +1 -1
- package/ai/skills/testdriver-screenshot/SKILL.md +5 -5
- package/ai/skills/testdriver-scroll/SKILL.md +30 -160
- package/ai/skills/testdriver-test-writer/SKILL.md +3 -5
- package/ai/skills/testdriver-testdriver/SKILL.md +3 -7
- package/ai/skills/testdriver-wait/SKILL.md +1 -1
- package/{docs/v7/ai.mdx → ai/skills/testdriver:ai/SKILL.md} +3 -4
- package/ai/skills/testdriver:assert/SKILL.md +315 -0
- package/ai/skills/testdriver:aws-setup/SKILL.md +448 -0
- package/ai/skills/testdriver:cache/SKILL.md +221 -0
- package/ai/skills/testdriver:caching/SKILL.md +124 -0
- package/ai/skills/testdriver:captcha/SKILL.md +158 -0
- package/ai/skills/testdriver:ci-cd/SKILL.md +659 -0
- package/ai/skills/testdriver:click/SKILL.md +286 -0
- package/ai/skills/testdriver:client/SKILL.md +477 -0
- package/ai/skills/testdriver:customizing-devices/SKILL.md +319 -0
- package/ai/skills/testdriver:dashcam/SKILL.md +451 -0
- package/ai/skills/testdriver:debugging-with-screenshots/SKILL.md +415 -0
- package/{docs/v7/device-config.mdx → ai/skills/testdriver:device-config/SKILL.md} +8 -8
- package/ai/skills/testdriver:double-click/SKILL.md +102 -0
- package/ai/skills/testdriver:elements/SKILL.md +605 -0
- package/ai/skills/testdriver:enterprise/SKILL.md +7 -0
- package/ai/skills/testdriver:errors/SKILL.md +246 -0
- package/ai/skills/testdriver:events/SKILL.md +356 -0
- package/ai/skills/testdriver:exec/SKILL.md +317 -0
- package/ai/skills/testdriver:find/SKILL.md +860 -0
- package/ai/skills/testdriver:focus-application/SKILL.md +293 -0
- package/ai/skills/testdriver:generating-tests/SKILL.md +25 -0
- package/ai/skills/testdriver:hosted/SKILL.md +156 -0
- package/ai/skills/testdriver:hover/SKILL.md +278 -0
- package/{docs/v7/locating-elements.mdx → ai/skills/testdriver:locating-elements/SKILL.md} +3 -3
- package/ai/skills/testdriver:making-assertions/SKILL.md +32 -0
- package/ai/skills/testdriver:mcp/SKILL.md +7 -0
- package/ai/skills/testdriver:mouse-down/SKILL.md +161 -0
- package/ai/skills/testdriver:mouse-up/SKILL.md +164 -0
- package/ai/skills/testdriver:parse/SKILL.md +236 -0
- package/ai/skills/testdriver:performing-actions/SKILL.md +53 -0
- package/ai/skills/testdriver:press-keys/SKILL.md +348 -0
- package/ai/skills/testdriver:provision/SKILL.md +331 -0
- package/ai/skills/testdriver:quickstart/SKILL.md +172 -0
- package/ai/skills/testdriver:redraw/SKILL.md +214 -0
- package/ai/skills/testdriver:reusable-code/SKILL.md +249 -0
- package/ai/skills/testdriver:right-click/SKILL.md +123 -0
- package/{docs/v7/running-tests.mdx → ai/skills/testdriver:running-tests/SKILL.md} +4 -4
- package/ai/skills/testdriver:screenshot/SKILL.md +248 -0
- package/ai/skills/testdriver:screenshots/SKILL.md +184 -0
- package/ai/skills/testdriver:scroll/SKILL.md +205 -0
- package/ai/skills/testdriver:secrets/SKILL.md +115 -0
- package/ai/skills/testdriver:self-hosted/SKILL.md +147 -0
- package/ai/skills/testdriver:test-results-json/SKILL.md +257 -0
- package/ai/skills/testdriver:testdriver/SKILL.md +624 -0
- package/ai/skills/testdriver:type/SKILL.md +357 -0
- package/ai/skills/testdriver:variables/SKILL.md +111 -0
- package/ai/skills/testdriver:wait/SKILL.md +50 -0
- package/{docs/v7/waiting-for-elements.mdx → ai/skills/testdriver:waiting-for-elements/SKILL.md} +3 -3
- package/ai/skills/testdriver:what-is-testdriver/SKILL.md +54 -0
- package/debugger/index.html +12 -0
- package/docs/_data/examples-manifest.json +54 -46
- package/docs/_data/examples-manifest.schema.json +12 -2
- package/docs/_scripts/extract-example-urls.js +21 -3
- package/docs/_scripts/generate-examples.js +64 -16
- package/docs/changelog.mdx +29 -2
- package/docs/claude-mcp-plugin.mdx +65 -18
- package/docs/docs.json +16 -33
- package/docs/snippets/tests/scroll-yaml.mdx +2 -2
- package/docs/v6/commands/scroll-until-image.mdx +1 -1
- package/docs/v6/commands/scroll-until-text.mdx +2 -2
- package/docs/v6/commands/scroll.mdx +2 -2
- package/docs/v7/_drafts/agents.mdx +0 -4
- package/docs/v7/_drafts/best-practices.mdx +0 -12
- package/docs/v7/_drafts/commands/scroll-until-image.mdx +1 -1
- package/docs/v7/_drafts/commands/scroll-until-text.mdx +2 -2
- package/docs/v7/_drafts/commands/scroll.mdx +1 -1
- package/docs/v7/_drafts/configuration.mdx +0 -12
- package/docs/v7/_drafts/faq.mdx +2 -10
- package/docs/v7/_drafts/readme.mdx +0 -1
- package/docs/v7/_drafts/troubleshooting.mdx +1 -4
- package/docs/v7/assert.mdx +0 -1
- package/docs/v7/aws-setup.mdx +1 -1
- package/docs/v7/caching.mdx +14 -10
- package/docs/v7/ci-cd.mdx +98 -14
- package/docs/v7/client.mdx +10 -6
- package/docs/v7/copilot/auto-healing.mdx +167 -18
- package/docs/v7/copilot/running-tests.mdx +915 -54
- package/docs/v7/customizing-devices.mdx +7 -5
- package/docs/v7/dashcam.mdx +36 -3
- package/docs/v7/debugging-with-screenshots.mdx +31 -7
- package/docs/v7/examples/ai.mdx +13 -8
- package/docs/v7/examples/assert.mdx +1 -1
- package/docs/v7/examples/chrome-extension.mdx +30 -13
- package/docs/v7/examples/element-not-found.mdx +1 -1
- package/docs/v7/examples/findall-coffee-icons.mdx +3 -2
- package/docs/v7/examples/formatted-logging.mdx +74 -0
- package/docs/v7/examples/hover-image.mdx +1 -1
- package/docs/v7/examples/hover-text-with-description.mdx +2 -2
- 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 +27 -27
- package/docs/v7/examples/match-image.mdx +1 -1
- package/docs/v7/examples/parse.mdx +3 -2
- package/docs/v7/examples/press-keys.mdx +2 -2
- package/docs/v7/examples/scroll-keyboard.mdx +2 -2
- 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/find.mdx +50 -11
- package/docs/v7/generating-tests.mdx +166 -10
- package/docs/v7/hosted.mdx +1 -1
- package/docs/v7/making-assertions.mdx +81 -4
- package/docs/v7/parse.mdx +1 -1
- package/docs/v7/performing-actions.mdx +100 -5
- package/docs/v7/provision.mdx +0 -20
- package/docs/v7/quickstart.mdx +299 -21
- package/docs/v7/reusable-code.mdx +3 -3
- package/docs/v7/screenshot.mdx +5 -5
- package/docs/v7/scroll.mdx +30 -160
- package/docs/v7/wait.mdx +1 -1
- package/examples/chrome-extension.test.mjs +29 -12
- package/examples/config.mjs +1 -1
- package/examples/launch-vscode-linux.test.mjs +25 -25
- package/interfaces/cli/commands/init.js +84 -2
- package/interfaces/vitest-plugin.mjs +51 -61
- package/lib/core/Dashcam.js +43 -2
- package/lib/core/index.d.ts +13 -1
- package/lib/github-comment.mjs +11 -5
- package/lib/init-project.js +98 -44
- package/lib/install-clients.js +470 -0
- package/lib/provision.js +749 -0
- package/lib/resolve-channel.js +2 -2
- package/lib/sentry.js +15 -2
- package/lib/vitest/hooks.mjs +44 -34
- package/mcp-server/README.md +32 -0
- package/mcp-server/dist/core/actions.d.ts +176 -0
- package/mcp-server/dist/core/actions.js +753 -0
- package/mcp-server/dist/env-utils.d.ts +45 -0
- package/mcp-server/dist/env-utils.js +63 -0
- package/mcp-server/dist/provision-types.d.ts +6 -2
- package/mcp-server/dist/provision-types.js +3 -1
- package/mcp-server/dist/server.mjs +449 -751
- package/mcp-server/package-lock.json +384 -1
- package/mcp-server/package.json +5 -2
- package/mcp-server/src/core/actions.ts +912 -0
- package/mcp-server/src/env-utils.test.ts +82 -0
- package/mcp-server/src/env-utils.ts +77 -0
- package/mcp-server/src/provision-types.ts +4 -1
- package/mcp-server/src/server.ts +533 -954
- package/mcp-server/tsconfig.json +1 -1
- package/mcp-server/vitest.config.ts +7 -0
- package/package.json +15 -3
- package/sdk.d.ts +11 -9
- package/sdk.js +116 -746
- package/setup/aws/spawn-runner.sh +24 -3
- package/docs/v7/_drafts/caching-ai.mdx +0 -215
- package/docs/v7/_drafts/caching.mdx +0 -366
- package/docs/v7/_drafts/prompt-cache.mdx +0 -200
- package/docs/v7/copilot/creating-tests.mdx +0 -156
- package/docs/v7/copilot/github.mdx +0 -143
- package/docs/v7/copilot/setup.mdx +0 -143
- package/docs/v7/examples/exec-output.mdx +0 -84
- package/docs/v7/examples/exec-pwsh.mdx +0 -82
- package/docs/v7/examples/focus-window.mdx +0 -61
- package/docs/v7/examples/scroll-until-image.mdx +0 -82
- package/docs/v7/examples/windows-installer.mdx +0 -95
- package/examples/formatted-logging.test.mjs +0 -27
- package/examples/match-image.test.mjs +0 -55
- package/manual/exec-stream-logs.test.mjs +0 -25
|
@@ -9,7 +9,7 @@ description: Capture and save screenshots during test execution
|
|
|
9
9
|
Capture a screenshot of the current screen and automatically save it to a local file. Screenshots are organized by test file for easy debugging and review.
|
|
10
10
|
|
|
11
11
|
<Note>
|
|
12
|
-
**Automatic Screenshots
|
|
12
|
+
**Automatic Screenshots**: TestDriver can automatically capture screenshots before and after every command (click, type, find, etc.). These are saved with descriptive filenames like `001-click-before-L42-submit-button.png` that include the line number from your test file. Enable this with `autoScreenshots: true` in your TestDriver options.
|
|
13
13
|
</Note>
|
|
14
14
|
|
|
15
15
|
## Syntax
|
|
@@ -50,7 +50,7 @@ Screenshots are automatically saved to `.testdriver/screenshots/<test-file-name>
|
|
|
50
50
|
|
|
51
51
|
### Automatic Screenshot Naming
|
|
52
52
|
|
|
53
|
-
When `autoScreenshots` is enabled
|
|
53
|
+
When `autoScreenshots` is enabled, filenames follow this format:
|
|
54
54
|
|
|
55
55
|
`<seq>-<action>-<phase>-L<line>-<description>.png`
|
|
56
56
|
|
|
@@ -91,7 +91,7 @@ await testdriver.screenshot("after-click");
|
|
|
91
91
|
|
|
92
92
|
```javascript
|
|
93
93
|
import { describe, expect, it } from "vitest";
|
|
94
|
-
import { TestDriver } from "testdriverai/
|
|
94
|
+
import { TestDriver } from "testdriverai/vitest/hooks";
|
|
95
95
|
|
|
96
96
|
describe("Login Flow", () => {
|
|
97
97
|
it("should log in successfully", async (context) => {
|
|
@@ -153,7 +153,7 @@ Automatic screenshots are taken around these commands:
|
|
|
153
153
|
- `find()` / `findAll()`
|
|
154
154
|
- `click()` / `hover()` / `doubleClick()` / `rightClick()`
|
|
155
155
|
- `type()` / `pressKeys()`
|
|
156
|
-
- `scroll()`
|
|
156
|
+
- `scroll()`
|
|
157
157
|
- `waitForText()` / `waitForImage()`
|
|
158
158
|
- `focusApplication()`
|
|
159
159
|
- `assert()` / `extract()` / `exec()`
|
|
@@ -188,7 +188,7 @@ If an error occurs, the phase will be `error` instead of `after`.
|
|
|
188
188
|
|
|
189
189
|
<AccordionGroup>
|
|
190
190
|
<Accordion title="Let automatic screenshots do the work">
|
|
191
|
-
With `autoScreenshots: true
|
|
191
|
+
With `autoScreenshots: true`, you get comprehensive coverage without adding manual `screenshot()` calls. Only add manual screenshots for specific named checkpoints.
|
|
192
192
|
</Accordion>
|
|
193
193
|
|
|
194
194
|
<Accordion title="Use screenshots for debugging flaky tests">
|
|
@@ -26,21 +26,21 @@ Scroll the page or active element in any direction using mouse wheel or keyboard
|
|
|
26
26
|
## Syntax
|
|
27
27
|
|
|
28
28
|
```javascript
|
|
29
|
-
await testdriver.scroll(direction,
|
|
29
|
+
await testdriver.scroll(direction, options)
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
## Parameters
|
|
33
33
|
|
|
34
34
|
<ParamField path="direction" type="string" default="down">
|
|
35
|
-
Direction to scroll: `'up'`, `'down'
|
|
35
|
+
Direction to scroll: `'up'`, `'down'`
|
|
36
36
|
</ParamField>
|
|
37
37
|
|
|
38
|
-
<ParamField path="
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
<ParamField path="options" type="object">
|
|
39
|
+
<Expandable title="properties">
|
|
40
|
+
<ParamField path="amount" type="number" default="300">
|
|
41
|
+
Amount to scroll in pixels
|
|
42
|
+
</ParamField>
|
|
43
|
+
</Expandable>
|
|
44
44
|
</ParamField>
|
|
45
45
|
|
|
46
46
|
## Returns
|
|
@@ -55,95 +55,34 @@ await testdriver.scroll(direction, amount, method)
|
|
|
55
55
|
// Scroll down (default)
|
|
56
56
|
await testdriver.scroll();
|
|
57
57
|
|
|
58
|
-
// Scroll down
|
|
59
|
-
await testdriver.scroll('down',
|
|
58
|
+
// Scroll down 5 clicks
|
|
59
|
+
await testdriver.scroll('down', { amount: 5 });
|
|
60
60
|
|
|
61
61
|
// Scroll up
|
|
62
62
|
await testdriver.scroll('up');
|
|
63
63
|
|
|
64
|
-
// Scroll up
|
|
65
|
-
await testdriver.scroll('up',
|
|
64
|
+
// Scroll up 2 clicks
|
|
65
|
+
await testdriver.scroll('up', { amount: 2 });
|
|
66
66
|
```
|
|
67
67
|
|
|
68
68
|
### Horizontal Scrolling
|
|
69
69
|
|
|
70
70
|
```javascript
|
|
71
71
|
// Scroll right
|
|
72
|
-
await testdriver.scroll('right',
|
|
72
|
+
await testdriver.scroll('right', { amount: 3 });
|
|
73
73
|
|
|
74
74
|
// Scroll left
|
|
75
|
-
await testdriver.scroll('left',
|
|
75
|
+
await testdriver.scroll('left', { amount: 3 });
|
|
76
76
|
```
|
|
77
77
|
|
|
78
78
|
### Scroll Methods
|
|
79
79
|
|
|
80
80
|
```javascript
|
|
81
|
-
// Mouse wheel scroll (
|
|
82
|
-
await testdriver.scroll('down',
|
|
83
|
-
|
|
84
|
-
// Keyboard scroll (uses Page Down/Up, more compatible)
|
|
85
|
-
await testdriver.scroll('down', 300, 'keyboard');
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
## Scroll Until Found
|
|
89
|
-
|
|
90
|
-
### scrollUntilText()
|
|
91
|
-
|
|
92
|
-
Scroll until specific text appears on screen.
|
|
93
|
-
|
|
94
|
-
```javascript
|
|
95
|
-
await testdriver.scrollUntilText(text, direction, maxDistance, textMatchMethod, method, invert)
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
**Parameters:**
|
|
99
|
-
- `text` (string) - Text to find
|
|
100
|
-
- `direction` (string) - Scroll direction (default: `'down'`)
|
|
101
|
-
- `maxDistance` (number) - Max pixels to scroll (default: 10000)
|
|
102
|
-
- `textMatchMethod` (string) - `'turbo'` or `'ai'` (default: `'turbo'`)
|
|
103
|
-
- `method` (string) - `'keyboard'` or `'mouse'` (default: `'keyboard'`)
|
|
104
|
-
- `invert` (boolean) - Scroll until text disappears (default: false)
|
|
105
|
-
|
|
106
|
-
**Examples:**
|
|
107
|
-
```javascript
|
|
108
|
-
// Scroll down until "Contact Us" appears
|
|
109
|
-
await testdriver.scrollUntilText('Contact Us');
|
|
110
|
-
|
|
111
|
-
// Scroll up to find text
|
|
112
|
-
await testdriver.scrollUntilText('Header', 'up');
|
|
113
|
-
|
|
114
|
-
// Scroll until text disappears
|
|
115
|
-
await testdriver.scrollUntilText('Loading...', 'down', 5000, 'turbo', 'keyboard', true);
|
|
81
|
+
// Mouse wheel scroll (default)
|
|
82
|
+
await testdriver.scroll('down', { amount: 3 });
|
|
116
83
|
|
|
117
|
-
//
|
|
118
|
-
await testdriver.
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
### scrollUntilImage()
|
|
122
|
-
|
|
123
|
-
Scroll until a visual element appears.
|
|
124
|
-
|
|
125
|
-
```javascript
|
|
126
|
-
await testdriver.scrollUntilImage(description, direction, maxDistance, method, path, invert)
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
**Parameters:**
|
|
130
|
-
- `description` (string) - Description of the image/element
|
|
131
|
-
- `direction` (string) - Scroll direction (default: `'down'`)
|
|
132
|
-
- `maxDistance` (number) - Max pixels to scroll (default: 10000)
|
|
133
|
-
- `method` (string) - `'keyboard'` or `'mouse'` (default: `'keyboard'`)
|
|
134
|
-
- `path` (string | null) - Path to image template (optional)
|
|
135
|
-
- `invert` (boolean) - Scroll until image disappears (default: false)
|
|
136
|
-
|
|
137
|
-
**Examples:**
|
|
138
|
-
```javascript
|
|
139
|
-
// Scroll until visual element appears
|
|
140
|
-
await testdriver.scrollUntilImage('red subscribe button');
|
|
141
|
-
|
|
142
|
-
// Scroll using image template
|
|
143
|
-
await testdriver.scrollUntilImage('', 'down', 10000, 'keyboard', './footer-logo.png');
|
|
144
|
-
|
|
145
|
-
// Scroll until image disappears
|
|
146
|
-
await testdriver.scrollUntilImage('loading spinner', 'down', 5000, 'keyboard', null, true);
|
|
84
|
+
// For keyboard-based scrolling, use pressKeys instead
|
|
85
|
+
await testdriver.pressKeys(['pagedown']);
|
|
147
86
|
```
|
|
148
87
|
|
|
149
88
|
## Best Practices
|
|
@@ -162,7 +101,7 @@ await testdriver.scrollUntilImage('loading spinner', 'down', 5000, 'keyboard', n
|
|
|
162
101
|
// await testdriver.find('page background').click();
|
|
163
102
|
|
|
164
103
|
// Now scroll will work properly
|
|
165
|
-
await testdriver.scroll('down'
|
|
104
|
+
await testdriver.scroll('down');
|
|
166
105
|
|
|
167
106
|
// If scroll still doesn't work, use Page Down directly
|
|
168
107
|
// await testdriver.pressKeys(['pagedown']);
|
|
@@ -170,84 +109,31 @@ await testdriver.scrollUntilImage('loading spinner', 'down', 5000, 'keyboard', n
|
|
|
170
109
|
</Check>
|
|
171
110
|
|
|
172
111
|
<Check>
|
|
173
|
-
**
|
|
174
|
-
|
|
175
|
-
```javascript
|
|
176
|
-
// For web pages, mouse scroll is usually smoother
|
|
177
|
-
await testdriver.scroll('down', 300, 'mouse');
|
|
178
|
-
|
|
179
|
-
// For desktop apps or when mouse doesn't work
|
|
180
|
-
await testdriver.scroll('down', 300, 'keyboard');
|
|
181
|
-
```
|
|
182
|
-
</Check>
|
|
183
|
-
|
|
184
|
-
<Check>
|
|
185
|
-
**Use scrollUntil for dynamic content**
|
|
112
|
+
**Control scroll distance with the options object**
|
|
186
113
|
|
|
187
114
|
```javascript
|
|
188
|
-
//
|
|
189
|
-
await testdriver.
|
|
115
|
+
// For web pages, mouse scroll works well
|
|
116
|
+
await testdriver.scroll('down', { amount: 3 });
|
|
190
117
|
|
|
191
|
-
|
|
192
|
-
await
|
|
193
|
-
```
|
|
194
|
-
</Check>
|
|
195
|
-
|
|
196
|
-
<Check>
|
|
197
|
-
**Set reasonable max distance**
|
|
198
|
-
|
|
199
|
-
```javascript
|
|
200
|
-
// Avoid infinite scrolling
|
|
201
|
-
await testdriver.scrollUntilText('Footer', 'down', 5000); // Max 5000px
|
|
118
|
+
// For desktop apps or when mouse doesn't work, use keyboard
|
|
119
|
+
await testdriver.pressKeys(['pagedown']);
|
|
202
120
|
```
|
|
203
121
|
</Check>
|
|
204
122
|
|
|
205
123
|
<Warning>
|
|
206
124
|
**Keyboard scroll uses Page Down/Up**
|
|
207
125
|
|
|
208
|
-
Keyboard scrolling typically moves by one "page" at a time, which may be more than the specified
|
|
126
|
+
Keyboard scrolling typically moves by one "page" at a time, which may be more than the specified click amount. It's more compatible but less precise than mouse scrolling.
|
|
209
127
|
</Warning>
|
|
210
128
|
|
|
211
129
|
## Use Cases
|
|
212
130
|
|
|
213
131
|
<AccordionGroup>
|
|
214
|
-
<Accordion title="Navigate to Footer">
|
|
215
|
-
```javascript
|
|
216
|
-
// Scroll to bottom of page
|
|
217
|
-
await testdriver.scrollUntilText('Contact Us');
|
|
218
|
-
|
|
219
|
-
const contactLink = await testdriver.find('Contact Us link');
|
|
220
|
-
await contactLink.click();
|
|
221
|
-
```
|
|
222
|
-
</Accordion>
|
|
223
|
-
|
|
224
|
-
<Accordion title="Load More Results">
|
|
225
|
-
```javascript
|
|
226
|
-
// Scroll to load more button
|
|
227
|
-
await testdriver.scrollUntilText('Load More');
|
|
228
|
-
|
|
229
|
-
const loadBtn = await testdriver.find('Load More button');
|
|
230
|
-
await loadBtn.click();
|
|
231
|
-
|
|
232
|
-
await new Promise(r => setTimeout(r, 2000));
|
|
233
|
-
```
|
|
234
|
-
</Accordion>
|
|
235
|
-
|
|
236
|
-
<Accordion title="Find Element in Long List">
|
|
237
|
-
```javascript
|
|
238
|
-
// Scroll through list to find item
|
|
239
|
-
await testdriver.scrollUntilText('Product #42');
|
|
240
|
-
|
|
241
|
-
const product = await testdriver.find('Product #42');
|
|
242
|
-
await product.click();
|
|
243
|
-
```
|
|
244
|
-
</Accordion>
|
|
245
|
-
|
|
246
132
|
<Accordion title="Infinite Scroll">
|
|
247
133
|
```javascript
|
|
248
134
|
// Scroll multiple times for infinite scroll
|
|
249
135
|
for (let i = 0; i < 5; i++) {
|
|
250
|
-
await testdriver.scroll('down',
|
|
136
|
+
await testdriver.scroll('down', { amount: 5 });
|
|
251
137
|
await new Promise(r => setTimeout(r, 1000)); // Wait for load
|
|
252
138
|
}
|
|
253
139
|
```
|
|
@@ -256,7 +142,7 @@ await testdriver.scrollUntilImage('loading spinner', 'down', 5000, 'keyboard', n
|
|
|
256
142
|
<Accordion title="Horizontal Gallery">
|
|
257
143
|
```javascript
|
|
258
144
|
// Navigate horizontal carousel
|
|
259
|
-
await testdriver.scroll('right',
|
|
145
|
+
await testdriver.scroll('right', { amount: 3 });
|
|
260
146
|
await new Promise(r => setTimeout(r, 500));
|
|
261
147
|
|
|
262
148
|
const nextImage = await testdriver.find('next image in carousel');
|
|
@@ -287,8 +173,8 @@ describe('Scrolling', () => {
|
|
|
287
173
|
it('should scroll to find elements', async () => {
|
|
288
174
|
await testdriver.focusApplication('Google Chrome');
|
|
289
175
|
|
|
290
|
-
// Scroll
|
|
291
|
-
await testdriver.
|
|
176
|
+
// Scroll down the page
|
|
177
|
+
await testdriver.scroll('down', { amount: 5 });
|
|
292
178
|
|
|
293
179
|
// Click footer link
|
|
294
180
|
const privacyLink = await testdriver.find('Privacy Policy link');
|
|
@@ -302,29 +188,13 @@ describe('Scrolling', () => {
|
|
|
302
188
|
|
|
303
189
|
// Scroll multiple times to load content
|
|
304
190
|
for (let i = 0; i < 3; i++) {
|
|
305
|
-
await testdriver.scroll('down',
|
|
191
|
+
await testdriver.scroll('down', { amount: 5 });
|
|
306
192
|
await new Promise(r => setTimeout(r, 1500)); // Wait for load
|
|
307
193
|
}
|
|
308
194
|
|
|
309
195
|
// Verify content loaded
|
|
310
196
|
await testdriver.assert('more than 10 items are visible');
|
|
311
197
|
});
|
|
312
|
-
|
|
313
|
-
it('should scroll until loading completes', async () => {
|
|
314
|
-
// Scroll until loading spinner disappears
|
|
315
|
-
await testdriver.scrollUntilImage(
|
|
316
|
-
'loading spinner',
|
|
317
|
-
'down',
|
|
318
|
-
5000,
|
|
319
|
-
'keyboard',
|
|
320
|
-
null,
|
|
321
|
-
true // invert - wait for it to disappear
|
|
322
|
-
);
|
|
323
|
-
|
|
324
|
-
// Now interact with loaded content
|
|
325
|
-
const firstResult = await testdriver.find('first search result');
|
|
326
|
-
await firstResult.click();
|
|
327
|
-
});
|
|
328
198
|
});
|
|
329
199
|
```
|
|
330
200
|
|
|
@@ -50,12 +50,12 @@ Get your API key at: **https://console.testdriver.ai/team**
|
|
|
50
50
|
|
|
51
51
|
### Installation
|
|
52
52
|
|
|
53
|
-
Always use the **
|
|
53
|
+
Always use the **canary** tag when installing TestDriver:
|
|
54
54
|
|
|
55
55
|
```bash
|
|
56
|
-
npm install --save-dev testdriverai@
|
|
56
|
+
npm install --save-dev testdriverai@canary
|
|
57
57
|
# or
|
|
58
|
-
npx testdriverai@
|
|
58
|
+
npx testdriverai@canary init
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
### Test Runner
|
|
@@ -392,8 +392,6 @@ await element.click();
|
|
|
392
392
|
|
|
393
393
|
```javascript
|
|
394
394
|
await testdriver.scroll("down");
|
|
395
|
-
await testdriver.scrollUntilText("Footer text");
|
|
396
|
-
await testdriver.scrollUntilImage("Product image at bottom");
|
|
397
395
|
```
|
|
398
396
|
|
|
399
397
|
### Executing Code in Sandbox
|
|
@@ -34,7 +34,7 @@ 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
|
|
37
|
+
7. **⚠️ RUN THE TEST YOURSELF**: Use `vitest run <testFile>` 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
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.
|
|
39
39
|
|
|
40
40
|
## Prerequisites
|
|
@@ -305,11 +305,9 @@ assert({ assertion: "the dashboard is visible" })
|
|
|
305
305
|
**⚠️ YOU must run the test - do NOT tell the user to run it. NEVER use `npx vitest` - always use `vitest` directly:**
|
|
306
306
|
|
|
307
307
|
```bash
|
|
308
|
-
vitest run tests/login.test.mjs
|
|
308
|
+
vitest run tests/login.test.mjs
|
|
309
309
|
```
|
|
310
310
|
|
|
311
|
-
**Always use `--reporter=dot`** for cleaner, more concise output that's easier to parse.
|
|
312
|
-
|
|
313
311
|
Analyze the output, fix any issues, and iterate until the test passes.
|
|
314
312
|
|
|
315
313
|
**⚠️ 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.
|
|
@@ -558,8 +556,6 @@ await testdriver.pressKeys(["escape"]);
|
|
|
558
556
|
|
|
559
557
|
// Now scroll
|
|
560
558
|
await testdriver.scroll("down");
|
|
561
|
-
await testdriver.scrollUntilText("Footer text");
|
|
562
|
-
await testdriver.scrollUntilImage("Product image at bottom");
|
|
563
559
|
|
|
564
560
|
// If scroll is not working, try using Page Down key directly
|
|
565
561
|
await testdriver.pressKeys(["pagedown"]);
|
|
@@ -604,7 +600,7 @@ await testdriver.screenshot(1, false, true);
|
|
|
604
600
|
## Tips for Agents
|
|
605
601
|
|
|
606
602
|
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.
|
|
607
|
-
2. **⚠️ RUN TESTS YOURSELF** - Do NOT tell the user to run tests. YOU must run the tests using `vitest run <testFile
|
|
603
|
+
2. **⚠️ RUN TESTS YOURSELF** - Do NOT tell the user to run tests. YOU must run the tests using `vitest run <testFile>` (NEVER use `npx vitest`). Analyze the output and iterate until the test passes.
|
|
608
604
|
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.
|
|
609
605
|
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.
|
|
610
606
|
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.
|
|
@@ -47,4 +47,4 @@ await testdriver.wait();
|
|
|
47
47
|
const element = await testdriver.find('success message');
|
|
48
48
|
```
|
|
49
49
|
- Avoid excessively long timeouts to keep tests efficient.
|
|
50
|
-
- Use sparingly — TestDriver's [redraw detection](/v7/waiting-for-
|
|
50
|
+
- Use sparingly — TestDriver's [redraw detection](/v7/performing-actions#waiting-for-dynamic-content) automatically waits for screen and network stability after each action.
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
description: "Execute natural language tasks using AI"
|
|
5
|
-
icon: "wand-magic-sparkles"
|
|
2
|
+
name: testdriver:ai
|
|
3
|
+
description: Execute natural language tasks using AI
|
|
6
4
|
---
|
|
5
|
+
<!-- Generated from ai.mdx. DO NOT EDIT. -->
|
|
7
6
|
|
|
8
7
|
## Overview
|
|
9
8
|
|