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,123 @@
1
+ ---
2
+ title: "rightClick"
3
+ description: "Perform a right-click action to open context menus"
4
+ icon: "bars"
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ The `rightClick()` method performs a right-click action on an element, typically used to open context menus. 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
+ // Right-click on an element
15
+ await element.rightClick();
16
+
17
+ // Right-click using a selector
18
+ await ai.rightClick('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 right-click |
30
+
31
+ ## Returns
32
+
33
+ Returns a `Promise<void>` that resolves when the right-click action completes.
34
+
35
+ ## Examples
36
+
37
+ ### Right-Click to Open Context Menu
38
+
39
+ ```javascript
40
+ const fileItem = await ai.find('README.md file');
41
+ await fileItem.rightClick();
42
+
43
+ // Select menu option
44
+ await ai.click('Delete from context menu');
45
+ ```
46
+
47
+ ### Direct Right-Click with Selector
48
+
49
+ ```javascript
50
+ await ai.rightClick('image in the gallery');
51
+ await ai.click('Save image as');
52
+ ```
53
+
54
+ ### VS Code Context Menu
55
+
56
+ ```javascript
57
+ import { test } from 'vitest';
58
+ import { vscode } from '@testdriver/sdk';
59
+
60
+ test('renames a file via context menu', async () => {
61
+ const { ai } = await vscode();
62
+
63
+ // Right-click on a file
64
+ await ai.rightClick('test.js in the file explorer');
65
+
66
+ // Click rename option
67
+ await ai.click('Rename');
68
+
69
+ // Type new name
70
+ await ai.type('test.spec.js');
71
+ await ai.pressKeys('Enter');
72
+
73
+ // Verify rename
74
+ const renamedFile = await ai.find('test.spec.js in the file explorer');
75
+ expect(renamedFile).toBeTruthy();
76
+ });
77
+ ```
78
+
79
+ ### Browser Context Menu
80
+
81
+ ```javascript
82
+ import { test } from 'vitest';
83
+ import { chrome } from '@testdriver/sdk';
84
+
85
+ test('opens link in new tab', async () => {
86
+ const { ai } = await chrome('https://example.com');
87
+
88
+ // Right-click on a link
89
+ await ai.rightClick('Documentation link');
90
+
91
+ // Select "Open in new tab"
92
+ await ai.click('Open link in new tab');
93
+ });
94
+ ```
95
+
96
+ ### Custom Context Menu in Web App
97
+
98
+ ```javascript
99
+ test('uses custom context menu', async () => {
100
+ const { ai } = await chrome('https://app.example.com');
101
+
102
+ // Right-click on custom element
103
+ await ai.rightClick('project item in the list');
104
+
105
+ // Wait for custom menu to appear
106
+ await ai.find('custom context menu');
107
+
108
+ // Click menu option
109
+ await ai.click('Duplicate project');
110
+
111
+ // Verify duplication
112
+ const duplicatedProject = await ai.find('project item (copy)');
113
+ expect(duplicatedProject).toBeTruthy();
114
+ });
115
+ ```
116
+
117
+ ## Related Methods
118
+
119
+ - [`click()`](/v7/api/click) - Single click on an element
120
+ - [`doubleClick()`](/v7/api/doubleClick) - Double-click on an element
121
+ - [`mouseDown()`](/v7/api/mouseDown) - Press mouse button without releasing
122
+ - [`mouseUp()`](/v7/api/mouseUp) - Release mouse button
123
+ - [`hover()`](/v7/api/hover) - Move mouse over element without clicking
@@ -0,0 +1,404 @@
1
+ ---
2
+ title: "Sandbox Management"
3
+ sidebarTitle: "Sandbox"
4
+ description: "Execute scripts and manage the sandbox environment"
5
+ icon: "server"
6
+ ---
7
+
8
+ ## Overview
9
+
10
+ The sandbox is a virtual machine where your tests run. You can execute shell commands, JavaScript, and manage applications within the sandbox environment.
11
+
12
+ ## Code Execution
13
+
14
+ ### exec()
15
+
16
+ Execute code or shell commands in the sandbox.
17
+
18
+ ```javascript
19
+ await testdriver.exec(language, code, timeout, silent)
20
+ ```
21
+
22
+ **Parameters:**
23
+ - `language` (string) - Language to execute: `'js'` (JavaScript) or `'pwsh'` (PowerShell)
24
+ - `code` (string) - Code or command to execute
25
+ - `timeout` (number) - Timeout in milliseconds
26
+ - `silent` (boolean, optional) - Suppress output if `true`
27
+
28
+ **Returns:** `Promise<string>` - Command output
29
+
30
+ ### JavaScript Execution
31
+
32
+ Execute JavaScript code in the browser context (Windows sandbox only).
33
+
34
+ ```javascript
35
+ // Execute JavaScript in the browser
36
+ const result = await testdriver.exec('js', 'document.title', 5000);
37
+ console.log('Page title:', result);
38
+
39
+ // Manipulate the DOM
40
+ await testdriver.exec('js', `
41
+ document.querySelector('#username').value = 'testuser';
42
+ `, 5000);
43
+
44
+ // Return data from the page
45
+ const elementText = await testdriver.exec('js', `
46
+ document.querySelector('.message').textContent
47
+ `, 5000);
48
+ ```
49
+
50
+ ### PowerShell Execution
51
+
52
+ Execute PowerShell commands in the Windows sandbox.
53
+
54
+ ```javascript
55
+ // Run a simple command
56
+ const output = await testdriver.exec('pwsh', 'Get-Process chrome', 5000);
57
+ console.log('Chrome processes:', output);
58
+
59
+ // Install software
60
+ await testdriver.exec('pwsh', 'npm install -g dashcam@beta', 10000);
61
+
62
+ // Start an application
63
+ await testdriver.exec('pwsh', `
64
+ Start-Process "C:/Program Files/Google/Chrome/Application/chrome.exe" -ArgumentList "--start-maximized", "https://example.com"
65
+ `, 10000);
66
+
67
+ // File operations
68
+ await testdriver.exec('pwsh', 'New-Item -Path "C:\\test.txt" -ItemType File', 5000);
69
+ ```
70
+
71
+ ### Silent Execution
72
+
73
+ Use the `silent` parameter to suppress output for background operations:
74
+
75
+ ```javascript
76
+ // Silent installation
77
+ await testdriver.exec('pwsh', 'npm install -g some-package', 10000, true);
78
+
79
+ // Start background process
80
+ await testdriver.exec('pwsh', 'Start-Process notepad', 5000, true);
81
+ ```
82
+
83
+ ## Application Management
84
+
85
+ ### focusApplication()
86
+
87
+ Bring an application window to the foreground.
88
+
89
+ ```javascript
90
+ await testdriver.focusApplication(name)
91
+ ```
92
+
93
+ **Parameters:**
94
+ - `name` (string) - Application name (e.g., `'Google Chrome'`, `'Microsoft Edge'`, `'Notepad'`)
95
+
96
+ **Returns:** `Promise<string>` - Result message
97
+
98
+ **Example:**
99
+ ```javascript
100
+ // Focus Chrome browser
101
+ await testdriver.focusApplication('Google Chrome');
102
+
103
+ // Focus Edge
104
+ await testdriver.focusApplication('Microsoft Edge');
105
+
106
+ // Focus Notepad
107
+ await testdriver.focusApplication('Notepad');
108
+ ```
109
+
110
+ <Tip>
111
+ Call `focusApplication()` before interacting with UI elements to ensure the correct window is active.
112
+ </Tip>
113
+
114
+ ## Common Sandbox Operations
115
+
116
+ ### Installing Software
117
+
118
+ ```javascript
119
+ // Install npm package globally
120
+ await testdriver.exec('pwsh', 'npm install -g package-name', 30000);
121
+
122
+ // Install via Chocolatey (if available)
123
+ await testdriver.exec('pwsh', 'choco install firefox -y', 60000);
124
+
125
+ // Download and install
126
+ await testdriver.exec('pwsh', `
127
+ Invoke-WebRequest -Uri "https://example.com/installer.exe" -OutFile "C:\\installer.exe"
128
+ Start-Process -FilePath "C:\\installer.exe" -ArgumentList "/S" -Wait
129
+ `, 120000);
130
+ ```
131
+
132
+ ### File Operations
133
+
134
+ ```javascript
135
+ // Create a file
136
+ await testdriver.exec('pwsh', `
137
+ Set-Content -Path "C:\\test.txt" -Value "Hello World"
138
+ `, 5000);
139
+
140
+ // Read a file
141
+ const content = await testdriver.exec('pwsh', 'Get-Content -Path "C:\\test.txt"', 5000);
142
+
143
+ // Copy files
144
+ await testdriver.exec('pwsh', 'Copy-Item -Path "C:\\source.txt" -Destination "C:\\dest.txt"', 5000);
145
+
146
+ // Delete files
147
+ await testdriver.exec('pwsh', 'Remove-Item -Path "C:\\test.txt"', 5000);
148
+ ```
149
+
150
+ ### Environment Variables
151
+
152
+ ```javascript
153
+ // Set environment variable
154
+ await testdriver.exec('pwsh', '$env:MY_VAR = "value"', 5000);
155
+
156
+ // Get environment variable
157
+ const value = await testdriver.exec('pwsh', '$env:MY_VAR', 5000);
158
+
159
+ // Set persistent environment variable
160
+ await testdriver.exec('pwsh', '[Environment]::SetEnvironmentVariable("MY_VAR", "value", "User")', 5000);
161
+ ```
162
+
163
+ ### Network Operations
164
+
165
+ ```javascript
166
+ // Test connectivity
167
+ const pingResult = await testdriver.exec('pwsh', 'Test-NetConnection google.com', 10000);
168
+
169
+ // Download file
170
+ await testdriver.exec('pwsh', `
171
+ Invoke-WebRequest -Uri "https://example.com/file.zip" -OutFile "C:\\Downloads\\file.zip"
172
+ `, 30000);
173
+
174
+ // Check if port is open
175
+ const portCheck = await testdriver.exec('pwsh', 'Test-NetConnection -ComputerName localhost -Port 3000', 5000);
176
+ ```
177
+
178
+ ### Process Management
179
+
180
+ ```javascript
181
+ // List running processes
182
+ const processes = await testdriver.exec('pwsh', 'Get-Process', 5000);
183
+
184
+ // Kill a process
185
+ await testdriver.exec('pwsh', 'Stop-Process -Name "chrome" -Force', 5000);
186
+
187
+ // Start a process and wait for it
188
+ await testdriver.exec('pwsh', 'Start-Process notepad -Wait', 30000);
189
+
190
+ // Start process with arguments
191
+ await testdriver.exec('pwsh', `
192
+ Start-Process "chrome.exe" -ArgumentList "--incognito", "https://example.com"
193
+ `, 5000);
194
+ ```
195
+
196
+ ## Browser Automation with JavaScript
197
+
198
+ ### DOM Manipulation
199
+
200
+ ```javascript
201
+ // Click an element
202
+ await testdriver.exec('js', `
203
+ document.querySelector('#submit-button').click();
204
+ `, 5000);
205
+
206
+ // Fill a form
207
+ await testdriver.exec('js', `
208
+ document.querySelector('#username').value = 'user@example.com';
209
+ document.querySelector('#password').value = 'secret';
210
+ document.querySelector('#login-form').submit();
211
+ `, 5000);
212
+
213
+ // Scroll to element
214
+ await testdriver.exec('js', `
215
+ document.querySelector('#footer').scrollIntoView();
216
+ `, 5000);
217
+ ```
218
+
219
+ ### Reading Page Data
220
+
221
+ ```javascript
222
+ // Get page title
223
+ const title = await testdriver.exec('js', 'document.title', 5000);
224
+
225
+ // Get all links
226
+ const links = await testdriver.exec('js', `
227
+ Array.from(document.querySelectorAll('a')).map(a => a.href).join('\\n')
228
+ `, 5000);
229
+
230
+ // Check if element exists
231
+ const exists = await testdriver.exec('js', `
232
+ document.querySelector('.error-message') !== null
233
+ `, 5000);
234
+
235
+ // Get element text
236
+ const text = await testdriver.exec('js', `
237
+ document.querySelector('.notification').textContent
238
+ `, 5000);
239
+ ```
240
+
241
+ ### Waiting for Conditions
242
+
243
+ ```javascript
244
+ // Wait for element to appear (using polling)
245
+ await testdriver.exec('js', `
246
+ await new Promise((resolve) => {
247
+ const interval = setInterval(() => {
248
+ if (document.querySelector('.loaded')) {
249
+ clearInterval(interval);
250
+ resolve();
251
+ }
252
+ }, 100);
253
+ });
254
+ `, 30000);
255
+
256
+ // Wait for page load
257
+ await testdriver.exec('js', `
258
+ if (document.readyState !== 'complete') {
259
+ await new Promise(resolve => window.addEventListener('load', resolve));
260
+ }
261
+ `, 10000);
262
+ ```
263
+
264
+ ## Complete Example
265
+
266
+ ```javascript
267
+ import { beforeAll, afterAll, describe, it } from 'vitest';
268
+ import TestDriver from 'testdriverai';
269
+
270
+ describe('Sandbox Operations', () => {
271
+ let testdriver;
272
+
273
+ beforeAll(async () => {
274
+ client = new TestDriver(process.env.TD_API_KEY, {
275
+ os: 'windows',
276
+ resolution: '1366x768'
277
+ });
278
+
279
+ await testdriver.auth();
280
+ await testdriver.connect({ newSandbox: true });
281
+ });
282
+
283
+ afterAll(async () => {
284
+ await testdriver.disconnect();
285
+ });
286
+
287
+ it('should install and use a tool', async () => {
288
+ // Install a tool
289
+ await testdriver.exec('pwsh', 'npm install -g http-server', 30000, true);
290
+
291
+ // Create a simple HTML file
292
+ await testdriver.exec('pwsh', `
293
+ Set-Content -Path "C:\\index.html" -Value "<h1>Hello World</h1>"
294
+ `, 5000);
295
+
296
+ // Start HTTP server (background process)
297
+ await testdriver.exec('pwsh', `
298
+ Start-Process pwsh -ArgumentList "-Command", "http-server C:\\ -p 8080"
299
+ `, 5000, true);
300
+
301
+ // Wait for server to start
302
+ await new Promise(resolve => setTimeout(resolve, 3000));
303
+
304
+ // Launch browser to view the page
305
+ await testdriver.exec('pwsh', `
306
+ Start-Process chrome -ArgumentList "http://localhost:8080"
307
+ `, 5000);
308
+
309
+ // Focus the browser
310
+ await testdriver.focusApplication('Google Chrome');
311
+
312
+ // Verify the page loaded
313
+ const pageText = await testdriver.exec('js', 'document.body.textContent', 5000);
314
+ expect(pageText).toContain('Hello World');
315
+ });
316
+
317
+ it('should manage files and processes', async () => {
318
+ // Create test file
319
+ await testdriver.exec('pwsh', `
320
+ "Test content" | Out-File -FilePath "C:\\test.txt"
321
+ `, 5000);
322
+
323
+ // Open file in notepad
324
+ await testdriver.exec('pwsh', 'Start-Process notepad C:\\test.txt', 5000);
325
+
326
+ // Focus notepad
327
+ await testdriver.focusApplication('Notepad');
328
+
329
+ // Wait a moment
330
+ await new Promise(resolve => setTimeout(resolve, 1000));
331
+
332
+ // Close notepad
333
+ await testdriver.exec('pwsh', 'Stop-Process -Name notepad -Force', 5000);
334
+ });
335
+ });
336
+ ```
337
+
338
+ ## Best Practices
339
+
340
+ <AccordionGroup>
341
+ <Accordion title="Use appropriate timeouts">
342
+ Set realistic timeouts based on the operation:
343
+
344
+ ```javascript
345
+ // Quick operations: 5000ms
346
+ await testdriver.exec('js', 'document.title', 5000);
347
+
348
+ // Installations: 30000-60000ms
349
+ await testdriver.exec('pwsh', 'npm install -g package', 30000);
350
+
351
+ // Downloads or complex operations: 60000-120000ms
352
+ await testdriver.exec('pwsh', 'Install-Module Something', 120000);
353
+ ```
354
+ </Accordion>
355
+
356
+ <Accordion title="Handle errors gracefully">
357
+ Wrap exec calls in try-catch for better error handling:
358
+
359
+ ```javascript
360
+ try {
361
+ await testdriver.exec('pwsh', 'Some-Command', 5000);
362
+ } catch (error) {
363
+ console.error('Command failed:', error.message);
364
+ // Fall back or retry
365
+ }
366
+ ```
367
+ </Accordion>
368
+
369
+ <Accordion title="Use silent mode for background operations">
370
+ Suppress output for installation and background tasks:
371
+
372
+ ```javascript
373
+ // Silent install
374
+ await testdriver.exec('pwsh', 'npm install -g tool', 30000, true);
375
+
376
+ // Background process
377
+ await testdriver.exec('pwsh', 'Start-Process app', 5000, true);
378
+ ```
379
+ </Accordion>
380
+
381
+ <Accordion title="Focus applications before interaction">
382
+ Always focus the target application before UI interactions:
383
+
384
+ ```javascript
385
+ await testdriver.focusApplication('Google Chrome');
386
+ const button = await testdriver.find('submit button');
387
+ await button.click();
388
+ ```
389
+ </Accordion>
390
+
391
+ <Accordion title="Escape strings properly in PowerShell">
392
+ Use proper escaping for special characters:
393
+
394
+ ```javascript
395
+ // Use backticks for newlines in PowerShell strings
396
+ await testdriver.exec('pwsh', `
397
+ Write-Host "Line 1\`nLine 2"
398
+ `, 5000);
399
+
400
+ // Use single quotes to avoid variable expansion
401
+ await testdriver.exec('pwsh', "Write-Host 'Text with $special chars'", 5000);
402
+ ```
403
+ </Accordion>
404
+ </AccordionGroup>