testdriverai 6.2.2 → 7.1.0

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 (300) hide show
  1. package/.github/workflows/acceptance-linux.yml +75 -0
  2. package/.github/workflows/acceptance-sdk-tests.yml +133 -0
  3. package/.vscode/settings.json +5 -1
  4. package/AGENTS.md +550 -0
  5. package/CODEOWNERS +0 -1
  6. package/README.md +126 -0
  7. package/{testdriver → _testdriver}/acceptance/drag-and-drop.yaml +2 -2
  8. package/{testdriver → _testdriver}/acceptance/snippets/login.yaml +1 -1
  9. package/_testdriver/examples/desktop/lifecycle/prerun.yaml +0 -0
  10. package/{testdriver → _testdriver}/examples/web/lifecycle/prerun.yaml +6 -1
  11. package/{testdriver → _testdriver}/lifecycle/postrun.yaml +3 -2
  12. package/_testdriver/lifecycle/prerun.yaml +15 -0
  13. package/{testdriver → _testdriver}/lifecycle/provision.yaml +7 -2
  14. package/agent/index.js +300 -85
  15. package/agent/interface.js +15 -0
  16. package/agent/lib/cache.js +142 -0
  17. package/agent/lib/commander.js +1 -39
  18. package/agent/lib/commands.js +910 -296
  19. package/agent/lib/redraw.js +129 -41
  20. package/agent/lib/sandbox.js +29 -6
  21. package/agent/lib/sdk.js +22 -0
  22. package/agent/lib/system.js +0 -3
  23. package/agent/lib/validation.js +1 -7
  24. package/debug-locate-response.js +82 -0
  25. package/debugger/index.html +15 -4
  26. package/docs/ARCHITECTURE.md +424 -0
  27. package/docs/AWESOME_LOGS_QUICK_REF.md +100 -0
  28. package/docs/MIGRATION.md +425 -0
  29. package/docs/PRESETS.md +210 -0
  30. package/docs/QUICK_START_TEST_RECORDING.md +215 -0
  31. package/docs/SDK_AWESOME_LOGS.md +468 -0
  32. package/docs/TEST_RECORDING.md +388 -0
  33. package/docs/docs.json +286 -152
  34. package/docs/guide/best-practices-polling.mdx +154 -0
  35. package/docs/sdk-browser-rendering.md +167 -0
  36. package/docs/v6/getting-started/self-hosting.mdx +407 -0
  37. package/docs/{guide → v6/guide}/dashcam.mdx +1 -1
  38. package/docs/{guide → v6/guide}/environment-variables.mdx +4 -5
  39. package/docs/{guide → v6/guide}/lifecycle.mdx +1 -1
  40. package/docs/v6/overview/comparison.mdx +101 -0
  41. package/docs/v7/README.md +135 -0
  42. package/docs/v7/api/ai.mdx +205 -0
  43. package/docs/v7/api/assert.mdx +285 -0
  44. package/docs/v7/api/assertions.mdx +403 -0
  45. package/docs/v7/api/click.mdx +287 -0
  46. package/docs/v7/api/client.mdx +322 -0
  47. package/docs/v7/api/dashcam.mdx +497 -0
  48. package/docs/v7/api/doubleClick.mdx +102 -0
  49. package/docs/v7/api/elements.mdx +479 -0
  50. package/docs/v7/api/exec.mdx +346 -0
  51. package/docs/v7/api/find.mdx +316 -0
  52. package/docs/v7/api/focusApplication.mdx +294 -0
  53. package/docs/v7/api/hover.mdx +279 -0
  54. package/docs/v7/api/mouseDown.mdx +161 -0
  55. package/docs/v7/api/mouseUp.mdx +164 -0
  56. package/docs/v7/api/pressKeys.mdx +349 -0
  57. package/docs/v7/api/rightClick.mdx +123 -0
  58. package/docs/v7/api/sandbox.mdx +404 -0
  59. package/docs/v7/api/scroll.mdx +300 -0
  60. package/docs/v7/api/type.mdx +314 -0
  61. package/docs/v7/commands/assert.mdx +45 -0
  62. package/docs/v7/commands/exec.mdx +282 -0
  63. package/docs/v7/commands/focus-application.mdx +44 -0
  64. package/docs/v7/commands/hover-image.mdx +69 -0
  65. package/docs/v7/commands/hover-text.mdx +47 -0
  66. package/docs/v7/commands/if.mdx +53 -0
  67. package/docs/v7/commands/match-image.mdx +67 -0
  68. package/docs/v7/commands/press-keys.mdx +87 -0
  69. package/docs/v7/commands/remember.mdx +49 -0
  70. package/docs/v7/commands/run.mdx +44 -0
  71. package/docs/v7/commands/scroll-until-image.mdx +66 -0
  72. package/docs/v7/commands/scroll-until-text.mdx +60 -0
  73. package/docs/v7/commands/scroll.mdx +69 -0
  74. package/docs/v7/commands/type.mdx +45 -0
  75. package/docs/v7/commands/wait-for-image.mdx +54 -0
  76. package/docs/v7/commands/wait-for-text.mdx +48 -0
  77. package/docs/v7/commands/wait.mdx +45 -0
  78. package/docs/v7/getting-started/configuration.mdx +380 -0
  79. package/docs/v7/getting-started/quickstart.mdx +332 -0
  80. package/docs/v7/guides/best-practices.mdx +486 -0
  81. package/docs/v7/guides/caching-ai.mdx +215 -0
  82. package/docs/v7/guides/caching-selectors.mdx +292 -0
  83. package/docs/v7/guides/caching.mdx +366 -0
  84. package/docs/v7/guides/ci-cd/azure.mdx +587 -0
  85. package/docs/v7/guides/ci-cd/circleci.mdx +523 -0
  86. package/docs/v7/guides/ci-cd/github-actions.mdx +457 -0
  87. package/docs/v7/guides/ci-cd/gitlab.mdx +498 -0
  88. package/docs/v7/guides/ci-cd/jenkins.mdx +664 -0
  89. package/docs/v7/guides/ci-cd/travis.mdx +438 -0
  90. package/docs/v7/guides/debugging.mdx +349 -0
  91. package/docs/v7/guides/faq.mdx +393 -0
  92. package/docs/v7/guides/migration.mdx +562 -0
  93. package/docs/v7/guides/performance.mdx +517 -0
  94. package/docs/{getting-started → v7/guides}/self-hosting.mdx +11 -12
  95. package/docs/v7/guides/troubleshooting.mdx +526 -0
  96. package/docs/v7/guides/vitest-plugin.mdx +477 -0
  97. package/docs/v7/guides/vitest.mdx +535 -0
  98. package/docs/v7/platforms/linux.mdx +308 -0
  99. package/docs/v7/platforms/macos.mdx +433 -0
  100. package/docs/v7/platforms/windows.mdx +430 -0
  101. package/docs/v7/playwright.mdx +342 -0
  102. package/docs/v7/presets/chrome-extension.mdx +223 -0
  103. package/docs/v7/presets/chrome.mdx +287 -0
  104. package/docs/v7/presets/electron.mdx +435 -0
  105. package/docs/v7/presets/vscode.mdx +398 -0
  106. package/docs/v7/presets/webapp.mdx +396 -0
  107. package/docs/v7/progressive-apis/CORE.md +459 -0
  108. package/docs/v7/progressive-apis/HOOKS.md +360 -0
  109. package/docs/v7/progressive-apis/PROGRESSIVE_DISCLOSURE.md +230 -0
  110. package/docs/v7/progressive-apis/PROVISION.md +266 -0
  111. package/eslint.config.js +19 -1
  112. package/interfaces/cli/lib/base.js +10 -4
  113. package/interfaces/logger.js +2 -1
  114. package/interfaces/shared-test-state.mjs +69 -0
  115. package/interfaces/vitest-plugin.mjs +830 -0
  116. package/package.json +29 -5
  117. package/schema.json +8 -29
  118. package/scripts/view-test-results.mjs +96 -0
  119. package/sdk-log-formatter.js +714 -0
  120. package/sdk.d.ts +1028 -0
  121. package/sdk.js +2567 -0
  122. package/{.github/workflows/self-hosted.yml → self-hosted.yml} +13 -4
  123. package/setup/aws/cloudformation.yaml +9 -2
  124. package/src/core/Dashcam.js +469 -0
  125. package/src/core/index.d.ts +150 -0
  126. package/src/core/index.js +12 -0
  127. package/src/presets/index.mjs +331 -0
  128. package/src/vitest/extended.mjs +108 -0
  129. package/src/vitest/hooks.d.ts +119 -0
  130. package/src/vitest/hooks.mjs +298 -0
  131. package/src/vitest/index.mjs +64 -0
  132. package/src/vitest/lifecycle.mjs +277 -0
  133. package/src/vitest/utils.mjs +150 -0
  134. package/test/dashcam.test.js +137 -0
  135. package/test/mcp-example-test.yaml +27 -0
  136. package/testdriver/acceptance-sdk/QUICK_REFERENCE.md +61 -0
  137. package/testdriver/acceptance-sdk/README.md +128 -0
  138. package/testdriver/acceptance-sdk/TEST_REPORTING.md +245 -0
  139. package/testdriver/acceptance-sdk/assert.test.mjs +26 -0
  140. package/testdriver/acceptance-sdk/auto-cache-key-demo.test.mjs +56 -0
  141. package/testdriver/acceptance-sdk/chrome-extension.test.mjs +89 -0
  142. package/testdriver/acceptance-sdk/drag-and-drop.test.mjs +58 -0
  143. package/testdriver/acceptance-sdk/element-not-found.test.mjs +25 -0
  144. package/testdriver/acceptance-sdk/exec-js.test.mjs +43 -0
  145. package/testdriver/acceptance-sdk/exec-output.test.mjs +59 -0
  146. package/testdriver/acceptance-sdk/exec-pwsh.test.mjs +57 -0
  147. package/testdriver/acceptance-sdk/focus-window.test.mjs +36 -0
  148. package/testdriver/acceptance-sdk/formatted-logging.test.mjs +26 -0
  149. package/testdriver/acceptance-sdk/hooks-example.test.mjs +38 -0
  150. package/testdriver/acceptance-sdk/hover-image.test.mjs +34 -0
  151. package/testdriver/acceptance-sdk/hover-text-with-description.test.mjs +38 -0
  152. package/testdriver/acceptance-sdk/hover-text.test.mjs +27 -0
  153. package/testdriver/acceptance-sdk/match-image.test.mjs +36 -0
  154. package/testdriver/acceptance-sdk/presets-example.test.mjs +87 -0
  155. package/testdriver/acceptance-sdk/press-keys.test.mjs +50 -0
  156. package/testdriver/acceptance-sdk/prompt.test.mjs +33 -0
  157. package/testdriver/acceptance-sdk/scroll-keyboard.test.mjs +38 -0
  158. package/testdriver/acceptance-sdk/scroll-until-image.test.mjs +39 -0
  159. package/testdriver/acceptance-sdk/scroll-until-text.test.mjs +28 -0
  160. package/testdriver/acceptance-sdk/scroll.test.mjs +41 -0
  161. package/testdriver/acceptance-sdk/setup/globalTeardown.mjs +11 -0
  162. package/testdriver/acceptance-sdk/setup/testHelpers.mjs +420 -0
  163. package/testdriver/acceptance-sdk/setup/vitestSetup.mjs +40 -0
  164. package/testdriver/acceptance-sdk/sully-ai.test.mjs +234 -0
  165. package/testdriver/acceptance-sdk/test-console-logs.test.mjs +42 -0
  166. package/testdriver/acceptance-sdk/type-checking-demo.js +49 -0
  167. package/testdriver/acceptance-sdk/type.test.mjs +45 -0
  168. package/verify-element-api.js +89 -0
  169. package/verify-types.js +0 -0
  170. package/vitest.config.example.js +19 -0
  171. package/vitest.config.mjs +66 -0
  172. package/vitest.config.mjs.bak +44 -0
  173. package/.github/workflows/acceptance-v6.yml +0 -169
  174. package/.vscode/mcp.json +0 -9
  175. package/docs/overview/comparison.mdx +0 -82
  176. package/testdriver/lifecycle/prerun.yaml +0 -17
  177. /package/{testdriver/examples/desktop/lifecycle/prerun.yaml → .env.example} +0 -0
  178. /package/{testdriver → _testdriver}/acceptance/assert.yaml +0 -0
  179. /package/{testdriver → _testdriver}/acceptance/dashcam.yaml +0 -0
  180. /package/{testdriver → _testdriver}/acceptance/embed.yaml +0 -0
  181. /package/{testdriver → _testdriver}/acceptance/exec-js.yaml +0 -0
  182. /package/{testdriver → _testdriver}/acceptance/exec-output.yaml +0 -0
  183. /package/{testdriver → _testdriver}/acceptance/exec-shell.yaml +0 -0
  184. /package/{testdriver → _testdriver}/acceptance/focus-window.yaml +0 -0
  185. /package/{testdriver → _testdriver}/acceptance/hover-image.yaml +0 -0
  186. /package/{testdriver → _testdriver}/acceptance/hover-text-with-description.yaml +0 -0
  187. /package/{testdriver → _testdriver}/acceptance/hover-text.yaml +0 -0
  188. /package/{testdriver → _testdriver}/acceptance/if-else.yaml +0 -0
  189. /package/{testdriver → _testdriver}/acceptance/match-image.yaml +0 -0
  190. /package/{testdriver → _testdriver}/acceptance/press-keys.yaml +0 -0
  191. /package/{testdriver → _testdriver}/acceptance/prompt.yaml +0 -0
  192. /package/{testdriver → _testdriver}/acceptance/remember.yaml +0 -0
  193. /package/{testdriver → _testdriver}/acceptance/screenshots/cart.png +0 -0
  194. /package/{testdriver → _testdriver}/acceptance/scroll-keyboard.yaml +0 -0
  195. /package/{testdriver → _testdriver}/acceptance/scroll-until-image.yaml +0 -0
  196. /package/{testdriver → _testdriver}/acceptance/scroll-until-text.yaml +0 -0
  197. /package/{testdriver → _testdriver}/acceptance/scroll.yaml +0 -0
  198. /package/{testdriver → _testdriver}/acceptance/snippets/match-cart.yaml +0 -0
  199. /package/{testdriver → _testdriver}/acceptance/type.yaml +0 -0
  200. /package/{testdriver → _testdriver}/behavior/failure.yaml +0 -0
  201. /package/{testdriver → _testdriver}/behavior/hover-text.yaml +0 -0
  202. /package/{testdriver → _testdriver}/behavior/lifecycle/postrun.yaml +0 -0
  203. /package/{testdriver → _testdriver}/behavior/lifecycle/prerun.yaml +0 -0
  204. /package/{testdriver → _testdriver}/behavior/lifecycle/provision.yaml +0 -0
  205. /package/{testdriver → _testdriver}/behavior/secrets.yaml +0 -0
  206. /package/{testdriver → _testdriver}/edge-cases/dashcam-chrome.yaml +0 -0
  207. /package/{testdriver → _testdriver}/edge-cases/exec-pwsh-multiline.yaml +0 -0
  208. /package/{testdriver → _testdriver}/edge-cases/js-exception.yaml +0 -0
  209. /package/{testdriver → _testdriver}/edge-cases/js-promise.yaml +0 -0
  210. /package/{testdriver → _testdriver}/edge-cases/lifecycle/postrun.yaml +0 -0
  211. /package/{testdriver → _testdriver}/edge-cases/prompt-in-middle.yaml +0 -0
  212. /package/{testdriver → _testdriver}/edge-cases/prompt-nested.yaml +0 -0
  213. /package/{testdriver → _testdriver}/edge-cases/success-test.yaml +0 -0
  214. /package/{testdriver → _testdriver}/examples/android/example.yaml +0 -0
  215. /package/{testdriver → _testdriver}/examples/android/lifecycle/postrun.yaml +0 -0
  216. /package/{testdriver → _testdriver}/examples/android/lifecycle/provision.yaml +0 -0
  217. /package/{testdriver → _testdriver}/examples/android/readme.md +0 -0
  218. /package/{testdriver → _testdriver}/examples/chrome-extension/lifecycle/provision.yaml +0 -0
  219. /package/{testdriver → _testdriver}/examples/desktop/lifecycle/provision.yaml +0 -0
  220. /package/{testdriver → _testdriver}/examples/vscode-extension/lifecycle/provision.yaml +0 -0
  221. /package/{testdriver → _testdriver}/examples/web/lifecycle/postrun.yaml +0 -0
  222. /package/docs/{account → v6/account}/dashboard.mdx +0 -0
  223. /package/docs/{account → v6/account}/enterprise.mdx +0 -0
  224. /package/docs/{account → v6/account}/pricing.mdx +0 -0
  225. /package/docs/{account → v6/account}/projects.mdx +0 -0
  226. /package/docs/{account → v6/account}/team.mdx +0 -0
  227. /package/docs/{action → v6/action}/ami.mdx +0 -0
  228. /package/docs/{action → v6/action}/performance.mdx +0 -0
  229. /package/docs/{action → v6/action}/secrets.mdx +0 -0
  230. /package/docs/{apps → v6/apps}/chrome-extensions.mdx +0 -0
  231. /package/docs/{apps → v6/apps}/desktop-apps.mdx +0 -0
  232. /package/docs/{apps → v6/apps}/mobile-apps.mdx +0 -0
  233. /package/docs/{apps → v6/apps}/static-websites.mdx +0 -0
  234. /package/docs/{apps → v6/apps}/tauri-apps.mdx +0 -0
  235. /package/docs/{bugs → v6/bugs}/jira.mdx +0 -0
  236. /package/docs/{cli → v6/cli}/overview.mdx +0 -0
  237. /package/docs/{commands → v6/commands}/assert.mdx +0 -0
  238. /package/docs/{commands → v6/commands}/exec.mdx +0 -0
  239. /package/docs/{commands → v6/commands}/focus-application.mdx +0 -0
  240. /package/docs/{commands → v6/commands}/hover-image.mdx +0 -0
  241. /package/docs/{commands → v6/commands}/hover-text.mdx +0 -0
  242. /package/docs/{commands → v6/commands}/if.mdx +0 -0
  243. /package/docs/{commands → v6/commands}/match-image.mdx +0 -0
  244. /package/docs/{commands → v6/commands}/press-keys.mdx +0 -0
  245. /package/docs/{commands → v6/commands}/remember.mdx +0 -0
  246. /package/docs/{commands → v6/commands}/run.mdx +0 -0
  247. /package/docs/{commands → v6/commands}/scroll-until-image.mdx +0 -0
  248. /package/docs/{commands → v6/commands}/scroll-until-text.mdx +0 -0
  249. /package/docs/{commands → v6/commands}/scroll.mdx +0 -0
  250. /package/docs/{commands → v6/commands}/type.mdx +0 -0
  251. /package/docs/{commands → v6/commands}/wait-for-image.mdx +0 -0
  252. /package/docs/{commands → v6/commands}/wait-for-text.mdx +0 -0
  253. /package/docs/{commands → v6/commands}/wait.mdx +0 -0
  254. /package/docs/{exporting → v6/exporting}/junit.mdx +0 -0
  255. /package/docs/{exporting → v6/exporting}/playwright.mdx +0 -0
  256. /package/docs/{features → v6/features}/auto-healing.mdx +0 -0
  257. /package/docs/{features → v6/features}/generation.mdx +0 -0
  258. /package/docs/{features → v6/features}/parallel-testing.mdx +0 -0
  259. /package/docs/{features → v6/features}/reusable-snippets.mdx +0 -0
  260. /package/docs/{features → v6/features}/selectorless.mdx +0 -0
  261. /package/docs/{features → v6/features}/visual-assertions.mdx +0 -0
  262. /package/docs/{getting-started → v6/getting-started}/ci.mdx +0 -0
  263. /package/docs/{getting-started → v6/getting-started}/cli.mdx +0 -0
  264. /package/docs/{getting-started → v6/getting-started}/editing.mdx +0 -0
  265. /package/docs/{getting-started → v6/getting-started}/playwright.mdx +0 -0
  266. /package/docs/{getting-started → v6/getting-started}/running.mdx +0 -0
  267. /package/docs/{getting-started → v6/getting-started}/vscode.mdx +0 -0
  268. /package/docs/{guide → v6/guide}/assertions.mdx +0 -0
  269. /package/docs/{guide → v6/guide}/authentication.mdx +0 -0
  270. /package/docs/{guide → v6/guide}/code.mdx +0 -0
  271. /package/docs/{guide → v6/guide}/locating.mdx +0 -0
  272. /package/docs/{guide → v6/guide}/protips.mdx +0 -0
  273. /package/docs/{guide → v6/guide}/variables.mdx +0 -0
  274. /package/docs/{guide → v6/guide}/waiting.mdx +0 -0
  275. /package/docs/{importing → v6/importing}/csv.mdx +0 -0
  276. /package/docs/{importing → v6/importing}/gherkin.mdx +0 -0
  277. /package/docs/{importing → v6/importing}/jira.mdx +0 -0
  278. /package/docs/{importing → v6/importing}/testrail.mdx +0 -0
  279. /package/docs/{integrations → v6/integrations}/electron.mdx +0 -0
  280. /package/docs/{integrations → v6/integrations}/netlify.mdx +0 -0
  281. /package/docs/{integrations → v6/integrations}/vercel.mdx +0 -0
  282. /package/docs/{interactive → v6/interactive}/explore.mdx +0 -0
  283. /package/docs/{interactive → v6/interactive}/run.mdx +0 -0
  284. /package/docs/{interactive → v6/interactive}/save.mdx +0 -0
  285. /package/docs/{overview → v6/overview}/faq.mdx +0 -0
  286. /package/docs/{overview → v6/overview}/performance.mdx +0 -0
  287. /package/docs/{overview → v6/overview}/quickstart.mdx +0 -0
  288. /package/docs/{overview → v6/overview}/what-is-testdriver.mdx +0 -0
  289. /package/docs/{scenarios → v6/scenarios}/ai-chatbot.mdx +0 -0
  290. /package/docs/{scenarios → v6/scenarios}/cookie-banner.mdx +0 -0
  291. /package/docs/{scenarios → v6/scenarios}/file-upload.mdx +0 -0
  292. /package/docs/{scenarios → v6/scenarios}/form-filling.mdx +0 -0
  293. /package/docs/{scenarios → v6/scenarios}/log-in.mdx +0 -0
  294. /package/docs/{scenarios → v6/scenarios}/pdf-generation.mdx +0 -0
  295. /package/docs/{scenarios → v6/scenarios}/spell-check.mdx +0 -0
  296. /package/docs/{security → v6/security}/action.mdx +0 -0
  297. /package/docs/{security → v6/security}/agent.mdx +0 -0
  298. /package/docs/{security → v6/security}/platform.mdx +0 -0
  299. /package/docs/{tutorials → v6/tutorials}/advanced-test.mdx +0 -0
  300. /package/docs/{tutorials → v6/tutorials}/basic-test.mdx +0 -0
@@ -0,0 +1,398 @@
1
+ ---
2
+ title: "VS Code Extensions"
3
+ sidebarTitle: "VS Code Extensions"
4
+ description: "Automatically launch and test Visual Studio Code extensions"
5
+ icon: "code"
6
+ ---
7
+
8
+ ## Overview
9
+
10
+ The `vscode()` preset automatically sets up Visual Studio Code with TestDriver and Dashcam recording. Perfect for testing VS Code extensions and IDE workflows.
11
+
12
+ ## Quick Start
13
+
14
+ ```javascript
15
+ import { test } from 'vitest';
16
+ import { vscode } from 'testdriverai/presets';
17
+
18
+ test('extension test', async (context) => {
19
+ const { vscode } = await vscode(context, {
20
+ workspace: '/tmp/test-project',
21
+ extensions: ['ms-python.python']
22
+ });
23
+
24
+ await vscode.find('File menu').click();
25
+ await vscode.find('New File').click();
26
+ await vscode.find('Python file type').click();
27
+ });
28
+ ```
29
+
30
+ ## Signature
31
+
32
+ ```typescript
33
+ vscode(context, options): Promise<VSCodeResult>
34
+ ```
35
+
36
+ ### Parameters
37
+
38
+ <ParamField path="context" type="object" required>
39
+ Vitest test context - automatically passed to your test function
40
+ </ParamField>
41
+
42
+ <ParamField path="options" type="object">
43
+ Configuration options for VS Code
44
+
45
+ <Expandable title="properties">
46
+ <ParamField path="workspace" type="string">
47
+ Path to workspace/folder to open in VS Code
48
+ </ParamField>
49
+
50
+ <ParamField path="extensions" type="string[]" default={[]}>
51
+ Array of extension IDs to install before launching
52
+ </ParamField>
53
+
54
+ <ParamField path="dashcam" type="boolean" default={true}>
55
+ Enable Dashcam test recording
56
+ </ParamField>
57
+
58
+ <ParamField path="os" type="'linux' | 'mac' | 'windows'" default="linux">
59
+ Target operating system for the test
60
+ </ParamField>
61
+ </Expandable>
62
+ </ParamField>
63
+
64
+ ### Returns
65
+
66
+ <ResponseField name="testdriver" type="TestDriver" required>
67
+ TestDriver instance ready to use
68
+ </ResponseField>
69
+
70
+ <ResponseField name="vscode" type="TestDriver" required>
71
+ Alias for testdriver (semantic clarity for VS Code testing)
72
+ </ResponseField>
73
+
74
+ <ResponseField name="dashcam" type="Dashcam">
75
+ Dashcam instance for test recording (if enabled)
76
+ </ResponseField>
77
+
78
+ ## Examples
79
+
80
+ ### Basic Extension Testing
81
+
82
+ ```javascript
83
+ import { test } from 'vitest';
84
+ import { vscode } from 'testdriverai/presets';
85
+
86
+ test('python extension creates new file', async (context) => {
87
+ const { vscode } = await vscode(context, {
88
+ workspace: '/tmp/python-project',
89
+ extensions: ['ms-python.python']
90
+ });
91
+
92
+ // Open command palette
93
+ await vscode.pressKeys(['cmd', 'shift', 'p']);
94
+
95
+ // Create new Python file
96
+ await vscode.type('Python: Create New File');
97
+ await vscode.pressKeys(['enter']);
98
+
99
+ // Verify file was created
100
+ await vscode.assert('Untitled Python file is open');
101
+ });
102
+ ```
103
+
104
+ ### Testing Multiple Extensions
105
+
106
+ ```javascript
107
+ import { test } from 'vitest';
108
+ import { vscode } from 'testdriverai/presets';
109
+
110
+ test('eslint and prettier integration', async (context) => {
111
+ const { vscode } = await vscode(context, {
112
+ workspace: '/tmp/js-project',
113
+ extensions: [
114
+ 'dbaeumer.vscode-eslint',
115
+ 'esbenp.prettier-vscode'
116
+ ]
117
+ });
118
+
119
+ // Open a JavaScript file
120
+ await vscode.find('File').click();
121
+ await vscode.find('Open File').click();
122
+ await vscode.type('src/index.js');
123
+ await vscode.pressKeys(['enter']);
124
+
125
+ // Format document
126
+ await vscode.pressKeys(['shift', 'alt', 'f']);
127
+
128
+ await vscode.assert('Document is formatted');
129
+ });
130
+ ```
131
+
132
+ ### Empty Workspace
133
+
134
+ ```javascript
135
+ import { test } from 'vitest';
136
+ import { vscode } from 'testdriverai/presets';
137
+
138
+ test('empty workspace welcome screen', async (context) => {
139
+ const { vscode } = await vscode(context, {
140
+ // No workspace specified - opens to welcome screen
141
+ });
142
+
143
+ await vscode.find('Open Folder button').click();
144
+ await vscode.type('/tmp/my-project');
145
+ await vscode.pressKeys(['enter']);
146
+
147
+ await vscode.assert('Folder is opened');
148
+ });
149
+ ```
150
+
151
+ ### Testing on Different Operating Systems
152
+
153
+ ```javascript
154
+ import { test } from 'vitest';
155
+ import { vscode } from 'testdriverai/presets';
156
+
157
+ test('windows vscode test', async (context) => {
158
+ const { vscode } = await vscode(context, {
159
+ workspace: 'C:\\Users\\TestUser\\project',
160
+ os: 'windows'
161
+ });
162
+
163
+ await vscode.find('Explorer view').click();
164
+ });
165
+
166
+ test('mac vscode test', async (context) => {
167
+ const { vscode } = await vscode(context, {
168
+ workspace: '/Users/testuser/project',
169
+ os: 'mac'
170
+ });
171
+
172
+ await vscode.find('Explorer view').click();
173
+ });
174
+ ```
175
+
176
+ ### Extension Settings
177
+
178
+ ```javascript
179
+ import { test } from 'vitest';
180
+ import { vscode } from 'testdriverai/presets';
181
+
182
+ test('configure extension settings', async (context) => {
183
+ const { vscode } = await vscode(context, {
184
+ extensions: ['ms-python.python']
185
+ });
186
+
187
+ // Open settings
188
+ await vscode.pressKeys(['cmd', ',']);
189
+
190
+ // Search for Python settings
191
+ await vscode.find('Search settings').type('python.linting');
192
+
193
+ // Enable linting
194
+ await vscode.find('Python > Linting: Enabled checkbox').click();
195
+
196
+ await vscode.assert('Linting is enabled');
197
+ });
198
+ ```
199
+
200
+ ### Debugging Workflow
201
+
202
+ ```javascript
203
+ import { test } from 'vitest';
204
+ import { vscode } from 'testdriverai/presets';
205
+
206
+ test('debug javascript file', async (context) => {
207
+ const { vscode, dashcam } = await vscode(context, {
208
+ workspace: '/tmp/debug-test',
209
+ extensions: ['ms-vscode.js-debug']
210
+ });
211
+
212
+ // Open file
213
+ await vscode.find('index.js in Explorer').click();
214
+
215
+ // Set breakpoint
216
+ await vscode.find('line 10 gutter').click();
217
+
218
+ // Start debugging
219
+ await vscode.pressKeys(['F5']);
220
+
221
+ // Wait for breakpoint
222
+ await vscode.assert('Debugger paused at breakpoint');
223
+
224
+ // Step over
225
+ await vscode.pressKeys(['F10']);
226
+
227
+ await vscode.assert('Debugger moved to next line');
228
+
229
+ // Dashcam captures entire debug session
230
+ });
231
+ ```
232
+
233
+ ## What It Does
234
+
235
+ When you call `vscode()`, it automatically:
236
+
237
+ 1. **Initializes TestDriver** - Creates and connects to sandbox
238
+ 2. **Sets up Dashcam** - Authenticates and starts recording (if enabled)
239
+ 3. **Installs Extensions** - Downloads and installs specified extensions
240
+ 4. **Launches VS Code** - Opens VS Code with your workspace
241
+ 5. **Waits for Ready** - Ensures VS Code is focused and loaded
242
+ 6. **Returns Instances** - Provides ready-to-use testdriver, vscode alias, and dashcam
243
+
244
+ At test end:
245
+ - Dashcam automatically stops and saves replay URL
246
+ - TestDriver automatically disconnects
247
+ - All cleanup is handled for you
248
+
249
+ ## Common Patterns
250
+
251
+ ### File Explorer Interaction
252
+
253
+ ```javascript
254
+ test('create new folder', async (context) => {
255
+ const { vscode } = await vscode(context, {
256
+ workspace: '/tmp/test-workspace'
257
+ });
258
+
259
+ // Right-click in Explorer
260
+ await vscode.find('Explorer view').click({ button: 'right' });
261
+ await vscode.find('New Folder').click();
262
+ await vscode.type('src');
263
+ await vscode.pressKeys(['enter']);
264
+
265
+ await vscode.assert('src folder appears in Explorer');
266
+ });
267
+ ```
268
+
269
+ ### Terminal Commands
270
+
271
+ ```javascript
272
+ test('run npm install', async (context) => {
273
+ const { vscode } = await vscode(context, {
274
+ workspace: '/tmp/node-project'
275
+ });
276
+
277
+ // Open integrated terminal
278
+ await vscode.pressKeys(['ctrl', '`']);
279
+
280
+ // Run command
281
+ await vscode.type('npm install');
282
+ await vscode.pressKeys(['enter']);
283
+
284
+ // Wait for completion
285
+ await vscode.assert('node_modules folder created');
286
+ });
287
+ ```
288
+
289
+ ### Search and Replace
290
+
291
+ ```javascript
292
+ test('find and replace', async (context) => {
293
+ const { vscode } = await vscode(context, {
294
+ workspace: '/tmp/project'
295
+ });
296
+
297
+ // Open file
298
+ await vscode.find('app.js').click();
299
+
300
+ // Open find/replace
301
+ await vscode.pressKeys(['cmd', 'h']);
302
+
303
+ // Enter search term
304
+ await vscode.find('Find input').type('oldFunction');
305
+
306
+ // Enter replacement
307
+ await vscode.find('Replace input').type('newFunction');
308
+
309
+ // Replace all
310
+ await vscode.find('Replace All button').click();
311
+
312
+ await vscode.assert('All occurrences replaced');
313
+ });
314
+ ```
315
+
316
+ ### Git Integration
317
+
318
+ ```javascript
319
+ test('commit changes', async (context) => {
320
+ const { vscode } = await vscode(context, {
321
+ workspace: '/tmp/git-project',
322
+ extensions: ['vscode.git']
323
+ });
324
+
325
+ // Open Source Control
326
+ await vscode.find('Source Control icon').click();
327
+
328
+ // Stage changes
329
+ await vscode.find('Stage All Changes button').click();
330
+
331
+ // Enter commit message
332
+ await vscode.find('Commit message input').type('Initial commit');
333
+
334
+ // Commit
335
+ await vscode.find('Commit button').click();
336
+
337
+ await vscode.assert('Changes committed');
338
+ });
339
+ ```
340
+
341
+ ## Extension ID Reference
342
+
343
+ Common extension IDs for testing:
344
+
345
+ | Extension | ID |
346
+ |-----------|-----|
347
+ | Python | `ms-python.python` |
348
+ | ESLint | `dbaeumer.vscode-eslint` |
349
+ | Prettier | `esbenp.prettier-vscode` |
350
+ | GitLens | `eamodio.gitlens` |
351
+ | Live Server | `ritwickdey.liveserver` |
352
+ | Docker | `ms-azuretools.vscode-docker` |
353
+ | REST Client | `humao.rest-client` |
354
+ | Debugger for Chrome | `msjsdiag.debugger-for-chrome` |
355
+
356
+ Find more extension IDs on the [VS Code Marketplace](https://marketplace.visualstudio.com/).
357
+
358
+ ## Using with provision()
359
+
360
+ The `vscode()` preset can also be called via the unified `provision()` function:
361
+
362
+ ```javascript
363
+ import { provision } from 'testdriverai/presets';
364
+
365
+ test('using provision', async (context) => {
366
+ const { vscode } = await provision('vscode', {
367
+ workspace: '/tmp/project',
368
+ extensions: ['ms-python.python']
369
+ }, context);
370
+
371
+ // Same functionality as vscode() directly
372
+ });
373
+ ```
374
+
375
+ ## Error Handling
376
+
377
+ ```javascript
378
+ test('handles missing extension', async (context) => {
379
+ try {
380
+ const { vscode } = await vscode(context, {
381
+ extensions: ['non.existent.extension']
382
+ });
383
+
384
+ // Will throw error if extension installation fails
385
+ } catch (error) {
386
+ // Cleanup still happens automatically
387
+ expect(error.message).toContain('extension');
388
+ }
389
+ });
390
+ ```
391
+
392
+ ## See Also
393
+
394
+ - [Provision API](/v7/progressive-apis/PROVISION) - Overview of all presets
395
+ - [Chrome Preset](/v7/presets/chrome) - Testing web applications
396
+ - [Electron Preset](/v7/presets/electron) - Testing Electron apps
397
+ - [Vitest Integration](/v7/guides/vitest) - Complete Vitest setup guide
398
+ - [Hooks API](/v7/progressive-apis/HOOKS) - Manual lifecycle control