@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
@@ -2,104 +2,108 @@
2
2
  "$schema": "./examples-manifest.schema.json",
3
3
  "examples": {
4
4
  "assert.test.mjs": {
5
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d038058ffe89003c6adc",
6
- "lastUpdated": "2026-03-27T00:44:44.009Z"
5
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b6fea57200d3f72adc69",
6
+ "lastUpdated": "2026-07-02T00:55:25.864Z"
7
7
  },
8
8
  "drag-and-drop.test.mjs": {
9
9
  "url": "https://console.testdriver.ai/runs/69a62b3aaa712ecd3dea730a/69a62b42fc0ac3cc632a918b",
10
10
  "lastUpdated": "2026-03-03T00:32:25.275Z"
11
11
  },
12
12
  "exec-pwsh.test.mjs": {
13
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d026a0a3ef8239de4746",
14
- "lastUpdated": "2026-03-27T00:33:58.317Z"
13
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b6234608e3f6c45ddf76",
14
+ "lastUpdated": "2026-07-02T00:58:50.738Z"
15
15
  },
16
16
  "match-image.test.mjs": {
17
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d0270201196437256ccf",
18
- "lastUpdated": "2026-03-27T00:33:59.709Z"
17
+ "url": "https://console-test.testdriver.ai/runs/69c8738614b73310c7839412/69c8738c14b73310c783941d",
18
+ "lastUpdated": "2026-03-29T00:35:43.814Z"
19
19
  },
20
20
  "scroll-until-text.test.mjs": {
21
21
  "url": "https://console.testdriver.ai/runs/69a62b3aaa712ecd3dea730a/69a62b99dc33133fc0da9440",
22
22
  "lastUpdated": "2026-03-03T00:32:25.282Z"
23
23
  },
24
24
  "hover-text-with-description.test.mjs": {
25
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d029c2e6e94933886764",
26
- "lastUpdated": "2026-03-27T00:32:41.295Z"
25
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b653a57200d3f72adc5a",
26
+ "lastUpdated": "2026-07-02T00:59:36.056Z"
27
27
  },
28
28
  "windows-installer.test.mjs": {
29
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d02ce8a04db4b705cbe9",
30
- "lastUpdated": "2026-03-27T00:34:04.862Z"
29
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b656a57200d3f72adc5c",
30
+ "lastUpdated": "2026-07-02T01:16:50.573Z"
31
31
  },
32
32
  "exec-output.test.mjs": {
33
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d02ee8a04db4b705cbeb",
34
- "lastUpdated": "2026-03-27T00:34:06.467Z"
33
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b6584608e3f6c45ddf8d",
34
+ "lastUpdated": "2026-07-02T01:06:34.502Z"
35
35
  },
36
36
  "chrome-extension.test.mjs": {
37
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d024c2e6e94933886763",
38
- "lastUpdated": "2026-03-27T00:33:19.157Z"
37
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b6214608e3f6c45ddf74",
38
+ "lastUpdated": "2026-07-02T00:58:47.331Z"
39
39
  },
40
40
  "launch-vscode-linux.test.mjs": {
41
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d02be8a04db4b705cbe5",
42
- "lastUpdated": "2026-03-27T00:38:16.512Z"
41
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b63ba57200d3f72adc4c",
42
+ "lastUpdated": "2026-07-02T01:06:05.378Z"
43
43
  },
44
44
  "hover-image.test.mjs": {
45
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d0300201196437256cd3",
46
- "lastUpdated": "2026-03-27T00:33:30.129Z"
45
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b671a57200d3f72adc65",
46
+ "lastUpdated": "2026-07-02T00:53:05.430Z"
47
47
  },
48
48
  "installer.test.mjs": {
49
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d032c2e6e94933886769",
50
- "lastUpdated": "2026-03-27T00:32:50.006Z"
49
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b69e4608e3f6c45ddf96",
50
+ "lastUpdated": "2026-07-02T00:53:50.151Z"
51
51
  },
52
52
  "type.test.mjs": {
53
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d034c2e6e9493388676c",
54
- "lastUpdated": "2026-03-27T00:33:33.802Z"
53
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b6cb4608e3f6c45ddf98",
54
+ "lastUpdated": "2026-07-02T01:08:31.378Z"
55
55
  },
56
56
  "press-keys.test.mjs": {
57
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d036058ffe89003c6ada",
58
- "lastUpdated": "2026-03-27T00:43:59.035Z"
57
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b6e5a57200d3f72adc68",
58
+ "replayUrl": "https://console-test.testdriver.ai/replay/6a45bd51a57200d3f72adcbd?share=ty93E0byJrJD5eiBxh3nTQ",
59
+ "embedUrl": "https://console-test.testdriver.ai/replay/6a45bd51a57200d3f72adcbd?share=ty93E0byJrJD5eiBxh3nTQ&embed=true",
60
+ "lastUpdated": "2026-07-02T01:22:31.522Z"
59
61
  },
60
62
  "scroll-keyboard.test.mjs": {
61
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d03da0a3ef8239de474f",
62
- "lastUpdated": "2026-03-27T00:34:18.283Z"
63
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b72da57200d3f72adc70",
64
+ "lastUpdated": "2026-07-02T01:10:07.429Z"
63
65
  },
64
66
  "scroll.test.mjs": {
65
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d043058ffe89003c6ae0",
66
- "lastUpdated": "2026-03-27T00:48:40.373Z"
67
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b74ca57200d3f72adc72",
68
+ "lastUpdated": "2026-07-02T01:03:40.730Z"
67
69
  },
68
70
  "scroll-until-image.test.mjs": {
69
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d03f0201196437256cda",
70
- "lastUpdated": "2026-03-27T00:33:03.090Z"
71
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b72f4608e3f6c45ddf9a",
72
+ "lastUpdated": "2026-07-02T00:56:16.070Z"
71
73
  },
72
74
  "prompt.test.mjs": {
73
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d040c2e6e9493388676f",
74
- "lastUpdated": "2026-03-27T00:34:21.306Z"
75
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b7314608e3f6c45ddf9b",
76
+ "lastUpdated": "2026-07-02T01:10:12.253Z"
75
77
  },
76
78
  "focus-window.test.mjs": {
77
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d042e8a04db4b705cbf2",
78
- "lastUpdated": "2026-03-27T00:33:06.137Z"
79
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b733a57200d3f72adc71",
80
+ "lastUpdated": "2026-07-02T01:10:14.288Z"
79
81
  },
80
82
  "captcha-api.test.mjs": {
81
83
  "url": "https://console.testdriver.ai/runs/698f7df69e27ce1528d7d087/698f7fb0d3b320ad547d9d44",
82
84
  "lastUpdated": "2026-02-13T19:55:05.951Z"
83
85
  },
84
86
  "element-not-found.test.mjs": {
85
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d047058ffe89003c6ae4",
86
- "lastUpdated": "2026-03-27T00:34:27.452Z"
87
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b764a57200d3f72adc73",
88
+ "lastUpdated": "2026-07-02T01:04:04.551Z"
87
89
  },
88
90
  "formatted-logging.test.mjs": {
89
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d045058ffe89003c6ae1",
90
- "lastUpdated": "2026-03-27T00:34:25.797Z"
91
+ "url": "https://console-test.testdriver.ai/runs/69c8738614b73310c7839412/69c873a714b73310c7839450",
92
+ "lastUpdated": "2026-03-29T00:36:10.628Z"
91
93
  },
92
94
  "hover-text.test.mjs": {
93
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d04b0201196437256ce6",
94
- "lastUpdated": "2026-03-27T00:33:15.698Z"
95
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b7984608e3f6c45ddfa5",
96
+ "lastUpdated": "2026-07-02T01:04:53.374Z"
95
97
  },
96
98
  "no-provision.test.mjs": {
97
99
  "url": "https://console.testdriver.ai/runs/69a62b3aaa712ecd3dea730a/69a62b7706a177a05bccd1cf",
98
100
  "lastUpdated": "2026-03-03T00:32:25.279Z"
99
101
  },
100
102
  "ai.test.mjs": {
101
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d04ac2e6e94933886778",
102
- "lastUpdated": "2026-03-27T00:52:24.469Z"
103
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b77da57200d3f72adc74",
104
+ "replayUrl": "https://console-test.testdriver.ai/replay/6a45bf434608e3f6c45de01b?share=eQ8yZOqg3UqrJKjELcDm2A",
105
+ "embedUrl": "https://console-test.testdriver.ai/replay/6a45bf434608e3f6c45de01b?share=eQ8yZOqg3UqrJKjELcDm2A&embed=true",
106
+ "lastUpdated": "2026-07-02T01:30:50.186Z"
103
107
  },
104
108
  "popup-loading.test.mjs": {
105
109
  "url": "https://console.testdriver.ai/runs/698bc89f7140c3fa7daaca8d/698bca7f7140c3fa7daacbf7",
@@ -134,12 +138,12 @@
134
138
  "lastUpdated": "2026-02-13T19:55:05.953Z"
135
139
  },
136
140
  "findall-coffee-icons.test.mjs": {
137
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d03ae8a04db4b705cbf0",
138
- "lastUpdated": "2026-03-27T00:33:38.971Z"
141
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b714a57200d3f72adc6a",
142
+ "lastUpdated": "2026-07-02T00:55:48.391Z"
139
143
  },
140
144
  "parse.test.mjs": {
141
- "url": "https://console-test.testdriver.ai/runs/69c5d0220201196437256cce/69c5d04d0201196437256ce7",
142
- "lastUpdated": "2026-03-27T00:34:32.300Z"
145
+ "url": "https://console-test.testdriver.ai/runs/6a45b608fa48a35463bd55d8/6a45b7af4608e3f6c45ddfaa",
146
+ "lastUpdated": "2026-07-02T01:05:15.804Z"
143
147
  },
144
148
  "flake-diffthreshold-001.test.mjs": {
145
149
  "url": "https://console.testdriver.ai/runs/69a62b3aaa712ecd3dea730a/69a62bcafc0ac3cc632a91aa",
@@ -172,6 +176,10 @@
172
176
  "flake-diffthreshold-01.test.mjs": {
173
177
  "url": "https://console.testdriver.ai/runs/69a62b3aaa712ecd3dea730a/69a62bd0348bcf90ca081079",
174
178
  "lastUpdated": "2026-03-03T00:32:25.283Z"
179
+ },
180
+ "exec-stream-logs.test.mjs": {
181
+ "url": "https://console-test.testdriver.ai/runs/69c9c4feffa05350a7d3abc1/69c9c520ffa05350a7d3abd9",
182
+ "lastUpdated": "2026-03-30T00:35:14.437Z"
175
183
  }
176
184
  }
177
185
  }
@@ -14,8 +14,18 @@
14
14
  "properties": {
15
15
  "url": {
16
16
  "type": "string",
17
- "description": "Full URL to the test run (without ?embed=true)",
18
- "pattern": "^https://console\\.testdriver\\.ai/runs/.+"
17
+ "description": "Full URL to the test run (legacy source for testcase ID)",
18
+ "pattern": "^https://console(?:-(?:test|canary))?\\.testdriver\\.ai/runs/.+"
19
+ },
20
+ "replayUrl": {
21
+ "type": "string",
22
+ "description": "Public replay URL with share key",
23
+ "pattern": "^https://console(?:-(?:test|canary))?\\.testdriver\\.ai/replay/.+"
24
+ },
25
+ "embedUrl": {
26
+ "type": "string",
27
+ "description": "Public replay embed URL used by docs iframes",
28
+ "pattern": "^https://console(?:-(?:test|canary))?\\.testdriver\\.ai/replay/.+"
19
29
  },
20
30
  "lastUpdated": {
21
31
  "type": "string",
@@ -15,6 +15,19 @@ const path = require("path");
15
15
 
16
16
  const MANIFEST_PATH = path.join(__dirname, "../_data/examples-manifest.json");
17
17
 
18
+ function deriveEmbedUrlFromReplayUrl(replayUrl) {
19
+ if (!replayUrl) return null;
20
+ try {
21
+ const url = new URL(replayUrl);
22
+ if (!url.pathname.includes("/replay/")) return null;
23
+ if (!url.searchParams.get("share")) return null;
24
+ url.searchParams.set("embed", "true");
25
+ return url.toString();
26
+ } catch {
27
+ return null;
28
+ }
29
+ }
30
+
18
31
  // Parse command line arguments
19
32
  function parseArgs() {
20
33
  const args = process.argv.slice(2);
@@ -81,12 +94,16 @@ function processResultsDir(resultsDir) {
81
94
  const result = JSON.parse(content);
82
95
  const testFileName = path.basename(result.test?.file || result.testFile || entry.name);
83
96
  const url = result.urls?.testRun || result.testRunLink;
97
+ const replayUrl = result.replay?.url || result.replayUrl || null;
98
+ const embedUrl = result.replay?.embedUrl || deriveEmbedUrlFromReplayUrl(replayUrl);
84
99
 
85
- if (!url) continue;
100
+ if (!url && !embedUrl) continue;
86
101
 
87
102
  const isNew = !manifest.examples[testFileName];
88
103
  manifest.examples[testFileName] = {
89
- url: url,
104
+ url: url || manifest.examples[testFileName]?.url || null,
105
+ ...(replayUrl ? { replayUrl } : {}),
106
+ ...(embedUrl ? { embedUrl } : {}),
90
107
  lastUpdated: result.date || new Date().toISOString(),
91
108
  };
92
109
 
@@ -96,7 +113,8 @@ function processResultsDir(resultsDir) {
96
113
  stats.updated++;
97
114
  }
98
115
 
99
- console.log(`${isNew ? "➕" : "🔄"} ${testFileName}: ${url}`);
116
+ const displayUrl = embedUrl || url || "(no URL)";
117
+ console.log(`${isNew ? "➕" : "🔄"} ${testFileName}: ${displayUrl}`);
100
118
  } catch (err) {
101
119
  console.warn(`⚠️ Failed to read ${jsonFile}: ${err.message}`);
102
120
  }
@@ -21,6 +21,16 @@ const MANIFEST_PATH = path.join(__dirname, "../_data/examples-manifest.json");
21
21
  const OUTPUT_DIR = path.join(__dirname, "../v7/examples");
22
22
  const DOCS_JSON_PATH = path.join(__dirname, "../docs.json");
23
23
 
24
+ // Examples to exclude from docs generation (filenames without path)
25
+ const EXCLUDE_FROM_DOCS = [
26
+ "exec-output.test.mjs",
27
+ "exec-pwsh.test.mjs",
28
+ "focus-window.test.mjs",
29
+ "prompt.test.mjs",
30
+ "scroll-until-image.test.mjs",
31
+ "windows-installer.test.mjs",
32
+ ];
33
+
24
34
  // Icon mapping based on test type/content
25
35
  const ICON_MAP = {
26
36
  ai: "wand-magic-sparkles",
@@ -74,11 +84,11 @@ function saveDocsJson(docsJson) {
74
84
  fs.writeFileSync(DOCS_JSON_PATH, JSON.stringify(docsJson, null, 2) + "\n", "utf-8");
75
85
  }
76
86
 
77
- // Get all example files
87
+ // Get all example files (excluding ones in EXCLUDE_FROM_DOCS)
78
88
  function getExampleFiles() {
79
89
  return fs
80
90
  .readdirSync(EXAMPLES_DIR)
81
- .filter((f) => f.endsWith(".test.mjs"))
91
+ .filter((f) => f.endsWith(".test.mjs") && !EXCLUDE_FROM_DOCS.includes(f))
82
92
  .sort();
83
93
  }
84
94
 
@@ -279,22 +289,61 @@ function extractTestcaseId(url) {
279
289
  return pathParts.length >= 2 ? pathParts[pathParts.length - 1] : null;
280
290
  }
281
291
 
282
- // Generate replay URL from testcase ID
283
- function generateReplayUrl(testcaseId) {
284
- // Use the API replay endpoint which handles the redirect with embed=true
285
- const apiRoot = process.env.TD_API_ROOT || 'https://api.testdriver.ai';
292
+ // Derive API root from a console URL (e.g. console-test.testdriver.ai → api-test.testdriver.ai)
293
+ function apiRootFromConsoleUrl(sourceUrl) {
294
+ if (!sourceUrl) return null;
295
+ try {
296
+ const url = new URL(sourceUrl);
297
+ // Map console* hostname to api* hostname
298
+ const apiHostname = url.hostname.replace(/^console/, 'api');
299
+ return `${url.protocol}//${apiHostname}`;
300
+ } catch {
301
+ return null;
302
+ }
303
+ }
304
+
305
+ function normalizeEmbedUrl(rawUrl) {
306
+ if (!rawUrl) return null;
307
+ try {
308
+ const url = new URL(rawUrl);
309
+ if (!url.pathname.includes('/replay/')) return null;
310
+ if (!url.searchParams.get('share')) return null;
311
+ url.searchParams.set('embed', 'true');
312
+ return url.toString();
313
+ } catch {
314
+ return null;
315
+ }
316
+ }
317
+
318
+ // Resolve the best embed URL for docs:
319
+ // 1) explicit embedUrl from manifest (preferred)
320
+ // 2) replayUrl in manifest (converted to embed=true)
321
+ // 3) legacy run URL via testcase replay redirect endpoint
322
+ function resolveReplayEmbedUrl(manifestEntry) {
323
+ const directEmbed = normalizeEmbedUrl(manifestEntry?.embedUrl);
324
+ if (directEmbed) return directEmbed;
325
+
326
+ const replayEmbed = normalizeEmbedUrl(manifestEntry?.replayUrl);
327
+ if (replayEmbed) return replayEmbed;
328
+
329
+ const testcaseId = manifestEntry?.url ? extractTestcaseId(manifestEntry.url) : null;
330
+ if (!testcaseId) return null;
331
+
332
+ const apiRoot = apiRootFromConsoleUrl(manifestEntry?.url) || process.env.TD_API_ROOT || 'https://api.testdriver.ai';
286
333
  return `${apiRoot}/api/v1/testdriver/testcase/${testcaseId}/replay`;
287
334
  }
288
335
 
289
336
  // Update existing MDX file by finding the marker comment and replacing the iframe
290
- function updateExistingMDX(existingContent, filename, testcaseId) {
337
+ function updateExistingMDX(existingContent, filename, replayEmbedUrl) {
291
338
  const marker = `{/* ${filename} output */}`;
292
339
 
293
340
  if (!existingContent.includes(marker)) {
294
341
  return null; // Marker not found, can't update
295
342
  }
296
343
 
297
- const replayUrl = generateReplayUrl(testcaseId);
344
+ if (!replayEmbedUrl) {
345
+ return null;
346
+ }
298
347
 
299
348
  // Pattern to match the marker followed by the iframe tag
300
349
  const escapedFilename = filename.replace(/\./g, '\\.');
@@ -303,7 +352,7 @@ function updateExistingMDX(existingContent, filename, testcaseId) {
303
352
  's'
304
353
  );
305
354
 
306
- const replacement = `$1<iframe \n src="${replayUrl}"$2/>`;
355
+ const replacement = `$1<iframe \n src="${replayEmbedUrl}"$2/>`;
307
356
  const updated = existingContent.replace(pattern, replacement);
308
357
 
309
358
  if (updated === existingContent) {
@@ -339,7 +388,7 @@ function generateMDX(testMeta, manifest, description) {
339
388
  const sidebarTitle = generateSidebarTitle(testMeta.filename);
340
389
  const shortDescription = generateShortDescription(testMeta);
341
390
  const manifestEntry = manifest.examples[testMeta.filename];
342
- const testcaseId = manifestEntry?.url ? extractTestcaseId(manifestEntry.url) : null;
391
+ const replayEmbedUrl = resolveReplayEmbedUrl(manifestEntry);
343
392
 
344
393
  let mdx = `---
345
394
  title: "${title}"
@@ -355,15 +404,14 @@ ${description}
355
404
  `;
356
405
 
357
406
  // Add Live Test Run section if URL exists
358
- if (testcaseId) {
359
- const replayUrl = generateReplayUrl(testcaseId);
407
+ if (replayEmbedUrl) {
360
408
  mdx += `## Live Test Run
361
409
 
362
410
  Watch this test execute in a real sandbox environment:
363
411
 
364
412
  {/* ${testMeta.filename} output */}
365
413
  <iframe
366
- src="${replayUrl}"
414
+ src="${replayEmbedUrl}"
367
415
  width="100%"
368
416
  height="600"
369
417
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -560,9 +608,9 @@ async function main() {
560
608
 
561
609
  // Update iframe URL if manifest entry exists
562
610
  const manifestEntry = manifest.examples[testMeta.filename];
563
- const testcaseId = manifestEntry?.url ? extractTestcaseId(manifestEntry.url) : null;
564
- if (testcaseId) {
565
- const iframeUpdated = updateExistingMDX(content, testMeta.filename, testcaseId);
611
+ const replayEmbedUrl = resolveReplayEmbedUrl(manifestEntry);
612
+ if (replayEmbedUrl) {
613
+ const iframeUpdated = updateExistingMDX(content, testMeta.filename, replayEmbedUrl);
566
614
  if (iframeUpdated && iframeUpdated !== content) {
567
615
  content = iframeUpdated;
568
616
  changed = true;
@@ -5,6 +5,33 @@ rss: true
5
5
  icon: "code-compare"
6
6
  ---
7
7
 
8
+ <Update label="v7.9.51-canary" description="April 2026" tags={["canary"]}>
9
+
10
+ 🚀 Canary release
11
+
12
+ This release promotes changes from `v7.9.4-test` through `v7.9.51-test` to canary, rolling up all updates since `v7.9.3`.
13
+
14
+ ✨ New features
15
+
16
+ - (Internal) **Autoscaling**
17
+ - (Internal) **End-to-end distributed tracing**
18
+
19
+ 🔧 Improvements
20
+
21
+ - **Faster image matching**
22
+ - **Storage and infra hardening**
23
+ - **Sentry environment consistency**
24
+ - **Chrome extension interaction reliability**
25
+ - **Docs and onboarding refresh** — Updated v7 docs, SDK examples, and VS Code onboarding/init flows.
26
+
27
+ 🐛 Bug fixes
28
+
29
+ - **Windows AMI build stability** — Fixed `chrome.exe` startup/build failures.
30
+ - **Realtime cleanup reliability** — Fixed connection cleanup leaks in session shutdown paths.
31
+ - **Environment and deployment fixes**
32
+
33
+ </Update>
34
+
8
35
  <Update label="v7.8.0-test.22" description="March 2026" tags={["test"]}>
9
36
 
10
37
  Releases test.11 through test.22 include version bumps and internal CI improvements across all packages. No new user-facing changes — see [v7.8.0-test.10](#v780-test10) for the latest updates in this release stream.
@@ -66,7 +93,7 @@ This release includes all changes from v7.8.0-test.6 with version bumps across a
66
93
 
67
94
  ✨ New features
68
95
 
69
- - **[GitHub Copilot integration](/v7/copilot/setup)** — Use TestDriver directly from GitHub Copilot in VS Code. The new MCP server lets Copilot launch sandboxes, interact with elements, and run assertions through natural language. Includes guides for [creating tests](/v7/copilot/creating-tests), [running tests](/v7/copilot/running-tests), [GitHub Actions integration](/v7/copilot/github), and [auto-healing](/v7/copilot/auto-healing).
96
+ - **[GitHub Copilot integration](/v7/copilot/running-tests)** — Use TestDriver directly from GitHub Copilot in VS Code. The new MCP server lets Copilot launch sandboxes, interact with elements, and run assertions through natural language. Includes guides for [creating tests](/v7/generating-tests), [running tests](/v7/copilot/running-tests), [GitHub Actions integration](/v7/copilot/auto-healing#use-testdriver-in-github), and [auto-healing](/v7/copilot/auto-healing).
70
97
 
71
98
  🔧 Improvements
72
99
 
@@ -83,7 +110,7 @@ This release includes all changes from v7.8.0-canary.4 with version bumps.
83
110
  ✨ New features
84
111
 
85
112
  - **[Cache API](/v7/cache)** — Speed up repeated test runs with screenshot-based caching. The system compares screenshots to cached results and reuses element positions when the screen hasn't changed, reducing AI calls.
86
- - **[Custom error classes](/v7/errors)** — New `ElementNotFoundError` and `AIError` classes with rich debugging info including screenshot paths, pixel diffs, and detailed messages.
113
+ - **[Custom error classes](/v7/errors)** — New `ElementNotFoundError` class with rich debugging info including screenshot paths, pixel diffs, and detailed messages.
87
114
  - **[Events system](/v7/events)** — Listen to SDK lifecycle events with wildcard support via `testdriver.emitter`. Uses colon-delimited namespaces (e.g., `command:start`, `log:*`).
88
115
  - **[Provision API](/v7/provision)** — Launch browsers, desktop apps, VS Code, and Chrome extensions in your sandbox before tests run. Access via `testdriver.provision.*`.
89
116
  - **[Redraw detection](/v7/redraw)** — Wait for screens to stabilize after interactions using two-phase detection with pixel comparison and z-score analysis.
@@ -2,29 +2,74 @@
2
2
  title: Using TestDriver with Claude Code (MCP)
3
3
  ---
4
4
 
5
- TestDriver exposes test results and analytics over an **HTTP MCP server**, so Claude Code (or any MCP-compatible client) can inspect your test runs, failures, and filters.
5
+ TestDriver ships as a native [Claude Code plugin](https://docs.claude.com/en/docs/claude-code/plugins) that bundles the **TestDriver MCP server**, the **`testdriver` expert sub-agent**, and all **TestDriver skills**. You get everything you need to drive TestDriver from Claude Code with a single install.
6
6
 
7
- This guide assumes:
7
+ > The plugin lives inside the `testdriverai` npm package at `ai/.claude-plugin/plugin.json`, and the marketplace entry lives at `.claude-plugin/marketplace.json` in this repo.
8
8
 
9
- - Your API server is running the MCP endpoint at `POST /api/v1/mcp`
10
- - You have a **team or user API key** for authentication
11
- - You are using this repo (`testdriverai`) as the SDK / local tooling
12
-
13
- ## 1. Configure an API key
14
-
15
- Get your API key from the team settings:
9
+ ## 1. Get a TestDriver API key
16
10
 
17
11
  - Visit your team page (e.g. `https://console.testdriver.ai/team`)
18
12
  - Create or copy a **Team API Key** (or User API Key)
19
- - Store it locally as an environment variable, for example:
13
+ - Export it in your shell so Claude Code can pass it to the MCP server:
14
+
15
+ ```bash
16
+ export TD_API_KEY="your_api_key_here"
17
+ ```
18
+
19
+ ## 2. Install the plugin in Claude Code
20
+
21
+ From inside Claude Code, add this repo as a plugin marketplace and install the `testdriver` plugin:
22
+
23
+ ```text
24
+ /plugin marketplace add testdriverai/testdriverai
25
+ /plugin install testdriver@testdriver
26
+ ```
20
27
 
21
- ```bash
22
- export TD_API_KEY="your_api_key_here"
28
+ That registers three things:
29
+
30
+ - **`testdriver` MCP server** — spawned via `npx -p testdriverai testdriverai-mcp`, with `TD_API_KEY` forwarded from your environment.
31
+ - **`testdriver` sub-agent** — the TestDriver expert agent from `ai/agents/testdriver.md`. Invoke it with `@testdriver ...`.
32
+ - **TestDriver skills** — every `ai/skills/testdriver-*` skill, auto-loaded by Claude Code.
33
+
34
+ ## 3. Write tests with the agent
35
+
36
+ In a Claude Code session, delegate to the agent:
37
+
38
+ ```text
39
+ @testdriver Write a test that signs into https://example.com and adds an item to the cart.
23
40
  ```
24
41
 
25
- The MCP server expects this API key in the `X-Api-Key` header (or `Authorization: Bearer <key>`).
42
+ The agent will use the TestDriver MCP tools (`session_start`, `find`, `click`, `type`, `assert`, …) to interactively build a Vitest test, append generated code to your test file after every action, and run it with `vitest run` until it passes.
43
+
44
+ For the full agent guide, see the [`testdriver` agent definition](https://github.com/testdriverai/testdriverai/blob/main/ai/agents/testdriver.md) and the [MCP workflow skill](https://github.com/testdriverai/testdriverai/blob/main/ai/skills/testdriver-mcp-workflow/SKILL.md).
26
45
 
27
- ## 2. HTTP MCP endpoint contract
46
+ ## Manual MCP configuration (no plugin)
47
+
48
+ If you prefer not to use the plugin, you can register the MCP server manually in any MCP-compatible client (Claude Desktop, Cursor, VS Code, …):
49
+
50
+ ```json
51
+ {
52
+ "mcpServers": {
53
+ "testdriver": {
54
+ "command": "npx",
55
+ "args": ["-p", "testdriverai", "testdriverai-mcp"],
56
+ "env": {
57
+ "TD_API_KEY": "${TD_API_KEY}"
58
+ }
59
+ }
60
+ }
61
+ }
62
+ ```
63
+
64
+ This is the same config the plugin wires up for you — the plugin just bundles it alongside the agent and skills.
65
+
66
+ ---
67
+
68
+ ## Observing test runs via HTTP MCP
69
+
70
+ TestDriver also exposes **test results and analytics** over an HTTP MCP endpoint, so Claude Code (or any MCP-compatible client) can inspect your test runs, failures, and filters without provisioning a sandbox.
71
+
72
+ ### HTTP MCP endpoint contract
28
73
 
29
74
  The HTTP endpoint lives at:
30
75
 
@@ -32,6 +77,8 @@ The HTTP endpoint lives at:
32
77
  POST /api/v1/mcp
33
78
  ```
34
79
 
80
+ It expects the TestDriver API key in the `X-Api-Key` header (or `Authorization: Bearer <key>`).
81
+
35
82
  Common request shapes:
36
83
 
37
84
  - **List tools**
@@ -89,7 +136,7 @@ The MCP server advertises at least these tools in `list_tools`:
89
136
  - `get_filter_options`
90
137
  Get branch, suite, repo, filename, commit, status, platform, and test name options for building queries.
91
138
 
92
- ## 3. Claude Code MCP server configuration
139
+ ### Pointing Claude Code at the HTTP MCP endpoint
93
140
 
94
141
  You can point Claude Code at the HTTP MCP endpoint using a JSON configuration similar to:
95
142
 
@@ -137,12 +184,12 @@ For local development:
137
184
  }
138
185
  ```
139
186
 
140
- ## 4. Skills documentation for Claude
187
+ ### Skills documentation for Claude
141
188
 
142
- Claude Code expects a `SKILLs.md` file to explain how to use a server. In this repo:
189
+ Claude Code loads the agent and skills automatically when you install the plugin (see step 2). The underlying sources are:
143
190
 
144
191
  - `ai/agents/testdriver.md` contains the **full TestDriver Agent Guide**
145
- - `SKILLs.md` acts as a short wrapper that points Claude (and other agents) to the agent guide
192
+ - `ai/skills/testdriver-*/SKILL.md` provide task-specific skills (MCP workflow, assertions, provisioning, etc.)
146
193
 
147
194
  Use these as the primary reference for:
148
195