@testdriverai/agent 7.11.229-canary → 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/client.mdx
CHANGED
|
@@ -1,323 +1,269 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "Client &
|
|
3
|
-
sidebarTitle: "Client &
|
|
4
|
-
description: "Create
|
|
2
|
+
title: "Client & connection"
|
|
3
|
+
sidebarTitle: "Client & connection"
|
|
4
|
+
description: "Create a TestDriver client, connect it to a sandbox, and disconnect when you're done."
|
|
5
5
|
icon: "plug"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
import { EnterpriseBadge, EnterpriseCta } from '/snippets/enterprise.mdx';
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Every test talks to its sandbox through a TestDriver client. There are two ways to create one:
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
- **`TestDriver(context)`** from `testdriverai/vitest/hooks`. Use this in Vitest tests. It connects and disconnects for you.
|
|
13
|
+
- **`new TestDriver()`** from `testdriverai`. Use this outside Vitest's per-test hooks, when you manage the connection yourself.
|
|
13
14
|
|
|
14
15
|
```javascript
|
|
15
|
-
|
|
16
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
17
|
+
|
|
18
|
+
test('opens the login page', async (context) => {
|
|
19
|
+
const testdriver = TestDriver(context);
|
|
20
|
+
await testdriver.provision.chrome({ url: 'https://testdriver-sandbox.vercel.app/login' });
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## TestDriver(context, options)
|
|
25
|
+
|
|
26
|
+
Creates a client for the current Vitest test.
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
TestDriver(context: TestContext, options?: TestDriverOptions): TestDriver
|
|
16
30
|
```
|
|
17
31
|
|
|
18
32
|
### Parameters
|
|
19
33
|
|
|
20
|
-
<ParamField path="
|
|
21
|
-
|
|
34
|
+
<ParamField path="context" type="TestContext" required>
|
|
35
|
+
The context Vitest passes to your test function, as in `async (context) => { ... }`. TestDriver throws if it's missing.
|
|
22
36
|
</ParamField>
|
|
23
37
|
|
|
24
|
-
<ParamField path="options" type="
|
|
25
|
-
|
|
38
|
+
<ParamField path="options" type="TestDriverOptions">
|
|
39
|
+
Client options, such as `os`, `preview`, `cache`, or `keepAlive`. See [Options](/options) for the full list.
|
|
40
|
+
|
|
41
|
+
<Expandable title="hook-only options">
|
|
42
|
+
<ParamField path="apiKey" type="string">
|
|
43
|
+
Your TestDriver API key. Defaults to the `TD_API_KEY` environment variable, which TestDriver also loads from `.env`.
|
|
44
|
+
</ParamField>
|
|
45
|
+
<ParamField path="debugOnFailure" type="boolean" default="false">
|
|
46
|
+
If the test fails, keep its sandbox running instead of disconnecting, and print the sandbox id so you can reconnect to it.
|
|
47
|
+
</ParamField>
|
|
48
|
+
</Expandable>
|
|
26
49
|
</ParamField>
|
|
27
50
|
|
|
28
|
-
###
|
|
51
|
+
### What it does
|
|
29
52
|
|
|
30
|
-
|
|
31
|
-
|
|
53
|
+
- **Connects automatically.** It authenticates and connects to a sandbox in the background. Your first command waits for the connection.
|
|
54
|
+
- **Disconnects automatically** when the test finishes.
|
|
55
|
+
- **Returns one client per test.** Calling it again in the same test returns the same client. A retried test gets a new one.
|
|
56
|
+
- **Reads `TD_OS`.** If you don't pass `os`, it uses the `TD_OS` environment variable, then Linux.
|
|
32
57
|
|
|
33
|
-
|
|
34
|
-
const testdriver = new TestDriver({
|
|
35
|
-
os: 'windows',
|
|
36
|
-
resolution: '1920x1080',
|
|
37
|
-
logging: true,
|
|
38
|
-
analytics: true
|
|
39
|
-
});
|
|
58
|
+
### Returns
|
|
40
59
|
|
|
41
|
-
|
|
42
|
-
const testdriver = new TestDriver({
|
|
43
|
-
ai: { temperature: 0, top: { p: 0.9, k: 40 } }
|
|
44
|
-
});
|
|
60
|
+
A connected `TestDriver` client.
|
|
45
61
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
62
|
+
## new TestDriver(apiKey, options)
|
|
63
|
+
|
|
64
|
+
Creates a client that you connect and disconnect yourself.
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
new TestDriver(apiKey?: string, options?: TestDriverOptions)
|
|
68
|
+
new TestDriver(options?: TestDriverOptions)
|
|
50
69
|
```
|
|
51
70
|
|
|
52
|
-
|
|
71
|
+
### Parameters
|
|
53
72
|
|
|
54
|
-
|
|
73
|
+
<ParamField path="apiKey" type="string">
|
|
74
|
+
Your TestDriver API key. Defaults to `TD_API_KEY`, which TestDriver loads from `.env`. Create one at [console.testdriver.ai/team/api-keys](https://console.testdriver.ai/team/api-keys).
|
|
75
|
+
</ParamField>
|
|
55
76
|
|
|
56
|
-
|
|
77
|
+
<ParamField path="options" type="TestDriverOptions">
|
|
78
|
+
Client options. See [Options](/options).
|
|
79
|
+
</ParamField>
|
|
57
80
|
|
|
58
|
-
|
|
59
|
-
await testdriver.auth()
|
|
60
|
-
```
|
|
81
|
+
### Example
|
|
61
82
|
|
|
62
|
-
|
|
83
|
+
Share one sandbox across a test file by connecting in `beforeAll`:
|
|
63
84
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
```
|
|
85
|
+
```javascript tests/dashboard.test.mjs
|
|
86
|
+
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
|
87
|
+
import TestDriver from 'testdriverai';
|
|
68
88
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
</Note>
|
|
89
|
+
describe('Dashboard', () => {
|
|
90
|
+
let testdriver;
|
|
72
91
|
|
|
73
|
-
|
|
92
|
+
beforeAll(async () => {
|
|
93
|
+
testdriver = new TestDriver({ os: 'linux' });
|
|
94
|
+
await testdriver.connect();
|
|
95
|
+
await testdriver.provision.chrome({ url: 'https://testdriver-sandbox.vercel.app/login' });
|
|
96
|
+
});
|
|
74
97
|
|
|
75
|
-
|
|
98
|
+
afterAll(async () => {
|
|
99
|
+
await testdriver.disconnect();
|
|
100
|
+
});
|
|
76
101
|
|
|
77
|
-
|
|
102
|
+
it('shows the login form', async () => {
|
|
103
|
+
const result = await testdriver.assert('a login form is visible');
|
|
104
|
+
expect(result).toBe(true);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
```
|
|
78
108
|
|
|
79
|
-
|
|
80
|
-
|
|
109
|
+
## connect(options)
|
|
110
|
+
|
|
111
|
+
Connects the client to a sandbox. By default, it creates a new sandbox.
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
testdriver.connect(options?: ConnectOptions): Promise<SandboxInstance>
|
|
81
115
|
```
|
|
82
116
|
|
|
83
|
-
|
|
117
|
+
`connect()` authenticates first if needed. You don't need to call `auth()` yourself.
|
|
84
118
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
119
|
+
### Parameters
|
|
120
|
+
|
|
121
|
+
<ParamField path="options" type="ConnectOptions">
|
|
88
122
|
<Expandable title="properties">
|
|
89
|
-
<ParamField path="newSandbox" type="boolean" default="false">
|
|
90
|
-
Force creation of a new sandbox instead of reusing an existing one
|
|
91
|
-
</ParamField>
|
|
92
|
-
|
|
93
123
|
<ParamField path="sandboxId" type="string">
|
|
94
|
-
|
|
124
|
+
Reconnect to this existing sandbox instead of creating one.
|
|
125
|
+
</ParamField>
|
|
126
|
+
<ParamField path="requireSandbox" type="boolean" default="false">
|
|
127
|
+
With `sandboxId`, throw if that sandbox is gone, instead of creating a new, empty one in its place.
|
|
128
|
+
</ParamField>
|
|
129
|
+
<ParamField path="reconnect" type="boolean">
|
|
130
|
+
Reconnect to the last sandbox this project used, recorded in `.testdriver/last-sandbox`. Provision calls are skipped, because the app is already running. Throws if there's no previous sandbox.
|
|
131
|
+
</ParamField>
|
|
132
|
+
<ParamField path="newSandbox" type="boolean" default="true">
|
|
133
|
+
Create a new sandbox. Set to `false` when you pass `sandboxId` or `reconnect`.
|
|
134
|
+
</ParamField>
|
|
135
|
+
<ParamField path="keepAlive" type="number" default="60000">
|
|
136
|
+
Milliseconds to keep the sandbox running after `disconnect()`, so you can reconnect. Capped at 30 minutes. `0` uses the default.
|
|
137
|
+
</ParamField>
|
|
138
|
+
<ParamField path="os" type="string" default="linux">
|
|
139
|
+
`"linux"` or `"windows"`. <EnterpriseBadge /> Windows is available on Enterprise plans.
|
|
140
|
+
</ParamField>
|
|
141
|
+
<ParamField path="preview" type="string" default="browser">
|
|
142
|
+
Where to show the live run: `"browser"`, `"ide"` (needs the TestDriver extension), or `"none"`.
|
|
143
|
+
</ParamField>
|
|
144
|
+
<ParamField path="reuseConnection" type="boolean" default="true">
|
|
145
|
+
Reuse a recent connection if one is available.
|
|
95
146
|
</ParamField>
|
|
96
|
-
|
|
97
147
|
<ParamField path="ip" type="string">
|
|
98
|
-
|
|
148
|
+
Connect directly to a running sandbox at this IP address, for self-hosted machines. <EnterpriseBadge />
|
|
99
149
|
</ParamField>
|
|
100
|
-
|
|
101
150
|
<ParamField path="sandboxAmi" type="string">
|
|
102
|
-
AMI
|
|
151
|
+
Custom AMI ID for the sandbox, for self-hosted AWS deployments. <EnterpriseBadge />
|
|
103
152
|
</ParamField>
|
|
104
|
-
|
|
105
153
|
<ParamField path="sandboxInstance" type="string">
|
|
106
|
-
|
|
154
|
+
EC2 instance type for the sandbox, for self-hosted AWS deployments. <EnterpriseBadge />
|
|
107
155
|
</ParamField>
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
Preview mode for live test visualization:
|
|
111
|
-
- `"browser"` - Opens debugger in default browser (default)
|
|
112
|
-
- `"ide"` - Opens preview in IDE panel (VSCode, Cursor - requires TestDriver extension)
|
|
113
|
-
- `"none"` - Headless mode, no visual preview
|
|
156
|
+
<ParamField path="e2bTemplateId" type="string">
|
|
157
|
+
E2B template ID to create the sandbox from.
|
|
114
158
|
</ParamField>
|
|
115
|
-
|
|
116
159
|
<ParamField path="headless" type="boolean" default="false">
|
|
117
|
-
|
|
118
|
-
</ParamField>
|
|
119
|
-
|
|
120
|
-
<ParamField path="keepAlive" type="number" default="60000">
|
|
121
|
-
Keep sandbox alive for the specified number of milliseconds after disconnect. Set to `0` to terminate immediately on disconnect. Useful for debugging or reconnecting to the same sandbox.
|
|
160
|
+
Deprecated. Use `preview: "none"` instead.
|
|
122
161
|
</ParamField>
|
|
123
162
|
</Expandable>
|
|
124
163
|
</ParamField>
|
|
125
164
|
|
|
126
|
-
|
|
165
|
+
### Returns
|
|
127
166
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
167
|
+
<ResponseField name="SandboxInstance" type="object">
|
|
168
|
+
<Expandable title="properties">
|
|
169
|
+
<ResponseField name="instanceId" type="string">
|
|
170
|
+
The sandbox's ID.
|
|
171
|
+
</ResponseField>
|
|
172
|
+
<ResponseField name="ip" type="string">
|
|
173
|
+
The sandbox's IP address.
|
|
174
|
+
</ResponseField>
|
|
175
|
+
<ResponseField name="vncPort" type="number">
|
|
176
|
+
The port for the sandbox's remote display.
|
|
177
|
+
</ResponseField>
|
|
178
|
+
</Expandable>
|
|
179
|
+
</ResponseField>
|
|
141
180
|
|
|
142
|
-
|
|
143
|
-
```javascript
|
|
144
|
-
await testdriver.connect({
|
|
145
|
-
ip: '192.168.1.100'
|
|
146
|
-
});
|
|
147
|
-
```
|
|
181
|
+
### Errors
|
|
148
182
|
|
|
149
|
-
|
|
183
|
+
Throws `Already connected` if the client is already connected. Create a new client to connect again.
|
|
150
184
|
|
|
151
|
-
|
|
185
|
+
### Example
|
|
152
186
|
|
|
153
187
|
```javascript
|
|
154
|
-
|
|
188
|
+
const testdriver = new TestDriver();
|
|
189
|
+
|
|
190
|
+
// Reattach to a sandbox you kept alive earlier
|
|
191
|
+
const sandbox = await testdriver.connect({ sandboxId: 'sandbox-abc123', newSandbox: false });
|
|
192
|
+
console.log(sandbox.instanceId);
|
|
155
193
|
```
|
|
156
194
|
|
|
157
|
-
|
|
195
|
+
## disconnect()
|
|
158
196
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
});
|
|
197
|
+
Disconnects from the sandbox. The sandbox keeps running for the `keepAlive` time, then shuts down.
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
testdriver.disconnect(): Promise<void>
|
|
164
201
|
```
|
|
165
202
|
|
|
166
|
-
|
|
203
|
+
The Vitest hook calls this for you.
|
|
167
204
|
|
|
168
|
-
|
|
205
|
+
## auth()
|
|
169
206
|
|
|
170
|
-
|
|
207
|
+
Authenticates with the TestDriver API and resolves to a session token.
|
|
171
208
|
|
|
172
|
-
```
|
|
173
|
-
|
|
209
|
+
```typescript
|
|
210
|
+
testdriver.auth(): Promise<string>
|
|
174
211
|
```
|
|
175
212
|
|
|
176
|
-
|
|
213
|
+
You rarely need it, because `connect()` calls it when needed.
|
|
177
214
|
|
|
178
|
-
|
|
179
|
-
```javascript
|
|
180
|
-
const instance = testdriver.getInstance();
|
|
181
|
-
console.log('Instance ID:', instance.instanceId);
|
|
182
|
-
console.log('IP Address:', instance.ip);
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
### getSessionId()
|
|
215
|
+
## getInstance()
|
|
186
216
|
|
|
187
|
-
|
|
217
|
+
Returns the connected sandbox's details, or `null` if the client isn't connected.
|
|
188
218
|
|
|
189
|
-
```
|
|
190
|
-
|
|
219
|
+
```typescript
|
|
220
|
+
testdriver.getInstance(): SandboxInstance | null
|
|
191
221
|
```
|
|
192
222
|
|
|
193
|
-
|
|
223
|
+
## getSessionId()
|
|
194
224
|
|
|
195
|
-
|
|
196
|
-
```javascript
|
|
197
|
-
const sessionId = testdriver.getSessionId();
|
|
198
|
-
console.log('Session:', sessionId);
|
|
199
|
-
```
|
|
225
|
+
Returns the current session ID, or `null`. Include it when you report a problem.
|
|
200
226
|
|
|
201
|
-
|
|
227
|
+
```typescript
|
|
228
|
+
testdriver.getSessionId(): string | null
|
|
229
|
+
```
|
|
202
230
|
|
|
203
|
-
|
|
231
|
+
## getLastSandboxId()
|
|
204
232
|
|
|
205
|
-
|
|
233
|
+
Returns the most recent sandbox, or `null` if there isn't one. It reads from the connected client, or from `.testdriver/last-sandbox`.
|
|
206
234
|
|
|
207
|
-
```
|
|
208
|
-
testdriver.
|
|
235
|
+
```typescript
|
|
236
|
+
testdriver.getLastSandboxId(): { sandboxId: string; os?: 'windows' | 'linux'; createdAt?: number } | null
|
|
209
237
|
```
|
|
210
238
|
|
|
211
|
-
|
|
212
|
-
- `enabled` (boolean) - Whether to enable logging
|
|
239
|
+
## setLogging(enabled)
|
|
213
240
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
testdriver.setLogging(
|
|
218
|
-
await testdriver.disconnect();
|
|
219
|
-
testdriver.setLogging(true);
|
|
241
|
+
Turns console logging on or off while the test runs.
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
testdriver.setLogging(enabled: boolean): void
|
|
220
245
|
```
|
|
221
246
|
|
|
222
|
-
|
|
247
|
+
## getEmitter()
|
|
223
248
|
|
|
224
|
-
|
|
249
|
+
Returns the client's event emitter, so you can react to what TestDriver does.
|
|
225
250
|
|
|
226
|
-
```
|
|
227
|
-
|
|
251
|
+
```typescript
|
|
252
|
+
testdriver.getEmitter(): EventEmitter2
|
|
228
253
|
```
|
|
229
254
|
|
|
230
|
-
**Returns:** `EventEmitter2` - Event emitter instance
|
|
231
|
-
|
|
232
|
-
**Example:**
|
|
233
255
|
```javascript
|
|
234
256
|
const emitter = testdriver.getEmitter();
|
|
235
257
|
|
|
236
|
-
emitter.on('
|
|
237
|
-
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
emitter.on('command:success', (data) => {
|
|
241
|
-
console.log('Command succeeded:', data);
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
emitter.on('command:error', (error) => {
|
|
245
|
-
console.error('Command failed:', error);
|
|
246
|
-
});
|
|
258
|
+
emitter.on('log:warn', (message) => console.warn('TestDriver warning:', message));
|
|
259
|
+
emitter.on('error:sdk', (error) => console.error('TestDriver API error:', error.message));
|
|
247
260
|
```
|
|
248
261
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
```javascript
|
|
252
|
-
import { beforeAll, afterAll, describe, it } from 'vitest';
|
|
253
|
-
import TestDriver from 'testdriverai';
|
|
254
|
-
|
|
255
|
-
describe('My Test Suite', () => {
|
|
256
|
-
let testdriver;
|
|
262
|
+
See [Events](/events) for every event name.
|
|
257
263
|
|
|
258
|
-
|
|
259
|
-
// Initialize client - API key loaded automatically from .env
|
|
260
|
-
testdriver = new TestDriver({
|
|
261
|
-
os: 'windows',
|
|
262
|
-
resolution: '1366x768',
|
|
263
|
-
logging: true
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
// Set up event listeners
|
|
267
|
-
const emitter = testdriver.getEmitter();
|
|
268
|
-
emitter.on('log:info', (msg) => console.log('[INFO]', msg));
|
|
269
|
-
|
|
270
|
-
// Authenticate and connect
|
|
271
|
-
await testdriver.auth();
|
|
272
|
-
const instance = await testdriver.connect();
|
|
273
|
-
|
|
274
|
-
console.log('Connected to sandbox:', instance.instanceId);
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
afterAll(async () => {
|
|
278
|
-
await testdriver.disconnect();
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
it('runs a test', async () => {
|
|
282
|
-
// Your test code here
|
|
283
|
-
});
|
|
284
|
-
});
|
|
285
|
-
```
|
|
264
|
+
## Related
|
|
286
265
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
Use `beforeAll`/`afterAll` to create one sandbox per test suite rather than per test. This significantly reduces execution time.
|
|
292
|
-
</Accordion>
|
|
293
|
-
|
|
294
|
-
<Accordion title="Handle connection errors gracefully">
|
|
295
|
-
Wrap `connect()` in a try-catch block to handle network issues or quota limits:
|
|
296
|
-
|
|
297
|
-
```javascript
|
|
298
|
-
try {
|
|
299
|
-
await testdriver.connect();
|
|
300
|
-
} catch (error) {
|
|
301
|
-
console.error('Failed to connect:', error.message);
|
|
302
|
-
throw error;
|
|
303
|
-
}
|
|
304
|
-
```
|
|
305
|
-
</Accordion>
|
|
306
|
-
|
|
307
|
-
<Accordion title="Always disconnect">
|
|
308
|
-
Use `afterAll` or try-finally blocks to ensure `disconnect()` is called even if tests fail. This prevents orphaned sandboxes.
|
|
309
|
-
</Accordion>
|
|
310
|
-
|
|
311
|
-
<Accordion title="Use environment variables for API keys">
|
|
312
|
-
Never hardcode API keys. The SDK automatically loads `TD_API_KEY` from your `.env` file:
|
|
313
|
-
|
|
314
|
-
```bash .env
|
|
315
|
-
TD_API_KEY=your_api_key_here
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
```javascript
|
|
319
|
-
// API key is loaded automatically - no need to pass it!
|
|
320
|
-
const testdriver = new TestDriver();
|
|
321
|
-
```
|
|
322
|
-
</Accordion>
|
|
323
|
-
</AccordionGroup>
|
|
266
|
+
- [Options](/options): every option you can pass to the client
|
|
267
|
+
- [Launch apps](/provision): start Chrome, extensions, and desktop apps once connected
|
|
268
|
+
- [Run tests](/copilot/running-tests#reuse-a-sandbox-while-you-iterate): reuse a sandbox between runs
|
|
269
|
+
- [Events](/events): listen for commands, logs, and errors
|