@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
@@ -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>
@@ -72,8 +72,8 @@ new Dashcam(client, options)
72
72
  Configuration options
73
73
 
74
74
  <Expandable title="options properties">
75
- <ParamField path="apiKey" type="string" default="4e93d8bf-3886-4d26-a144-116c4063522d">
76
- Dashcam API key for authentication
75
+ <ParamField path="apiKey" type="string">
76
+ Dashcam API key for authentication. Set via `TD_API_KEY` environment variable.
77
77
  </ParamField>
78
78
 
79
79
  <ParamField path="autoStart" type="boolean" default={false}>
@@ -193,6 +193,29 @@ await dashcam.addApplicationLog(application, name)
193
193
  await dashcam.addApplicationLog('Google Chrome', 'Browser Logs');
194
194
  ```
195
195
 
196
+ ### addWebLog()
197
+
198
+ Track web request logs by URL pattern:
199
+
200
+ ```javascript
201
+ await dashcam.addWebLog(pattern, name)
202
+ ```
203
+
204
+ <ParamField path="pattern" type="string" required>
205
+ URL pattern to match (e.g., `"*example.com*"`)
206
+ </ParamField>
207
+
208
+ <ParamField path="name" type="string" required>
209
+ Display name for the log
210
+ </ParamField>
211
+
212
+ **Returns:** `Promise<void>`
213
+
214
+ **Example:**
215
+ ```javascript
216
+ await dashcam.addWebLog('*example.com*', 'Web Logs');
217
+ ```
218
+
196
219
  ### addLog()
197
220
 
198
221
  Generic method to add any type of log:
@@ -210,7 +233,7 @@ await dashcam.addLog(config)
210
233
  </ParamField>
211
234
 
212
235
  <ParamField path="type" type="string" required>
213
- Log type: `'file'`, `'stdout'`, or `'application'`
236
+ Log type: `'file'`, `'application'`, or `'web'`
214
237
  </ParamField>
215
238
 
216
239
  <ParamField path="path" type="string">
@@ -220,6 +243,10 @@ await dashcam.addLog(config)
220
243
  <ParamField path="application" type="string">
221
244
  Application name (required for type='application')
222
245
  </ParamField>
246
+
247
+ <ParamField path="pattern" type="string">
248
+ URL pattern to match (required for type='web', e.g., `"*example.com*"`)
249
+ </ParamField>
223
250
  </Expandable>
224
251
  </ParamField>
225
252
 
@@ -238,6 +265,12 @@ await dashcam.addLog({
238
265
  type: 'application',
239
266
  application: 'Google Chrome'
240
267
  });
268
+
269
+ await dashcam.addLog({
270
+ name: 'Web Logs',
271
+ type: 'web',
272
+ pattern: '*example.com*'
273
+ });
241
274
  ```
242
275
 
243
276
  ### isRecording()
@@ -1,13 +1,13 @@
1
1
  ---
2
- title: "Debugging with Screenshots"
3
- sidebarTitle: "Debugging with Screenshots"
4
- description: "View and analyze saved screenshots using MCP commands for test debugging and development"
5
- icon: "magnifying-glass"
2
+ title: "Debug"
3
+ sidebarTitle: "Debug"
4
+ description: "Diagnose failing tests with screenshots, replays, and logs"
5
+ icon: "bug"
6
6
  ---
7
7
 
8
8
  ## Overview
9
9
 
10
- 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.
10
+ 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.
11
11
 
12
12
  <Note>
13
13
  **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`
@@ -123,7 +123,7 @@ view_local_screenshot({ path: "/full/path/to/screenshot.png" })
123
123
 
124
124
  ### Test Debugging After Failures
125
125
 
126
- When a test fails, use powerful filtering to quickly find relevant screenshots:
126
+ 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:
127
127
 
128
128
  **1. Find screenshots at the failing line:**
129
129
 
@@ -329,6 +329,20 @@ Understanding the directory structure helps with efficient screenshot viewing:
329
329
  - All screenshots are PNG format
330
330
  - Disable automatic screenshots with `autoScreenshots: false` if needed
331
331
 
332
+ ## Interaction List Sidebar (Source of Truth)
333
+
334
+ 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.
335
+
336
+ <Note>
337
+ **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.
338
+ </Note>
339
+
340
+ Use the interaction list to:
341
+ - **Verify what the AI saw** — confirm the correct page/state was visible when `find()` or `assert()` ran
342
+ - **Debug misclicks** — see whether the target element was actually on screen
343
+ - **Identify timing issues** — spot cases where the UI hadn't finished loading before an interaction fired
344
+ - **Compare runs** — review interaction screenshots across multiple runs to catch flaky behavior
345
+
332
346
  ## Integration with Test Development
333
347
 
334
348
  ### During MCP Interactive Development
@@ -345,7 +359,7 @@ This helps verify your test logic before running the full test file.
345
359
 
346
360
  ### After Test Runs
347
361
 
348
- When tests fail or behave unexpectedly:
362
+ When tests fail or behave unexpectedly, replay what happened step by step:
349
363
 
350
364
  1. **Run the test** with `vitest run tests/my-test.test.mjs`
351
365
  2. **List screenshots** using `list_local_screenshots`
@@ -395,8 +409,18 @@ When tests fail or behave unexpectedly:
395
409
  </Accordion>
396
410
  </AccordionGroup>
397
411
 
412
+ ## Where this fits in the Guide
413
+
414
+ 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.
415
+
398
416
  ## Related
399
417
 
400
418
  - [screenshot()](/v7/screenshot) - Capture screenshots during test execution
401
419
  - [Dashcam](/v7/dashcam) - Record full test sessions with video and logs
402
420
  - [assert()](/v7/assert) - Make AI-powered assertions that benefit from screenshot context
421
+
422
+ ## Next
423
+
424
+ <Card title="Prevent" icon="shield-check" href="/v7/copilot/auto-healing">
425
+ You've seen what went wrong — now keep it from happening again. Let auto-healing repair flaky tests automatically before they fail your suite.
426
+ </Card>
@@ -1,27 +1,32 @@
1
1
  ---
2
- title: "AI Test Example"
3
- sidebarTitle: "AI"
4
- description: "Example test using the AI exploratory loop to automate complex multi-step interactions."
2
+ title: "AI Test"
3
+ sidebarTitle: "Ai"
4
+ description: "TestDriver SDK - AI Test (Vitest) Tests the AI exploratory loop (ai) functionality."
5
5
  icon: "wand-magic-sparkles"
6
- mode: "wide"
7
6
  ---
8
7
 
9
- ## Demo Test Run
8
+ ## Overview
9
+
10
+ TestDriver SDK - AI Test (Vitest) Tests the AI exploratory loop (ai) functionality
11
+
12
+ Review the source code below to understand the implementation details and patterns used.
13
+
14
+ ## Live Test Run
10
15
 
11
16
  Watch this test execute in a real sandbox environment:
12
17
 
13
18
  {/* ai.test.mjs output */}
14
19
  <iframe
15
- src="https://api.testdriver.ai/api/v1/testdriver/testcase/69c5d04ac2e6e94933886778/replay"
20
+ src="https://console-test.testdriver.ai/replay/6a45bf434608e3f6c45de01b?share=eQ8yZOqg3UqrJKjELcDm2A&embed=true"
16
21
  width="100%"
17
- height="390"
22
+ height="600"
18
23
  style={{ border: "1px solid #333", borderRadius: "8px" }}
19
24
  allow="fullscreen"
20
25
  />
21
26
 
22
27
  ## Source Code
23
28
 
24
- ```javascript title="ai.test.mjs" {17}
29
+ ```javascript title="ai.test.mjs"
25
30
  /**
26
31
  * TestDriver SDK - AI Test (Vitest)
27
32
  * Tests the AI exploratory loop (ai) functionality
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* assert.test.mjs output */}
14
14
  <iframe
15
- src="https://api.testdriver.ai/api/v1/testdriver/testcase/69c5d038058ffe89003c6adc/replay"
15
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a45b6fea57200d3f72adc69/replay"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* chrome-extension.test.mjs output */}
14
14
  <iframe
15
- src="https://api.testdriver.ai/api/v1/testdriver/testcase/69c5d024c2e6e94933886763/replay"
15
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a45b6214608e3f6c45ddf74/replay"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -75,18 +75,35 @@ describe("Chrome Extension Test", () => {
75
75
  // The hello-world extension adds a puzzle piece icon to the toolbar
76
76
  // When clicked, it shows a popup with "Hello Extensions"
77
77
 
78
- // Click on the extensions button (puzzle piece icon) in Chrome toolbar
79
- const extensionsButton = await testdriver.find("The extensions button in the Chrome toolbar", {zoom: true});
80
- await extensionsButton.click();
81
-
82
- // Look for the hello world extension in the extensions menu
83
- const helloExtension = await testdriver.find("Hello Extensions extension in the extensions dropdown");
84
- await helloExtension.click();
85
-
86
- await testdriver.wait(2000); // wait for the popup to open
87
-
88
- // Verify the extension popup shows "Hello Extensions" text
89
- const popupResult = await testdriver.assert("a popup shows with the text 'Hello Extensions'");
78
+ // Retry opening the extension popup and verifying it up to 3 times
79
+ let popupResult;
80
+ let lastError;
81
+ for (let attempt = 1; attempt <= 3; attempt++) {
82
+ try {
83
+ // Click on the extensions button (puzzle piece icon) in Chrome toolbar
84
+ const extensionsButton = await testdriver.find("The extensions button in the Chrome toolbar", {zoom: true, verify: true, timeout: 10000});
85
+ await extensionsButton.click();
86
+
87
+ // Look for the hello world extension in the extensions menu
88
+ const helloExtension = await testdriver.find("Hello Extensions extension in the extensions dropdown", {zoom: true, verify: true, timeout: 10000});
89
+ await helloExtension.click();
90
+
91
+ await testdriver.wait(2000); // wait for the popup to open
92
+
93
+ // Verify the extension popup shows "Hello Extensions" text
94
+ popupResult = await testdriver.assert("a popup shows with the text 'Hello Extensions'");
95
+ if (popupResult) break;
96
+ } catch (err) {
97
+ lastError = err;
98
+ console.log(`Attempt ${attempt} failed:`, err.message);
99
+ }
100
+ if (attempt < 3) {
101
+ // Dismiss any open popup/menu before retrying
102
+ await testdriver.pressKeys(["escape"]);
103
+ await testdriver.wait(1000);
104
+ }
105
+ }
106
+ if (!popupResult && lastError) throw lastError;
90
107
  expect(popupResult).toBeTruthy();
91
108
  });
92
109
 
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* element-not-found.test.mjs output */}
14
14
  <iframe
15
- src="https://api.testdriver.ai/api/v1/testdriver/testcase/69c5d047058ffe89003c6ae4/replay"
15
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a45b764a57200d3f72adc73/replay"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -1,8 +1,9 @@
1
1
  ---
2
- title: "FindAll Coffee Icons"
2
+ title: "FindAll Test Example"
3
3
  sidebarTitle: "Findall Coffee Icons"
4
4
  description: "TestDriver SDK - FindAll Coffee Icons Test Loads a random icon grid and uses findAll() to locate and click all 4 coffee cup icons."
5
5
  icon: "play"
6
+ mode: "wide"
6
7
  ---
7
8
 
8
9
  ## Overview
@@ -17,7 +18,7 @@ Watch this test execute in a real sandbox environment:
17
18
 
18
19
  {/* findall-coffee-icons.test.mjs output */}
19
20
  <iframe
20
- src="https://api.testdriver.ai/api/v1/testdriver/testcase/69c5d03ae8a04db4b705cbf0/replay"
21
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a45b714a57200d3f72adc6a/replay"
21
22
  width="100%"
22
23
  height="600"
23
24
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -0,0 +1,74 @@
1
+ ---
2
+ title: "Formatted Logging Test"
3
+ sidebarTitle: "Formatted Logging"
4
+ description: "TestDriver SDK - Formatted Logging Demo Demonstrates nice Vitest-style formatted logs for Dashcam replay."
5
+ icon: "play"
6
+ ---
7
+
8
+ ## Overview
9
+
10
+ TestDriver SDK - Formatted Logging Demo Demonstrates nice Vitest-style formatted logs for Dashcam replay
11
+
12
+ Review the source code below to understand the implementation details and patterns used.
13
+
14
+ ## Live Test Run
15
+
16
+ Watch this test execute in a real sandbox environment:
17
+
18
+ {/* formatted-logging.test.mjs output */}
19
+ <iframe
20
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69c873a714b73310c7839450/replay"
21
+ width="100%"
22
+ height="600"
23
+ style={{ border: "1px solid #333", borderRadius: "8px" }}
24
+ allow="fullscreen"
25
+ />
26
+
27
+ ## Source Code
28
+
29
+ ```javascript title="formatted-logging.test.mjs"
30
+ /**
31
+ * TestDriver SDK - Formatted Logging Demo
32
+ * Demonstrates nice Vitest-style formatted logs for Dashcam replay
33
+ */
34
+
35
+ import { describe, expect, it } from "vitest";
36
+ import { TestDriver } from "testdriverai/vitest/hooks";
37
+
38
+ describe("Formatted Logging Test", () => {
39
+ it("should demonstrate formatted logs in dashcam replay", async (context) => {
40
+ const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
41
+ await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
42
+
43
+ // Find and click - logs will be nicely formatted
44
+ const signInButton = await testdriver.find(
45
+ "Sign In, black button below the password field",
46
+ );
47
+ await signInButton.click();
48
+
49
+ // Assert - logs will show pass/fail with nice formatting
50
+ const result = await testdriver.assert(
51
+ "an error shows that fields are required",
52
+ );
53
+ expect(result).toBeTruthy();
54
+ });
55
+ });
56
+ ```
57
+
58
+ ## Running This Example
59
+
60
+ ```bash
61
+ # Clone the TestDriver repository
62
+ git clone https://github.com/testdriverai/testdriverai
63
+
64
+ # Install dependencies
65
+ cd testdriverai
66
+ npm install
67
+
68
+ # Run this specific example
69
+ npx vitest run examples/formatted-logging.test.mjs
70
+ ```
71
+
72
+ <Note>
73
+ Make sure you have `TD_API_KEY` set in your environment. Get one at [testdriver.ai](https://testdriver.ai).
74
+ </Note>
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* hover-image.test.mjs output */}
14
14
  <iframe
15
- src="https://api.testdriver.ai/api/v1/testdriver/testcase/69c5d0300201196437256cd3/replay"
15
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a45b671a57200d3f72adc65/replay"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: "Hover Text With Description Test"
2
+ title: "Hover Text With Description Test Example"
3
3
  sidebarTitle: "Hover Text With Description"
4
4
  description: "TestDriver SDK - Hover Text With Description Test (Vitest) Converted from: testdriver/acceptance/hover-text-with-description.yaml."
5
5
  icon: "hand-pointer"
@@ -18,7 +18,7 @@ Watch this test execute in a real sandbox environment:
18
18
 
19
19
  {/* hover-text-with-description.test.mjs output */}
20
20
  <iframe
21
- src="https://api.testdriver.ai/api/v1/testdriver/testcase/69c5d029c2e6e94933886764/replay"
21
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a45b653a57200d3f72adc5a/replay"
22
22
  width="100%"
23
23
  height="600"
24
24
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* hover-text.test.mjs output */}
14
14
  <iframe
15
- src="https://api.testdriver.ai/api/v1/testdriver/testcase/69c5d04b0201196437256ce6/replay"
15
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a45b7984608e3f6c45ddfa5/replay"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* installer.test.mjs output */}
14
14
  <iframe
15
- src="https://api.testdriver.ai/api/v1/testdriver/testcase/69c5d032c2e6e94933886769/replay"
15
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a45b69e4608e3f6c45ddf96/replay"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: "Launching VS Code Example"
2
+ title: "Launching VS Code Test Example"
3
3
  sidebarTitle: "Launch VS Code"
4
4
  description: "Example test demonstrating how to launch VS Code and install extensions on Linux."
5
5
  icon: "play"
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* launch-vscode-linux.test.mjs output */}
14
14
  <iframe
15
- src="https://api.testdriver.ai/api/v1/testdriver/testcase/69c5d02be8a04db4b705cbe5/replay"
15
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a45b63ba57200d3f72adc4c/replay"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -45,36 +45,36 @@ describe("Launch VS Code on Linux", () => {
45
45
  },
46
46
  );
47
47
 
48
- it.skipIf(!isLinux)(
49
- "should install and use a VS Code extension",
50
- async (context) => {
51
- const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP});
48
+ // it.skipIf(!isLinux)(
49
+ // "should install and use a VS Code extension",
50
+ // async (context) => {
51
+ // const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP});
52
52
 
53
- // Launch VS Code with the Prettier extension installed
54
- await testdriver.provision.vscode({
55
- extensions: ["esbenp.prettier-vscode"],
56
- });
53
+ // // Launch VS Code with the Prettier extension installed
54
+ // await testdriver.provision.vscode({
55
+ // extensions: ["esbenp.prettier-vscode"],
56
+ // });
57
57
 
58
- const vsCodeWindow = await testdriver.find(
59
- "Visual Studio Code window",
60
- { timeout: 60000 }
61
- );
58
+ // const vsCodeWindow = await testdriver.find(
59
+ // "Visual Studio Code window",
60
+ // { timeout: 60000 }
61
+ // );
62
62
 
63
- expect(vsCodeWindow.found()).toBeTruthy();
63
+ // expect(vsCodeWindow.found()).toBeTruthy();
64
64
 
65
- // Open the extensions panel to verify Prettier is installed
66
- await testdriver.pressKeys(["ctrl", "shift", "x"]);
65
+ // // Open the extensions panel to verify Prettier is installed
66
+ // await testdriver.pressKeys(["ctrl", "shift", "x"]);
67
67
 
68
- // Wait for extensions panel to open
69
- await new Promise((resolve) => setTimeout(resolve, 2000));
70
-
71
- // Assert that Prettier extension is visible in the installed extensions
72
- const prettierVisible = await testdriver.assert(
73
- "Prettier extension is visible in the extensions panel or sidebar",
74
- );
75
- expect(prettierVisible).toBeTruthy();
76
- },
77
- );
68
+ // // Wait for extensions panel to open
69
+ // await new Promise((resolve) => setTimeout(resolve, 2000));
70
+
71
+ // // Assert that Prettier extension is visible in the installed extensions
72
+ // const prettierVisible = await testdriver.assert(
73
+ // "Prettier extension is visible in the extensions panel or sidebar",
74
+ // );
75
+ // expect(prettierVisible).toBeTruthy();
76
+ // },
77
+ // );
78
78
  });
79
79
  ```
80
80
 
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* match-image.test.mjs output */}
14
14
  <iframe
15
- src="https://api.testdriver.ai/api/v1/testdriver/testcase/69c5d0270201196437256ccf/replay"
15
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/69c8738c14b73310c783941d/replay"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -1,8 +1,9 @@
1
1
  ---
2
- title: "Parse Test"
2
+ title: "Parse Test Example"
3
3
  sidebarTitle: "Parse"
4
4
  description: "TestDriver SDK - Parse Test (Vitest) Opens Airbnb and runs the .parse() SDK command to analyze the screen."
5
5
  icon: "play"
6
+ mode: "wide"
6
7
  ---
7
8
 
8
9
  ## Overview
@@ -17,7 +18,7 @@ Watch this test execute in a real sandbox environment:
17
18
 
18
19
  {/* parse.test.mjs output */}
19
20
  <iframe
20
- src="https://api.testdriver.ai/api/v1/testdriver/testcase/69c5d04d0201196437256ce7/replay"
21
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a45b7af4608e3f6c45ddfaa/replay"
21
22
  width="100%"
22
23
  height="600"
23
24
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: "Pressing Keys Test"
2
+ title: "Pressing Keys Test Example"
3
3
  sidebarTitle: "Pressing Keys"
4
4
  description: "Example test demonstrating keyboard shortcuts and key combinations for browser navigation."
5
5
  icon: "keyboard"
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* press-keys.test.mjs output */}
14
14
  <iframe
15
- src="https://api.testdriver.ai/api/v1/testdriver/testcase/69c5d036058ffe89003c6ada/replay"
15
+ src="https://console-test.testdriver.ai/replay/6a45bd51a57200d3f72adcbd?share=ty93E0byJrJD5eiBxh3nTQ&embed=true"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: "Scrolling with Keyboard Test"
2
+ title: "Scrolling with Keyboard Test Example"
3
3
  sidebarTitle: "Scrolling with Keyboard"
4
4
  description: "Example test demonstrating page scrolling using keyboard-based scroll controls."
5
5
  icon: "scroll"
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* scroll-keyboard.test.mjs output */}
14
14
  <iframe
15
- src="https://api.testdriver.ai/api/v1/testdriver/testcase/69c5d03da0a3ef8239de474f/replay"
15
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a45b72da57200d3f72adc70/replay"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: "Scroll Until Text Test"
2
+ title: "Scroll Until Text Test Example"
3
3
  sidebarTitle: "Scroll Until Text"
4
4
  description: "Example test demonstrating how to scroll a page until specific text becomes visible."
5
5
  icon: "scroll"
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* scroll.test.mjs output */}
14
14
  <iframe
15
- src="https://api.testdriver.ai/api/v1/testdriver/testcase/69c5d043058ffe89003c6ae0/replay"
15
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a45b74ca57200d3f72adc72/replay"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* type.test.mjs output */}
14
14
  <iframe
15
- src="https://api.testdriver.ai/api/v1/testdriver/testcase/69c5d034c2e6e9493388676c/replay"
15
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a45b6cb4608e3f6c45ddf98/replay"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}