testdriverai 7.2.18 β 7.2.20
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/README.md +169 -258
- package/package.json +1 -1
- package/.testdriver/last-sandbox +0 -7
package/README.md
CHANGED
|
@@ -1,314 +1,225 @@
|
|
|
1
|
-
<
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
TestDriver v7 introduces **three levels of API** to match your experience level:
|
|
16
|
-
|
|
17
|
-
### π’ Beginner: Presets (Zero Config)
|
|
18
|
-
|
|
19
|
-
```javascript
|
|
20
|
-
import { test } from 'vitest';
|
|
21
|
-
import { chromePreset } from 'testdriverai/presets';
|
|
22
|
-
|
|
23
|
-
test('login test', async (context) => {
|
|
24
|
-
const { client } = await chromePreset(context, {
|
|
25
|
-
url: 'https://myapp.com'
|
|
26
|
-
});
|
|
1
|
+
<div align="center">
|
|
2
|
+
<a href="https://testdriver.ai">
|
|
3
|
+
<img src="https://github.com/dashcamio/testdriver/assets/318295/2a0ad981-8504-46f0-ad97-60cb6c26f1e7" height="200" alt="TestDriver.ai"/>
|
|
4
|
+
</a>
|
|
5
|
+
</div>
|
|
6
|
+
<h4 align="center">
|
|
7
|
+
Reliably test your most difficult flows. Don't ship bugs because flows are too hard to test.
|
|
8
|
+
</h4>
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
TestDriver helps engineering teams easily test, debug, and monitor E2E flows that are hard or impossible to cover with other tools.
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<div align="center">
|
|
27
15
|
|
|
28
|
-
|
|
29
|
-
});
|
|
30
|
-
```
|
|
16
|
+
[π **Quick Start**](#-quick-start) β’ [π **Documentation**](https://docs.testdriver.ai) β’ [π» **Examples**](https://github.com/testdriverai/testdriverai/tree/main/test/testdriver) β’ [π¬ **Discord**](https://discord.com/invite/cWDFW8DzPm) β’ [π **Website**](https://testdriver.ai)
|
|
31
17
|
|
|
32
|
-
|
|
18
|
+
</div>
|
|
33
19
|
|
|
34
|
-
|
|
20
|
+
---
|
|
35
21
|
|
|
36
|
-
|
|
37
|
-
import { test } from 'vitest';
|
|
38
|
-
import { useTestDriver, useDashcam } from 'testdriverai/vitest/hooks';
|
|
39
|
-
|
|
40
|
-
test('my test', async (context) => {
|
|
41
|
-
const client = useTestDriver(context, { os: 'linux' });
|
|
42
|
-
const dashcam = useDashcam(context, client, {
|
|
43
|
-
autoStart: true,
|
|
44
|
-
autoStop: true
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
await client.find('button').click();
|
|
48
|
-
});
|
|
49
|
-
```
|
|
22
|
+
## π¬ What Can You Test?
|
|
50
23
|
|
|
51
|
-
|
|
24
|
+
<div align="center">
|
|
52
25
|
|
|
53
|
-
|
|
26
|
+
**Third-Party Web Apps** β’ **Desktop Apps** β’ **VS Code Extensions** β’ **Chrome Extensions** β’ **AI Chatbots** β’ **OAuth Flows** β’ **PDF Content** β’ **Spelling & Grammar** β’ **File System & Uploads** β’ **OS Accessibility** β’ **Visual Content** β’ **`<iframe>`** β’ **`<canvas>`** β’ **`<video>`**
|
|
54
27
|
|
|
55
|
-
|
|
56
|
-
import { test } from 'vitest';
|
|
57
|
-
import { TestDriver, Dashcam } from 'testdriverai/core';
|
|
28
|
+
</div>
|
|
58
29
|
|
|
59
|
-
|
|
60
|
-
const client = new TestDriver(apiKey, { os: 'linux' });
|
|
61
|
-
const dashcam = new Dashcam(client);
|
|
62
|
-
|
|
63
|
-
await client.auth();
|
|
64
|
-
await client.connect();
|
|
65
|
-
await dashcam.start();
|
|
66
|
-
|
|
67
|
-
await client.find('button').click();
|
|
68
|
-
|
|
69
|
-
await dashcam.stop();
|
|
70
|
-
await client.disconnect();
|
|
71
|
-
});
|
|
72
|
-
```
|
|
30
|
+
---
|
|
73
31
|
|
|
74
|
-
|
|
32
|
+
## π― Why TestDriver?
|
|
75
33
|
|
|
76
|
-
|
|
34
|
+
TestDriver isn't just another testing frameworkβit's a **computer-use agent for QA**. Using AI vision and mouse/keyboard emulation, TestDriver can test anything you can see on screen, just like a human QA engineer would.
|
|
77
35
|
|
|
78
|
-
|
|
36
|
+
### The Problem with Traditional Testing
|
|
79
37
|
|
|
80
|
-
|
|
38
|
+
Modern testing tools like Playwright are powerful but limited to selector-based testing in single browser tabs. This breaks down when you need to test:
|
|
81
39
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
40
|
+
| Challenge | Traditional Tools | TestDriver |
|
|
41
|
+
|-----------|------------------|------------|
|
|
42
|
+
| **Dynamic AI Content** | β No selectors for chatbots, images, videos | β
AI vision sees everything |
|
|
43
|
+
| **Fast-Moving Teams** | β Brittle selectors break constantly | β
Natural language adapts to changes |
|
|
44
|
+
| **Desktop Applications** | β Web-only tools | β
Full OS control |
|
|
45
|
+
| **Third-Party Software** | β No access to selectors | β
Tests anything visible |
|
|
46
|
+
| **Visual States** | β Can't verify layouts, charts, images | β
Computer vision validation |
|
|
47
|
+
| **Multi-App Workflows** | β Single-app limitation | β
Cross-application testing |
|
|
85
48
|
|
|
86
|
-
###
|
|
49
|
+
### The TestDriver Solution
|
|
87
50
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
#
|
|
91
|
-
|
|
92
|
-
- Test any user flow on any website in any browser
|
|
93
|
-
- Clone, build, and test any desktop app
|
|
94
|
-
- Render multiple browser windows and popups like 3rd party auth
|
|
95
|
-
- Test `<canvas>`, `<iframe>`, and `<video>` tags with ease
|
|
96
|
-
- Use file selectors to upload files to the browser
|
|
97
|
-
- Test chrome extensions
|
|
98
|
-
- Test integrations between applications
|
|
99
|
-
- Integrates into CI/CD via GitHub Actions ($)
|
|
100
|
-
|
|
101
|
-
Check out [the docs](https://docs.testdriver.ai/).
|
|
102
|
-
|
|
103
|
-
# Workflow
|
|
104
|
-
|
|
105
|
-
1. Tell TestDriver what to do in natural language on your local machine using `npm i testdriverai -g`
|
|
106
|
-
2. TestDriver looks at the screen and uses mouse and keyboard emulation to accomplish the goal
|
|
107
|
-
3. Run TestDriver tests on our test infrastructure
|
|
108
|
-
|
|
109
|
-
# Quickstart
|
|
110
|
-
|
|
111
|
-
## Initialize TestDriver
|
|
112
|
-
|
|
113
|
-
In your project directory:
|
|
114
|
-
|
|
115
|
-
```sh
|
|
116
|
-
npx testdriverai@latest init
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
## Teach TestDriver a test
|
|
120
|
-
|
|
121
|
-
Let's show TestDriver what we want to test. Run the following command:
|
|
51
|
+
```javascript
|
|
52
|
+
// Instead of fragile selectors...
|
|
53
|
+
await page.locator('#user-menu > div.dropdown > button[data-testid="profile-btn"]').click();
|
|
122
54
|
|
|
123
|
-
|
|
124
|
-
|
|
55
|
+
// ...use natural language that adapts to UI changes
|
|
56
|
+
await testdriver.find('profile button in the top right').click();
|
|
125
57
|
```
|
|
126
58
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
TestDriver best practice is to start instructing TestDriver with your app in it's initial state. For browsers, this means creating a new tab with the website you want to test.
|
|
130
|
-
|
|
131
|
-
If you have multiple monitors, make sure you do this on your primary display.
|
|
59
|
+
---
|
|
132
60
|
|
|
133
|
-
##
|
|
61
|
+
## π Quick Start
|
|
134
62
|
|
|
135
|
-
|
|
63
|
+
Get your first test running in under 5 minutes:
|
|
136
64
|
|
|
137
|
-
|
|
65
|
+
### Step 1: Create a TestDriver Account
|
|
138
66
|
|
|
139
|
-
|
|
140
|
-
> Click on sign up
|
|
141
|
-
TestDriver Generates a Test
|
|
142
|
-
TestDriver will look at your screen and generate a test script. TestDriver can see the screen, control the mouse, keyboard, and more!
|
|
143
|
-
TestDriver can only see your primary display!
|
|
144
|
-
To navigate to testdriver.ai, we need to focus on the
|
|
145
|
-
Google Chrome application, click on the search bar, type
|
|
146
|
-
the URL, and then press Enter.
|
|
67
|
+
<a href="https://app.testdriver.ai/team"><img src="https://img.shields.io/badge/Sign_Up-Free_Account-blue?style=for-the-badge" alt="Sign Up"/></a>
|
|
147
68
|
|
|
148
|
-
|
|
69
|
+
*No credit card required!*
|
|
149
70
|
|
|
150
|
-
|
|
151
|
-
2. Click on the search bar.
|
|
152
|
-
3. Type "testdriver.ai".
|
|
153
|
-
4. Press Enter.
|
|
71
|
+
### Step 2: Initialize Your Project
|
|
154
72
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
commands:
|
|
159
|
-
- command: focus-application
|
|
160
|
-
name: Google Chrome
|
|
161
|
-
- command: hover-text
|
|
162
|
-
text: Search Google or type a URL
|
|
163
|
-
description: main google search
|
|
164
|
-
action: click
|
|
165
|
-
|
|
166
|
-
After this, we will type the URL and press Enter.
|
|
73
|
+
```bash
|
|
74
|
+
npx testdriverai@beta init
|
|
167
75
|
```
|
|
168
76
|
|
|
169
|
-
|
|
77
|
+
This will:
|
|
78
|
+
- Create a project folder
|
|
79
|
+
- Install dependencies (Vitest + TestDriver)
|
|
80
|
+
- Set up your API key
|
|
81
|
+
- Generate an example test
|
|
170
82
|
|
|
171
|
-
|
|
83
|
+
### Step 3: Run Your First Test
|
|
172
84
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
> Take your hands off the mouse and keyboard while TestDriver executes! TestDriver is not a fan of backseat drivers.
|
|
176
|
-
|
|
177
|
-
## Keep going!
|
|
178
|
-
|
|
179
|
-
Feel free to ask TestDriver to perform some more tasks. Every time you prompt TestDriver it will look at your screen and generate more test step to complete your goal.
|
|
180
|
-
|
|
181
|
-
```sh
|
|
182
|
-
> navigate to airbnb.com
|
|
183
|
-
> search for destinations in austin tx
|
|
184
|
-
> click check in
|
|
185
|
-
> select august 8
|
|
85
|
+
```bash
|
|
86
|
+
vitest run
|
|
186
87
|
```
|
|
187
88
|
|
|
188
|
-
|
|
89
|
+
Watch as TestDriver:
|
|
90
|
+
1. Spawns a cloud sandbox
|
|
91
|
+
2. Launches Chrome
|
|
92
|
+
3. Runs your test using AI vision
|
|
93
|
+
4. Returns results with video replay
|
|
189
94
|
|
|
190
|
-
|
|
95
|
+
<div align="center">
|
|
96
|
+
<a href="https://docs.testdriver.ai/v7/quickstart"><img src="https://img.shields.io/badge/π_Read_Full_Quickstart-4A90E2?style=for-the-badge" alt="Full Quickstart"/></a>
|
|
97
|
+
</div>
|
|
191
98
|
|
|
192
|
-
|
|
99
|
+
---
|
|
193
100
|
|
|
194
|
-
|
|
195
|
-
npx testdriverai@latest run testdriver/test.yaml
|
|
196
|
-
```
|
|
101
|
+
## οΏ½οΈ Core Concepts
|
|
197
102
|
|
|
198
|
-
|
|
103
|
+
### Real-World Examples
|
|
199
104
|
|
|
200
|
-
|
|
105
|
+
#### Web Applications
|
|
201
106
|
|
|
202
|
-
|
|
107
|
+
```javascript
|
|
108
|
+
// Test dynamic AI chatbots (no selectors needed!)
|
|
109
|
+
test('chatbot conversation', async (context) => {
|
|
110
|
+
const { testdriver } = await chrome(context, { url: 'https://chatapp.com' });
|
|
111
|
+
|
|
112
|
+
await testdriver.find('message input').type('What is TestDriver?');
|
|
113
|
+
await testdriver.find('send button').click();
|
|
114
|
+
|
|
115
|
+
const response = await testdriver.assert('AI response is visible');
|
|
116
|
+
expect(response).toBeTruthy();
|
|
117
|
+
});
|
|
203
118
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
119
|
+
// Test OAuth flows across multiple domains
|
|
120
|
+
test('OAuth login', async (context) => {
|
|
121
|
+
const { testdriver } = await chrome(context, { url: 'https://myapp.com' });
|
|
122
|
+
|
|
123
|
+
await testdriver.find('Login with Google').click();
|
|
124
|
+
// Handles popup, enters credentials, returns to app
|
|
125
|
+
await testdriver.find('email input').type('user@gmail.com');
|
|
126
|
+
await testdriver.find('password input').type('password');
|
|
127
|
+
await testdriver.find('Sign in').click();
|
|
128
|
+
|
|
129
|
+
await testdriver.assert('successfully logged into the app');
|
|
130
|
+
});
|
|
208
131
|
```
|
|
209
132
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
## Using as a Module
|
|
213
|
-
|
|
214
|
-
TestDriver can also be used programmatically as a Node.js module. This is useful when you want to integrate TestDriver into your own applications or customize the test file paths.
|
|
215
|
-
|
|
216
|
-
### Custom Test File Paths
|
|
217
|
-
|
|
218
|
-
By default, TestDriver looks for test files at `testdriver/testdriver.yaml` relative to the current working directory. You can customize this:
|
|
133
|
+
#### Desktop Applications
|
|
219
134
|
|
|
220
135
|
```javascript
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
136
|
+
// Install and test native desktop apps
|
|
137
|
+
test('desktop app', async (context) => {
|
|
138
|
+
const testdriver = TestDriver(context, { os: 'windows' });
|
|
139
|
+
|
|
140
|
+
await testdriver.provision.installer({
|
|
141
|
+
url: 'https://example.com/MyApp.msi',
|
|
142
|
+
launch: true
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
await testdriver.find('main window').assert('app launched successfully');
|
|
226
146
|
});
|
|
227
|
-
|
|
228
|
-
// Option 2: Explicitly specify test file
|
|
229
|
-
const agent2 = new TestDriverAgent(
|
|
230
|
-
{},
|
|
231
|
-
{
|
|
232
|
-
args: ["path/to/specific/test.yaml"],
|
|
233
|
-
},
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
// Option 3: Custom working directory + relative path
|
|
237
|
-
const agent3 = new TestDriverAgent(
|
|
238
|
-
{ TD_DEFAULT_TEST_FILE: "tests/smoke.yaml" },
|
|
239
|
-
{ options: { workingDir: "/path/to/your/project" } },
|
|
240
|
-
);
|
|
241
|
-
|
|
242
|
-
// Run the test
|
|
243
|
-
await agent1.run();
|
|
244
147
|
```
|
|
245
148
|
|
|
246
|
-
|
|
149
|
+
#### Browser Extensions
|
|
247
150
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
151
|
+
```javascript
|
|
152
|
+
// Test Chrome extensions from the Web Store
|
|
153
|
+
test('chrome extension', async (context) => {
|
|
154
|
+
const { testdriver } = await chrome(context);
|
|
155
|
+
|
|
156
|
+
await testdriver.provision.chromeExtension({
|
|
157
|
+
extensionId: 'liecbddmkiiihnedobmlmillhodjkdmb' // Loom
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const button = await testdriver.find('extension icon in toolbar');
|
|
161
|
+
await button.click();
|
|
162
|
+
|
|
163
|
+
const panel = await testdriver.find('extension popup');
|
|
164
|
+
expect(panel.found()).toBeTruthy();
|
|
165
|
+
});
|
|
253
166
|
```
|
|
254
167
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
TestDriver includes a Model Context Protocol (MCP) server that enables AI agents to **interactively create Vitest test files**.
|
|
168
|
+
#### Visual Validation
|
|
258
169
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
npm run deploy # Install to ~/.mcp/testdriver
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
### Configuration
|
|
170
|
+
```javascript
|
|
171
|
+
// Verify visual states, charts, images
|
|
172
|
+
test('dashboard chart', async (context) => {
|
|
173
|
+
const { testdriver } = await chrome(context, { url: 'https://analytics.example.com' });
|
|
174
|
+
|
|
175
|
+
await testdriver.assert('line chart shows upward trend');
|
|
176
|
+
await testdriver.assert('data points are visible on the graph');
|
|
177
|
+
|
|
178
|
+
// Extract text from images/PDFs
|
|
179
|
+
const value = await testdriver.extract('the total revenue number');
|
|
180
|
+
console.log('Revenue:', value);
|
|
181
|
+
});
|
|
275
182
|
|
|
276
|
-
|
|
183
|
+
// Test spelling and grammar checking
|
|
184
|
+
test('content validation', async (context) => {
|
|
185
|
+
const { testdriver } = await chrome(context, { url: 'https://docs.example.com' });
|
|
186
|
+
|
|
187
|
+
await testdriver.assert('there are no spelling errors on the page');
|
|
188
|
+
await testdriver.assert('all headings use title case');
|
|
189
|
+
});
|
|
277
190
|
|
|
278
|
-
|
|
279
|
-
{
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
191
|
+
// Test canvas and video elements
|
|
192
|
+
test('canvas rendering', async (context) => {
|
|
193
|
+
const { testdriver } = await chrome(context, { url: 'https://canvas-app.com' });
|
|
194
|
+
|
|
195
|
+
await testdriver.find('draw tool').click();
|
|
196
|
+
await testdriver.assert('canvas shows a red circle');
|
|
197
|
+
|
|
198
|
+
// Video content validation
|
|
199
|
+
await testdriver.assert('video is playing');
|
|
200
|
+
await testdriver.assert('video progress bar shows 50% complete');
|
|
201
|
+
});
|
|
288
202
|
```
|
|
289
203
|
|
|
290
|
-
|
|
204
|
+
#### Multi-Application Workflows
|
|
291
205
|
|
|
206
|
+
```javascript
|
|
207
|
+
// Test interactions across multiple apps
|
|
208
|
+
test('copy from browser to VS Code', async (context) => {
|
|
209
|
+
const testdriver = TestDriver(context, { os: 'linux' });
|
|
210
|
+
|
|
211
|
+
await testdriver.provision.chrome({ url: 'https://example.com' });
|
|
212
|
+
await testdriver.find('code snippet').click();
|
|
213
|
+
await testdriver.pressKeys(['ctrl', 'c']);
|
|
214
|
+
|
|
215
|
+
await testdriver.provision.vscode();
|
|
216
|
+
await testdriver.find('editor').click();
|
|
217
|
+
await testdriver.pressKeys(['ctrl', 'v']);
|
|
218
|
+
|
|
219
|
+
await testdriver.assert('code is pasted in editor');
|
|
220
|
+
});
|
|
292
221
|
```
|
|
293
|
-
User: "Create a test that logs into the app"
|
|
294
|
-
|
|
295
|
-
AI: [Connects to sandbox with user's API key]
|
|
296
|
-
AI: [Takes screenshot to see login page]
|
|
297
|
-
AI: [Finds username field: await testdriver_find({ description: "username field" })]
|
|
298
|
-
AI: [Clicks and types: await testdriver_type({ text: "test_user" })]
|
|
299
|
-
AI: [Finds password field, enters password]
|
|
300
|
-
AI: [Clicks login button]
|
|
301
|
-
AI: [Asserts login succeeded]
|
|
302
|
-
AI: [Generates Vitest test file from these steps]
|
|
303
|
-
AI: [Saves test/login.test.mjs]
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
### Key Features
|
|
307
|
-
|
|
308
|
-
- **Persistent sandbox** - Connection stays alive throughout test creation
|
|
309
|
-
- **Live debugger URL** - User can watch the AI test in real-time
|
|
310
|
-
- **Full SDK access** - All v7 SDK methods available
|
|
311
|
-
- **Code generation** - AI translates interactions into proper Vitest code
|
|
312
|
-
|
|
313
|
-
See [mcp-server/TEST_CREATION_GUIDE.md](mcp-server/TEST_CREATION_GUIDE.md) for the complete guide.
|
|
314
222
|
|
|
223
|
+
<div align="center">
|
|
224
|
+
<a href="https://github.com/testdriverai/testdriverai/tree/main/test/testdriver"><img src="https://img.shields.io/badge/π»_Browse_More_Examples-gray?style=for-the-badge" alt="More Examples"/></a>
|
|
225
|
+
</div>
|
package/package.json
CHANGED