testdriverai 7.2.20 β†’ 7.2.22

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 CHANGED
@@ -1,67 +1,52 @@
1
1
  <div align="center">
2
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"/>
3
+ <img width="250" alt="TestDriver.ai Icon" src="https://github.com/user-attachments/assets/c591b39d-6e17-454b-b36d-370ae8618840" />
4
4
  </a>
5
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
6
 
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>
7
+ <h1 align="center">Computer-Use SDK for E2E QA Testing</h1>
13
8
 
14
- <div align="center">
9
+ <div align="center">The TestDriver SDK is a JS plugin for vitest that makes it easy to spawn ephemeral devices and use vision-based LLMs to construct detemanistic and reliable tests.
10
+
11
+ <br />
12
+ <br />
15
13
 
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)
14
+ [πŸš€ **Quick Start**](#-quick-start) β€’ [πŸ“– **Documentation**](https://docs.testdriver.ai) β€’ [πŸ’» **Examples**](https://github.com/testdriverai/testdriverai/tree/main/test/testdriver) β€’ [πŸ“– **Pricing**](https://docs.testdriver.ai) β€’ [πŸ’¬ **Discord**](https://discord.com/invite/cWDFW8DzPm) β€’ [🌐 **Website**](https://testdriver.ai)
17
15
 
18
16
  </div>
19
17
 
20
- ---
21
-
22
- ## 🎬 What Can You Test?
23
-
24
- <div align="center">
25
-
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>`**
27
-
28
- </div>
18
+ <img width="1490" height="854" alt="image" src="https://github.com/user-attachments/assets/36e426cc-e740-426f-b9f6-6e8565e66ad6" />
29
19
 
30
20
  ---
31
21
 
32
- ## 🎯 Why TestDriver?
22
+ ## Why TestDriver?
33
23
 
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.
24
+ Don't ship bugs because flows are too hard to test. TestDriver helps engineering teams easily test, debug, and monitor E2E flows that are hard or impossible to cover with other tools like:
35
25
 
36
- ### The Problem with Traditional Testing
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>`*
37
27
 
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:
28
+ ## Example
39
29
 
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 |
30
+ ```js
31
+ // Click on the new text document
32
+ await testdriver.find("New text document").mouseDown();
48
33
 
49
- ### The TestDriver Solution
34
+ // Drag the "New Text Document" icon to the "Recycle Bin"
35
+ await testdriver.find("Recycle Bin icon").mouseUp();
50
36
 
51
- ```javascript
52
- // Instead of fragile selectors...
53
- await page.locator('#user-menu > div.dropdown > button[data-testid="profile-btn"]').click();
54
-
55
- // ...use natural language that adapts to UI changes
56
- await testdriver.find('profile button in the top right').click();
37
+ // Assert "New Text Document" icon is not on the Desktop
38
+ const result = await testdriver.assert(
39
+ 'the "New Text Document" icon is not visible on the Desktop'
40
+ );
41
+ expect(result).toBeTruthy();
57
42
  ```
58
43
 
44
+ [See Full Example](https://github.com/testdriverai/testdriverai/blob/main/test/testdriver/drag-and-drop.test.mjs) β€’ [Browse All Examples](https://github.com/testdriverai/testdriverai/tree/main/test/testdriver)
45
+
59
46
  ---
60
47
 
61
48
  ## πŸš€ Quick Start
62
49
 
63
- Get your first test running in under 5 minutes:
64
-
65
50
  ### Step 1: Create a TestDriver Account
66
51
 
67
52
  <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>
@@ -92,134 +77,4 @@ Watch as TestDriver:
92
77
  3. Runs your test using AI vision
93
78
  4. Returns results with video replay
94
79
 
95
- <div align="center">
96
80
  <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>
98
-
99
- ---
100
-
101
- ## �️ Core Concepts
102
-
103
- ### Real-World Examples
104
-
105
- #### Web Applications
106
-
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
- });
118
-
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
- });
131
- ```
132
-
133
- #### Desktop Applications
134
-
135
- ```javascript
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');
146
- });
147
- ```
148
-
149
- #### Browser Extensions
150
-
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
- });
166
- ```
167
-
168
- #### Visual Validation
169
-
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
- });
182
-
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
- });
190
-
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
- });
202
- ```
203
-
204
- #### Multi-Application Workflows
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
- });
221
- ```
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>
@@ -142,11 +142,9 @@ export default defineConfig({
142
142
 
143
143
  ### Test Helpers
144
144
 
145
- - βœ… **Updated**: `testdriver/acceptance-sdk/setup/testHelpers.mjs`
146
- - Removed temp file writing
147
- - Removed `__testdriverRegistry` initialization
148
- - Removed `__testdriverMeta` initialization
149
- - Uses `globalThis.__testdriverPlugin.registerDashcamUrl()` instead
145
+ - βœ… **Removed**: `test/testdriver/setup/` folder (legacy helpers)
146
+ - Code moved to `lib/vitest/hooks.mjs` framework
147
+ - Tests now use `TestDriver(context, options)` pattern directly
150
148
 
151
149
  ### Documentation
152
150
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "7.2.20",
3
+ "version": "7.2.22",
4
4
  "description": "Next generation autonomous AI agent for end-to-end testing of web & desktop",
5
5
  "main": "sdk.js",
6
6
  "exports": {
@@ -5,7 +5,25 @@
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
7
  import { TestDriver } from "../../lib/vitest/hooks.mjs";
8
- import { performLogin } from "./setup/testHelpers.mjs";
8
+
9
+ /**
10
+ * Perform login flow for SauceLabs demo app
11
+ * @param {TestDriver} client - TestDriver client
12
+ * @param {string} username - Username (default: 'standard_user')
13
+ */
14
+ async function performLogin(client, username = "standard_user") {
15
+ await client.focusApplication("Google Chrome");
16
+ const password = await client.extract("the password");
17
+ const usernameField = await client.find(
18
+ "Username, label above the username input field on the login form",
19
+ );
20
+ await usernameField.click();
21
+ await client.type(username);
22
+ await client.pressKeys(["tab"]);
23
+ await client.type(password, { secret: true });
24
+ await client.pressKeys(["tab"]);
25
+ await client.pressKeys(["enter"]);
26
+ }
9
27
 
10
28
  describe("Hover Image Test", () => {
11
29
  it("should click on shopping cart icon and verify empty cart", async (context) => {
@@ -5,7 +5,25 @@
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
7
  import { TestDriver } from "../../lib/vitest/hooks.mjs";
8
- import { performLogin } from "./setup/testHelpers.mjs";
8
+
9
+ /**
10
+ * Perform login flow for SauceLabs demo app
11
+ * @param {TestDriver} client - TestDriver client
12
+ * @param {string} username - Username (default: 'standard_user')
13
+ */
14
+ async function performLogin(client, username = "standard_user") {
15
+ await client.focusApplication("Google Chrome");
16
+ const password = await client.extract("the password");
17
+ const usernameField = await client.find(
18
+ "Username, label above the username input field on the login form",
19
+ );
20
+ await usernameField.click();
21
+ await client.type(username);
22
+ await client.pressKeys(["tab"]);
23
+ await client.type(password, { secret: true });
24
+ await client.pressKeys(["tab"]);
25
+ await client.pressKeys(["enter"]);
26
+ }
9
27
 
10
28
  describe("Hover Text With Description Test", () => {
11
29
  it("should add TestDriver Hat to cart and verify", async (context) => {
@@ -7,7 +7,25 @@ import path, { dirname } from "path";
7
7
  import { fileURLToPath } from "url";
8
8
  import { describe, expect, it } from "vitest";
9
9
  import { TestDriver } from "../../lib/vitest/hooks.mjs";
10
- import { performLogin } from "./setup/testHelpers.mjs";
10
+
11
+ /**
12
+ * Perform login flow for SauceLabs demo app
13
+ * @param {TestDriver} client - TestDriver client
14
+ * @param {string} username - Username (default: 'standard_user')
15
+ */
16
+ async function performLogin(client, username = "standard_user") {
17
+ await client.focusApplication("Google Chrome");
18
+ const password = await client.extract("the password");
19
+ const usernameField = await client.find(
20
+ "Username, label above the username input field on the login form",
21
+ );
22
+ await usernameField.click();
23
+ await client.type(username);
24
+ await client.pressKeys(["tab"]);
25
+ await client.type(password, { secret: true });
26
+ await client.pressKeys(["tab"]);
27
+ await client.pressKeys(["enter"]);
28
+ }
11
29
 
12
30
  // Get the directory of the current module
13
31
  const __filename = fileURLToPath(import.meta.url);
@@ -5,7 +5,25 @@
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
7
  import { TestDriver } from "../../lib/vitest/hooks.mjs";
8
- import { performLogin } from "./setup/testHelpers.mjs";
8
+
9
+ /**
10
+ * Perform login flow for SauceLabs demo app
11
+ * @param {TestDriver} client - TestDriver client
12
+ * @param {string} username - Username (default: 'standard_user')
13
+ */
14
+ async function performLogin(client, username = "standard_user") {
15
+ await client.focusApplication("Google Chrome");
16
+ const password = await client.extract("the password");
17
+ const usernameField = await client.find(
18
+ "Username, label above the username input field on the login form",
19
+ );
20
+ await usernameField.click();
21
+ await client.type(username);
22
+ await client.pressKeys(["tab"]);
23
+ await client.type(password, { secret: true });
24
+ await client.pressKeys(["tab"]);
25
+ await client.pressKeys(["enter"]);
26
+ }
9
27
 
10
28
  describe("Scroll Until Text Test", () => {
11
29
  it('should scroll until "testdriver socks" appears', async (context) => {