testdriverai 7.2.77 → 7.2.79

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/agent/index.js CHANGED
@@ -2026,6 +2026,7 @@ ${regression}
2026
2026
  url: url,
2027
2027
  token: "V3b8wG9",
2028
2028
  testFile: this.testFile || null,
2029
+ os: this.sandboxOs || "linux",
2029
2030
  };
2030
2031
 
2031
2032
  // Base64 encode the data (the debugger expects base64, not URL encoding)
@@ -2034,7 +2035,47 @@ ${regression}
2034
2035
  // Use the debugger URL instead of the VNC URL
2035
2036
  const urlToOpen = `${this.debuggerUrl}?data=${encodedData}`;
2036
2037
 
2037
- this.emitter.emit(events.showWindow, urlToOpen);
2038
+ // Check preview mode from config
2039
+ const previewMode = this.config.TD_PREVIEW || "browser";
2040
+
2041
+ if (previewMode === "ide") {
2042
+ // Write session file for VSCode extension to pick up
2043
+ this.writeIdeSessionFile(urlToOpen, data);
2044
+ } else if (previewMode !== "none") {
2045
+ // Open in browser (default behavior)
2046
+ this.emitter.emit(events.showWindow, urlToOpen);
2047
+ }
2048
+ // If preview is "none", don't open anything
2049
+ }
2050
+ }
2051
+
2052
+ // Write session file for IDE preview mode
2053
+ writeIdeSessionFile(debuggerUrl, data) {
2054
+ const fs = require("fs");
2055
+ const os = require("os");
2056
+ const path = require("path");
2057
+
2058
+ const sessionDir = path.join(os.homedir(), ".testdriver");
2059
+ const sessionFile = path.join(sessionDir, "ide-session.json");
2060
+
2061
+ try {
2062
+ // Ensure directory exists
2063
+ if (!fs.existsSync(sessionDir)) {
2064
+ fs.mkdirSync(sessionDir, { recursive: true });
2065
+ }
2066
+
2067
+ const sessionData = {
2068
+ debuggerUrl: debuggerUrl,
2069
+ resolution: data.resolution || this.config.TD_RESOLUTION,
2070
+ testFile: data.testFile || this.thisFile,
2071
+ os: data.os || this.sandboxOs || "linux",
2072
+ timestamp: Date.now(),
2073
+ };
2074
+
2075
+ fs.writeFileSync(sessionFile, JSON.stringify(sessionData, null, 2));
2076
+ logger.log(`IDE session file written: ${sessionFile}`);
2077
+ } catch (error) {
2078
+ logger.warn(`Failed to write IDE session file: ${error.message}`);
2038
2079
  }
2039
2080
  }
2040
2081
 
@@ -113,6 +113,10 @@ async function startDebugger(config = {}, emitter) {
113
113
  });
114
114
  }
115
115
 
116
+ // Store the debugger URL and config for later use
117
+ module.exports.debuggerUrl = url;
118
+ module.exports.config = config;
119
+
116
120
  return { port, url };
117
121
  } catch (error) {
118
122
  console.error("Failed to start debugger server:", error);
@@ -140,4 +144,6 @@ module.exports = {
140
144
  stopDebugger,
141
145
  broadcastEvent,
142
146
  createDebuggerServer,
147
+ debuggerUrl: null,
148
+ config: null,
143
149
  };
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: testdriver
3
3
  description: An expert at creating and refining automated tests using TestDriver.ai
4
- tools: ["*"]
4
+ tools: ['vscode/getProjectSetupInfo', 'vscode/installExtension', 'vscode/newWorkspace', 'vscode/openSimpleBrowser', 'vscode/runCommand', 'vscode/askQuestions', 'vscode/switchAgent', 'vscode/vscodeAPI', 'vscode/extensions', 'execute/runNotebookCell', 'execute/testFailure', 'execute/getTerminalOutput', 'execute/awaitTerminal', 'execute/killTerminal', 'execute/runTask', 'execute/createAndRunTask', 'execute/runInTerminal', 'execute/runTests', 'read/getNotebookSummary', 'read/problems', 'read/readFile', 'read/readNotebookCellOutput', 'read/terminalSelection', 'read/terminalLastCommand', 'read/getTaskOutput', 'agent/runSubagent', 'edit/createDirectory', 'edit/createFile', 'edit/createJupyterNotebook', 'edit/editFiles', 'edit/editNotebook', 'search/changes', 'search/codebase', 'search/fileSearch', 'search/listDirectory', 'search/searchResults', 'search/textSearch', 'search/usages', 'search/searchSubagent', 'web/fetch', 'web/githubRepo', 'testdriver/assert', 'testdriver/check', 'testdriver/click', 'testdriver/exec', 'testdriver/find', 'testdriver/find_and_click', 'testdriver/findall', 'testdriver/focus_application', 'testdriver/hover', 'testdriver/list_local_screenshots', 'testdriver/press_keys', 'testdriver/screenshot', 'testdriver/scroll', 'testdriver/session_extend', 'testdriver/session_start', 'testdriver/session_status', 'testdriver/type', 'testdriver/view_local_screenshot', 'testdriver/wait', 'todo']
5
5
  mcp-servers:
6
6
  testdriver:
7
7
  command: npx
@@ -48,6 +48,41 @@ Use this agent when the user asks to:
48
48
 
49
49
  ## Prerequisites
50
50
 
51
+ ### Quick Start - Creating Your First TestDriver Test
52
+
53
+ **For new projects, use the `init` command to automatically set up everything:**
54
+
55
+ **CLI:**
56
+ ```bash
57
+ npx testdriverai@beta init
58
+ ```
59
+
60
+ **MCP (via this agent):**
61
+ ```
62
+ // apiKey is optional - if not provided, user adds it to .env manually after init
63
+ init({ directory: "." })
64
+
65
+ // Or with API key if available (though MCP typically won't have access to it)
66
+ init({ directory: ".", apiKey: "your_api_key" })
67
+ ```
68
+
69
+ **Note:** The `apiKey` parameter is optional. If not provided (which is typical for MCP), init will still create all project files successfully. The user can manually add `TD_API_KEY=...` to the `.env` file afterward.
70
+
71
+ The `init` command creates:
72
+ - ✅ `package.json` with proper dependencies
73
+ - ✅ Example test files (`tests/example.test.js`, `tests/login.js`)
74
+ - ✅ `vitest.config.js` with correct timeouts
75
+ - ✅ `.gitignore` with `.env`
76
+ - ✅ GitHub Actions workflow (`.github/workflows/testdriver.yml`)
77
+ - ✅ VSCode MCP config (`.vscode/mcp.json`)
78
+ - ✅ TestDriver skills and agents in `.github/`
79
+ - ✅ `.env` file (user adds API key manually if not provided to init)
80
+
81
+ **After running init:**
82
+ 1. User adds their API key to `.env`: `TD_API_KEY=...`
83
+ 2. Test the setup: `npx vitest run`
84
+ 3. Start building custom tests using the examples as templates
85
+
51
86
  ### API Key Setup
52
87
 
53
88
  The user **must** have a TestDriver API key set in their environment:
@@ -59,14 +94,12 @@ TD_API_KEY=your_api_key_here
59
94
 
60
95
  Get your API key at: **https://console.testdriver.ai/team**
61
96
 
62
- ### Installation
97
+ ### Manual Installation
63
98
 
64
- Always use the **beta** tag when installing TestDriver:
99
+ If not using `init`, always use the **beta** tag when installing TestDriver:
65
100
 
66
101
  ```bash
67
102
  npm install --save-dev testdriverai@beta
68
- # or
69
- npx testdriverai@beta init
70
103
  ```
71
104
 
72
105
  ### Test Runner
@@ -119,6 +152,7 @@ describe("My Test Suite", () => {
119
152
  const button = await testdriver.find("Sign In button");
120
153
  await testdriver.screenshot(); // Capture before click
121
154
  await button.click();
155
+ await testdriver.wait(2000); // Wait for state change
122
156
  await testdriver.screenshot(); // Capture after click
123
157
 
124
158
  // Assert using natural language
@@ -207,6 +241,23 @@ await testdriver.screenshot(1, false, true);
207
241
  - After any action that changes the page state
208
242
  - When debugging a flaky or failing test
209
243
 
244
+ **⚠️ Important: Add delays before screenshots after actions**
245
+
246
+ When you click or interact with an element that triggers a state change (page navigation, modal opening, content loading), **add a short delay before taking a screenshot** to allow the application state to update:
247
+
248
+ ```javascript
249
+ await element.click();
250
+ await testdriver.wait(2000); // Wait 2-3 seconds for state change
251
+ await testdriver.screenshot(); // Now capture the updated state
252
+ ```
253
+
254
+ This is especially important for:
255
+ - Navigation clicks (page transitions)
256
+ - Button clicks that open modals or dialogs
257
+ - Form submissions
258
+ - Actions that trigger AJAX requests or animations
259
+ - Any interaction where visual feedback takes time to appear
260
+
210
261
  **Screenshot file organization:**
211
262
 
212
263
  ```
@@ -258,6 +309,7 @@ find_and_click({ description: "email input field" })
258
309
  → Returns: screenshot with element highlighted
259
310
  → ⚠️ IMMEDIATELY append to test file:
260
311
  await testdriver.find("email input field").click();
312
+ await testdriver.wait(2000); // Wait for state change
261
313
  await testdriver.screenshot(); // Capture after click
262
314
 
263
315
  type({ text: "user@example.com" })
@@ -320,17 +372,60 @@ Analyze the output, fix any issues, and iterate until the test passes.
320
372
  | `assert` | AI-powered boolean assertion - GENERATES CODE for test files |
321
373
  | `exec` | Execute JavaScript, shell, or PowerShell in sandbox |
322
374
  | `screenshot` | Capture screenshot - **only use when user explicitly asks** |
375
+ | `list_local_screenshots` | List screenshots saved in `.testdriver` directory |
376
+ | `view_local_screenshot` | View a local screenshot (returns image to AI + displays to user) |
377
+
378
+ ### Debugging with Local Screenshots
379
+
380
+ After test runs (successful or failed), you can view saved screenshots to understand test behavior:
381
+
382
+ **1. List available screenshots:**
383
+
384
+ ```
385
+ list_local_screenshots({ directory: "login.test" })
386
+ ```
387
+
388
+ This returns all screenshots from the specified test file, sorted by modification time (newest first).
389
+
390
+ **2. View specific screenshots:**
391
+
392
+ ```
393
+ view_local_screenshot({ path: ".testdriver/screenshots/login.test/after-click.png" })
394
+ ```
395
+
396
+ This displays the screenshot to both you (the AI) and the user via MCP App.
397
+
398
+ **When to use screenshot viewing:**
399
+
400
+ - **After test failures** - View screenshots to see exactly what the UI looked like when the test failed
401
+ - **Debugging element finding issues** - See if elements are actually visible or have different appearances than expected
402
+ - **Comparing test runs** - View screenshots from multiple runs to identify flaky behavior
403
+ - **Verifying test logic** - Before running a test, view screenshots from previous runs to understand the UI flow
404
+
405
+ **Workflow example:**
406
+
407
+ ```
408
+ # Test failed, let's debug
409
+ list_local_screenshots({ directory: "checkout.test" })
410
+
411
+ # View the last few screenshots to see what happened
412
+ view_local_screenshot({ path: ".testdriver/screenshots/checkout.test/screenshot-1737633620000.png" })
413
+ view_local_screenshot({ path: ".testdriver/screenshots/checkout.test/before-assertion.png" })
414
+
415
+ # Analyze the UI state and update test code accordingly
416
+ ```
323
417
 
324
418
  ### Tips for MCP Workflow
325
419
 
326
420
  1. **⚠️ Write code IMMEDIATELY** - After EVERY action, append generated code to test file RIGHT AWAY
327
421
  2. **⚠️ Run tests YOURSELF** - Use `npx vitest run` - do NOT tell user to run tests
328
422
  3. **⚠️ Add screenshots liberally** - Include `await testdriver.screenshot()` after every significant action for debugging
329
- 4. **Work incrementally** - Don't try to build the entire test at once
330
- 5. **Use `check` after actions** - Verify your actions succeeded before moving on (for YOUR understanding)
331
- 6. **Use `assert` for test verifications** - These generate code that goes in the test file
332
- 7. **Be specific with element descriptions** - "the blue Sign In button in the header" is better than "button"
333
- 8. **Extend session proactively** - Sessions expire after 5 minutes; use `session_extend` if needed
423
+ 4. **⚠️ Use screenshot viewing for debugging** - When tests fail, use `list_local_screenshots` and `view_local_screenshot` to understand what went wrong
424
+ 5. **Work incrementally** - Don't try to build the entire test at once
425
+ 6. **Use `check` after actions** - Verify your actions succeeded before moving on (for YOUR understanding)
426
+ 7. **Use `assert` for test verifications** - These generate code that goes in the test file
427
+ 8. **Be specific with element descriptions** - "the blue Sign In button in the header" is better than "button"
428
+ 9. **Extend session proactively** - Sessions expire after 5 minutes; use `session_extend` if needed
334
429
 
335
430
  ## Recommended Development Workflow
336
431
 
@@ -356,6 +451,7 @@ it("should incrementally build test", async (context) => {
356
451
 
357
452
  // Step 2: Interact
358
453
  await element.click();
454
+ await testdriver.wait(2000); // Wait for state change
359
455
  await testdriver.screenshot(); // Capture after click
360
456
 
361
457
  // Step 3: Assert and log
@@ -420,10 +516,23 @@ await element.click();
420
516
 
421
517
  ### Scrolling
422
518
 
519
+ **⚠️ Important: Ensure proper focus before scrolling**
520
+
521
+ Scrolling requires the page or frame to be focused, not an input field or other interactive element. If an input is focused, scroll commands may not work as expected.
522
+
423
523
  ```javascript
524
+ // If you've been typing in an input, click elsewhere first
525
+ await testdriver.find("page background").click();
526
+ // Or press Escape to unfocus
527
+ await testdriver.pressKeys(["escape"]);
528
+
529
+ // Now scroll
424
530
  await testdriver.scroll("down");
425
531
  await testdriver.scrollUntilText("Footer text");
426
532
  await testdriver.scrollUntilImage("Product image at bottom");
533
+
534
+ // If scroll is not working, try using Page Down key directly
535
+ await testdriver.pressKeys(["pagedown"]);
427
536
  ```
428
537
 
429
538
  ### Executing Code in Sandbox
@@ -455,6 +564,7 @@ await testdriver.provision.chrome({ url: "https://example.com" });
455
564
  await testdriver.screenshot(); // After page load
456
565
 
457
566
  await testdriver.find("Login button").click();
567
+ await testdriver.wait(2000); // Wait for state change
458
568
  await testdriver.screenshot(); // After click
459
569
 
460
570
  await testdriver.type("user@example.com");
@@ -469,15 +579,16 @@ const result = await testdriver.assert("dashboard is visible");
469
579
  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.
470
580
  2. **⚠️ RUN TESTS YOURSELF** - Do NOT tell the user to run tests. YOU must run the tests using `npx vitest run <testFile> --reporter=dot`. Always use `--reporter=dot` for cleaner output. Analyze the output and iterate until the test passes. **Always share the test report link** (e.g., `https://app.testdriver.ai/projects/.../reports/...`) with the user after each run.
471
581
  3. **⚠️ ADD SCREENSHOTS LIBERALLY** - Include `await testdriver.screenshot()` throughout your tests: after provision, before/after clicks, after typing, and before assertions. This creates a visual trail that makes debugging failures much easier.
472
- 4. **⚠️ NEVER USE `.wait()`** - Do NOT use any `.wait()` method. Instead, use `find()` with a `timeout` option to poll for elements, or use `assert()` / `check()` to verify state. Explicit waits are flaky and slow.
473
- 5. **Use MCP tools for development** - Build tests interactively with visual feedback
474
- 6. **Always check `sdk.d.ts`** for method signatures and types when debugging generated tests
475
- 7. **Look at test samples** in `node_modules/testdriverai/test` for working examples
476
- 8. **Use `check` to understand screen state** - This is how you verify what the sandbox shows during MCP development.
477
- 9. **Use `check` after actions, `assert` for test files** - `check` gives detailed AI analysis (no code), `assert` gives boolean pass/fail (generates code)
478
- 10. **Be specific with element descriptions** - "blue Sign In button in the header" > "button"
479
- 11. **Start simple** - get one step working before adding more
480
- 12. **Always `await` async methods** - TestDriver will warn if you forget, but for TypeScript projects, add `@typescript-eslint/no-floating-promises` to your ESLint config to catch missing `await` at compile time:
582
+ 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. This is often faster than re-running the test.
583
+ 5. **⚠️ NEVER USE `.wait()`** - Do NOT use any `.wait()` method. Instead, use `find()` with a `timeout` option to poll for elements, or use `assert()` / `check()` to verify state. Explicit waits are flaky and slow.
584
+ 6. **Use MCP tools for development** - Build tests interactively with visual feedback
585
+ 7. **Always check `sdk.d.ts`** for method signatures and types when debugging generated tests
586
+ 8. **Look at test samples** in `node_modules/testdriverai/test` for working examples
587
+ 9. **Use `check` to understand screen state** - This is how you verify what the sandbox shows during MCP development.
588
+ 10. **Use `check` after actions, `assert` for test files** - `check` gives detailed AI analysis (no code), `assert` gives boolean pass/fail (generates code)
589
+ 11. **Be specific with element descriptions** - "blue Sign In button in the header" > "button"
590
+ 12. **Start simple** - get one step working before adding more
591
+ 13. **Always `await` async methods** - TestDriver will warn if you forget, but for TypeScript projects, add `@typescript-eslint/no-floating-promises` to your ESLint config to catch missing `await` at compile time:
481
592
 
482
593
  ```json
483
594
  // eslint.config.js (for TypeScript projects)
@@ -55,12 +55,18 @@ const testdriver = new TestDriver(apiKey, options)
55
55
  ```javascript
56
56
  import TestDriver from 'testdriverai';
57
57
 
58
- const testdriver = new TestDriver(process.env.TD_API_KEY, {
58
+ // API key is automatically loaded from TD_API_KEY in .env
59
+ const testdriver = new TestDriver({
59
60
  os: 'windows',
60
61
  resolution: '1920x1080',
61
62
  logging: true,
62
63
  analytics: true
63
64
  });
65
+
66
+ // Or pass API key explicitly
67
+ const testdriver = new TestDriver('your-api-key', {
68
+ os: 'windows'
69
+ });
64
70
  ```
65
71
 
66
72
  ## Authentication
@@ -266,8 +272,8 @@ describe('My Test Suite', () => {
266
272
  let testdriver;
267
273
 
268
274
  beforeAll(async () => {
269
- // Initialize client
270
- client = new TestDriver(process.env.TD_API_KEY, {
275
+ // Initialize client - API key loaded automatically from .env
276
+ testdriver = new TestDriver({
271
277
  os: 'windows',
272
278
  resolution: '1366x768',
273
279
  logging: true
@@ -319,10 +325,15 @@ describe('My Test Suite', () => {
319
325
  </Accordion>
320
326
 
321
327
  <Accordion title="Use environment variables for API keys">
322
- Never hardcode API keys. Use environment variables:
328
+ Never hardcode API keys. The SDK automatically loads `TD_API_KEY` from your `.env` file:
329
+
330
+ ```bash .env
331
+ TD_API_KEY=your_api_key_here
332
+ ```
323
333
 
324
334
  ```javascript
325
- const testdriver = new TestDriver(process.env.TD_API_KEY);
335
+ // API key is loaded automatically - no need to pass it!
336
+ const testdriver = new TestDriver();
326
337
  ```
327
338
  </Accordion>
328
339
  </AccordionGroup>
@@ -6,10 +6,10 @@ description: Use AI coding agents and exploration mode to generate TestDriver te
6
6
 
7
7
  ## Instructions for Coding Agents
8
8
 
9
- We recommend starting with [our quickstart](./quickstart) then supplying your coding agent with our agents.md file.
9
+ We recommend starting with [our quickstart](./quickstart) then supplying your coding agent with our agent instructions file.
10
10
 
11
- <Card title="Agents.md" icon="link" arrow="true" horizontal href="https://github.com/testdriverai/testdriverai/blob/main/agents.md?plain=1">
12
- Copy the current version of agents.md to provide your coding agent with up-to-date instructions on how to generate TestDriver tests.
11
+ <Card title="TestDriver Agent Instructions" icon="link" arrow="true" horizontal href="https://github.com/testdriverai/testdriverai/blob/main/ai/agents/testdriver.md?plain=1">
12
+ Copy the current version of our agent instructions to provide your coding agent with up-to-date instructions on how to generate TestDriver tests.
13
13
  </Card>
14
14
 
15
15
  Then, you can prompt your coding agent to generate tests. Here is an example prompt:
@@ -133,7 +133,35 @@ describe("Login Flow", () => {
133
133
  </Accordion>
134
134
  </AccordionGroup>
135
135
 
136
+ ## Viewing Saved Screenshots
137
+
138
+ After saving screenshots during test execution, you can view them using TestDriver MCP commands. This is especially useful for debugging failed tests or verifying test behavior.
139
+
140
+ ### MCP Commands for Screenshot Viewing
141
+
142
+ **List all saved screenshots:**
143
+
144
+ ```
145
+ list_local_screenshots()
146
+ ```
147
+
148
+ **View a specific screenshot:**
149
+
150
+ ```
151
+ view_local_screenshot({ path: "/full/path/to/screenshot.png" })
152
+ ```
153
+
154
+ These commands allow you to:
155
+ - View screenshots from failed tests to understand what went wrong
156
+ - Review test execution flow by examining screenshots in chronological order
157
+ - Compare screenshots across test runs to identify flaky behavior
158
+
159
+ <Note>
160
+ For detailed workflows and examples of using these MCP commands for debugging, see the [Debugging with Screenshots](/v7/debugging-with-screenshots) guide.
161
+ </Note>
162
+
136
163
  ## Related
137
164
 
165
+ - [Debugging with Screenshots](/v7/debugging-with-screenshots) - View and analyze saved screenshots using MCP
138
166
  - [assert()](/v7/assert) - Make AI-powered assertions
139
167
  - [find()](/v7/find) - Locate elements on screen