@testdriverai/agent 7.11.229-test → 7.11.232-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 +79 -22
- 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 +26 -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/provision.mdx
CHANGED
|
@@ -1,314 +1,269 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "
|
|
3
|
-
sidebarTitle: "
|
|
4
|
-
description: "
|
|
2
|
+
title: "Launch apps in the sandbox"
|
|
3
|
+
sidebarTitle: "Launching apps"
|
|
4
|
+
description: "Start Chrome, a Chrome extension, VS Code, an Electron app, or an installer in the sandbox."
|
|
5
5
|
icon: "rocket"
|
|
6
6
|
mode: "wide"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
The Provision API sets up applications in your sandbox before the tests run. It downloads, installs, and starts browsers, desktop apps, VS Code, Chrome extensions, and more.
|
|
12
|
-
|
|
13
|
-
Use the provision methods through `testdriver.provision.*`:
|
|
9
|
+
Start the app you want to test with a `provision` method. Call one at the beginning of each test.
|
|
14
10
|
|
|
15
11
|
```javascript
|
|
16
|
-
await testdriver.provision.chrome({ url: 'https://
|
|
12
|
+
await testdriver.provision.chrome({ url: 'https://testdriver-sandbox.vercel.app/login' });
|
|
17
13
|
```
|
|
18
14
|
|
|
19
|
-
|
|
15
|
+
Every provision method:
|
|
20
16
|
|
|
21
|
-
|
|
17
|
+
- Launches or installs the app in the sandbox. The Chrome methods also wait until Chrome is ready.
|
|
18
|
+
- Starts the [Dashcam](/dashcam) recording, unless you turned it off with `dashcam: false`.
|
|
19
|
+
- Does nothing when the client was created with `reconnect: true`, because the app is already running.
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
| Method | Use it to test |
|
|
22
|
+
| --- | --- |
|
|
23
|
+
| [`chrome()`](#chrome-options) | A website |
|
|
24
|
+
| [`chromeExtension()`](#chromeextension-options) | A Chrome extension |
|
|
25
|
+
| [`vscode()`](#vscode-options) | VS Code or a VS Code extension |
|
|
26
|
+
| [`installer()`](#installer-options) | A desktop app you download and install |
|
|
27
|
+
| [`electron()`](#electron-options) | An Electron app |
|
|
28
|
+
| [`dashcam()`](#dashcam-options) | Custom recording settings |
|
|
24
29
|
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
## chrome(options)
|
|
31
|
+
|
|
32
|
+
Opens Chrome at a URL.
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
testdriver.provision.chrome(options?: ProvisionChromeOptions): Promise<void>
|
|
27
36
|
```
|
|
28
37
|
|
|
29
38
|
<ParamField path="options" type="ProvisionChromeOptions">
|
|
30
39
|
<Expandable title="properties">
|
|
31
40
|
<ParamField path="url" type="string" default="http://testdriver-sandbox.vercel.app/">
|
|
32
|
-
The
|
|
41
|
+
The page to open.
|
|
33
42
|
</ParamField>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Start Chrome with the window at the maximum size.
|
|
43
|
+
<ParamField path="maximized" type="boolean" default="true">
|
|
44
|
+
Start with the window maximized.
|
|
37
45
|
</ParamField>
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
Start Chrome in the guest profile mode.
|
|
46
|
+
<ParamField path="guest" type="boolean" default="false">
|
|
47
|
+
Use Chrome's guest profile, with no saved data.
|
|
41
48
|
</ParamField>
|
|
42
49
|
</Expandable>
|
|
43
50
|
</ParamField>
|
|
44
51
|
|
|
52
|
+
Chrome also records the site's network traffic in the Dashcam replay.
|
|
53
|
+
|
|
45
54
|
```javascript
|
|
46
|
-
|
|
47
|
-
await testdriver.provision.chrome({ url: 'https://example.com' });
|
|
48
|
-
|
|
49
|
-
// With guest mode
|
|
50
|
-
await testdriver.provision.chrome({
|
|
51
|
-
url: 'https://example.com',
|
|
52
|
-
guest: true,
|
|
53
|
-
maximized: true,
|
|
54
|
-
});
|
|
55
|
+
await testdriver.provision.chrome({ url: 'https://example.com', guest: true });
|
|
55
56
|
```
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
## chromeExtension(options)
|
|
58
59
|
|
|
59
|
-
|
|
60
|
+
Opens Chrome with an extension loaded.
|
|
60
61
|
|
|
61
|
-
```
|
|
62
|
-
|
|
62
|
+
```typescript
|
|
63
|
+
testdriver.provision.chromeExtension(options: ProvisionChromeExtensionOptions): Promise<void>
|
|
63
64
|
```
|
|
64
65
|
|
|
65
66
|
<ParamField path="options" type="ProvisionChromeExtensionOptions" required>
|
|
66
|
-
|
|
67
|
+
Pass either `extensionId` or `extensionPath`. It throws if you pass neither.
|
|
67
68
|
|
|
68
69
|
<Expandable title="properties">
|
|
69
|
-
<ParamField path="extensionPath" type="string">
|
|
70
|
-
Local path to an unpacked extension directory. The extension files are uploaded to the sandbox.
|
|
71
|
-
</ParamField>
|
|
72
|
-
|
|
73
70
|
<ParamField path="extensionId" type="string">
|
|
74
|
-
Chrome Web Store extension ID
|
|
71
|
+
A Chrome Web Store extension ID. TestDriver downloads the extension into the sandbox.
|
|
75
72
|
</ParamField>
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
<ParamField path="extensionPath" type="string">
|
|
74
|
+
The path to an unpacked extension **inside the sandbox**. Nothing is copied from your machine, so get the files there first, for example with [`exec()`](/exec).
|
|
75
|
+
</ParamField>
|
|
76
|
+
<ParamField path="maximized" type="boolean" default="true">
|
|
77
|
+
Start with the window maximized.
|
|
79
78
|
</ParamField>
|
|
80
79
|
</Expandable>
|
|
81
80
|
</ParamField>
|
|
82
81
|
|
|
82
|
+
From the Chrome Web Store:
|
|
83
|
+
|
|
83
84
|
```javascript
|
|
84
|
-
// From local directory
|
|
85
85
|
await testdriver.provision.chromeExtension({
|
|
86
|
-
|
|
86
|
+
extensionId: 'cjpalhdlnbpafiamejdnhcphjbkeiagm', // uBlock Origin
|
|
87
87
|
});
|
|
88
|
+
```
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
From source:
|
|
91
|
+
|
|
92
|
+
```javascript
|
|
93
|
+
await testdriver.exec({
|
|
94
|
+
language: 'sh',
|
|
95
|
+
code: 'git clone https://github.com/your-org/your-extension.git /tmp/your-extension',
|
|
92
96
|
});
|
|
97
|
+
await testdriver.provision.chromeExtension({ extensionPath: '/tmp/your-extension' });
|
|
93
98
|
```
|
|
94
99
|
|
|
95
|
-
|
|
100
|
+
## vscode(options)
|
|
96
101
|
|
|
97
|
-
|
|
102
|
+
Opens VS Code, optionally with a folder and extensions.
|
|
98
103
|
|
|
99
|
-
```
|
|
100
|
-
|
|
104
|
+
```typescript
|
|
105
|
+
testdriver.provision.vscode(options?: ProvisionVSCodeOptions): Promise<void>
|
|
101
106
|
```
|
|
102
107
|
|
|
103
108
|
<ParamField path="options" type="ProvisionVSCodeOptions">
|
|
104
109
|
<Expandable title="properties">
|
|
105
110
|
<ParamField path="workspace" type="string">
|
|
106
|
-
|
|
111
|
+
A folder or `.code-workspace` file in the sandbox to open.
|
|
107
112
|
</ParamField>
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
Array of VS Code extension IDs to install before launching.
|
|
113
|
+
<ParamField path="extensions" type="string[]" default="[]">
|
|
114
|
+
Marketplace extension IDs to install before VS Code opens.
|
|
111
115
|
</ParamField>
|
|
112
116
|
</Expandable>
|
|
113
117
|
</ParamField>
|
|
114
118
|
|
|
115
119
|
```javascript
|
|
116
120
|
await testdriver.provision.vscode({
|
|
117
|
-
workspace: '/
|
|
118
|
-
extensions: ['
|
|
121
|
+
workspace: '/tmp/my-project',
|
|
122
|
+
extensions: ['esbenp.prettier-vscode'],
|
|
119
123
|
});
|
|
120
124
|
```
|
|
121
125
|
|
|
122
|
-
|
|
126
|
+
## installer(options)
|
|
123
127
|
|
|
124
|
-
|
|
128
|
+
Downloads a file into the sandbox, installs it, and returns the downloaded file's path.
|
|
125
129
|
|
|
126
|
-
```
|
|
127
|
-
|
|
130
|
+
```typescript
|
|
131
|
+
testdriver.provision.installer(options: ProvisionInstallerOptions): Promise<string>
|
|
128
132
|
```
|
|
129
133
|
|
|
130
134
|
<ParamField path="options" type="ProvisionInstallerOptions" required>
|
|
131
135
|
<Expandable title="properties">
|
|
132
136
|
<ParamField path="url" type="string" required>
|
|
133
|
-
|
|
137
|
+
Where to download the file from.
|
|
134
138
|
</ParamField>
|
|
135
|
-
|
|
136
139
|
<ParamField path="filename" type="string">
|
|
137
|
-
|
|
140
|
+
The name to save the file as. By default, it comes from the download.
|
|
138
141
|
</ParamField>
|
|
139
|
-
|
|
140
142
|
<ParamField path="appName" type="string">
|
|
141
|
-
|
|
143
|
+
The app to bring to the front after installing.
|
|
142
144
|
</ParamField>
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
145
|
+
<ParamField path="launch" type="boolean" default="true">
|
|
146
|
+
Start the app after installing it.
|
|
147
|
+
|
|
148
|
+
- **`.deb` on Linux:** starts the app from its `.desktop` entry. If there isn't one and you set `appName`, it starts the package's first `/usr/bin` program.
|
|
149
|
+
- **`.sh` scripts:** runs the script.
|
|
150
|
+
- **Everywhere:** focuses `appName`, if you set it.
|
|
151
|
+
|
|
152
|
+
With `false`, packages are still installed, and a script is only made executable.
|
|
146
153
|
</ParamField>
|
|
147
154
|
</Expandable>
|
|
148
155
|
</ParamField>
|
|
149
156
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
+
TestDriver picks the install method from the file extension:
|
|
158
|
+
|
|
159
|
+
| OS | Extension | What happens |
|
|
160
|
+
| --- | --- | --- |
|
|
161
|
+
| Windows | `.msi` | Installed quietly with `msiexec` |
|
|
162
|
+
| Windows | `.exe` | Run with `/S` for a silent install |
|
|
163
|
+
| Linux | `.deb` | Installed with `dpkg`. Missing dependencies are installed with `apt-get`, and the step fails if the package still isn't fully installed |
|
|
164
|
+
| Linux | `.rpm` | Installed with `rpm` |
|
|
165
|
+
| Linux | `.AppImage` | Made executable |
|
|
166
|
+
| Linux | `.sh` | Made executable and run (only made executable with `launch: false`) |
|
|
167
|
+
| macOS | `.dmg`, `.pkg` | Copied to Applications, or installed with `installer` |
|
|
168
|
+
|
|
169
|
+
Other file types are downloaded but not installed.
|
|
157
170
|
|
|
158
171
|
```javascript
|
|
159
|
-
//
|
|
172
|
+
// Install bat, then check that it runs (bat has no window, so nothing is launched)
|
|
160
173
|
await testdriver.provision.installer({
|
|
161
|
-
url: 'https://
|
|
162
|
-
appName: 'MyApp',
|
|
174
|
+
url: 'https://github.com/sharkdp/bat/releases/download/v0.24.0/bat_0.24.0_amd64.deb',
|
|
163
175
|
});
|
|
176
|
+
const output = await testdriver.exec({ language: 'sh', code: 'bat --version' });
|
|
177
|
+
console.log(output); // for example "bat 0.24.0"
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Install a desktop app and start it:
|
|
164
181
|
|
|
165
|
-
|
|
182
|
+
```javascript
|
|
183
|
+
// Installs Yaak and its dependencies, starts it, and brings its window to the front
|
|
166
184
|
await testdriver.provision.installer({
|
|
167
|
-
url: 'https://
|
|
168
|
-
appName: '
|
|
185
|
+
url: 'https://github.com/mountain-loop/yaak/releases/download/v2026.9.0/yaak_2026.9.0_amd64.deb',
|
|
186
|
+
appName: 'Yaak',
|
|
169
187
|
});
|
|
170
188
|
```
|
|
171
189
|
|
|
172
|
-
|
|
190
|
+
## electron(options)
|
|
173
191
|
|
|
174
|
-
|
|
192
|
+
Opens an Electron app that's already in the sandbox.
|
|
175
193
|
|
|
176
|
-
```
|
|
177
|
-
|
|
194
|
+
```typescript
|
|
195
|
+
testdriver.provision.electron(options: ProvisionElectronOptions): Promise<void>
|
|
178
196
|
```
|
|
179
197
|
|
|
180
198
|
<ParamField path="options" type="ProvisionElectronOptions" required>
|
|
181
199
|
<Expandable title="properties">
|
|
182
200
|
<ParamField path="appPath" type="string" required>
|
|
183
|
-
|
|
201
|
+
The path to the app in the sandbox. It throws if this is missing.
|
|
184
202
|
</ParamField>
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
Additional command-line arguments to pass to the Electron app.
|
|
203
|
+
<ParamField path="args" type="string[]" default="[]">
|
|
204
|
+
Extra command-line arguments for the app.
|
|
188
205
|
</ParamField>
|
|
189
206
|
</Expandable>
|
|
190
207
|
</ParamField>
|
|
191
208
|
|
|
192
209
|
```javascript
|
|
193
|
-
await testdriver.provision.electron({
|
|
194
|
-
appPath: '/home/testdriver/my-electron-app',
|
|
195
|
-
args: ['--no-sandbox'],
|
|
196
|
-
});
|
|
210
|
+
await testdriver.provision.electron({ appPath: '/tmp/my-electron-app', args: ['--no-sandbox'] });
|
|
197
211
|
```
|
|
198
212
|
|
|
199
|
-
|
|
213
|
+
## dashcam(options)
|
|
200
214
|
|
|
201
|
-
|
|
215
|
+
Starts the Dashcam recording with your own settings. The other provision methods start it for you, so call this only to change the log file, the log name, or the recording's title.
|
|
202
216
|
|
|
203
|
-
```
|
|
204
|
-
|
|
217
|
+
```typescript
|
|
218
|
+
testdriver.provision.dashcam(options?: ProvisionDashcamOptions): Promise<void>
|
|
205
219
|
```
|
|
206
220
|
|
|
207
221
|
<ParamField path="options" type="ProvisionDashcamOptions">
|
|
208
222
|
<Expandable title="properties">
|
|
209
223
|
<ParamField path="logPath" type="string">
|
|
210
|
-
|
|
224
|
+
A log file in the sandbox to include in the replay. Defaults to `/tmp/testdriver.log` on Linux, or `C:\Users\testdriver\testdriver.log` on Windows.
|
|
211
225
|
</ParamField>
|
|
212
|
-
|
|
213
226
|
<ParamField path="logName" type="string" default="TestDriver Log">
|
|
214
|
-
|
|
227
|
+
The log's name in the replay.
|
|
215
228
|
</ParamField>
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
Enable web traffic log capture.
|
|
229
|
+
<ParamField path="webLogs" type="boolean" default="true">
|
|
230
|
+
Record network traffic. It covers the site opened with `chrome()`, or all traffic otherwise.
|
|
219
231
|
</ParamField>
|
|
220
|
-
|
|
221
232
|
<ParamField path="title" type="string">
|
|
222
|
-
|
|
233
|
+
A title for the recording.
|
|
223
234
|
</ParamField>
|
|
224
235
|
</Expandable>
|
|
225
236
|
</ParamField>
|
|
226
237
|
|
|
227
238
|
```javascript
|
|
228
|
-
await testdriver.provision.dashcam({
|
|
229
|
-
title: 'Login Flow Test',
|
|
230
|
-
logPath: '/tmp/my-app.log',
|
|
231
|
-
logName: 'Application Log',
|
|
232
|
-
webLogs: true,
|
|
233
|
-
});
|
|
239
|
+
await testdriver.provision.dashcam({ title: 'Checkout flow', logPath: '/tmp/my-app.log', logName: 'App log' });
|
|
234
240
|
```
|
|
235
241
|
|
|
236
|
-
##
|
|
242
|
+
## Complete example
|
|
237
243
|
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
maximized?: boolean; // Default: true
|
|
242
|
-
guest?: boolean; // Default: false
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
interface ProvisionChromeExtensionOptions {
|
|
246
|
-
extensionPath?: string; // Local unpacked extension path
|
|
247
|
-
extensionId?: string; // Chrome Web Store ID
|
|
248
|
-
maximized?: boolean; // Default: true
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
interface ProvisionVSCodeOptions {
|
|
252
|
-
workspace?: string; // Workspace path
|
|
253
|
-
extensions?: string[]; // Extension IDs to install
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
interface ProvisionInstallerOptions {
|
|
257
|
-
url: string; // Download URL (required)
|
|
258
|
-
filename?: string; // Override filename
|
|
259
|
-
appName?: string; // App name to focus
|
|
260
|
-
launch?: boolean; // Default: true
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
interface ProvisionElectronOptions {
|
|
264
|
-
appPath: string; // Path to Electron app (required)
|
|
265
|
-
args?: string[]; // Additional args
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
interface ProvisionDashcamOptions {
|
|
269
|
-
logPath?: string; // Log file path
|
|
270
|
-
logName?: string; // Default: "TestDriver Log"
|
|
271
|
-
webLogs?: boolean; // Default: true
|
|
272
|
-
title?: string; // Recording title
|
|
273
|
-
}
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
## Complete Example
|
|
244
|
+
```javascript tests/extension.test.mjs
|
|
245
|
+
import { describe, expect, it } from 'vitest';
|
|
246
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
277
247
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
describe('Chrome Extension Test', () => {
|
|
283
|
-
let testdriver;
|
|
248
|
+
describe('Loom extension', () => {
|
|
249
|
+
it('appears in the extensions menu', async (context) => {
|
|
250
|
+
const testdriver = TestDriver(context);
|
|
284
251
|
|
|
285
|
-
beforeAll(async () => {
|
|
286
|
-
testdriver = new TestDriver({
|
|
287
|
-
os: 'linux',
|
|
288
|
-
resolution: '1920x1080',
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
await testdriver.ready();
|
|
292
|
-
|
|
293
|
-
// Install extension and open Chrome
|
|
294
252
|
await testdriver.provision.chromeExtension({
|
|
295
|
-
|
|
253
|
+
extensionId: 'liecbddmkiiihnedobmlmillhodjkdmb',
|
|
296
254
|
});
|
|
297
|
-
|
|
298
|
-
// Start Dashcam with custom logs
|
|
299
|
-
await testdriver.provision.dashcam({
|
|
300
|
-
title: 'Extension Test',
|
|
301
|
-
webLogs: true,
|
|
302
|
-
});
|
|
303
|
-
});
|
|
304
255
|
|
|
305
|
-
|
|
306
|
-
await testdriver.disconnect();
|
|
307
|
-
});
|
|
256
|
+
await testdriver.find('puzzle-piece extensions icon in the Chrome toolbar').click();
|
|
308
257
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
await testdriver.find('popup content').click();
|
|
258
|
+
const loom = await testdriver.find('Loom in the extensions dropdown');
|
|
259
|
+
expect(loom.found()).toBe(true);
|
|
312
260
|
});
|
|
313
261
|
});
|
|
314
262
|
```
|
|
263
|
+
|
|
264
|
+
## Related
|
|
265
|
+
|
|
266
|
+
- [Client & connection](/client): create and connect the client
|
|
267
|
+
- [exec()](/exec): run commands in the sandbox, for example to fetch files before provisioning
|
|
268
|
+
- [Dashcam](/dashcam): how runs are recorded
|
|
269
|
+
- [Examples](/examples/installer): complete tests that install and launch apps
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Add TestDriver to Claude Code"
|
|
3
|
+
sidebarTitle: "Claude Code"
|
|
4
|
+
description: "Install one plugin to get the TestDriver MCP server, agent, and skills in Claude Code."
|
|
5
|
+
icon: "terminal"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Install the TestDriver plugin, and Claude Code can write, run, and debug end-to-end tests in a live sandbox.
|
|
9
|
+
|
|
10
|
+
The plugin bundles three things:
|
|
11
|
+
|
|
12
|
+
- The TestDriver MCP server
|
|
13
|
+
- The `testdriver` agent, which builds tests step by step
|
|
14
|
+
- Skills that teach Claude the TestDriver SDK
|
|
15
|
+
|
|
16
|
+
## Before you begin
|
|
17
|
+
|
|
18
|
+
- **[Claude Code](https://code.claude.com)** and **Node.js 20.19 or later**, which runs the MCP server.
|
|
19
|
+
- **A TestDriver API key.** Create one at [console.testdriver.ai/team/api-keys](https://console.testdriver.ai/team/api-keys).
|
|
20
|
+
- **A project with the TestDriver SDK installed**, so the agent can run the tests it writes. If you don't have one yet, see [Set up a project](/quickstart-manual).
|
|
21
|
+
|
|
22
|
+
<Steps>
|
|
23
|
+
<Step title="Set your API key">
|
|
24
|
+
|
|
25
|
+
The plugin's MCP server reads your key from the `TD_API_KEY` environment variable. Add it to your shell profile (such as `~/.zshrc`) so every Claude Code session can use it:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
export TD_API_KEY="your_api_key"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Open a new terminal, or run `source ~/.zshrc`, before you start Claude Code.
|
|
32
|
+
|
|
33
|
+
</Step>
|
|
34
|
+
<Step title="Install the plugin">
|
|
35
|
+
|
|
36
|
+
TestDriver is a community plugin. In Claude Code, run `/plugin`, open the **Discover** tab, search for **TestDriver**, and install it.
|
|
37
|
+
|
|
38
|
+
You can also install it from TestDriver's own marketplace:
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
/plugin marketplace add testdriverai/testdriverai
|
|
42
|
+
/plugin install testdriver@testdriver
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
</Step>
|
|
46
|
+
<Step title="Check the connection">
|
|
47
|
+
|
|
48
|
+
Run `/mcp` in Claude Code. The `testdriver` server should be listed as connected.
|
|
49
|
+
|
|
50
|
+
If it isn't, check that `TD_API_KEY` is set in the terminal you started Claude Code from.
|
|
51
|
+
|
|
52
|
+
</Step>
|
|
53
|
+
<Step title="Write your first test">
|
|
54
|
+
|
|
55
|
+
Ask for the TestDriver agent by name:
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
Use the testdriver agent to write a test that logs in to https://testdriver-sandbox.vercel.app/login and adds an item to the cart.
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The agent starts a sandbox and performs each step. It writes the code into a test file under `tests/`, then runs it with Vitest until it passes.
|
|
62
|
+
|
|
63
|
+
</Step>
|
|
64
|
+
</Steps>
|
|
65
|
+
|
|
66
|
+
<Tip>
|
|
67
|
+
Only need TestDriver's tools in chat, without the agent or skills? Add the hosted server instead. It signs in through your browser and needs no API key. See [MCP Setup](/mcp-setup).
|
|
68
|
+
</Tip>
|
|
69
|
+
|
|
70
|
+
## Next steps
|
|
71
|
+
|
|
72
|
+
<CardGroup cols={2}>
|
|
73
|
+
<Card title="Generate tests with AI" icon="compass" href="/generating-tests">
|
|
74
|
+
Prompt the agent and steer it while it works.
|
|
75
|
+
</Card>
|
|
76
|
+
<Card title="Make assertions" icon="circle-check" href="/making-assertions">
|
|
77
|
+
Check what's on screen in plain language.
|
|
78
|
+
</Card>
|
|
79
|
+
<Card title="Run tests" icon="play" href="/copilot/running-tests">
|
|
80
|
+
Run your tests locally and choose a device.
|
|
81
|
+
</Card>
|
|
82
|
+
<Card title="Run in CI/CD" icon="code-branch" href="/ci-cd">
|
|
83
|
+
Run your tests on every pull request.
|
|
84
|
+
</Card>
|
|
85
|
+
</CardGroup>
|
|
@@ -1,54 +1,84 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Add TestDriver to GitHub"
|
|
3
3
|
sidebarTitle: "Add to GitHub"
|
|
4
|
-
description: "
|
|
4
|
+
description: "Get an AI code review on every pull request, backed by a real run of your app."
|
|
5
5
|
icon: "github"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Install the TestDriver GitHub app, and the TestDriver agent reviews every pull request in your repository.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
- It reads the diff for bugs.
|
|
11
|
+
- When a user would see the change, it runs your app in a real sandbox to prove what it finds.
|
|
12
|
+
- It writes and maintains end-to-end tests whenever you ask.
|
|
13
|
+
|
|
14
|
+
There's nothing to install locally.
|
|
15
|
+
|
|
16
|
+
## Before you begin
|
|
17
|
+
|
|
18
|
+
- **A GitHub repository** where you can install apps (you own it, or you're an admin of its organization).
|
|
19
|
+
- **A TestDriver account.** You create one or sign in during installation.
|
|
20
|
+
- **A paid plan or trial for automatic reviews.** On the free plan, the agent still reviews a pull request when you @mention it. See [pricing](https://testdriver.ai/pricing).
|
|
19
21
|
|
|
20
22
|
<Steps>
|
|
21
|
-
<Step title="Install the GitHub
|
|
22
|
-
|
|
23
|
+
<Step title="Install the GitHub app">
|
|
24
|
+
|
|
25
|
+
Open [TestDriver on GitHub](https://go.testdriver.ai/github). Install the app on the repositories you want reviewed, and sign in to TestDriver when prompted.
|
|
26
|
+
|
|
27
|
+
You can add more repositories later from your GitHub settings.
|
|
28
|
+
|
|
29
|
+
</Step>
|
|
30
|
+
<Step title="Get your first tests">
|
|
31
|
+
|
|
32
|
+
Choose a repository to set up. TestDriver opens a **Set up TestDriver** issue in it.
|
|
33
|
+
|
|
34
|
+
The agent picks up the issue, writes a few sample tests for your app, and runs them. It opens a pull request with the tests and their recordings. Review it and merge it like any other pull request.
|
|
35
|
+
|
|
23
36
|
</Step>
|
|
37
|
+
<Step title="Open a pull request">
|
|
24
38
|
|
|
25
|
-
|
|
26
|
-
|
|
39
|
+
From now on, every pull request you open gets a review without anyone asking. The agent reads the change and runs it when there's something to drive.
|
|
40
|
+
|
|
41
|
+
It posts a single review comment with:
|
|
42
|
+
|
|
43
|
+
- A summary
|
|
44
|
+
- A walkthrough of the changed files
|
|
45
|
+
- Any bugs it found, each labelled `observed` (seen during a run) or `suspected` (inferred from the code)
|
|
46
|
+
|
|
47
|
+
Pushing new commits triggers a fresh review.
|
|
48
|
+
|
|
49
|
+
The review is a comment, so it never approves or blocks a merge. To fail a pull request when a test breaks, [run your tests in CI](/ci-cd).
|
|
50
|
+
|
|
51
|
+
</Step>
|
|
52
|
+
<Step title="Ask for more with @testdriverai">
|
|
53
|
+
|
|
54
|
+
Mention the agent on any issue or pull request to ask a follow-up question or request a new test:
|
|
27
55
|
|
|
28
56
|
```text
|
|
29
|
-
@testdriverai Write a test that
|
|
57
|
+
@testdriverai Write a test that logs in, adds the first product to the cart, and confirms the cart badge shows 1.
|
|
30
58
|
```
|
|
31
59
|
|
|
32
|
-
|
|
60
|
+
The agent replies in the thread and posts screenshots as it works. When it's done, it opens a pull request with the test.
|
|
33
61
|
|
|
34
62
|
<Tip>
|
|
35
|
-
|
|
63
|
+
Describe what a user does and what they should see, not how the page is built. "Confirm the cart badge shows 1" works better than "check `#cart-count`".
|
|
36
64
|
</Tip>
|
|
37
|
-
</Step>
|
|
38
65
|
|
|
39
|
-
<Step title="Catch regressions automatically">
|
|
40
|
-
Once tests are committed, TestDriver runs them on every pull request that changes something a user would see and posts a review with what it observed, including a recording. Mention `@testdriverai` on any PR to ask follow-up questions or request more tests.
|
|
41
66
|
</Step>
|
|
42
67
|
</Steps>
|
|
43
68
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
<
|
|
47
|
-
title="
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
>
|
|
53
|
-
|
|
54
|
-
|
|
69
|
+
## Next steps
|
|
70
|
+
|
|
71
|
+
<CardGroup cols={2}>
|
|
72
|
+
<Card title="How the agent works" icon="hand-horns" href="/agent">
|
|
73
|
+
What the agent does on pull requests, issues, and mentions.
|
|
74
|
+
</Card>
|
|
75
|
+
<Card title="Prevent regressions" icon="shield-check" href="/copilot/auto-healing">
|
|
76
|
+
Run tests in CI and have the agent fix them when your app changes.
|
|
77
|
+
</Card>
|
|
78
|
+
<Card title="Run tests in CI/CD" icon="code-branch" href="/ci-cd">
|
|
79
|
+
Run your TestDriver tests in GitHub Actions.
|
|
80
|
+
</Card>
|
|
81
|
+
<Card title="Set up a project" icon="wrench" href="/quickstart-manual">
|
|
82
|
+
Write and run tests yourself in your own repository.
|
|
83
|
+
</Card>
|
|
84
|
+
</CardGroup>
|