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,287 @@
1
+ ---
2
+ title: "click()"
3
+ sidebarTitle: "click"
4
+ description: "Click at specific coordinates or on elements"
5
+ icon: "mouse-pointer"
6
+ ---
7
+
8
+ ## Element Click
9
+
10
+ When called on an Element object, clicks on the located element.
11
+
12
+ ### Syntax
13
+
14
+ ```javascript
15
+ await element.click(action)
16
+ ```
17
+
18
+ ### Parameters
19
+
20
+ <ParamField path="action" type="string" default="click">
21
+ Type of click action: `'click'`, `'double-click'`, `'right-click'`, `'hover'`, `'mouseDown'`, `'mouseUp'`
22
+ </ParamField>
23
+
24
+ ### Returns
25
+
26
+ `Promise<void>`
27
+
28
+ ### Examples
29
+
30
+ ```javascript
31
+ // Regular click
32
+ const button = await testdriver.find('submit button');
33
+ await button.click();
34
+
35
+ // Double-click
36
+ const file = await testdriver.find('README.txt file');
37
+ await file.click('double-click');
38
+
39
+ // Right-click
40
+ const item = await testdriver.find('menu item');
41
+ await item.click('right-click');
42
+
43
+ // Hover (same as element.hover())
44
+ const tooltip = await testdriver.find('info icon');
45
+ await button.click('hover');
46
+ ```
47
+
48
+ ## Coordinate Click
49
+
50
+ Click at specific screen coordinates.
51
+
52
+ ### Syntax
53
+
54
+ ```javascript
55
+ await testdriver.click(x, y, action)
56
+ ```
57
+
58
+ ### Parameters
59
+
60
+ <ParamField path="x" type="number" required>
61
+ X coordinate
62
+ </ParamField>
63
+
64
+ <ParamField path="y" type="number" required>
65
+ Y coordinate
66
+ </ParamField>
67
+
68
+ <ParamField path="action" type="string" default="click">
69
+ Type of click: `'click'`, `'double-click'`, `'right-click'`, `'mouseDown'`, `'mouseUp'`
70
+ </ParamField>
71
+
72
+ ### Returns
73
+
74
+ `Promise<void>`
75
+
76
+ ### Examples
77
+
78
+ ```javascript
79
+ // Click at coordinates
80
+ await testdriver.click(500, 300);
81
+
82
+ // Double-click at coordinates
83
+ await testdriver.click(500, 300, 'double-click');
84
+
85
+ // Right-click at coordinates
86
+ await testdriver.click(500, 300, 'right-click');
87
+ ```
88
+
89
+ ## Click Actions
90
+
91
+ ### Regular Click
92
+
93
+ Single left-click action.
94
+
95
+ ```javascript
96
+ const button = await testdriver.find('Login button');
97
+ await button.click();
98
+ ```
99
+
100
+ ### Double Click
101
+
102
+ Double-click action, commonly used to open files or select text.
103
+
104
+ ```javascript
105
+ const file = await testdriver.find('document.pdf');
106
+ await file.click('double-click');
107
+
108
+ // Or use the dedicated method
109
+ await file.doubleClick();
110
+ ```
111
+
112
+ ### Right Click
113
+
114
+ Right-click to open context menus.
115
+
116
+ ```javascript
117
+ const folder = await testdriver.find('Documents folder');
118
+ await folder.click('right-click');
119
+
120
+ // Or use the dedicated method
121
+ await folder.rightClick();
122
+ ```
123
+
124
+ ### Mouse Down / Mouse Up
125
+
126
+ For drag operations or custom click behavior.
127
+
128
+ ```javascript
129
+ const draggable = await testdriver.find('draggable item');
130
+ await draggable.click('mouseDown');
131
+
132
+ // Move to target
133
+ const dropZone = await testdriver.find('drop zone');
134
+ await dropZone.hover();
135
+ await dropZone.click('mouseUp');
136
+
137
+ // Or use dedicated methods
138
+ await draggable.mouseDown();
139
+ await dropZone.mouseUp();
140
+ ```
141
+
142
+ ## Best Practices
143
+
144
+ <Check>
145
+ **Prefer element clicks over coordinate clicks**
146
+
147
+ Element-based clicking is more reliable and resolution-independent:
148
+
149
+ ```javascript
150
+ // ✅ Preferred
151
+ const button = await testdriver.find('submit button');
152
+ await button.click();
153
+
154
+ // ❌ Avoid (fragile)
155
+ await testdriver.click(500, 300);
156
+ ```
157
+ </Check>
158
+
159
+ <Check>
160
+ **Verify element was found**
161
+
162
+ ```javascript
163
+ const element = await testdriver.find('button');
164
+ if (!element.found()) {
165
+ throw new Error('Element not found');
166
+ }
167
+ await element.click();
168
+ ```
169
+ </Check>
170
+
171
+ <Warning>
172
+ **Element must be found before clicking**
173
+
174
+ The `find()` method automatically locates elements, but clicking an element that wasn't found will throw an error:
175
+
176
+ ```javascript
177
+ const element = await testdriver.find('button');
178
+ // This will throw if element wasn't found
179
+ await element.click();
180
+ ```
181
+ </Warning>
182
+
183
+ ## Use Cases
184
+
185
+ <AccordionGroup>
186
+ <Accordion title="Button Clicks">
187
+ ```javascript
188
+ const submitBtn = await testdriver.find('submit button');
189
+ await submitBtn.click();
190
+
191
+ const cancelBtn = await testdriver.find('cancel button');
192
+ await cancelBtn.click();
193
+ ```
194
+ </Accordion>
195
+
196
+ <Accordion title="Opening Files">
197
+ ```javascript
198
+ const file = await testdriver.find('report.pdf file icon');
199
+ await file.doubleClick();
200
+ ```
201
+ </Accordion>
202
+
203
+ <Accordion title="Context Menus">
204
+ ```javascript
205
+ const item = await testdriver.find('file item');
206
+ await item.rightClick();
207
+
208
+ // Select menu option
209
+ const deleteOption = await testdriver.find('Delete option');
210
+ await deleteOption.click();
211
+ ```
212
+ </Accordion>
213
+
214
+ <Accordion title="Drag and Drop">
215
+ ```javascript
216
+ const source = await testdriver.find('source item');
217
+ await source.mouseDown();
218
+
219
+ const target = await testdriver.find('target zone');
220
+ await target.hover();
221
+ await target.mouseUp();
222
+ ```
223
+ </Accordion>
224
+ </AccordionGroup>
225
+
226
+ ## Complete Example
227
+
228
+ ```javascript
229
+ import { beforeAll, afterAll, describe, it } from 'vitest';
230
+ import TestDriver from 'testdriverai';
231
+
232
+ describe('Click Interactions', () => {
233
+ let testdriver;
234
+
235
+ beforeAll(async () => {
236
+ client = new TestDriver(process.env.TD_API_KEY);
237
+ await testdriver.auth();
238
+ await testdriver.connect({ newSandbox: true });
239
+ });
240
+
241
+ afterAll(async () => {
242
+ await testdriver.disconnect();
243
+ });
244
+
245
+ it('should perform various click actions', async () => {
246
+ await testdriver.focusApplication('Google Chrome');
247
+
248
+ // Regular click
249
+ const loginBtn = await testdriver.find('login button');
250
+ await loginBtn.click();
251
+
252
+ // Right-click for context menu
253
+ const profileIcon = await testdriver.find('profile icon');
254
+ await profileIcon.rightClick();
255
+
256
+ const settingsOption = await testdriver.find('Settings menu option');
257
+ await settingsOption.click();
258
+
259
+ // Double-click to edit
260
+ const nameField = await testdriver.find('name display field');
261
+ await nameField.doubleClick();
262
+
263
+ // Verify state
264
+ await testdriver.assert('name field is now editable');
265
+ });
266
+
267
+ it('should perform drag and drop', async () => {
268
+ const item = await testdriver.find('draggable item');
269
+ await item.mouseDown();
270
+
271
+ // Drag to new location
272
+ const dropTarget = await testdriver.find('drop area');
273
+ await dropTarget.hover();
274
+ await dropTarget.mouseUp();
275
+
276
+ // Verify
277
+ await testdriver.assert('item is in the drop area');
278
+ });
279
+ });
280
+ ```
281
+
282
+ ## Related Methods
283
+
284
+ - [`find()`](/v7/api/find) - Locate elements to click
285
+ - [`hover()`](/v7/api/hover) - Hover without clicking
286
+ - [`doubleClick()`](/v7/api/doubleClick) - Dedicated double-click method
287
+ - [`rightClick()`](/v7/api/rightClick) - Dedicated right-click method
@@ -0,0 +1,322 @@
1
+ ---
2
+ title: "TestDriver Client"
3
+ sidebarTitle: "Client"
4
+ description: "Initialize and configure the TestDriver SDK client"
5
+ icon: "plug"
6
+ ---
7
+
8
+ ## Overview
9
+
10
+ The `TestDriver` client is the main entry point for the SDK. It handles authentication, sandbox connection, and provides access to all testing methods.
11
+
12
+ ## Constructor
13
+
14
+ ```javascript
15
+ const testdriver = new TestDriver(apiKey, options)
16
+ ```
17
+
18
+ ### Parameters
19
+
20
+ <ParamField path="apiKey" type="string" required>
21
+ Your TestDriver API key from the [dashboard](https://app.testdriver.ai/team)
22
+ </ParamField>
23
+
24
+ <ParamField path="options" type="object">
25
+ Configuration options for the client
26
+
27
+ <Expandable title="properties">
28
+ <ParamField path="os" type="string" default="windows">
29
+ Operating system for the sandbox: `'windows'` or `'linux'`
30
+ </ParamField>
31
+
32
+ <ParamField path="resolution" type="string" default="1366x768">
33
+ Screen resolution for the sandbox (e.g., `'1920x1080'`, `'1366x768'`)
34
+ </ParamField>
35
+
36
+ <ParamField path="apiRoot" type="string" default="https://testdriver-api.onrender.com">
37
+ API endpoint URL (typically only changed for self-hosted deployments)
38
+ </ParamField>
39
+
40
+ <ParamField path="analytics" type="boolean" default="true">
41
+ Enable or disable usage analytics
42
+ </ParamField>
43
+
44
+ <ParamField path="logging" type="boolean" default="true">
45
+ Enable or disable console logging
46
+ </ParamField>
47
+
48
+ <ParamField path="environment" type="object">
49
+ Additional environment variables to pass to the sandbox
50
+ </ParamField>
51
+ </Expandable>
52
+ </ParamField>
53
+
54
+ ### Example
55
+
56
+ ```javascript
57
+ import TestDriver from 'testdriverai';
58
+
59
+ const testdriver = new TestDriver(process.env.TD_API_KEY, {
60
+ os: 'windows',
61
+ resolution: '1920x1080',
62
+ logging: true,
63
+ analytics: true
64
+ });
65
+ ```
66
+
67
+ ## Authentication
68
+
69
+ ### auth()
70
+
71
+ Authenticate with the TestDriver API.
72
+
73
+ ```javascript
74
+ await testdriver.auth()
75
+ ```
76
+
77
+ **Returns:** `Promise<string>` - Authentication token
78
+
79
+ **Example:**
80
+ ```javascript
81
+ await testdriver.auth();
82
+ ```
83
+
84
+ <Note>
85
+ You must call `auth()` before `connect()`. Most examples call both sequentially.
86
+ </Note>
87
+
88
+ ## Connection Management
89
+
90
+ ### connect()
91
+
92
+ Connect to a sandbox environment. This creates or reconnects to a virtual machine where your tests will run.
93
+
94
+ ```javascript
95
+ await testdriver.connect(options)
96
+ ```
97
+
98
+ #### Parameters
99
+
100
+ <ParamField path="options" type="object">
101
+ Connection options
102
+
103
+ <Expandable title="properties">
104
+ <ParamField path="newSandbox" type="boolean" default="false">
105
+ Force creation of a new sandbox instead of reusing an existing one
106
+ </ParamField>
107
+
108
+ <ParamField path="sandboxId" type="string">
109
+ Existing sandbox ID to reconnect to
110
+ </ParamField>
111
+
112
+ <ParamField path="ip" type="string">
113
+ Direct IP address to connect to (for self-hosted sandboxes)
114
+ </ParamField>
115
+
116
+ <ParamField path="sandboxAmi" type="string">
117
+ AMI to use for the sandbox (AWS deployments)
118
+ </ParamField>
119
+
120
+ <ParamField path="sandboxInstance" type="string">
121
+ Instance type for the sandbox (AWS deployments)
122
+ </ParamField>
123
+
124
+ <ParamField path="headless" type="boolean" default="false">
125
+ Run in headless mode without opening the debugger
126
+ </ParamField>
127
+ </Expandable>
128
+ </ParamField>
129
+
130
+ **Returns:** `Promise<Object>` - Sandbox instance details including `instanceId`, `ip`, `vncPort`, etc.
131
+
132
+ #### Examples
133
+
134
+ **Basic connection:**
135
+ ```javascript
136
+ await testdriver.connect({ newSandbox: true });
137
+ ```
138
+
139
+ **Reconnect to existing sandbox:**
140
+ ```javascript
141
+ const instance = await testdriver.connect({
142
+ sandboxId: 'existing-sandbox-id-123'
143
+ });
144
+ ```
145
+
146
+ **Self-hosted sandbox:**
147
+ ```javascript
148
+ await testdriver.connect({
149
+ ip: '192.168.1.100'
150
+ });
151
+ ```
152
+
153
+ ### disconnect()
154
+
155
+ Disconnect from the sandbox and clean up resources.
156
+
157
+ ```javascript
158
+ await testdriver.disconnect()
159
+ ```
160
+
161
+ **Returns:** `Promise<void>`
162
+
163
+ **Example:**
164
+ ```javascript
165
+ afterAll(async () => {
166
+ await testdriver.disconnect();
167
+ });
168
+ ```
169
+
170
+ ## Instance Information
171
+
172
+ ### getInstance()
173
+
174
+ Get the current sandbox instance details.
175
+
176
+ ```javascript
177
+ const instance = testdriver.getInstance()
178
+ ```
179
+
180
+ **Returns:** `Object | null` - Sandbox instance information
181
+
182
+ **Example:**
183
+ ```javascript
184
+ const instance = testdriver.getInstance();
185
+ console.log('Instance ID:', instance.instanceId);
186
+ console.log('IP Address:', instance.ip);
187
+ ```
188
+
189
+ ### getSessionId()
190
+
191
+ Get the current session ID for tracking and debugging.
192
+
193
+ ```javascript
194
+ const sessionId = testdriver.getSessionId()
195
+ ```
196
+
197
+ **Returns:** `string | null` - Session ID
198
+
199
+ **Example:**
200
+ ```javascript
201
+ const sessionId = testdriver.getSessionId();
202
+ console.log('Session:', sessionId);
203
+ ```
204
+
205
+ ## Logging & Events
206
+
207
+ ### setLogging()
208
+
209
+ Enable or disable console logging at runtime.
210
+
211
+ ```javascript
212
+ testdriver.setLogging(enabled)
213
+ ```
214
+
215
+ **Parameters:**
216
+ - `enabled` (boolean) - Whether to enable logging
217
+
218
+ **Example:**
219
+ ```javascript
220
+ // Disable logging for cleanup operations
221
+ testdriver.setLogging(false);
222
+ await testdriver.disconnect();
223
+ testdriver.setLogging(true);
224
+ ```
225
+
226
+ ### getEmitter()
227
+
228
+ Get the event emitter for custom event handling.
229
+
230
+ ```javascript
231
+ const emitter = testdriver.getEmitter()
232
+ ```
233
+
234
+ **Returns:** `EventEmitter2` - Event emitter instance
235
+
236
+ **Example:**
237
+ ```javascript
238
+ const emitter = testdriver.getEmitter();
239
+
240
+ emitter.on('command:start', (data) => {
241
+ console.log('Command started:', data);
242
+ });
243
+
244
+ emitter.on('command:success', (data) => {
245
+ console.log('Command succeeded:', data);
246
+ });
247
+
248
+ emitter.on('command:error', (error) => {
249
+ console.error('Command failed:', error);
250
+ });
251
+ ```
252
+
253
+ ## Complete Example
254
+
255
+ ```javascript
256
+ import { beforeAll, afterAll, describe, it } from 'vitest';
257
+ import TestDriver from 'testdriverai';
258
+
259
+ describe('My Test Suite', () => {
260
+ let testdriver;
261
+
262
+ beforeAll(async () => {
263
+ // Initialize client
264
+ client = new TestDriver(process.env.TD_API_KEY, {
265
+ os: 'windows',
266
+ resolution: '1366x768',
267
+ logging: true
268
+ });
269
+
270
+ // Set up event listeners
271
+ const emitter = testdriver.getEmitter();
272
+ emitter.on('log:info', (msg) => console.log('[INFO]', msg));
273
+
274
+ // Authenticate and connect
275
+ await testdriver.auth();
276
+ const instance = await testdriver.connect({ newSandbox: true });
277
+
278
+ console.log('Connected to sandbox:', instance.instanceId);
279
+ });
280
+
281
+ afterAll(async () => {
282
+ await testdriver.disconnect();
283
+ });
284
+
285
+ it('runs a test', async () => {
286
+ // Your test code here
287
+ });
288
+ });
289
+ ```
290
+
291
+ ## Best Practices
292
+
293
+ <AccordionGroup>
294
+ <Accordion title="Reuse sandboxes across tests">
295
+ Use `beforeAll`/`afterAll` to create one sandbox per test suite rather than per test. This significantly reduces execution time.
296
+ </Accordion>
297
+
298
+ <Accordion title="Handle connection errors gracefully">
299
+ Wrap `connect()` in a try-catch block to handle network issues or quota limits:
300
+
301
+ ```javascript
302
+ try {
303
+ await testdriver.connect({ newSandbox: true });
304
+ } catch (error) {
305
+ console.error('Failed to connect:', error.message);
306
+ throw error;
307
+ }
308
+ ```
309
+ </Accordion>
310
+
311
+ <Accordion title="Always disconnect">
312
+ Use `afterAll` or try-finally blocks to ensure `disconnect()` is called even if tests fail. This prevents orphaned sandboxes.
313
+ </Accordion>
314
+
315
+ <Accordion title="Use environment variables for API keys">
316
+ Never hardcode API keys. Use environment variables:
317
+
318
+ ```javascript
319
+ const testdriver = new TestDriver(process.env.TD_API_KEY);
320
+ ```
321
+ </Accordion>
322
+ </AccordionGroup>