@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
@@ -0,0 +1,415 @@
1
+ ---
2
+ name: testdriver:debugging-with-screenshots
3
+ description: View and analyze saved screenshots using MCP commands for test debugging and development
4
+ ---
5
+ <!-- Generated from debugging-with-screenshots.mdx. DO NOT EDIT. -->
6
+
7
+ ## Overview
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.
10
+
11
+ <Note>
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`
13
+ </Note>
14
+
15
+ ## MCP Commands
16
+
17
+ ### list_local_screenshots
18
+
19
+ List and filter screenshots saved in the `.testdriver/screenshots/` directory:
20
+
21
+ ```
22
+ list_local_screenshots()
23
+ ```
24
+
25
+ **Filter Parameters:**
26
+
27
+ <ParamField path="directory" type="string" optional>
28
+ Filter screenshots by test file or subdirectory (e.g., "login.test", "mcp-screenshots"). If omitted, lists all screenshots.
29
+ </ParamField>
30
+
31
+ <ParamField path="line" type="number" optional>
32
+ Filter by exact line number from test file (e.g., 42 matches L42 in filename).
33
+ </ParamField>
34
+
35
+ <ParamField path="lineRange" type="object" optional>
36
+ Filter by line number range. Example: `{ start: 10, end: 20 }` matches screenshots from lines 10-20.
37
+ </ParamField>
38
+
39
+ <ParamField path="action" type="string" optional>
40
+ Filter by action type: `click`, `find`, `type`, `assert`, `provision`, `scroll`, `hover`, etc.
41
+ </ParamField>
42
+
43
+ <ParamField path="phase" type="string" optional>
44
+ Filter by phase: `"before"` (state before action) or `"after"` (state after action).
45
+ </ParamField>
46
+
47
+ <ParamField path="pattern" type="string" optional>
48
+ Regex pattern to match against filename. Example: `"login|signin"` or `"button.*click"`.
49
+ </ParamField>
50
+
51
+ <ParamField path="sequence" type="number" optional>
52
+ Filter by exact sequence number.
53
+ </ParamField>
54
+
55
+ <ParamField path="sequenceRange" type="object" optional>
56
+ Filter by sequence range. Example: `{ start: 1, end: 10 }` matches first 10 screenshots.
57
+ </ParamField>
58
+
59
+ <ParamField path="limit" type="number" optional>
60
+ Maximum number of results to return (default: 50).
61
+ </ParamField>
62
+
63
+ <ParamField path="sortBy" type="string" optional>
64
+ Sort results by: `"modified"` (newest first, default), `"sequence"` (execution order), or `"line"` (line number).
65
+ </ParamField>
66
+
67
+ **Returns:**
68
+
69
+ Array of screenshot metadata including:
70
+ - `path` - Full absolute path to the screenshot file
71
+ - `relativePath` - Path relative to `.testdriver/screenshots/`
72
+ - `name` - Screenshot filename
73
+ - `sizeBytes` - File size in bytes
74
+ - `modified` - Last modification timestamp
75
+ - `sequence` - Sequential number (from auto-screenshots)
76
+ - `action` - Action type (click, find, etc.)
77
+ - `phase` - Before/after phase
78
+ - `lineNumber` - Line number from test file
79
+ - `description` - Element or action description
80
+
81
+ **Example Responses:**
82
+
83
+ ```json
84
+ // Basic listing
85
+ [
86
+ {
87
+ "path": "/Users/user/project/.testdriver/screenshots/login.test/001-click-before-L42-submit-button.png",
88
+ "relativePath": "login.test/001-click-before-L42-submit-button.png",
89
+ "name": "001-click-before-L42-submit-button.png",
90
+ "sizeBytes": 145632,
91
+ "modified": "2026-01-23T10:00:00.000Z",
92
+ "sequence": 1,
93
+ "action": "click",
94
+ "phase": "before",
95
+ "lineNumber": 42,
96
+ "description": "submit-button"
97
+ }
98
+ ]
99
+ ```
100
+
101
+ ### view_local_screenshot
102
+
103
+ View a specific screenshot from the list:
104
+
105
+ ```
106
+ view_local_screenshot({ path: "/full/path/to/screenshot.png" })
107
+ ```
108
+
109
+ **Parameters:**
110
+
111
+ <ParamField path="path" type="string" required>
112
+ Full absolute path to the screenshot file (as returned by `list_local_screenshots`)
113
+ </ParamField>
114
+
115
+ **Returns:**
116
+
117
+ - Image content (displayed to both AI and user via MCP App)
118
+ - Screenshot metadata
119
+ - Success/error status
120
+
121
+ ## Common Workflows
122
+
123
+ ### Test Debugging After Failures
124
+
125
+ When a test fails, use powerful filtering to quickly find relevant screenshots:
126
+
127
+ **1. Find screenshots at the failing line:**
128
+
129
+ ```
130
+ // If test failed at line 42
131
+ list_local_screenshots({ line: 42 })
132
+
133
+ // View before and after states at that line
134
+ view_local_screenshot({ path: ".testdriver/screenshots/login.test/005-click-before-L42-submit-button.png" })
135
+ view_local_screenshot({ path: ".testdriver/screenshots/login.test/006-click-after-L42-submit-button.png" })
136
+ ```
137
+
138
+ **2. See what happened leading up to the failure:**
139
+
140
+ ```
141
+ // Get screenshots from lines 35-45 to see context
142
+ list_local_screenshots({ directory: "login.test", lineRange: { start: 35, end: 45 } })
143
+ ```
144
+
145
+ **3. Find all assertion screenshots:**
146
+
147
+ ```
148
+ // See what the screen looked like during assertions
149
+ list_local_screenshots({ action: "assert" })
150
+ ```
151
+
152
+ **4. View the final state before failure:**
153
+
154
+ ```
155
+ // Get the last 5 screenshots in execution order
156
+ list_local_screenshots({ directory: "login.test", sortBy: "sequence", limit: 5 })
157
+ ```
158
+
159
+ ### Finding Specific Actions
160
+
161
+ When debugging element interactions:
162
+
163
+ ```
164
+ // Find all click actions
165
+ list_local_screenshots({ action: "click" })
166
+
167
+ // Find what the screen looked like BEFORE each click
168
+ list_local_screenshots({ action: "click", phase: "before" })
169
+
170
+ // Find screenshots related to a specific element using regex
171
+ list_local_screenshots({ pattern: "submit|button" })
172
+
173
+ // Find all type actions (for form filling issues)
174
+ list_local_screenshots({ action: "type" })
175
+ ```
176
+
177
+ ### Understanding Test Flow
178
+
179
+ View screenshots in execution order to trace test behavior:
180
+
181
+ ```
182
+ // Get screenshots in execution order
183
+ list_local_screenshots({ directory: "checkout.test", sortBy: "sequence" })
184
+
185
+ // Get just the first 10 actions
186
+ list_local_screenshots({ sequenceRange: { start: 1, end: 10 }, sortBy: "sequence" })
187
+
188
+ // Get just the last 10 actions
189
+ list_local_screenshots({ directory: "checkout.test", sortBy: "sequence", limit: 10 })
190
+ ```
191
+
192
+ ### Interactive Test Development
193
+
194
+ While building tests using MCP tools, view screenshots to verify your test logic:
195
+
196
+ 1. **After a test run**, filter screenshots to see specific actions:
197
+
198
+ ```
199
+ // See all assertions
200
+ list_local_screenshots({ action: "assert" })
201
+
202
+ // See what happened at a specific line you're debugging
203
+ list_local_screenshots({ line: 25 })
204
+ ```
205
+
206
+ 2. **Review key points** in the test execution:
207
+
208
+ ```
209
+ view_local_screenshot({ path: ".testdriver/screenshots/my-test.test/after-login.png" })
210
+ ```
211
+
212
+ 3. **Verify element locations and states** before adding assertions
213
+
214
+ 4. **Iterate** - adjust your test code based on what you see in the screenshots
215
+
216
+ ### Comparison and Analysis
217
+
218
+ Compare screenshots to identify issues:
219
+
220
+ **Using phase filtering for before/after comparison:**
221
+
222
+ ```
223
+ // See state before all clicks
224
+ list_local_screenshots({ action: "click", phase: "before" })
225
+
226
+ // See state after all clicks
227
+ list_local_screenshots({ action: "click", phase: "after" })
228
+ ```
229
+
230
+ **Using line-based debugging:**
231
+
232
+ ```
233
+ // Something went wrong around line 50
234
+ list_local_screenshots({ lineRange: { start: 45, end: 55 } })
235
+ ```
236
+
237
+ **Using regex patterns:**
238
+
239
+ ```
240
+ // Find screenshots related to login functionality
241
+ list_local_screenshots({ pattern: "login|signin|email|password" })
242
+ ```
243
+
244
+ ## Best Practices
245
+
246
+ <AccordionGroup>
247
+ <Accordion title="Use descriptive filenames">
248
+ When saving screenshots in tests, use descriptive names to make them easier to identify:
249
+
250
+ ```javascript
251
+ await testdriver.screenshot("initial-page-load");
252
+ await testdriver.screenshot("after-login-click");
253
+ await testdriver.screenshot("dashboard-loaded");
254
+ ```
255
+
256
+ Then when listing screenshots, you can quickly identify key moments without viewing every image.
257
+ </Accordion>
258
+
259
+ <Accordion title="List before viewing">
260
+ Always call `list_local_screenshots` first to see what's available. The list is sorted by modification time (newest first), making it easy to find recent test runs.
261
+ </Accordion>
262
+
263
+ <Accordion title="Filter by test file">
264
+ When debugging a specific test, use the `directory` parameter to filter screenshots:
265
+
266
+ ```
267
+ list_local_screenshots({ directory: "problematic-test.test" })
268
+ ```
269
+
270
+ This avoids clutter from other tests.
271
+ </Accordion>
272
+
273
+ <Accordion title="View screenshots before and after failures">
274
+ When a test fails (especially with assertions), look at screenshots immediately before the failure. They show exactly what the AI or test "saw" at that moment, helping you understand why an assertion failed or why an element wasn't found.
275
+ </Accordion>
276
+
277
+ <Accordion title="Combine with test reports">
278
+ TestDriver test reports include screenshots in the timeline. Use MCP screenshot viewing for interactive debugging during development, and test reports for post-run analysis and team sharing.
279
+ </Accordion>
280
+
281
+ <Accordion title="Archive important screenshots">
282
+ Remember that each test run clears its screenshot folder. If you need to preserve screenshots for comparison:
283
+
284
+ ```bash
285
+ # Copy screenshots before next run
286
+ cp -r .testdriver/screenshots/my-test.test .testdriver/screenshots-backup/
287
+ ```
288
+ </Accordion>
289
+ </AccordionGroup>
290
+
291
+ ## Screenshot File Organization
292
+
293
+ Understanding the directory structure helps with efficient screenshot viewing:
294
+
295
+ ```
296
+ .testdriver/
297
+ screenshots/
298
+ login.test/ # Test file name (without .mjs extension)
299
+ 001-find-before-L15-email-input.png # Auto: before find() at line 15
300
+ 002-find-after-L15-email-input.png # Auto: after find() at line 15
301
+ 003-click-before-L16-email-input.png # Auto: before click() at line 16
302
+ 004-click-after-L16-email-input.png # Auto: after click() at line 16
303
+ login-complete.png # Manual: screenshot("login-complete")
304
+ checkout.test/
305
+ 001-find-before-L12-add-to-cart.png
306
+ 002-find-after-L12-add-to-cart.png
307
+ ...
308
+ ```
309
+
310
+ ### Automatic Screenshot Naming Format
311
+
312
+ `<seq>-<action>-<phase>-L<line>-<description>.png`
313
+
314
+ | Component | Description | Example |
315
+ |-----------|-------------|---------|
316
+ | `seq` | Sequential number | `001`, `002` |
317
+ | `action` | Command name | `click`, `type`, `find` |
318
+ | `phase` | Before, after, or error | `before`, `after`, `error` |
319
+ | `L<line>` | Line number from test file | `L42` |
320
+ | `description` | Element/action description | `submit-button` |
321
+
322
+ ### Key Points
323
+
324
+ - Each test file gets its own subdirectory
325
+ - Automatic screenshots include line numbers for easy tracing
326
+ - Manual `screenshot()` calls use custom names you provide
327
+ - Folders are cleared at the start of each test run
328
+ - All screenshots are PNG format
329
+ - Disable automatic screenshots with `autoScreenshots: false` if needed
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
+
345
+ ## Integration with Test Development
346
+
347
+ ### During MCP Interactive Development
348
+
349
+ When using TestDriver MCP tools (`session_start`, `find_and_click`, etc.), screenshots are automatically captured and displayed. Additionally, you can view previously saved screenshots:
350
+
351
+ ```
352
+ # After test development session
353
+ list_local_screenshots({ directory: "my-new-test.test" })
354
+ view_local_screenshot({ path: ".testdriver/screenshots/my-new-test.test/login-page.png" })
355
+ ```
356
+
357
+ This helps verify your test logic before running the full test file.
358
+
359
+ ### After Test Runs
360
+
361
+ When tests fail or behave unexpectedly:
362
+
363
+ 1. **Run the test** with `vitest run tests/my-test.test.mjs`
364
+ 2. **List screenshots** using `list_local_screenshots`
365
+ 3. **View relevant screenshots** to diagnose the issue
366
+ 4. **Update test code** based on what you see
367
+ 5. **Re-run and verify** the fix
368
+
369
+ ## Troubleshooting
370
+
371
+ <AccordionGroup>
372
+ <Accordion title="No screenshots found">
373
+ If `list_local_screenshots` returns an empty array:
374
+
375
+ - Ensure your test includes `await testdriver.screenshot()` calls
376
+ - Verify the test actually ran (check test output)
377
+ - Check that `.testdriver/screenshots/` directory exists
378
+ - Confirm you're in the correct project directory
379
+ </Accordion>
380
+
381
+ <Accordion title="Screenshot not displaying">
382
+ If `view_local_screenshot` returns an error:
383
+
384
+ - Verify the path is exactly as returned by `list_local_screenshots`
385
+ - Check file permissions - ensure the screenshot file is readable
386
+ - Confirm the file hasn't been deleted or moved
387
+ </Accordion>
388
+
389
+ <Accordion title="Too many screenshots">
390
+ If you have hundreds of screenshots making it hard to find what you need, use filtering:
391
+
392
+ - Filter by test file: `list_local_screenshots({ directory: "my-test.test" })`
393
+ - Filter by line number: `list_local_screenshots({ line: 42 })` or `list_local_screenshots({ lineRange: { start: 40, end: 50 } })`
394
+ - Filter by action: `list_local_screenshots({ action: "click" })`
395
+ - Filter by phase: `list_local_screenshots({ phase: "before" })`
396
+ - Use regex: `list_local_screenshots({ pattern: "submit|login" })`
397
+ - Limit results: `list_local_screenshots({ limit: 10 })`
398
+ - Sort by line: `list_local_screenshots({ sortBy: "line" })`
399
+ - Clean up old folders: `rm -rf .testdriver/screenshots/*`
400
+ </Accordion>
401
+
402
+ <Accordion title="Screenshots from old test runs">
403
+ Remember that screenshot folders are cleared at the start of each test run. If you see old screenshots:
404
+
405
+ - The test may not have run recently
406
+ - Or the test failed before reaching the clearing logic
407
+ - Manually clear: `rm -rf .testdriver/screenshots/<test-name>/`
408
+ </Accordion>
409
+ </AccordionGroup>
410
+
411
+ ## Related
412
+
413
+ - [screenshot()](/v7/screenshot) - Capture screenshots during test execution
414
+ - [Dashcam](/v7/dashcam) - Record full test sessions with video and logs
415
+ - [assert()](/v7/assert) - Make AI-powered assertions that benefit from screenshot context
@@ -1,8 +1,8 @@
1
1
  ---
2
- title: "Configuring the Device"
3
- description: "Launch browsers, desktop apps, and extensions in your TestDriver sandbox"
4
- icon: "wrench"
2
+ name: testdriver:device-config
3
+ description: Launch browsers, desktop apps, and extensions in your TestDriver sandbox
5
4
  ---
5
+ <!-- Generated from device-config.mdx. DO NOT EDIT. -->
6
6
 
7
7
  Provision methods are the starting point for most tests. They launch applications in your sandbox and prepare the environment for testing.
8
8
 
@@ -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) => {
@@ -0,0 +1,102 @@
1
+ ---
2
+ name: testdriver:double-click
3
+ description: Perform a double-click action on an element or at specific coordinates
4
+ ---
5
+ <!-- Generated from double-click.mdx. DO NOT EDIT. -->
6
+
7
+ ## Overview
8
+
9
+ The `doubleClick()` method performs a double-click action on an element. You can either call it on an [`Element`](/v7/core-concepts/elements) instance or use it directly with a selector.
10
+
11
+ ## Syntax
12
+
13
+ ```javascript
14
+ // Double-click on an element
15
+ await element.doubleClick();
16
+
17
+ // Double-click using a selector
18
+ await ai.doubleClick('selector');
19
+ ```
20
+
21
+ ## Parameters
22
+
23
+ When called on an `Element`, no parameters are required.
24
+
25
+ When called directly on the AI client:
26
+
27
+ | Parameter | Type | Description |
28
+ |-----------|------|-------------|
29
+ | `selector` | `string` | The selector describing the element to double-click |
30
+
31
+ ## Returns
32
+
33
+ Returns a `Promise<void>` that resolves when the double-click action completes.
34
+
35
+ ## Examples
36
+
37
+ ### Double-Click on Found Element
38
+
39
+ ```javascript
40
+ const fileItem = await ai.find('README.md file');
41
+ await fileItem.doubleClick();
42
+ ```
43
+
44
+ ### Direct Double-Click with Selector
45
+
46
+ ```javascript
47
+ await ai.doubleClick('README.md in the file list');
48
+ ```
49
+
50
+ ### Opening Files in VS Code
51
+
52
+ ```javascript
53
+ import { test } from 'vitest';
54
+ import { vscode } from '@testdriver/sdk';
55
+
56
+ test('opens a file by double-clicking', async () => {
57
+ const { ai } = await vscode();
58
+
59
+ // Double-click to open a file in the explorer
60
+ await ai.doubleClick('package.json in the file explorer');
61
+
62
+ // Verify the file opened
63
+ const editor = await ai.find('text editor showing package.json');
64
+ expect(editor).toBeTruthy();
65
+ });
66
+ ```
67
+
68
+ ### Opening Folders in File Manager
69
+
70
+ ```javascript
71
+ import { test } from 'vitest';
72
+ import { chrome } from '@testdriver/sdk';
73
+
74
+ test('navigates folders in Google Drive', async () => {
75
+ const { ai } = await chrome('https://drive.google.com');
76
+
77
+ // Double-click to open a folder
78
+ await ai.doubleClick('Documents folder');
79
+
80
+ // Wait for folder to open
81
+ await ai.find('breadcrumb showing Documents');
82
+ });
83
+ ```
84
+
85
+ ### Selecting Text with Double-Click
86
+
87
+ ```javascript
88
+ // Double-click to select a word
89
+ await ai.doubleClick('word "TestDriver" in the paragraph');
90
+
91
+ // Verify selection
92
+ const selectedText = await ai.exec('window.getSelection().toString()');
93
+ expect(selectedText).toBe('TestDriver');
94
+ ```
95
+
96
+ ## Related Methods
97
+
98
+ - [`click()`](/v7/click) - Single click on an element
99
+ - [`rightClick()`](/v7/right-click) - Right-click to open context menu
100
+ - [`mouseDown()`](/v7/mouse-down) - Press mouse button without releasing
101
+ - [`mouseUp()`](/v7/mouse-up) - Release mouse button
102
+ - [`hover()`](/v7/hover) - Move mouse over element without clicking