@testdriverai/mcp 7.10.0-canary.0 → 7.10.1-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.
Files changed (196) hide show
  1. package/.claude-plugin/marketplace.json +17 -0
  2. package/agent/index.js +116 -71
  3. package/agent/interface.js +13 -1
  4. package/agent/lib/commands.js +35 -15
  5. package/agent/lib/provision-commands.js +92 -11
  6. package/agent/lib/sandbox.js +263 -30
  7. package/agent/lib/sdk.js +16 -12
  8. package/agent/lib/system.js +107 -31
  9. package/ai/.claude-plugin/plugin.json +89 -4
  10. package/ai/agents/testdriver.md +4 -8
  11. package/ai/skills/testdriver-assert/SKILL.md +0 -1
  12. package/ai/skills/testdriver-aws-setup/SKILL.md +1 -1
  13. package/ai/skills/testdriver-caching/SKILL.md +13 -6
  14. package/ai/skills/testdriver-ci-cd/SKILL.md +57 -14
  15. package/ai/skills/testdriver-client/SKILL.md +10 -6
  16. package/ai/skills/testdriver-customizing-devices/SKILL.md +7 -5
  17. package/ai/skills/testdriver-dashcam/SKILL.md +36 -3
  18. package/ai/skills/testdriver-debugging-with-screenshots/SKILL.md +28 -4
  19. package/ai/skills/testdriver-device-config/SKILL.md +5 -5
  20. package/ai/skills/testdriver-find/SKILL.md +50 -11
  21. package/ai/skills/testdriver-generating-tests/SKILL.md +163 -8
  22. package/ai/skills/testdriver-hosted/SKILL.md +1 -1
  23. package/ai/skills/testdriver-machine-setup/SKILL.md +331 -0
  24. package/ai/skills/testdriver-making-assertions/SKILL.md +78 -2
  25. package/ai/skills/testdriver-mcp-workflow/SKILL.md +2 -2
  26. package/ai/skills/testdriver-parse/SKILL.md +1 -1
  27. package/ai/skills/testdriver-performing-actions/SKILL.md +97 -3
  28. package/ai/skills/testdriver-provision/SKILL.md +0 -20
  29. package/ai/skills/testdriver-quickstart/SKILL.md +299 -21
  30. package/ai/skills/testdriver-reusable-code/SKILL.md +3 -3
  31. package/ai/skills/testdriver-running-tests/SKILL.md +1 -1
  32. package/ai/skills/testdriver-screenshot/SKILL.md +5 -5
  33. package/ai/skills/testdriver-scroll/SKILL.md +30 -160
  34. package/ai/skills/testdriver-test-writer/SKILL.md +3 -5
  35. package/ai/skills/testdriver-testdriver/SKILL.md +3 -7
  36. package/ai/skills/testdriver-wait/SKILL.md +1 -1
  37. package/{docs/v7/ai.mdx → ai/skills/testdriver:ai/SKILL.md} +3 -4
  38. package/ai/skills/testdriver:assert/SKILL.md +315 -0
  39. package/ai/skills/testdriver:aws-setup/SKILL.md +448 -0
  40. package/ai/skills/testdriver:cache/SKILL.md +221 -0
  41. package/ai/skills/testdriver:caching/SKILL.md +124 -0
  42. package/ai/skills/testdriver:captcha/SKILL.md +158 -0
  43. package/ai/skills/testdriver:ci-cd/SKILL.md +659 -0
  44. package/ai/skills/testdriver:click/SKILL.md +286 -0
  45. package/ai/skills/testdriver:client/SKILL.md +477 -0
  46. package/ai/skills/testdriver:customizing-devices/SKILL.md +319 -0
  47. package/ai/skills/testdriver:dashcam/SKILL.md +451 -0
  48. package/ai/skills/testdriver:debugging-with-screenshots/SKILL.md +415 -0
  49. package/{docs/v7/device-config.mdx → ai/skills/testdriver:device-config/SKILL.md} +8 -8
  50. package/ai/skills/testdriver:double-click/SKILL.md +102 -0
  51. package/ai/skills/testdriver:elements/SKILL.md +605 -0
  52. package/ai/skills/testdriver:enterprise/SKILL.md +7 -0
  53. package/ai/skills/testdriver:errors/SKILL.md +246 -0
  54. package/ai/skills/testdriver:events/SKILL.md +356 -0
  55. package/ai/skills/testdriver:exec/SKILL.md +317 -0
  56. package/ai/skills/testdriver:find/SKILL.md +860 -0
  57. package/ai/skills/testdriver:focus-application/SKILL.md +293 -0
  58. package/ai/skills/testdriver:generating-tests/SKILL.md +25 -0
  59. package/ai/skills/testdriver:hosted/SKILL.md +156 -0
  60. package/ai/skills/testdriver:hover/SKILL.md +278 -0
  61. package/{docs/v7/locating-elements.mdx → ai/skills/testdriver:locating-elements/SKILL.md} +3 -3
  62. package/ai/skills/testdriver:making-assertions/SKILL.md +32 -0
  63. package/ai/skills/testdriver:mcp/SKILL.md +7 -0
  64. package/ai/skills/testdriver:mouse-down/SKILL.md +161 -0
  65. package/ai/skills/testdriver:mouse-up/SKILL.md +164 -0
  66. package/ai/skills/testdriver:parse/SKILL.md +236 -0
  67. package/ai/skills/testdriver:performing-actions/SKILL.md +53 -0
  68. package/ai/skills/testdriver:press-keys/SKILL.md +348 -0
  69. package/ai/skills/testdriver:provision/SKILL.md +331 -0
  70. package/ai/skills/testdriver:quickstart/SKILL.md +172 -0
  71. package/ai/skills/testdriver:redraw/SKILL.md +214 -0
  72. package/ai/skills/testdriver:reusable-code/SKILL.md +249 -0
  73. package/ai/skills/testdriver:right-click/SKILL.md +123 -0
  74. package/{docs/v7/running-tests.mdx → ai/skills/testdriver:running-tests/SKILL.md} +4 -4
  75. package/ai/skills/testdriver:screenshot/SKILL.md +248 -0
  76. package/ai/skills/testdriver:screenshots/SKILL.md +184 -0
  77. package/ai/skills/testdriver:scroll/SKILL.md +205 -0
  78. package/ai/skills/testdriver:secrets/SKILL.md +115 -0
  79. package/ai/skills/testdriver:self-hosted/SKILL.md +147 -0
  80. package/ai/skills/testdriver:test-results-json/SKILL.md +257 -0
  81. package/ai/skills/testdriver:testdriver/SKILL.md +624 -0
  82. package/ai/skills/testdriver:type/SKILL.md +357 -0
  83. package/ai/skills/testdriver:variables/SKILL.md +111 -0
  84. package/ai/skills/testdriver:wait/SKILL.md +50 -0
  85. package/{docs/v7/waiting-for-elements.mdx → ai/skills/testdriver:waiting-for-elements/SKILL.md} +3 -3
  86. package/ai/skills/testdriver:what-is-testdriver/SKILL.md +54 -0
  87. package/debugger/index.html +12 -0
  88. package/docs/_data/examples-manifest.json +54 -46
  89. package/docs/_data/examples-manifest.schema.json +12 -2
  90. package/docs/_scripts/extract-example-urls.js +21 -3
  91. package/docs/_scripts/generate-examples.js +64 -16
  92. package/docs/changelog.mdx +29 -2
  93. package/docs/claude-mcp-plugin.mdx +65 -18
  94. package/docs/docs.json +16 -33
  95. package/docs/snippets/tests/scroll-yaml.mdx +2 -2
  96. package/docs/v6/commands/scroll-until-image.mdx +1 -1
  97. package/docs/v6/commands/scroll-until-text.mdx +2 -2
  98. package/docs/v6/commands/scroll.mdx +2 -2
  99. package/docs/v7/_drafts/agents.mdx +0 -4
  100. package/docs/v7/_drafts/best-practices.mdx +0 -12
  101. package/docs/v7/_drafts/commands/scroll-until-image.mdx +1 -1
  102. package/docs/v7/_drafts/commands/scroll-until-text.mdx +2 -2
  103. package/docs/v7/_drafts/commands/scroll.mdx +1 -1
  104. package/docs/v7/_drafts/configuration.mdx +0 -12
  105. package/docs/v7/_drafts/faq.mdx +2 -10
  106. package/docs/v7/_drafts/readme.mdx +0 -1
  107. package/docs/v7/_drafts/troubleshooting.mdx +1 -4
  108. package/docs/v7/assert.mdx +0 -1
  109. package/docs/v7/aws-setup.mdx +1 -1
  110. package/docs/v7/caching.mdx +14 -10
  111. package/docs/v7/ci-cd.mdx +98 -14
  112. package/docs/v7/client.mdx +10 -6
  113. package/docs/v7/copilot/auto-healing.mdx +167 -18
  114. package/docs/v7/copilot/running-tests.mdx +915 -54
  115. package/docs/v7/customizing-devices.mdx +7 -5
  116. package/docs/v7/dashcam.mdx +36 -3
  117. package/docs/v7/debugging-with-screenshots.mdx +31 -7
  118. package/docs/v7/examples/ai.mdx +13 -8
  119. package/docs/v7/examples/assert.mdx +1 -1
  120. package/docs/v7/examples/chrome-extension.mdx +30 -13
  121. package/docs/v7/examples/element-not-found.mdx +1 -1
  122. package/docs/v7/examples/findall-coffee-icons.mdx +3 -2
  123. package/docs/v7/examples/formatted-logging.mdx +74 -0
  124. package/docs/v7/examples/hover-image.mdx +1 -1
  125. package/docs/v7/examples/hover-text-with-description.mdx +2 -2
  126. package/docs/v7/examples/hover-text.mdx +1 -1
  127. package/docs/v7/examples/installer.mdx +1 -1
  128. package/docs/v7/examples/launch-vscode-linux.mdx +27 -27
  129. package/docs/v7/examples/match-image.mdx +1 -1
  130. package/docs/v7/examples/parse.mdx +3 -2
  131. package/docs/v7/examples/press-keys.mdx +2 -2
  132. package/docs/v7/examples/scroll-keyboard.mdx +2 -2
  133. package/docs/v7/examples/scroll-until-text.mdx +1 -1
  134. package/docs/v7/examples/scroll.mdx +1 -1
  135. package/docs/v7/examples/type.mdx +1 -1
  136. package/docs/v7/find.mdx +50 -11
  137. package/docs/v7/generating-tests.mdx +166 -10
  138. package/docs/v7/hosted.mdx +1 -1
  139. package/docs/v7/making-assertions.mdx +81 -4
  140. package/docs/v7/parse.mdx +1 -1
  141. package/docs/v7/performing-actions.mdx +100 -5
  142. package/docs/v7/provision.mdx +0 -20
  143. package/docs/v7/quickstart.mdx +299 -21
  144. package/docs/v7/reusable-code.mdx +3 -3
  145. package/docs/v7/screenshot.mdx +5 -5
  146. package/docs/v7/scroll.mdx +30 -160
  147. package/docs/v7/wait.mdx +1 -1
  148. package/examples/chrome-extension.test.mjs +29 -12
  149. package/examples/config.mjs +1 -1
  150. package/examples/launch-vscode-linux.test.mjs +25 -25
  151. package/interfaces/cli/commands/init.js +84 -2
  152. package/interfaces/vitest-plugin.mjs +51 -61
  153. package/lib/core/Dashcam.js +43 -2
  154. package/lib/core/index.d.ts +13 -1
  155. package/lib/github-comment.mjs +11 -5
  156. package/lib/init-project.js +98 -44
  157. package/lib/install-clients.js +470 -0
  158. package/lib/provision.js +749 -0
  159. package/lib/resolve-channel.js +2 -2
  160. package/lib/sentry.js +15 -2
  161. package/lib/vitest/hooks.mjs +44 -34
  162. package/mcp-server/README.md +32 -0
  163. package/mcp-server/dist/core/actions.d.ts +176 -0
  164. package/mcp-server/dist/core/actions.js +753 -0
  165. package/mcp-server/dist/env-utils.d.ts +45 -0
  166. package/mcp-server/dist/env-utils.js +63 -0
  167. package/mcp-server/dist/provision-types.d.ts +6 -2
  168. package/mcp-server/dist/provision-types.js +3 -1
  169. package/mcp-server/dist/server.mjs +449 -751
  170. package/mcp-server/package-lock.json +384 -1
  171. package/mcp-server/package.json +5 -2
  172. package/mcp-server/src/core/actions.ts +912 -0
  173. package/mcp-server/src/env-utils.test.ts +82 -0
  174. package/mcp-server/src/env-utils.ts +77 -0
  175. package/mcp-server/src/provision-types.ts +4 -1
  176. package/mcp-server/src/server.ts +533 -954
  177. package/mcp-server/tsconfig.json +1 -1
  178. package/mcp-server/vitest.config.ts +7 -0
  179. package/package.json +15 -3
  180. package/sdk.d.ts +11 -9
  181. package/sdk.js +116 -746
  182. package/setup/aws/spawn-runner.sh +24 -3
  183. package/docs/v7/_drafts/caching-ai.mdx +0 -215
  184. package/docs/v7/_drafts/caching.mdx +0 -366
  185. package/docs/v7/_drafts/prompt-cache.mdx +0 -200
  186. package/docs/v7/copilot/creating-tests.mdx +0 -156
  187. package/docs/v7/copilot/github.mdx +0 -143
  188. package/docs/v7/copilot/setup.mdx +0 -143
  189. package/docs/v7/examples/exec-output.mdx +0 -84
  190. package/docs/v7/examples/exec-pwsh.mdx +0 -82
  191. package/docs/v7/examples/focus-window.mdx +0 -61
  192. package/docs/v7/examples/scroll-until-image.mdx +0 -82
  193. package/docs/v7/examples/windows-installer.mdx +0 -95
  194. package/examples/formatted-logging.test.mjs +0 -27
  195. package/examples/match-image.test.mjs +0 -55
  196. package/manual/exec-stream-logs.test.mjs +0 -25
@@ -1,9 +1,94 @@
1
1
  {
2
2
  "name": "testdriver",
3
- "description": "TestDriver plugin: SDK guidance plus MCP access to test runs and results.",
4
- "version": "1.0.0",
3
+ "version": "7.9.54-test",
4
+ "description": "TestDriver.ai Claude Code plugin: MCP server, TestDriver expert agent, and skills for authoring computer-use end-to-end tests with Vitest.",
5
5
  "author": {
6
- "name": "TestDriver"
7
- }
6
+ "name": "TestDriver.ai",
7
+ "url": "https://testdriver.ai"
8
+ },
9
+ "homepage": "https://docs.testdriver.ai",
10
+ "repository": "https://github.com/testdriverai/testdriverai",
11
+ "license": "AGPL-3.0",
12
+ "keywords": [
13
+ "testdriver",
14
+ "testing",
15
+ "e2e",
16
+ "mcp",
17
+ "vitest",
18
+ "automation",
19
+ "computer-use",
20
+ "browser",
21
+ "ai",
22
+ "qa"
23
+ ],
24
+ "mcpServers": {
25
+ "testdriver": {
26
+ "command": "npx",
27
+ "args": ["-p", "testdriverai", "testdriverai-mcp"],
28
+ "env": {
29
+ "TD_API_KEY": "${TD_API_KEY}"
30
+ }
31
+ }
32
+ },
33
+ "agents": [
34
+ "./agents/testdriver.md"
35
+ ],
36
+ "skills": [
37
+ "./skills/testdriver-ai",
38
+ "./skills/testdriver-assert",
39
+ "./skills/testdriver-aws-setup",
40
+ "./skills/testdriver-cache",
41
+ "./skills/testdriver-caching",
42
+ "./skills/testdriver-captcha",
43
+ "./skills/testdriver-ci-cd",
44
+ "./skills/testdriver-click",
45
+ "./skills/testdriver-client",
46
+ "./skills/testdriver-cloud",
47
+ "./skills/testdriver-customizing-devices",
48
+ "./skills/testdriver-dashcam",
49
+ "./skills/testdriver-debugging-with-screenshots",
50
+ "./skills/testdriver-device-config",
51
+ "./skills/testdriver-double-click",
52
+ "./skills/testdriver-elements",
53
+ "./skills/testdriver-enterprise",
54
+ "./skills/testdriver-errors",
55
+ "./skills/testdriver-events",
56
+ "./skills/testdriver-examples",
57
+ "./skills/testdriver-exec",
58
+ "./skills/testdriver-find",
59
+ "./skills/testdriver-focus-application",
60
+ "./skills/testdriver-generating-tests",
61
+ "./skills/testdriver-hosted",
62
+ "./skills/testdriver-hover",
63
+ "./skills/testdriver-locating-elements",
64
+ "./skills/testdriver-making-assertions",
65
+ "./skills/testdriver-mcp",
66
+ "./skills/testdriver-mcp-workflow",
67
+ "./skills/testdriver-mouse-down",
68
+ "./skills/testdriver-mouse-up",
69
+ "./skills/testdriver-parse",
70
+ "./skills/testdriver-performing-actions",
71
+ "./skills/testdriver-press-keys",
72
+ "./skills/testdriver-provision",
73
+ "./skills/testdriver-quickstart",
74
+ "./skills/testdriver-redraw",
75
+ "./skills/testdriver-reusable-code",
76
+ "./skills/testdriver-right-click",
77
+ "./skills/testdriver-running-tests",
78
+ "./skills/testdriver-screenshot",
79
+ "./skills/testdriver-screenshots",
80
+ "./skills/testdriver-scroll",
81
+ "./skills/testdriver-secrets",
82
+ "./skills/testdriver-self-hosted",
83
+ "./skills/testdriver-test-results-json",
84
+ "./skills/testdriver-test-writer",
85
+ "./skills/testdriver-testdriver",
86
+ "./skills/testdriver-testdriver-mechanic",
87
+ "./skills/testdriver-type",
88
+ "./skills/testdriver-variables",
89
+ "./skills/testdriver-wait",
90
+ "./skills/testdriver-waiting-for-elements",
91
+ "./skills/testdriver-what-is-testdriver"
92
+ ]
8
93
  }
9
94
 
@@ -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: ['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']
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/init', '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
@@ -44,7 +44,7 @@ Use this agent when the user asks to:
44
44
  4. **⚠️ WRITE CODE IMMEDIATELY**: After EVERY successful action, append the generated code to the test file RIGHT AWAY. Do NOT wait until the end.
45
45
  5. **Verify Actions**: Use `check` after actions to verify they succeeded (for YOUR understanding only).
46
46
  6. **Add Assertions**: Use `assert` for test conditions that should be in the final test file.
47
- 7. **⚠️ RUN THE TEST YOURSELF**: Use `vitest run <testFile> --reporter=dot` to run the test - do NOT tell the user to run it. Iterate until it passes. **NEVER use `npx vitest`** - always use `vitest` directly.
47
+ 7. **⚠️ RUN THE TEST YOURSELF**: Use `vitest run <testFile>` to run the test - do NOT tell the user to run it. Iterate until it passes. **NEVER use `npx vitest`** - always use `vitest` directly.
48
48
  8. **⚠️ SHARE THE TEST REPORT**: After EVERY test run, find the `TESTDRIVER_RUN_URL` in the output (e.g., `TESTDRIVER_RUN_URL=https://console.testdriver.ai/runs/...`) and share it with the user so they can view the recording and results.
49
49
 
50
50
  ## Prerequisites
@@ -315,11 +315,9 @@ assert({ assertion: "the dashboard is visible" })
315
315
  **⚠️ YOU must run the test - do NOT tell the user to run it. NEVER use `npx vitest` - always use `vitest` directly:**
316
316
 
317
317
  ```bash
318
- vitest run tests/login.test.mjs --reporter=dot
318
+ vitest run tests/login.test.mjs
319
319
  ```
320
320
 
321
- **Always use `--reporter=dot`** for cleaner, more concise output that's easier to parse.
322
-
323
321
  Analyze the output, fix any issues, and iterate until the test passes.
324
322
 
325
323
  **⚠️ ALWAYS share the test report link with the user.** After each test run, look for `TESTDRIVER_RUN_URL` in the test output (e.g., `TESTDRIVER_RUN_URL=https://console.testdriver.ai/runs/...`) and share it with the user so they can view the recording and results. This is CRITICAL - users need to see the visual recording to understand test behavior.
@@ -568,8 +566,6 @@ await testdriver.pressKeys(["escape"]);
568
566
 
569
567
  // Now scroll
570
568
  await testdriver.scroll("down");
571
- await testdriver.scrollUntilText("Footer text");
572
- await testdriver.scrollUntilImage("Product image at bottom");
573
569
 
574
570
  // If scroll is not working, try using Page Down key directly
575
571
  await testdriver.pressKeys(["pagedown"]);
@@ -614,7 +610,7 @@ await testdriver.screenshot(1, false, true);
614
610
  ## Tips for Agents
615
611
 
616
612
  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.
617
- 2. **⚠️ RUN TESTS YOURSELF** - Do NOT tell the user to run tests. YOU must run the tests using `vitest run <testFile> --reporter=dot` (NEVER use `npx vitest` - it breaks the reporter). Always use `--reporter=dot` for cleaner output. Analyze the output and iterate until the test passes.
613
+ 2. **⚠️ RUN TESTS YOURSELF** - Do NOT tell the user to run tests. YOU must run the tests using `vitest run <testFile>` (NEVER use `npx vitest`). Analyze the output and iterate until the test passes.
618
614
  3. **⚠️ SHARE THE TEST REPORT URL** - After EVERY test run, find `TESTDRIVER_RUN_URL=https://console.testdriver.ai/runs/...` in the output and share it with the user. This is CRITICAL - users need to view the recording to understand what happened.
619
615
  3. **Screenshots are automatic** - TestDriver captures screenshots before/after every command by default. Each screenshot filename includes the line number (e.g., `001-click-before-L42-submit-button.png`) making it easy to trace issues.
620
616
  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. The filenames tell you which line of code triggered each screenshot.
@@ -312,4 +312,3 @@ describe('Assertions', () => {
312
312
 
313
313
  - [`extract()`](/v7/extract) - Extract information for detailed assertions
314
314
  - [`find()`](/v7/find) - Locate elements to verify
315
- - [`ai()`](/v7/ai) - Complex AI-driven tasks
@@ -192,7 +192,7 @@ Tests should use `context.ip || process.env.TD_IP` for the IP configuration:
192
192
 
193
193
  ```javascript
194
194
  import { describe, it } from "vitest";
195
- import { TestDriver } from "testdriverai/lib/vitest/hooks.mjs";
195
+ import { TestDriver } from "testdriverai/vitest/hooks";
196
196
 
197
197
  describe("My Test", () => {
198
198
  it("should run on self-hosted instance", async (context) => {
@@ -1,11 +1,12 @@
1
1
  ---
2
2
  name: testdriver:caching
3
- description: 1.7x faster test execution with intelligent caching and optimization
3
+ description: How TestDriver learns your app and caches what it discovers for instant, deterministic replays
4
4
  ---
5
5
  <!-- Generated from caching.mdx. DO NOT EDIT. -->
6
6
 
7
- TestDriver is engineered for performance with intelligent caching that delivers up to **1.7x faster** test execution by skipping redundant AI vision analysis.
7
+ Once the agent has [explored your app](/v7/generating-tests), TestDriver remembers what it found. Every element the AI vision agent discovers is cached with a vision fingerprint—a perceptual hash of the screen state where it was located. On the next run, TestDriver matches against that cache instead of calling the AI again. Passing tests replay instantly, deterministically, and cheaply.
8
8
 
9
+ This learning is what makes TestDriver fast. Intelligent caching delivers up to **1.7x faster** test execution by skipping redundant AI vision analysis—the agent only thinks when it sees something new.
9
10
 
10
11
  ```javascript
11
12
  // First run: builds cache
@@ -17,7 +18,7 @@ await testdriver.find('submit button');
17
18
 
18
19
  ## Automatic Caching
19
20
 
20
- Caching is enabled automatically with zero configuration. The cache key is computed from:
21
+ Learning is enabled automatically with zero configuration. The cache key—the fingerprint TestDriver uses to recognize what it already knows—is computed from:
21
22
 
22
23
  - **File hash**: SHA-256 hash of the test file contents
23
24
  - **Selector prompt**: The exact text description passed to `find()`
@@ -53,7 +54,7 @@ You can clear the cache within the TestDriver console. There, you'll also find p
53
54
 
54
55
  ## Debugging Cache Hits and Misses
55
56
 
56
- You can track cache performance in your tests:
57
+ You can track what TestDriver has learned by inspecting cache performance in your tests:
57
58
 
58
59
  ```javascript
59
60
  test('monitor cache performance', async (context) => {
@@ -75,7 +76,7 @@ test('monitor cache performance', async (context) => {
75
76
 
76
77
  ## Configuring the Cache
77
78
 
78
- You can configure cache behavior globally when initializing TestDriver:
79
+ You can configure how TestDriver learns globally when initializing TestDriver:
79
80
 
80
81
  ```javascript
81
82
  import { TestDriver } from 'testdriverai';
@@ -103,7 +104,7 @@ await testdriver.find('submit button', {
103
104
 
104
105
  ## Caching with Variables
105
106
 
106
- Custom cache keys prevent cache pollution when using variables in prompts, dramatically improving cache hit rates.
107
+ Custom cache keys prevent cache pollution when using variables in prompts, dramatically improving cache hit rates—so TestDriver reuses what it learned even when your data changes.
107
108
 
108
109
  ```javascript
109
110
  // ❌ Without cache key - creates new cache for each variable value
@@ -122,3 +123,9 @@ await testdriver.find(`order ${orderId} status`, {
122
123
  cacheKey: 'order-status' // Same cache for all orders
123
124
  });
124
125
  ```
126
+
127
+ ## Next
128
+
129
+ <Card href="/v7/copilot/running-tests" title="Run" icon="play">
130
+ Now that TestDriver has learned your app, run your tests in CI and locally—replaying the cache for fast, deterministic results.
131
+ </Card>
@@ -6,29 +6,72 @@ description: Run TestDriver tests in CI/CD with parallel execution and cross-pla
6
6
 
7
7
  TestDriver integrates seamlessly with popular CI providers, enabling automated end-to-end testing on every push and pull request.
8
8
 
9
- ## Adding Your API Key
9
+ ## Authentication
10
10
 
11
- TestDriver requires an API key to authenticate with the TestDriver cloud. Store this securely as a secret in your CI provider.
11
+ On **GitHub Actions, prefer OIDC** via the published `testdriverai/action`
12
+ there's no `TD_API_KEY` secret to store, copy, or rotate. The action proves the
13
+ workflow is running inside your org and TestDriver exchanges that proof for your
14
+ team's key at run time. See the GitHub Actions tab below.
12
15
 
13
- <Steps>
14
- <Step title="Get Your API Key">
15
- Go to [console.testdriver.ai/team](https://console.testdriver.ai/team) and copy your team's API key
16
- </Step>
17
- <Step title="Add Secret to Your CI Provider">
18
- Add `TD_API_KEY` as a secret environment variable in your CI provider's settings.
19
- </Step>
20
- </Steps>
16
+ For other CI providers (or self-hosted runners without OIDC), fall back to a
17
+ stored API key from [console.testdriver.ai/team](https://console.testdriver.ai/team),
18
+ added as a `TD_API_KEY` secret in your CI provider's settings.
21
19
 
22
20
  <Note>
23
- Never commit your API key directly in code. Always use your CI provider's secrets management.
21
+ Never commit your API key directly in code. Always use OIDC or your CI provider's secrets management.
24
22
  </Note>
25
23
 
26
24
  ## CI Provider Examples
27
25
 
28
26
  <Tabs>
29
27
  <Tab title="GitHub Actions">
30
- ### Adding Secrets
31
-
28
+ ### Authenticate with OIDC via `testdriverai/action` (recommended)
29
+
30
+ Use the published [`testdriverai/action`](https://github.com/testdriverai/action) — it mints the OIDC token, exchanges it for your team's API key, and exports `TD_API_KEY` for the steps that follow. **No `TD_API_KEY` secret to store or rotate.**
31
+
32
+ <Note>
33
+ One-time setup: authorize the [TestDriver GitHub App](https://console.testdriver.ai) for your org so the org → team binding exists. If your org authorized the App before OIDC support shipped, re-authorize once. If the App isn't authorized, the action fails with a console link (or falls back to the `api-key` secret if you provide one).
34
+ </Note>
35
+
36
+ ```yaml .github/workflows/testdriver.yml
37
+ name: TestDriver Tests
38
+
39
+ on:
40
+ push:
41
+ branches: [main]
42
+ pull_request:
43
+ branches: [main]
44
+
45
+ jobs:
46
+ test:
47
+ runs-on: ubuntu-latest
48
+ permissions:
49
+ id-token: write # REQUIRED to mint an OIDC token
50
+ contents: read
51
+
52
+ steps:
53
+ - uses: actions/checkout@v4
54
+
55
+ - uses: actions/setup-node@v4
56
+ with:
57
+ node-version: '20'
58
+ cache: 'npm'
59
+
60
+ - run: npm ci
61
+
62
+ - name: Authenticate to TestDriver
63
+ uses: testdriverai/action@stable # pin @stable / @canary / @test to your SDK channel
64
+ with:
65
+ api-key: ${{ secrets.TD_API_KEY }} # optional fallback if OIDC isn't set up
66
+
67
+ - name: Run TestDriver tests
68
+ run: npx vitest run
69
+ ```
70
+
71
+ ### Stored-key fallback
72
+
73
+ Only if you can't use OIDC (e.g. self-hosted runners without an OIDC provider). Add the key as a secret and pass it via `env`:
74
+
32
75
  1. Navigate to your GitHub repository
33
76
  2. Go to **Settings** → **Secrets and variables** → **Actions**
34
77
  3. Click **New repository secret**
@@ -571,7 +614,7 @@ When using multi-platform testing, read the `TD_OS` environment variable in your
571
614
 
572
615
  ```javascript tests/cross-platform.test.mjs
573
616
  import { describe, expect, it } from "vitest";
574
- import { TestDriver } from "testdriverai/lib/vitest/hooks.mjs";
617
+ import { TestDriver } from "testdriverai/vitest/hooks";
575
618
 
576
619
  describe("Cross-platform tests", () => {
577
620
  it("should work on both Linux and Windows", async (context) => {
@@ -29,7 +29,7 @@ const testdriver = new TestDriver(apiKey, options)
29
29
  </ParamField>
30
30
 
31
31
  <ParamField path="resolution" type="string" default="1366x768">
32
- Screen resolution for the sandbox (e.g., `'1920x1080'`, `'1366x768'`)
32
+ Screen resolution for the sandbox (e.g., `'1920x1080'`, `'1366x768'`). Custom resolutions are only available on Enterprise plans.
33
33
  </ParamField>
34
34
 
35
35
  <ParamField path="apiRoot" type="string">
@@ -44,7 +44,7 @@ const testdriver = new TestDriver(apiKey, options)
44
44
  Enable or disable console logging
45
45
  </ParamField>
46
46
 
47
- <ParamField path="autoScreenshots" type="boolean" default="true">
47
+ <ParamField path="autoScreenshots" type="boolean" default="false">
48
48
  Automatically capture screenshots before and after each command. Screenshots are saved to `.testdriver/screenshots/<test>/` with descriptive filenames that include the line number and action name. Format: `<seq>-<action>-<phase>-L<line>-<description>.png`
49
49
  </ParamField>
50
50
 
@@ -53,11 +53,11 @@ const testdriver = new TestDriver(apiKey, options)
53
53
  </ParamField>
54
54
 
55
55
  <ParamField path="reconnect" type="boolean" default="false">
56
- Reconnect to the last used sandbox instead of creating a new one. When `true`, provision methods (`chrome`, `vscode`, `installer`, etc.) will be skipped since the application is already running. Throws error if no previous sandbox exists.
56
+ Reattach to the last used sandbox instead of creating a new one. When `true`, the SDK reads the sandbox id from `.testdriver/last-sandbox` (written automatically on every successful connect) and rejoins that VM. Provision methods (`chrome`, `vscode`, `installer`, etc.) are skipped because the application is already running. The previous sandbox must still be alive — see [`keepAlive`](#keepalive) and the [Run guide](/v7/copilot/running-tests#keeping-machines-alive-between-runs).
57
57
  </ParamField>
58
-
59
- <ParamField path="keepAlive" type="number" default="60000">
60
- 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.
58
+
59
+ <ParamField path="sandboxId" type="string">
60
+ Reattach to a specific sandbox id instead of the one recorded in `.testdriver/last-sandbox`. Use this for CI matrices or to pin a chain of tests to a known VM. Implies `reconnect: true` behavior (provision calls are skipped).
61
61
  </ParamField>
62
62
 
63
63
  <ParamField path="preview" type="string" default="browser">
@@ -274,6 +274,10 @@ await testdriver.connect(options)
274
274
  <ParamField path="headless" type="boolean" default="false">
275
275
  **Deprecated**: Use `preview: "none"` instead. Run in headless mode without opening the debugger.
276
276
  </ParamField>
277
+
278
+ <ParamField path="keepAlive" type="number" default="60000">
279
+ 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.
280
+ </ParamField>
277
281
  </Expandable>
278
282
  </ParamField>
279
283
 
@@ -39,7 +39,7 @@ const testdriver = TestDriver(context, {
39
39
 
40
40
  // === Recording & Screenshots ===
41
41
  dashcam: true, // Enable/disable Dashcam video recording (default: true)
42
- autoScreenshots: true, // Capture screenshots before/after each command (default: true)
42
+ autoScreenshots: true, // Capture screenshots before/after each command (default: false)
43
43
 
44
44
  // === AI Configuration ===
45
45
  ai: { // Global AI sampling configuration
@@ -283,9 +283,9 @@ const testdriver = TestDriver(context, {
283
283
  });
284
284
  ```
285
285
 
286
- ### Reconnecting to Existing Sandbox
286
+ ### Connecting to an Existing Sandbox
287
287
 
288
- Speed up test development by reconnecting to an existing sandbox instead of starting fresh each time. This lets you iterate quickly on failing steps without re-running the entire test from the beginning.
288
+ Speed up test development by connecting to an existing sandbox instead of starting fresh each time. This lets you iterate quickly on failing steps without re-running the entire test from the beginning.
289
289
 
290
290
  Split your test into two files: one for known-good steps that set up the desired state, and another for work-in-progress steps you want to debug.
291
291
 
@@ -298,8 +298,10 @@ const testdriver = TestDriver(context, {
298
298
  ```javascript work-in-progress.test.mjs
299
299
  // Second test file: experiment.test.mjs (run within keepAlive window)
300
300
  const testdriver = TestDriver(context, {
301
- reconnect: true, // Reconnect to existing sandbox
301
+ keepAlive: 60000,
302
302
  });
303
+
304
+ await testdriver.connect({ sandboxId: "sandbox-abc123" });
303
305
  ```
304
306
 
305
307
  Then, you can run both tests in sequence:
@@ -315,5 +317,5 @@ vitest run work-in-progress.test.mjs
315
317
  ```
316
318
 
317
319
  <Warning>
318
- Reconnect only works if run within the `keepAlive` window of the previous test.
320
+ Connecting to the same machine only works if run within the `keepAlive` window of the previous test.
319
321
  </Warning>
@@ -71,8 +71,8 @@ new Dashcam(client, options)
71
71
  Configuration options
72
72
 
73
73
  <Expandable title="options properties">
74
- <ParamField path="apiKey" type="string" default="4e93d8bf-3886-4d26-a144-116c4063522d">
75
- Dashcam API key for authentication
74
+ <ParamField path="apiKey" type="string">
75
+ Dashcam API key for authentication. Set via `TD_API_KEY` environment variable.
76
76
  </ParamField>
77
77
 
78
78
  <ParamField path="autoStart" type="boolean" default={false}>
@@ -192,6 +192,29 @@ await dashcam.addApplicationLog(application, name)
192
192
  await dashcam.addApplicationLog('Google Chrome', 'Browser Logs');
193
193
  ```
194
194
 
195
+ ### addWebLog()
196
+
197
+ Track web request logs by URL pattern:
198
+
199
+ ```javascript
200
+ await dashcam.addWebLog(pattern, name)
201
+ ```
202
+
203
+ <ParamField path="pattern" type="string" required>
204
+ URL pattern to match (e.g., `"*example.com*"`)
205
+ </ParamField>
206
+
207
+ <ParamField path="name" type="string" required>
208
+ Display name for the log
209
+ </ParamField>
210
+
211
+ **Returns:** `Promise<void>`
212
+
213
+ **Example:**
214
+ ```javascript
215
+ await dashcam.addWebLog('*example.com*', 'Web Logs');
216
+ ```
217
+
195
218
  ### addLog()
196
219
 
197
220
  Generic method to add any type of log:
@@ -209,7 +232,7 @@ await dashcam.addLog(config)
209
232
  </ParamField>
210
233
 
211
234
  <ParamField path="type" type="string" required>
212
- Log type: `'file'`, `'stdout'`, or `'application'`
235
+ Log type: `'file'`, `'application'`, or `'web'`
213
236
  </ParamField>
214
237
 
215
238
  <ParamField path="path" type="string">
@@ -219,6 +242,10 @@ await dashcam.addLog(config)
219
242
  <ParamField path="application" type="string">
220
243
  Application name (required for type='application')
221
244
  </ParamField>
245
+
246
+ <ParamField path="pattern" type="string">
247
+ URL pattern to match (required for type='web', e.g., `"*example.com*"`)
248
+ </ParamField>
222
249
  </Expandable>
223
250
  </ParamField>
224
251
 
@@ -237,6 +264,12 @@ await dashcam.addLog({
237
264
  type: 'application',
238
265
  application: 'Google Chrome'
239
266
  });
267
+
268
+ await dashcam.addLog({
269
+ name: 'Web Logs',
270
+ type: 'web',
271
+ pattern: '*example.com*'
272
+ });
240
273
  ```
241
274
 
242
275
  ### isRecording()
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  name: testdriver:debugging-with-screenshots
3
- description: View and analyze saved screenshots using MCP commands for test debugging and development
3
+ description: Diagnose failing tests with screenshots, replays, and logs
4
4
  ---
5
5
  <!-- Generated from debugging-with-screenshots.mdx. DO NOT EDIT. -->
6
6
 
7
7
  ## Overview
8
8
 
9
- TestDriver MCP provides powerful commands to view and analyze screenshots saved during test execution. This enables rapid debugging, test development, and comparison workflows without manually opening image files.
9
+ When a test fails, debug it by seeing exactly what happened — don't guess. TestDriver captures screenshots, video replays, and logs as your test runs, so you can replay the moment of failure instead of squinting at a stack trace. TestDriver MCP provides powerful commands to view and analyze the screenshots saved during test execution, enabling rapid debugging, test development, and comparison workflows without manually opening image files.
10
10
 
11
11
  <Note>
12
12
  **Automatic Screenshots (Default: Enabled)**: TestDriver automatically captures screenshots before and after every command. Screenshots are named with the line number and action, making it easy to trace exactly which line of code produced each screenshot. For example: `001-click-before-L42-submit-button.png`
@@ -122,7 +122,7 @@ view_local_screenshot({ path: "/full/path/to/screenshot.png" })
122
122
 
123
123
  ### Test Debugging After Failures
124
124
 
125
- When a test fails, use powerful filtering to quickly find relevant screenshots:
125
+ When a test fails, you don't have to wonder what went wrong — use powerful filtering to quickly find the screenshots that show exactly what happened:
126
126
 
127
127
  **1. Find screenshots at the failing line:**
128
128
 
@@ -328,6 +328,20 @@ Understanding the directory structure helps with efficient screenshot viewing:
328
328
  - All screenshots are PNG format
329
329
  - Disable automatic screenshots with `autoScreenshots: false` if needed
330
330
 
331
+ ## Interaction List Sidebar (Source of Truth)
332
+
333
+ When viewing a test run in the TestDriver console, the **interaction list sidebar** displays a screenshot for each interaction call (find, click, type, assert, etc.). These screenshots show exactly what was on the screen at the time each interaction was executed.
334
+
335
+ <Note>
336
+ **The sidebar screenshots are the source of truth.** If a test is behaving unexpectedly, check the screenshot attached to the specific interaction in the sidebar — it shows precisely what the AI saw when making its decision. This is more reliable than inferring screen state from test logs or local screenshots alone.
337
+ </Note>
338
+
339
+ Use the interaction list to:
340
+ - **Verify what the AI saw** — confirm the correct page/state was visible when `find()` or `assert()` ran
341
+ - **Debug misclicks** — see whether the target element was actually on screen
342
+ - **Identify timing issues** — spot cases where the UI hadn't finished loading before an interaction fired
343
+ - **Compare runs** — review interaction screenshots across multiple runs to catch flaky behavior
344
+
331
345
  ## Integration with Test Development
332
346
 
333
347
  ### During MCP Interactive Development
@@ -344,7 +358,7 @@ This helps verify your test logic before running the full test file.
344
358
 
345
359
  ### After Test Runs
346
360
 
347
- When tests fail or behave unexpectedly:
361
+ When tests fail or behave unexpectedly, replay what happened step by step:
348
362
 
349
363
  1. **Run the test** with `vitest run tests/my-test.test.mjs`
350
364
  2. **List screenshots** using `list_local_screenshots`
@@ -394,8 +408,18 @@ When tests fail or behave unexpectedly:
394
408
  </Accordion>
395
409
  </AccordionGroup>
396
410
 
411
+ ## Where this fits in the Guide
412
+
413
+ Debugging is what you reach for when a [Run](/v7/copilot/running-tests) goes sideways or a [Validate](/v7/making-assertions) assertion fails — the screenshots show you precisely what the AI saw before it acted. Once you've diagnosed the failure, the next step is to stop it from recurring.
414
+
397
415
  ## Related
398
416
 
399
417
  - [screenshot()](/v7/screenshot) - Capture screenshots during test execution
400
418
  - [Dashcam](/v7/dashcam) - Record full test sessions with video and logs
401
419
  - [assert()](/v7/assert) - Make AI-powered assertions that benefit from screenshot context
420
+
421
+ ## Next
422
+
423
+ <Card title="Prevent" icon="shield-check" href="/v7/copilot/auto-healing">
424
+ You've seen what went wrong — now keep it from happening again. Let auto-healing repair flaky tests automatically before they fail your suite.
425
+ </Card>
@@ -28,7 +28,7 @@ await testdriver.provision.chrome({
28
28
 
29
29
  ```javascript
30
30
  import { describe, expect, it } from "vitest";
31
- import { TestDriver } from "testdriverai/lib/vitest/hooks.mjs";
31
+ import { TestDriver } from "testdriverai/vitest/hooks";
32
32
 
33
33
  describe("Login Flow", () => {
34
34
  it("should log in successfully", async (context) => {
@@ -113,7 +113,7 @@ await testdriver.provision.chromeExtension({
113
113
 
114
114
  ```javascript
115
115
  import { describe, expect, it } from "vitest";
116
- import { TestDriver } from "testdriverai/lib/vitest/hooks.mjs";
116
+ import { TestDriver } from "testdriverai/vitest/hooks";
117
117
 
118
118
  describe("Chrome Extension Test", () => {
119
119
  it("should load and interact with extension", async (context) => {
@@ -187,7 +187,7 @@ const filePath = await testdriver.provision.installer({
187
187
 
188
188
  ```javascript
189
189
  import { describe, expect, it } from "vitest";
190
- import { TestDriver } from "testdriverai/lib/vitest/hooks.mjs";
190
+ import { TestDriver } from "testdriverai/vitest/hooks";
191
191
 
192
192
  describe("Desktop App Test", () => {
193
193
  it("should install and launch app", async (context) => {
@@ -209,7 +209,7 @@ describe("Desktop App Test", () => {
209
209
 
210
210
  ```javascript
211
211
  import { describe, expect, it } from "vitest";
212
- import { TestDriver } from "testdriverai/lib/vitest/hooks.mjs";
212
+ import { TestDriver } from "testdriverai/vitest/hooks";
213
213
 
214
214
  describe("Windows App Test", () => {
215
215
  it("should install on Windows", async (context) => {
@@ -276,7 +276,7 @@ await testdriver.provision.vscode({
276
276
 
277
277
  ```javascript
278
278
  import { describe, expect, it } from "vitest";
279
- import { TestDriver } from "testdriverai/lib/vitest/hooks.mjs";
279
+ import { TestDriver } from "testdriverai/vitest/hooks";
280
280
 
281
281
  describe("VS Code Test", () => {
282
282
  it("should open workspace with extensions", async (context) => {