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,294 @@
1
+ ---
2
+ title: "focusApplication()"
3
+ sidebarTitle: "focusApplication"
4
+ description: "Bring an application window to the foreground"
5
+ icon: "window-maximize"
6
+ ---
7
+
8
+ ## Overview
9
+
10
+ Bring a specific application window to the foreground and make it the active window for interactions.
11
+
12
+ ## Syntax
13
+
14
+ ```javascript
15
+ await testdriver.focusApplication(name)
16
+ ```
17
+
18
+ ## Parameters
19
+
20
+ <ParamField path="name" type="string" required>
21
+ Application name (e.g., `'Google Chrome'`, `'Microsoft Edge'`, `'Notepad'`)
22
+ </ParamField>
23
+
24
+ ## Returns
25
+
26
+ `Promise<string>` - Result message
27
+
28
+ ## Examples
29
+
30
+ ### Common Applications
31
+
32
+ ```javascript
33
+ // Focus Chrome browser
34
+ await testdriver.focusApplication('Google Chrome');
35
+
36
+ // Focus Edge browser
37
+ await testdriver.focusApplication('Microsoft Edge');
38
+
39
+ // Focus Notepad
40
+ await testdriver.focusApplication('Notepad');
41
+
42
+ // Focus File Explorer
43
+ await testdriver.focusApplication('File Explorer');
44
+
45
+ // Focus Visual Studio Code
46
+ await testdriver.focusApplication('Visual Studio Code');
47
+ ```
48
+
49
+ ### After Opening Applications
50
+
51
+ ```javascript
52
+ // Open Chrome and focus it
53
+ await testdriver.exec('pwsh', `
54
+ Start-Process "C:/Program Files/Google/Chrome/Application/chrome.exe" -ArgumentList "https://example.com"
55
+ `, 5000);
56
+
57
+ await new Promise(r => setTimeout(r, 2000)); // Wait for launch
58
+
59
+ // Focus the Chrome window
60
+ await testdriver.focusApplication('Google Chrome');
61
+ ```
62
+
63
+ ## Best Practices
64
+
65
+ <Check>
66
+ **Focus before UI interactions**
67
+
68
+ Always focus the target application before interacting with its UI:
69
+
70
+ ```javascript
71
+ await testdriver.focusApplication('Google Chrome');
72
+
73
+ const button = await testdriver.find('submit button');
74
+ await button.click();
75
+ ```
76
+ </Check>
77
+
78
+ <Check>
79
+ **Wait after launching apps**
80
+
81
+ Give applications time to open before focusing:
82
+
83
+ ```javascript
84
+ await testdriver.exec('pwsh', 'Start-Process notepad', 5000);
85
+ await new Promise(r => setTimeout(r, 1000)); // Wait for launch
86
+ await testdriver.focusApplication('Notepad');
87
+ ```
88
+ </Check>
89
+
90
+ <Check>
91
+ **Use exact application names**
92
+
93
+ ```javascript
94
+ // ✅ Correct
95
+ await testdriver.focusApplication('Google Chrome');
96
+
97
+ // ❌ May not work
98
+ await testdriver.focusApplication('Chrome');
99
+ await testdriver.focusApplication('chrome.exe');
100
+ ```
101
+ </Check>
102
+
103
+ <Warning>
104
+ **Application must be running**
105
+
106
+ The application must already be running. `focusApplication()` won't launch applications, only bring existing windows to the foreground.
107
+ </Warning>
108
+
109
+ ## Use Cases
110
+
111
+ <AccordionGroup>
112
+ <Accordion title="Multi-Application Testing">
113
+ ```javascript
114
+ // Test workflow across multiple apps
115
+ await testdriver.focusApplication('Google Chrome');
116
+ const data = await testdriver.remember('the order number');
117
+
118
+ await testdriver.focusApplication('Notepad');
119
+ await testdriver.type(data);
120
+ await testdriver.pressKeys(['ctrl', 's']);
121
+
122
+ await testdriver.focusApplication('Google Chrome');
123
+ const nextButton = await testdriver.find('next button');
124
+ await nextButton.click();
125
+ ```
126
+ </Accordion>
127
+
128
+ <Accordion title="Browser Switching">
129
+ ```javascript
130
+ // Compare behavior in different browsers
131
+ await testdriver.focusApplication('Google Chrome');
132
+ await testdriver.assert('page loaded correctly in Chrome');
133
+
134
+ await testdriver.focusApplication('Microsoft Edge');
135
+ await testdriver.assert('page loaded correctly in Edge');
136
+ ```
137
+ </Accordion>
138
+
139
+ <Accordion title="Desktop Application Testing">
140
+ ```javascript
141
+ // Launch and focus desktop app
142
+ await testdriver.exec('pwsh', 'Start-Process notepad', 5000);
143
+ await new Promise(r => setTimeout(r, 1000));
144
+
145
+ await testdriver.focusApplication('Notepad');
146
+ await testdriver.type('Test content');
147
+ ```
148
+ </Accordion>
149
+
150
+ <Accordion title="Window Management">
151
+ ```javascript
152
+ // Show desktop first
153
+ await testdriver.pressKeys(['winleft', 'd']);
154
+
155
+ // Click desktop icon
156
+ const icon = await testdriver.find('Chrome icon on desktop');
157
+ await icon.click();
158
+
159
+ await new Promise(r => setTimeout(r, 2000));
160
+
161
+ // Focus the opened window
162
+ await testdriver.focusApplication('Google Chrome');
163
+ ```
164
+ </Accordion>
165
+ </AccordionGroup>
166
+
167
+ ## Common Application Names
168
+
169
+ ### Browsers
170
+ - `'Google Chrome'`
171
+ - `'Microsoft Edge'`
172
+ - `'Mozilla Firefox'`
173
+ - `'Safari'` (macOS)
174
+
175
+ ### Office Applications
176
+ - `'Microsoft Word'`
177
+ - `'Microsoft Excel'`
178
+ - `'Microsoft PowerPoint'`
179
+ - `'Microsoft Outlook'`
180
+
181
+ ### Development Tools
182
+ - `'Visual Studio Code'`
183
+ - `'Visual Studio'`
184
+ - `'IntelliJ IDEA'`
185
+ - `'Sublime Text'`
186
+
187
+ ### System Applications
188
+ - `'Notepad'`
189
+ - `'File Explorer'`
190
+ - `'Command Prompt'`
191
+ - `'Windows PowerShell'`
192
+ - `'Task Manager'`
193
+
194
+ ### Communication
195
+ - `'Microsoft Teams'`
196
+ - `'Slack'`
197
+ - `'Discord'`
198
+ - `'Zoom'`
199
+
200
+ ## Complete Example
201
+
202
+ ```javascript
203
+ import { beforeAll, afterAll, describe, it } from 'vitest';
204
+ import TestDriver from 'testdriverai';
205
+
206
+ describe('Multi-Application Workflow', () => {
207
+ let testdriver;
208
+
209
+ beforeAll(async () => {
210
+ client = new TestDriver(process.env.TD_API_KEY);
211
+ await testdriver.auth();
212
+ await testdriver.connect({ newSandbox: true });
213
+ });
214
+
215
+ afterAll(async () => {
216
+ await testdriver.disconnect();
217
+ });
218
+
219
+ it('should work across multiple applications', async () => {
220
+ // Start in browser
221
+ await testdriver.focusApplication('Google Chrome');
222
+
223
+ // Get data from web page
224
+ const orderNumber = await testdriver.remember('the order number');
225
+ console.log('Order:', orderNumber);
226
+
227
+ // Open Notepad
228
+ await testdriver.exec('pwsh', 'Start-Process notepad', 5000);
229
+ await new Promise(r => setTimeout(r, 1500));
230
+
231
+ // Focus Notepad and save data
232
+ await testdriver.focusApplication('Notepad');
233
+ await testdriver.type(`Order Number: ${orderNumber}`);
234
+ await testdriver.type('\n');
235
+ await testdriver.type(`Date: ${new Date().toISOString()}`);
236
+
237
+ // Save file
238
+ await testdriver.pressKeys(['ctrl', 's']);
239
+ await new Promise(r => setTimeout(r, 500));
240
+
241
+ await testdriver.type('C:\\order-info.txt');
242
+ await testdriver.pressKeys(['enter']);
243
+
244
+ // Return to browser
245
+ await testdriver.focusApplication('Google Chrome');
246
+
247
+ const confirmButton = await testdriver.find('confirm order button');
248
+ await confirmButton.click();
249
+
250
+ await testdriver.assert('order confirmed');
251
+ });
252
+
253
+ it('should switch between browser tabs', async () => {
254
+ await testdriver.focusApplication('Google Chrome');
255
+
256
+ // Open new tab
257
+ await testdriver.pressKeys(['ctrl', 't']);
258
+ await new Promise(r => setTimeout(r, 500));
259
+
260
+ // Navigate to URL
261
+ await testdriver.pressKeys(['ctrl', 'l']);
262
+ await testdriver.type('https://example.com');
263
+ await testdriver.pressKeys(['enter']);
264
+
265
+ await new Promise(r => setTimeout(r, 2000));
266
+
267
+ // Ensure Chrome is still focused
268
+ await testdriver.focusApplication('Google Chrome');
269
+
270
+ await testdriver.assert('example.com page is loaded');
271
+ });
272
+
273
+ it('should handle dialog boxes', async () => {
274
+ await testdriver.focusApplication('Google Chrome');
275
+
276
+ const deleteButton = await testdriver.find('delete account button');
277
+ await deleteButton.click();
278
+
279
+ await new Promise(r => setTimeout(r, 500));
280
+
281
+ // Dialog appears - make sure it's focused
282
+ await testdriver.focusApplication('Google Chrome');
283
+
284
+ const confirmBtn = await testdriver.find('confirm deletion button');
285
+ await confirmBtn.click();
286
+ });
287
+ });
288
+ ```
289
+
290
+ ## Related Methods
291
+
292
+ - [`exec()`](/v7/api/exec) - Launch applications with PowerShell
293
+ - [`pressKeys()`](/v7/api/pressKeys) - Use Alt+Tab to switch windows
294
+ - [`find()`](/v7/api/find) - Locate elements in the focused window
@@ -0,0 +1,279 @@
1
+ ---
2
+ title: "hover()"
3
+ sidebarTitle: "hover"
4
+ description: "Hover over elements or coordinates"
5
+ icon: "hand-pointer"
6
+ ---
7
+
8
+ ## Overview
9
+
10
+ Move the mouse cursor over elements or specific coordinates without clicking, useful for revealing tooltips, dropdowns, and hover effects.
11
+
12
+ ## Element Hover
13
+
14
+ Hover over a located element.
15
+
16
+ ### Syntax
17
+
18
+ ```javascript
19
+ await element.hover()
20
+ ```
21
+
22
+ ### Returns
23
+
24
+ `Promise<void>`
25
+
26
+ ### Examples
27
+
28
+ ```javascript
29
+ // Find and hover
30
+ const tooltip = await testdriver.find('info icon');
31
+ await tooltip.hover();
32
+
33
+ // Wait to see tooltip
34
+ await new Promise(r => setTimeout(r, 1000));
35
+
36
+ // Hover over menu to reveal submenu
37
+ const menu = await testdriver.find('Products menu');
38
+ await menu.hover();
39
+
40
+ const submenu = await testdriver.find('Laptops submenu item');
41
+ await submenu.click();
42
+ ```
43
+
44
+ ## Coordinate Hover
45
+
46
+ Hover at specific screen coordinates.
47
+
48
+ ### Syntax
49
+
50
+ ```javascript
51
+ await testdriver.hover(x, y)
52
+ ```
53
+
54
+ ### Parameters
55
+
56
+ <ParamField path="x" type="number" required>
57
+ X coordinate
58
+ </ParamField>
59
+
60
+ <ParamField path="y" type="number" required>
61
+ Y coordinate
62
+ </ParamField>
63
+
64
+ ### Returns
65
+
66
+ `Promise<void>`
67
+
68
+ ### Examples
69
+
70
+ ```javascript
71
+ // Hover at coordinates
72
+ await testdriver.hover(500, 300);
73
+
74
+ // Hover and wait
75
+ await testdriver.hover(500, 300);
76
+ await new Promise(r => setTimeout(r, 1000));
77
+ ```
78
+
79
+ ## Best Practices
80
+
81
+ <Check>
82
+ **Prefer element hover over coordinates**
83
+
84
+ ```javascript
85
+ // ✅ Preferred
86
+ const icon = await testdriver.find('info icon');
87
+ await icon.hover();
88
+
89
+ // ❌ Avoid
90
+ await testdriver.hover(500, 300);
91
+ ```
92
+ </Check>
93
+
94
+ <Check>
95
+ **Wait after hovering for dynamic content**
96
+
97
+ ```javascript
98
+ const menuItem = await testdriver.find('Settings menu');
99
+ await menuItem.hover();
100
+
101
+ // Wait for submenu to appear
102
+ await new Promise(r => setTimeout(r, 500));
103
+
104
+ const subItem = await testdriver.find('Profile submenu');
105
+ await subItem.click();
106
+ ```
107
+ </Check>
108
+
109
+ <Check>
110
+ **Verify element was found before hovering**
111
+
112
+ ```javascript
113
+ const element = await testdriver.find('tooltip trigger');
114
+ if (!element.found()) {
115
+ throw new Error('Element not found');
116
+ }
117
+ await element.hover();
118
+ ```
119
+ </Check>
120
+
121
+ ## Use Cases
122
+
123
+ <AccordionGroup>
124
+ <Accordion title="Tooltips">
125
+ ```javascript
126
+ // Hover to show tooltip
127
+ const icon = await testdriver.find('help icon');
128
+ await icon.hover();
129
+
130
+ await new Promise(r => setTimeout(r, 1000));
131
+
132
+ // Read tooltip content
133
+ const tooltipText = await testdriver.remember('the tooltip text');
134
+ console.log('Tooltip:', tooltipText);
135
+ ```
136
+ </Accordion>
137
+
138
+ <Accordion title="Dropdown Menus">
139
+ ```javascript
140
+ // Hover to reveal dropdown
141
+ const menuItem = await testdriver.find('Products menu item');
142
+ await menuItem.hover();
143
+
144
+ // Wait for dropdown animation
145
+ await new Promise(r => setTimeout(r, 500));
146
+
147
+ // Click submenu option
148
+ const category = await testdriver.find('Electronics category');
149
+ await category.click();
150
+ ```
151
+ </Accordion>
152
+
153
+ <Accordion title="Image Previews">
154
+ ```javascript
155
+ // Hover over thumbnail to see preview
156
+ const thumbnail = await testdriver.find('product thumbnail');
157
+ await thumbnail.hover();
158
+
159
+ await new Promise(r => setTimeout(r, 800));
160
+
161
+ // Verify preview appears
162
+ await testdriver.assert('product preview is displayed');
163
+ ```
164
+ </Accordion>
165
+
166
+ <Accordion title="Hover Effects">
167
+ ```javascript
168
+ // Test hover state styling
169
+ const button = await testdriver.find('call to action button');
170
+ await button.hover();
171
+
172
+ await new Promise(r => setTimeout(r, 500));
173
+
174
+ // Verify hover effect
175
+ await testdriver.assert('button background changed to blue');
176
+ ```
177
+ </Accordion>
178
+
179
+ <Accordion title="Drag and Drop">
180
+ ```javascript
181
+ // Use hover in drag and drop
182
+ const item = await testdriver.find('draggable item');
183
+ await item.mouseDown();
184
+
185
+ // Hover over drop zone
186
+ const dropZone = await testdriver.find('drop area');
187
+ await dropZone.hover();
188
+
189
+ await new Promise(r => setTimeout(r, 300));
190
+ await dropZone.mouseUp();
191
+ ```
192
+ </Accordion>
193
+ </AccordionGroup>
194
+
195
+ ## Complete Example
196
+
197
+ ```javascript
198
+ import { beforeAll, afterAll, describe, it } from 'vitest';
199
+ import TestDriver from 'testdriverai';
200
+
201
+ describe('Hover Interactions', () => {
202
+ let testdriver;
203
+
204
+ beforeAll(async () => {
205
+ client = new TestDriver(process.env.TD_API_KEY);
206
+ await testdriver.auth();
207
+ await testdriver.connect({ newSandbox: true });
208
+ });
209
+
210
+ afterAll(async () => {
211
+ await testdriver.disconnect();
212
+ });
213
+
214
+ it('should show tooltip on hover', async () => {
215
+ await testdriver.focusApplication('Google Chrome');
216
+
217
+ // Find and hover over icon
218
+ const infoIcon = await testdriver.find('information icon');
219
+ await infoIcon.hover();
220
+
221
+ // Wait for tooltip to appear
222
+ await new Promise(r => setTimeout(r, 1000));
223
+
224
+ // Verify tooltip is visible
225
+ await testdriver.assert('tooltip is displayed');
226
+
227
+ // Extract tooltip text
228
+ const tooltipText = await testdriver.remember('the tooltip message');
229
+ console.log('Tooltip says:', tooltipText);
230
+ });
231
+
232
+ it('should navigate dropdown menu', async () => {
233
+ // Hover over main menu
234
+ const menu = await testdriver.find('Navigation menu');
235
+ await menu.hover();
236
+
237
+ // Wait for dropdown
238
+ await new Promise(r => setTimeout(r, 500));
239
+
240
+ // Hover over submenu item
241
+ const submenu = await testdriver.find('Account submenu');
242
+ await submenu.hover();
243
+
244
+ await new Promise(r => setTimeout(r, 300));
245
+
246
+ // Click nested menu item
247
+ const settings = await testdriver.find('Settings option');
248
+ await settings.click();
249
+
250
+ await testdriver.assert('settings page is displayed');
251
+ });
252
+
253
+ it('should preview images on hover', async () => {
254
+ // Hover over product image
255
+ const productImg = await testdriver.find('product 1 thumbnail');
256
+ await productImg.hover();
257
+
258
+ // Wait for preview
259
+ await new Promise(r => setTimeout(r, 800));
260
+
261
+ // Verify preview appeared
262
+ await testdriver.assert('large product preview is shown');
263
+
264
+ // Move away
265
+ const otherElement = await testdriver.find('page heading');
266
+ await otherElement.hover();
267
+
268
+ // Verify preview disappeared
269
+ await new Promise(r => setTimeout(r, 500));
270
+ await testdriver.assert('product preview is hidden');
271
+ });
272
+ });
273
+ ```
274
+
275
+ ## Related Methods
276
+
277
+ - [`find()`](/v7/api/find) - Locate elements to hover
278
+ - [`click()`](/v7/api/click) - Click after hovering
279
+ - [`mouseDown()`](/v7/api/click) - Start drag operations