@testdriverai/agent 7.8.0-test.38

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 (528) hide show
  1. package/.claude/settings.local.json +7 -0
  2. package/.env.example +4 -0
  3. package/.prettierignore +4 -0
  4. package/.prettierrc +1 -0
  5. package/CHANGELOG.md +953 -0
  6. package/README.md +81 -0
  7. package/agent/events.js +135 -0
  8. package/agent/index.js +2450 -0
  9. package/agent/interface.js +35 -0
  10. package/agent/lib/analytics.js +22 -0
  11. package/agent/lib/censorship.js +75 -0
  12. package/agent/lib/commander.js +246 -0
  13. package/agent/lib/commands.js +1684 -0
  14. package/agent/lib/config.js +60 -0
  15. package/agent/lib/generator.js +91 -0
  16. package/agent/lib/http.js +144 -0
  17. package/agent/lib/logger.js +56 -0
  18. package/agent/lib/outputs.js +29 -0
  19. package/agent/lib/parser.js +209 -0
  20. package/agent/lib/redraw.js +386 -0
  21. package/agent/lib/resources/cursor-2.png +0 -0
  22. package/agent/lib/sandbox.js +1104 -0
  23. package/agent/lib/sdk.js +633 -0
  24. package/agent/lib/session.js +25 -0
  25. package/agent/lib/source-mapper.js +342 -0
  26. package/agent/lib/subimage/index.js +77 -0
  27. package/agent/lib/subimage/opencv.js +69 -0
  28. package/agent/lib/system.js +204 -0
  29. package/agent/lib/theme.js +14 -0
  30. package/agent/lib/valid-version.js +21 -0
  31. package/agent/lib/validation.js +169 -0
  32. package/ai/.claude-plugin/plugin.json +9 -0
  33. package/ai/agents/testdriver.md +638 -0
  34. package/ai/skills/testdriver-ai/SKILL.md +204 -0
  35. package/ai/skills/testdriver-assert/SKILL.md +315 -0
  36. package/ai/skills/testdriver-aws-setup/SKILL.md +448 -0
  37. package/ai/skills/testdriver-cache/SKILL.md +221 -0
  38. package/ai/skills/testdriver-caching/SKILL.md +124 -0
  39. package/ai/skills/testdriver-captcha/SKILL.md +158 -0
  40. package/ai/skills/testdriver-ci-cd/SKILL.md +602 -0
  41. package/ai/skills/testdriver-click/SKILL.md +286 -0
  42. package/ai/skills/testdriver-client/SKILL.md +477 -0
  43. package/ai/skills/testdriver-cloud/SKILL.md +119 -0
  44. package/ai/skills/testdriver-customizing-devices/SKILL.md +319 -0
  45. package/ai/skills/testdriver-dashcam/SKILL.md +418 -0
  46. package/ai/skills/testdriver-debugging-with-screenshots/SKILL.md +401 -0
  47. package/ai/skills/testdriver-device-config/SKILL.md +317 -0
  48. package/ai/skills/testdriver-double-click/SKILL.md +102 -0
  49. package/ai/skills/testdriver-elements/SKILL.md +605 -0
  50. package/ai/skills/testdriver-enterprise/SKILL.md +114 -0
  51. package/ai/skills/testdriver-errors/SKILL.md +246 -0
  52. package/ai/skills/testdriver-events/SKILL.md +356 -0
  53. package/ai/skills/testdriver-examples/SKILL.md +7 -0
  54. package/ai/skills/testdriver-exec/SKILL.md +317 -0
  55. package/ai/skills/testdriver-find/SKILL.md +829 -0
  56. package/ai/skills/testdriver-focus-application/SKILL.md +293 -0
  57. package/ai/skills/testdriver-generating-tests/SKILL.md +36 -0
  58. package/ai/skills/testdriver-hover/SKILL.md +278 -0
  59. package/ai/skills/testdriver-locating-elements/SKILL.md +71 -0
  60. package/ai/skills/testdriver-making-assertions/SKILL.md +32 -0
  61. package/ai/skills/testdriver-mcp/SKILL.md +7 -0
  62. package/ai/skills/testdriver-mcp-workflow/SKILL.md +410 -0
  63. package/ai/skills/testdriver-mouse-down/SKILL.md +161 -0
  64. package/ai/skills/testdriver-mouse-up/SKILL.md +164 -0
  65. package/ai/skills/testdriver-parse/SKILL.md +236 -0
  66. package/ai/skills/testdriver-performing-actions/SKILL.md +54 -0
  67. package/ai/skills/testdriver-press-keys/SKILL.md +348 -0
  68. package/ai/skills/testdriver-provision/SKILL.md +331 -0
  69. package/ai/skills/testdriver-quickstart/SKILL.md +144 -0
  70. package/ai/skills/testdriver-redraw/SKILL.md +214 -0
  71. package/ai/skills/testdriver-reusable-code/SKILL.md +249 -0
  72. package/ai/skills/testdriver-right-click/SKILL.md +123 -0
  73. package/ai/skills/testdriver-running-tests/SKILL.md +185 -0
  74. package/ai/skills/testdriver-screenshot/SKILL.md +248 -0
  75. package/ai/skills/testdriver-screenshots/SKILL.md +184 -0
  76. package/ai/skills/testdriver-scroll/SKILL.md +335 -0
  77. package/ai/skills/testdriver-secrets/SKILL.md +115 -0
  78. package/ai/skills/testdriver-self-hosted/SKILL.md +65 -0
  79. package/ai/skills/testdriver-test-writer/SKILL.md +448 -0
  80. package/ai/skills/testdriver-testdriver/SKILL.md +628 -0
  81. package/ai/skills/testdriver-testdriver-mechanic/SKILL.md +165 -0
  82. package/ai/skills/testdriver-type/SKILL.md +357 -0
  83. package/ai/skills/testdriver-variables/SKILL.md +111 -0
  84. package/ai/skills/testdriver-wait/SKILL.md +50 -0
  85. package/ai/skills/testdriver-waiting-for-elements/SKILL.md +90 -0
  86. package/ai/skills/testdriver-what-is-testdriver/SKILL.md +54 -0
  87. package/bin/testdriverai.js +22 -0
  88. package/debugger/bg.png +0 -0
  89. package/debugger/icon.png +0 -0
  90. package/debugger/index.html +469 -0
  91. package/debugger/td.png +0 -0
  92. package/debugger/tray-buffered.png +0 -0
  93. package/debugger/tray.png +0 -0
  94. package/docs/GITHUB_COMMENTS.md +330 -0
  95. package/docs/GITHUB_COMMENTS_ANNOUNCEMENT.md +167 -0
  96. package/docs/QUICK-START-GITHUB-COMMENTS.md +84 -0
  97. package/docs/TEST-GITHUB-COMMENTS.md +129 -0
  98. package/docs/_data/examples-manifest.json +177 -0
  99. package/docs/_data/examples-manifest.schema.json +41 -0
  100. package/docs/_scripts/extract-example-urls.js +165 -0
  101. package/docs/_scripts/generate-examples.js +560 -0
  102. package/docs/_scripts/generate-skills.js +154 -0
  103. package/docs/_scripts/link-replacer.js +164 -0
  104. package/docs/_scripts/upload-docs-to-openai.js +284 -0
  105. package/docs/changelog.mdx +161 -0
  106. package/docs/claude-mcp-plugin.mdx +160 -0
  107. package/docs/docs.json +442 -0
  108. package/docs/github-integration-setup.md +266 -0
  109. package/docs/guide/best-practices-polling.mdx +174 -0
  110. package/docs/images/content/account/newprojectsettings.png +0 -0
  111. package/docs/images/content/account/projectpage.png +0 -0
  112. package/docs/images/content/account/projectreplays.png +0 -0
  113. package/docs/images/content/account/team-manage.png +0 -0
  114. package/docs/images/content/account/teampage.png +0 -0
  115. package/docs/images/content/extension/cursor.svg +1 -0
  116. package/docs/images/content/extension/vscode.svg +57 -0
  117. package/docs/images/content/extension/windsurf.svg +3 -0
  118. package/docs/images/content/parse/output.png +0 -0
  119. package/docs/images/content/self-hosted/launchtemplateid.png +0 -0
  120. package/docs/images/content/side-by-side.png +0 -0
  121. package/docs/images/content/vscode/ide-full.png +0 -0
  122. package/docs/images/content/vscode/running.png +0 -0
  123. package/docs/images/content/vscode/v7-chat.png +0 -0
  124. package/docs/images/content/vscode/v7-choose-agent.png +0 -0
  125. package/docs/images/content/vscode/v7-full.png +0 -0
  126. package/docs/images/content/vscode/v7-onboarding.png +0 -0
  127. package/docs/images/content/vscode/vscode-2-assert.png +0 -0
  128. package/docs/images/content/vscode/vscode-agent-preview.png +0 -0
  129. package/docs/images/content/vscode/vscode-copilot-ask.png +0 -0
  130. package/docs/images/content/vscode/vscode-file-creation.png +0 -0
  131. package/docs/images/content/vscode/vscode-install.png +0 -0
  132. package/docs/images/content/vscode/vscode-overview.png +0 -0
  133. package/docs/images/content/vscode/vscode-setup-walkthrough.png +0 -0
  134. package/docs/images/content/vscode/vscode-stopchat.png +0 -0
  135. package/docs/images/content/vscode/vscode-stoptest.png +0 -0
  136. package/docs/images/content/vscode/vscode-tdservice.png +0 -0
  137. package/docs/images/content/vscode/vscode-test-output.png +0 -0
  138. package/docs/images/content/vscode/vscode-testhistory.png +0 -0
  139. package/docs/images/content/vscode/vscode-testpane-runtests.png +0 -0
  140. package/docs/images/content/vscode/vscode-testpane.png +0 -0
  141. package/docs/images/template/dark.png +0 -0
  142. package/docs/images/template/icon.png +0 -0
  143. package/docs/images/template/light.png +0 -0
  144. package/docs/snippets/calendar-link.mdx +4 -0
  145. package/docs/snippets/gitignore-warning.mdx +7 -0
  146. package/docs/snippets/lifecycle-warning.mdx +6 -0
  147. package/docs/snippets/test-prereqs.mdx +12 -0
  148. package/docs/snippets/tests/assert-replay.mdx +7 -0
  149. package/docs/snippets/tests/assert-yaml.mdx +8 -0
  150. package/docs/snippets/tests/exec-js-replay.mdx +7 -0
  151. package/docs/snippets/tests/exec-js-yaml.mdx +32 -0
  152. package/docs/snippets/tests/exec-shell-replay.mdx +7 -0
  153. package/docs/snippets/tests/exec-shell-yaml.mdx +15 -0
  154. package/docs/snippets/tests/hover-image-replay.mdx +7 -0
  155. package/docs/snippets/tests/hover-image-yaml.mdx +17 -0
  156. package/docs/snippets/tests/hover-text-replay.mdx +7 -0
  157. package/docs/snippets/tests/hover-text-with-description-replay.mdx +7 -0
  158. package/docs/snippets/tests/hover-text-with-description-yaml.mdx +24 -0
  159. package/docs/snippets/tests/hover-text-yaml.mdx +14 -0
  160. package/docs/snippets/tests/match-image-replay.mdx +7 -0
  161. package/docs/snippets/tests/match-image-yaml.mdx +17 -0
  162. package/docs/snippets/tests/press-keys-replay.mdx +7 -0
  163. package/docs/snippets/tests/press-keys-yaml.mdx +36 -0
  164. package/docs/snippets/tests/remember-replay.mdx +7 -0
  165. package/docs/snippets/tests/remember-yaml.mdx +28 -0
  166. package/docs/snippets/tests/scroll-replay.mdx +7 -0
  167. package/docs/snippets/tests/scroll-until-image-replay.mdx +7 -0
  168. package/docs/snippets/tests/scroll-until-image-yaml.mdx +14 -0
  169. package/docs/snippets/tests/scroll-until-text-replay.mdx +7 -0
  170. package/docs/snippets/tests/scroll-until-text-yaml.mdx +17 -0
  171. package/docs/snippets/tests/scroll-yaml.mdx +30 -0
  172. package/docs/snippets/tests/type-repeated-replay.mdx +7 -0
  173. package/docs/snippets/tests/type-repeated-yaml.mdx +22 -0
  174. package/docs/snippets/tests/type-replay.mdx +7 -0
  175. package/docs/snippets/tests/type-yaml.mdx +28 -0
  176. package/docs/snippets/tests/wait-for-image-replay.mdx +7 -0
  177. package/docs/snippets/tests/wait-for-image-yaml.mdx +18 -0
  178. package/docs/snippets/tests/wait-for-text-replay.mdx +7 -0
  179. package/docs/snippets/tests/wait-for-text-yaml.mdx +18 -0
  180. package/docs/snippets/tests/wait-replay.mdx +7 -0
  181. package/docs/snippets/tests/wait-yaml.mdx +13 -0
  182. package/docs/styles.css +65 -0
  183. package/docs/v6/account/dashboard.mdx +16 -0
  184. package/docs/v6/account/enterprise.mdx +110 -0
  185. package/docs/v6/account/pricing.mdx +33 -0
  186. package/docs/v6/account/projects.mdx +33 -0
  187. package/docs/v6/account/team.mdx +35 -0
  188. package/docs/v6/action/ami.mdx +109 -0
  189. package/docs/v6/action/performance.mdx +105 -0
  190. package/docs/v6/action/secrets.mdx +93 -0
  191. package/docs/v6/apps/chrome-extensions.mdx +48 -0
  192. package/docs/v6/apps/desktop-apps.mdx +93 -0
  193. package/docs/v6/apps/mobile-apps.mdx +26 -0
  194. package/docs/v6/apps/static-websites.mdx +54 -0
  195. package/docs/v6/apps/tauri-apps.mdx +361 -0
  196. package/docs/v6/bugs/jira.mdx +232 -0
  197. package/docs/v6/cli/overview.mdx +66 -0
  198. package/docs/v6/commands/assert.mdx +45 -0
  199. package/docs/v6/commands/exec.mdx +276 -0
  200. package/docs/v6/commands/focus-application.mdx +44 -0
  201. package/docs/v6/commands/hover-image.mdx +69 -0
  202. package/docs/v6/commands/hover-text.mdx +47 -0
  203. package/docs/v6/commands/if.mdx +53 -0
  204. package/docs/v6/commands/match-image.mdx +67 -0
  205. package/docs/v6/commands/press-keys.mdx +87 -0
  206. package/docs/v6/commands/remember.mdx +49 -0
  207. package/docs/v6/commands/run.mdx +44 -0
  208. package/docs/v6/commands/scroll-until-image.mdx +66 -0
  209. package/docs/v6/commands/scroll-until-text.mdx +60 -0
  210. package/docs/v6/commands/scroll.mdx +69 -0
  211. package/docs/v6/commands/type.mdx +45 -0
  212. package/docs/v6/commands/wait-for-image.mdx +54 -0
  213. package/docs/v6/commands/wait-for-text.mdx +48 -0
  214. package/docs/v6/commands/wait.mdx +45 -0
  215. package/docs/v6/exporting/junit.mdx +218 -0
  216. package/docs/v6/exporting/playwright.mdx +197 -0
  217. package/docs/v6/features/auto-healing.mdx +144 -0
  218. package/docs/v6/features/generation.mdx +116 -0
  219. package/docs/v6/features/parallel-testing.mdx +151 -0
  220. package/docs/v6/features/reusable-snippets.mdx +131 -0
  221. package/docs/v6/features/selectorless.mdx +80 -0
  222. package/docs/v6/features/visual-assertions.mdx +139 -0
  223. package/docs/v6/getting-started/ci.mdx +146 -0
  224. package/docs/v6/getting-started/cli.mdx +91 -0
  225. package/docs/v6/getting-started/editing.mdx +100 -0
  226. package/docs/v6/getting-started/playwright.mdx +342 -0
  227. package/docs/v6/getting-started/running.mdx +48 -0
  228. package/docs/v6/getting-started/self-hosting.mdx +408 -0
  229. package/docs/v6/getting-started/vscode.mdx +88 -0
  230. package/docs/v6/guide/assertions.mdx +189 -0
  231. package/docs/v6/guide/authentication.mdx +136 -0
  232. package/docs/v6/guide/code.mdx +65 -0
  233. package/docs/v6/guide/dashcam.mdx +118 -0
  234. package/docs/v6/guide/environment-variables.mdx +26 -0
  235. package/docs/v6/guide/lifecycle.mdx +242 -0
  236. package/docs/v6/guide/locating.mdx +141 -0
  237. package/docs/v6/guide/protips.mdx +43 -0
  238. package/docs/v6/guide/variables.mdx +143 -0
  239. package/docs/v6/guide/waiting.mdx +130 -0
  240. package/docs/v6/importing/csv.mdx +196 -0
  241. package/docs/v6/importing/gherkin.mdx +143 -0
  242. package/docs/v6/importing/jira.mdx +164 -0
  243. package/docs/v6/importing/testrail.mdx +162 -0
  244. package/docs/v6/integrations/electron.mdx +146 -0
  245. package/docs/v6/integrations/netlify.mdx +100 -0
  246. package/docs/v6/integrations/vercel.mdx +125 -0
  247. package/docs/v6/interactive/explore.mdx +99 -0
  248. package/docs/v6/interactive/run.mdx +52 -0
  249. package/docs/v6/interactive/save.mdx +63 -0
  250. package/docs/v6/overview/comparison.mdx +101 -0
  251. package/docs/v6/overview/faq.mdx +162 -0
  252. package/docs/v6/overview/performance.mdx +52 -0
  253. package/docs/v6/overview/quickstart.mdx +137 -0
  254. package/docs/v6/overview/what-is-testdriver.mdx +85 -0
  255. package/docs/v6/scenarios/ai-chatbot.mdx +28 -0
  256. package/docs/v6/scenarios/cookie-banner.mdx +32 -0
  257. package/docs/v6/scenarios/file-upload.mdx +33 -0
  258. package/docs/v6/scenarios/form-filling.mdx +32 -0
  259. package/docs/v6/scenarios/log-in.mdx +75 -0
  260. package/docs/v6/scenarios/pdf-generation.mdx +25 -0
  261. package/docs/v6/scenarios/spell-check.mdx +22 -0
  262. package/docs/v6/security/action.mdx +84 -0
  263. package/docs/v6/security/agent.mdx +73 -0
  264. package/docs/v6/security/platform.mdx +77 -0
  265. package/docs/v6/tutorials/advanced-test.mdx +81 -0
  266. package/docs/v6/tutorials/basic-test.mdx +45 -0
  267. package/docs/v7/_drafts/agents.mdx +843 -0
  268. package/docs/v7/_drafts/architecture.mdx +399 -0
  269. package/docs/v7/_drafts/auto-cache-key.mdx +167 -0
  270. package/docs/v7/_drafts/awesome-logs-quick-ref.mdx +100 -0
  271. package/docs/v7/_drafts/best-practices.mdx +486 -0
  272. package/docs/v7/_drafts/caching-ai.mdx +215 -0
  273. package/docs/v7/_drafts/caching-selectors.mdx +424 -0
  274. package/docs/v7/_drafts/caching.mdx +366 -0
  275. package/docs/v7/_drafts/cli-to-sdk-migration.mdx +425 -0
  276. package/docs/v7/_drafts/commands/assert.mdx +45 -0
  277. package/docs/v7/_drafts/commands/exec.mdx +276 -0
  278. package/docs/v7/_drafts/commands/focus-application.mdx +44 -0
  279. package/docs/v7/_drafts/commands/hover-image.mdx +69 -0
  280. package/docs/v7/_drafts/commands/hover-text.mdx +47 -0
  281. package/docs/v7/_drafts/commands/if.mdx +53 -0
  282. package/docs/v7/_drafts/commands/match-image.mdx +67 -0
  283. package/docs/v7/_drafts/commands/press-keys.mdx +87 -0
  284. package/docs/v7/_drafts/commands/remember.mdx +49 -0
  285. package/docs/v7/_drafts/commands/run.mdx +44 -0
  286. package/docs/v7/_drafts/commands/scroll-until-image.mdx +66 -0
  287. package/docs/v7/_drafts/commands/scroll-until-text.mdx +60 -0
  288. package/docs/v7/_drafts/commands/scroll.mdx +69 -0
  289. package/docs/v7/_drafts/commands/type.mdx +45 -0
  290. package/docs/v7/_drafts/commands/wait-for-image.mdx +54 -0
  291. package/docs/v7/_drafts/commands/wait-for-text.mdx +48 -0
  292. package/docs/v7/_drafts/commands/wait.mdx +45 -0
  293. package/docs/v7/_drafts/configuration.mdx +378 -0
  294. package/docs/v7/_drafts/contributing.mdx +174 -0
  295. package/docs/v7/_drafts/core.mdx +458 -0
  296. package/docs/v7/_drafts/dashcam-title-feature.mdx +89 -0
  297. package/docs/v7/_drafts/debugging.mdx +349 -0
  298. package/docs/v7/_drafts/error-handling.mdx +501 -0
  299. package/docs/v7/_drafts/faq.mdx +393 -0
  300. package/docs/v7/_drafts/hooks.mdx +360 -0
  301. package/docs/v7/_drafts/init-command.mdx +95 -0
  302. package/docs/v7/_drafts/installation.mdx +420 -0
  303. package/docs/v7/_drafts/migration.mdx +562 -0
  304. package/docs/v7/_drafts/observable.mdx +604 -0
  305. package/docs/v7/_drafts/playwright.mdx +342 -0
  306. package/docs/v7/_drafts/plugin-migration.mdx +220 -0
  307. package/docs/v7/_drafts/powerful.mdx +419 -0
  308. package/docs/v7/_drafts/presets.mdx +210 -0
  309. package/docs/v7/_drafts/progressive-disclosure.mdx +230 -0
  310. package/docs/v7/_drafts/prompt-cache.mdx +200 -0
  311. package/docs/v7/_drafts/provision.mdx +390 -0
  312. package/docs/v7/_drafts/quick-start-test-recording.mdx +214 -0
  313. package/docs/v7/_drafts/readme.mdx +135 -0
  314. package/docs/v7/_drafts/reports.mdx +414 -0
  315. package/docs/v7/_drafts/scalable.mdx +763 -0
  316. package/docs/v7/_drafts/screenshot.mdx +155 -0
  317. package/docs/v7/_drafts/sdk-awesome-logs.mdx +468 -0
  318. package/docs/v7/_drafts/sdk-browser-rendering.mdx +167 -0
  319. package/docs/v7/_drafts/sdk-migration.mdx +474 -0
  320. package/docs/v7/_drafts/sdk-v7-complete.mdx +345 -0
  321. package/docs/v7/_drafts/self-hosting.mdx +369 -0
  322. package/docs/v7/_drafts/test-recording.mdx +382 -0
  323. package/docs/v7/_drafts/troubleshooting.mdx +526 -0
  324. package/docs/v7/_drafts/vitest-plugin.mdx +477 -0
  325. package/docs/v7/_drafts/vitest.mdx +535 -0
  326. package/docs/v7/_drafts/writing-tests.mdx +25 -0
  327. package/docs/v7/ai.mdx +205 -0
  328. package/docs/v7/assert.mdx +316 -0
  329. package/docs/v7/aws-setup.mdx +449 -0
  330. package/docs/v7/cache.mdx +223 -0
  331. package/docs/v7/caching.mdx +128 -0
  332. package/docs/v7/captcha.mdx +159 -0
  333. package/docs/v7/ci-cd.mdx +603 -0
  334. package/docs/v7/click.mdx +287 -0
  335. package/docs/v7/client.mdx +478 -0
  336. package/docs/v7/copilot/auto-healing.mdx +265 -0
  337. package/docs/v7/copilot/creating-tests.mdx +156 -0
  338. package/docs/v7/copilot/github.mdx +143 -0
  339. package/docs/v7/copilot/running-tests.mdx +149 -0
  340. package/docs/v7/copilot/setup.mdx +143 -0
  341. package/docs/v7/customizing-devices.mdx +319 -0
  342. package/docs/v7/dashcam.mdx +419 -0
  343. package/docs/v7/debugging-with-screenshots.mdx +402 -0
  344. package/docs/v7/device-config.mdx +317 -0
  345. package/docs/v7/double-click.mdx +102 -0
  346. package/docs/v7/elements.mdx +606 -0
  347. package/docs/v7/enterprise.mdx +9 -0
  348. package/docs/v7/errors.mdx +248 -0
  349. package/docs/v7/events.mdx +358 -0
  350. package/docs/v7/examples/ai.mdx +72 -0
  351. package/docs/v7/examples/assert.mdx +72 -0
  352. package/docs/v7/examples/captcha-api.mdx +92 -0
  353. package/docs/v7/examples/chrome-extension.mdx +132 -0
  354. package/docs/v7/examples/drag-and-drop.mdx +100 -0
  355. package/docs/v7/examples/element-not-found.mdx +67 -0
  356. package/docs/v7/examples/exec-output.mdx +85 -0
  357. package/docs/v7/examples/exec-pwsh.mdx +83 -0
  358. package/docs/v7/examples/focus-window.mdx +62 -0
  359. package/docs/v7/examples/hover-image.mdx +94 -0
  360. package/docs/v7/examples/hover-text.mdx +69 -0
  361. package/docs/v7/examples/installer.mdx +91 -0
  362. package/docs/v7/examples/launch-vscode-linux.mdx +101 -0
  363. package/docs/v7/examples/match-image.mdx +96 -0
  364. package/docs/v7/examples/press-keys.mdx +92 -0
  365. package/docs/v7/examples/scroll-keyboard.mdx +79 -0
  366. package/docs/v7/examples/scroll-until-image.mdx +81 -0
  367. package/docs/v7/examples/scroll-until-text.mdx +109 -0
  368. package/docs/v7/examples/scroll.mdx +81 -0
  369. package/docs/v7/examples/type.mdx +92 -0
  370. package/docs/v7/examples/windows-installer.mdx +89 -0
  371. package/docs/v7/exec.mdx +318 -0
  372. package/docs/v7/find.mdx +830 -0
  373. package/docs/v7/focus-application.mdx +294 -0
  374. package/docs/v7/generating-tests.mdx +36 -0
  375. package/docs/v7/hosted.mdx +158 -0
  376. package/docs/v7/hover.mdx +279 -0
  377. package/docs/v7/locating-elements.mdx +71 -0
  378. package/docs/v7/making-assertions.mdx +32 -0
  379. package/docs/v7/mcp.mdx +9 -0
  380. package/docs/v7/mouse-down.mdx +161 -0
  381. package/docs/v7/mouse-up.mdx +164 -0
  382. package/docs/v7/parse.mdx +237 -0
  383. package/docs/v7/performing-actions.mdx +54 -0
  384. package/docs/v7/press-keys.mdx +349 -0
  385. package/docs/v7/provision.mdx +333 -0
  386. package/docs/v7/quickstart.mdx +173 -0
  387. package/docs/v7/redraw.mdx +216 -0
  388. package/docs/v7/reusable-code.mdx +249 -0
  389. package/docs/v7/right-click.mdx +123 -0
  390. package/docs/v7/running-tests.mdx +185 -0
  391. package/docs/v7/screenshot.mdx +249 -0
  392. package/docs/v7/screenshots.mdx +186 -0
  393. package/docs/v7/scroll.mdx +336 -0
  394. package/docs/v7/secrets.mdx +115 -0
  395. package/docs/v7/self-hosted.mdx +149 -0
  396. package/docs/v7/type.mdx +358 -0
  397. package/docs/v7/variables.mdx +111 -0
  398. package/docs/v7/wait.mdx +52 -0
  399. package/docs/v7/waiting-for-elements.mdx +90 -0
  400. package/docs/v7/what-is-testdriver.mdx +54 -0
  401. package/eslint.config.js +67 -0
  402. package/examples/ai.test.mjs +31 -0
  403. package/examples/assert.test.mjs +47 -0
  404. package/examples/chrome-extension.test.mjs +97 -0
  405. package/examples/config.mjs +5 -0
  406. package/examples/element-not-found.test.mjs +27 -0
  407. package/examples/exec-output.test.mjs +60 -0
  408. package/examples/exec-pwsh.test.mjs +58 -0
  409. package/examples/findall-coffee-icons.test.mjs +42 -0
  410. package/examples/focus-window.test.mjs +37 -0
  411. package/examples/formatted-logging.test.mjs +27 -0
  412. package/examples/hover-image.test.mjs +53 -0
  413. package/examples/hover-text-with-description.test.mjs +57 -0
  414. package/examples/hover-text.test.mjs +28 -0
  415. package/examples/installer.test.mjs +50 -0
  416. package/examples/launch-vscode-linux.test.mjs +55 -0
  417. package/examples/match-image.test.mjs +55 -0
  418. package/examples/parse.test.mjs +19 -0
  419. package/examples/press-keys.test.mjs +44 -0
  420. package/examples/prompt.test.mjs +34 -0
  421. package/examples/scroll-keyboard.test.mjs +38 -0
  422. package/examples/scroll-until-image.test.mjs +40 -0
  423. package/examples/scroll.test.mjs +42 -0
  424. package/examples/type.test.mjs +46 -0
  425. package/examples/windows-installer.test.mjs +54 -0
  426. package/index.js +2 -0
  427. package/interfaces/cli/commands/init.js +438 -0
  428. package/interfaces/cli/commands/setup.js +382 -0
  429. package/interfaces/cli/lib/base.js +285 -0
  430. package/interfaces/cli.js +20 -0
  431. package/interfaces/junit-reporter.js +290 -0
  432. package/interfaces/logger.js +388 -0
  433. package/interfaces/readline.js +234 -0
  434. package/interfaces/shared-test-state.mjs +64 -0
  435. package/interfaces/vitest-plugin.d.ts +115 -0
  436. package/interfaces/vitest-plugin.mjs +1698 -0
  437. package/lib/captcha/solver.js +358 -0
  438. package/lib/core/Dashcam.js +533 -0
  439. package/lib/core/index.d.ts +172 -0
  440. package/lib/core/index.js +12 -0
  441. package/lib/environments.json +18 -0
  442. package/lib/github-comment-formatter.js +263 -0
  443. package/lib/github-comment.mjs +452 -0
  444. package/lib/init-project.js +575 -0
  445. package/lib/presets/index.mjs +331 -0
  446. package/lib/resolve-channel.js +46 -0
  447. package/lib/sentry.js +417 -0
  448. package/lib/vitest/hooks.d.ts +57 -0
  449. package/lib/vitest/hooks.mjs +674 -0
  450. package/lib/vitest/setup-aws.mjs +247 -0
  451. package/lib/vitest/setup-self-hosted.mjs +151 -0
  452. package/lib/vitest/setup.mjs +46 -0
  453. package/manual/captcha-api.test.mjs +51 -0
  454. package/manual/drag-and-drop.test.mjs +59 -0
  455. package/manual/flake-diffthreshold-001.test.mjs +9 -0
  456. package/manual/flake-diffthreshold-01.test.mjs +9 -0
  457. package/manual/flake-diffthreshold-05.test.mjs +9 -0
  458. package/manual/flake-noredraw-cache.test.mjs +9 -0
  459. package/manual/flake-noredraw-nocache.test.mjs +9 -0
  460. package/manual/flake-redraw-cache.test.mjs +9 -0
  461. package/manual/flake-redraw-nocache.test.mjs +9 -0
  462. package/manual/flake-rocket-match.test.mjs +30 -0
  463. package/manual/flake-shared.mjs +51 -0
  464. package/manual/no-provision.test.mjs +31 -0
  465. package/manual/packer-hover-image.test.mjs +176 -0
  466. package/manual/scroll-until-text.test.mjs +68 -0
  467. package/manual/test-init-command.js +223 -0
  468. package/mcp-server/README.md +322 -0
  469. package/mcp-server/dist/codegen.d.ts +9 -0
  470. package/mcp-server/dist/codegen.js +165 -0
  471. package/mcp-server/dist/mcp-app.html +114 -0
  472. package/mcp-server/dist/package.json +1 -0
  473. package/mcp-server/dist/provision-types.d.ts +290 -0
  474. package/mcp-server/dist/provision-types.js +174 -0
  475. package/mcp-server/dist/server.d.ts +6 -0
  476. package/mcp-server/dist/server.mjs +1925 -0
  477. package/mcp-server/dist/session.d.ts +85 -0
  478. package/mcp-server/dist/session.js +152 -0
  479. package/mcp-server/mcp-app.html +28 -0
  480. package/mcp-server/mcp-config.example.json +19 -0
  481. package/mcp-server/package-lock.json +4027 -0
  482. package/mcp-server/package.json +31 -0
  483. package/mcp-server/src/codegen.ts +189 -0
  484. package/mcp-server/src/mcp-app.css +360 -0
  485. package/mcp-server/src/mcp-app.ts +547 -0
  486. package/mcp-server/src/provision-types.ts +209 -0
  487. package/mcp-server/src/server.ts +2391 -0
  488. package/mcp-server/src/session.ts +194 -0
  489. package/mcp-server/tsconfig.json +16 -0
  490. package/mcp-server/vite.config.ts +23 -0
  491. package/package.json +158 -0
  492. package/schema.json +1046 -0
  493. package/scripts/generate-skills.js +94 -0
  494. package/sdk-log-formatter.js +1157 -0
  495. package/sdk.d.ts +1486 -0
  496. package/sdk.js +4336 -0
  497. package/setup/aws/cloudformation.yaml +463 -0
  498. package/setup/aws/disable-defender.sh +42 -0
  499. package/setup/aws/install-dev-runner.sh +79 -0
  500. package/setup/aws/spawn-runner.sh +289 -0
  501. package/test/captcha-solver.test.mjs +152 -0
  502. package/test/chrome-remote-debugging.test.mjs +66 -0
  503. package/test/duckduckgo/experiment.test.mjs +28 -0
  504. package/test/duckduckgo/setup.test.mjs +29 -0
  505. package/test/manual/debug-locate-response.js +82 -0
  506. package/test/manual/reconnect-provision.test.mjs +49 -0
  507. package/test/manual/test-console-logs.test.mjs +42 -0
  508. package/test/manual/test-find-api.js +73 -0
  509. package/test/manual/test-init.sh +54 -0
  510. package/test/manual/test-prompt-cache.js +97 -0
  511. package/test/manual/test-provision-auth.mjs +22 -0
  512. package/test/manual/test-sandbox-render.js +29 -0
  513. package/test/manual/test-sdk-methods.js +15 -0
  514. package/test/manual/test-sdk-refactor.js +53 -0
  515. package/test/manual/test-stack-trace.mjs +57 -0
  516. package/test/manual/verify-element-api.js +89 -0
  517. package/test/manual/verify-types.js +0 -0
  518. package/test/manual-unawaited-promise.test.mjs +31 -0
  519. package/vitest.config.mjs +58 -0
  520. package/vitest.runner.config.mjs +33 -0
  521. package/vscode-extension/.vscodeignore +12 -0
  522. package/vscode-extension/README.md +94 -0
  523. package/vscode-extension/media/icon.png +0 -0
  524. package/vscode-extension/package-lock.json +4126 -0
  525. package/vscode-extension/package.json +86 -0
  526. package/vscode-extension/src/extension.ts +829 -0
  527. package/vscode-extension/testdriverai-0.1.0.vsix +0 -0
  528. package/vscode-extension/tsconfig.json +16 -0
@@ -0,0 +1,322 @@
1
+ # TestDriver MCP Server
2
+
3
+ MCP server that enables AI agents to iteratively build TestDriver tests with visual feedback.
4
+
5
+ ## Features
6
+
7
+ - **Live Session Control**: Direct sandbox control via MCP tools
8
+ - **Visual Feedback**: Every action returns a screenshot with overlays (MCP Apps)
9
+ - **Inline Code Generation**: Each action returns the code to append to your test file
10
+ - **Assertions**: AI-powered assertions about screen state
11
+
12
+ ## Installation
13
+
14
+ ### Quick Install (Recommended)
15
+
16
+ Use `add-mcp` to automatically configure TestDriver for your MCP client:
17
+
18
+ ```bash
19
+ npx add-mcp testdriver
20
+ ```
21
+
22
+ This will prompt you to select your MCP client (VS Code, Cursor, Claude Desktop, etc.) and configure it automatically.
23
+
24
+ ### Manual Configuration
25
+
26
+ If you prefer to configure manually, add the following to your MCP config file:
27
+
28
+ ```json
29
+ {
30
+ "inputs": [
31
+ {
32
+ "type": "promptString",
33
+ "id": "testdriver-api-key",
34
+ "description": "TestDriver API Key From https://console.testdriver.ai/team",
35
+ "password": true
36
+ }
37
+ ],
38
+ "servers": {
39
+ "testdriver": {
40
+ "command": "npx",
41
+ "args": ["-p", "testdriverai", "testdriverai-mcp"],
42
+ "env": {
43
+ "TD_API_KEY": "${input:testdriver-api-key}"
44
+ }
45
+ }
46
+ }
47
+ }
48
+ ```
49
+
50
+ ### From Source
51
+
52
+ ```bash
53
+ cd mcp-server
54
+ npm install
55
+ npm run build
56
+ ```
57
+
58
+ ## Usage
59
+
60
+ ### With GitHub Copilot Coding Agent
61
+
62
+ To use the TestDriver MCP server with GitHub Copilot coding agent:
63
+
64
+ 1. **Create a Copilot environment secret:**
65
+ - Go to your repository **Settings** → **Environments**
66
+ - Create or select the `copilot` environment
67
+ - Add an environment secret named `COPILOT_MCP_TD_API_KEY`
68
+ - Set the value to your TestDriver API key from https://console.testdriver.ai/team
69
+
70
+ 2. **Add the MCP configuration** to your repository's **Settings** → **Copilot** → **Coding agent** → **MCP configuration**:
71
+
72
+ ```json
73
+ {
74
+ "mcpServers": {
75
+ "testdriver": {
76
+ "type": "local",
77
+ "command": "npx",
78
+ "args": ["-p", "testdriverai", "testdriverai-mcp"],
79
+ "tools": ["*"],
80
+ "env": {
81
+ "TD_API_KEY": "COPILOT_MCP_TD_API_KEY"
82
+ }
83
+ }
84
+ }
85
+ }
86
+ ```
87
+
88
+ **Note:** The MCP server supports both `TD_API_KEY` and `COPILOT_MCP_TD_API_KEY` environment variables for maximum compatibility with GitHub Copilot coding agent.
89
+
90
+ For more information, see [Extending GitHub Copilot coding agent with Model Context Protocol](https://docs.github.com/en/copilot/customizing-copilot/extending-copilot-coding-agent-with-mcp).
91
+
92
+ ### With Claude Desktop / Cursor
93
+
94
+ Add to your MCP config (`~/.cursor/mcp.json` or `~/Library/Application Support/Claude/claude_desktop_config.json`):
95
+
96
+ **Using npx (recommended):**
97
+
98
+ ```json
99
+ {
100
+ "inputs": [
101
+ {
102
+ "type": "promptString",
103
+ "id": "testdriver-api-key",
104
+ "description": "TestDriver API Key From https://console.testdriver.ai/team",
105
+ "password": true
106
+ }
107
+ ],
108
+ "servers": {
109
+ "testdriver": {
110
+ "command": "npx",
111
+ "args": ["-p", "testdriverai", "testdriverai-mcp"],
112
+ "env": {
113
+ "TD_API_KEY": "${input:testdriver-api-key}"
114
+ }
115
+ }
116
+ }
117
+ }
118
+ ```
119
+
120
+ **Using local build:**
121
+
122
+ ```json
123
+ {
124
+ "inputs": [
125
+ {
126
+ "type": "promptString",
127
+ "id": "testdriver-api-key",
128
+ "description": "TestDriver API Key From https://console.testdriver.ai/team",
129
+ "password": true
130
+ }
131
+ ],
132
+ "servers": {
133
+ "testdriver": {
134
+ "command": "node",
135
+ "args": ["/path/to/testdriverai/mcp-server/dist/server.js"],
136
+ "env": {
137
+ "TD_API_KEY": "${input:testdriver-api-key}"
138
+ }
139
+ }
140
+ }
141
+ }
142
+ ```
143
+
144
+ ### API Endpoint Configuration
145
+
146
+ The API endpoint can be configured in three ways (in order of precedence):
147
+
148
+ 1. **Per-session**: Pass `apiRoot` to `session_start` tool
149
+ 2. **Environment variable**: Set `TD_API_ROOT` in your MCP config
150
+ 3. **Default**: `https://api.testdriver.ai`
151
+
152
+ Common values:
153
+ - **Production**: `https://api.testdriver.ai`
154
+ - **Local dev**: Your ngrok URL (e.g., `https://abc123.ngrok.io`)
155
+
156
+ ### Self-Hosted AWS Instances
157
+
158
+ Connect to your own AWS-hosted Windows instances instead of using TestDriver cloud:
159
+
160
+ 1. **Deploy AWS Infrastructure**: Use the [CloudFormation template](https://docs.testdriver.ai/v7/aws-setup) to set up VPC, security groups, and launch templates
161
+
162
+ 2. **Spawn an instance**: Use `spawn-runner.sh` to launch an EC2 instance:
163
+ ```bash
164
+ AWS_REGION=us-east-2 \
165
+ AMI_ID=ami-0504bf50fad62f312 \
166
+ AWS_LAUNCH_TEMPLATE_ID=lt-xxx \
167
+ bash setup/aws/spawn-runner.sh
168
+ ```
169
+
170
+ 3. **Connect via MCP**: Pass the IP to `session_start`:
171
+ ```json
172
+ {
173
+ "type": "chrome",
174
+ "url": "https://example.com",
175
+ "os": "windows",
176
+ "ip": "1.2.3.4"
177
+ }
178
+ ```
179
+
180
+ Or set `TD_IP` environment variable:
181
+ ```json
182
+ {
183
+ "inputs": [
184
+ {
185
+ "type": "promptString",
186
+ "id": "testdriver-api-key",
187
+ "description": "TestDriver API Key From https://console.testdriver.ai/team",
188
+ "password": true
189
+ }
190
+ ],
191
+ "servers": {
192
+ "testdriver": {
193
+ "command": "node",
194
+ "args": ["/path/to/mcp-server/dist/server.js"],
195
+ "env": {
196
+ "TD_API_KEY": "${input:testdriver-api-key}",
197
+ "TD_IP": "1.2.3.4"
198
+ }
199
+ }
200
+ }
201
+ }
202
+ ```
203
+
204
+ **Benefits of self-hosted:**
205
+ - Flat license fee (no device-second metering)
206
+ - Use your own AI API keys
207
+ - Custom hardware and software configurations
208
+ - Full RDP access for debugging
209
+
210
+ ### Development
211
+
212
+ ```bash
213
+ # Run in development mode with auto-reload
214
+ npm run dev
215
+
216
+ # Build for production
217
+ npm run build
218
+
219
+ # Start production server
220
+ npm start
221
+ ```
222
+
223
+ ## Tools
224
+
225
+ ### Session Management
226
+
227
+ | Tool | Description |
228
+ |------|-------------|
229
+ | `session_start` | Start a new session and provision sandbox |
230
+ | `session_status` | Check session health and time remaining |
231
+ | `session_extend` | Extend session keepAlive time |
232
+
233
+ ### Element Interaction
234
+
235
+ | Tool | Description |
236
+ |------|-------------|
237
+ | `find` | Find element by natural language description |
238
+ | `click` | Click on element or coordinates |
239
+ | `find_and_click` | Find and click in one action |
240
+ | `type` | Type text into focused field |
241
+ | `press_keys` | Press keyboard shortcuts |
242
+ | `scroll` | Scroll the page |
243
+
244
+ ### Verification
245
+
246
+ | Tool | Description |
247
+ |------|-------------|
248
+ | `assert` | AI-powered assertion about screen state |
249
+ | `check` | AI analyzes screen state (for agent understanding, no code generated) |
250
+ | `exec` | Execute code in sandbox |
251
+ | `screenshot` | Capture screenshot (displays to user only) |
252
+
253
+ ### Local Screenshots
254
+
255
+ | Tool | Description |
256
+ |------|-------------|
257
+ | `list_local_screenshots` | List screenshots saved in `.testdriver` directory |
258
+ | `view_local_screenshot` | View a local screenshot (returns image to AI + displays to user) |
259
+
260
+ The local screenshot tools allow AI agents to review screenshots from previous test runs:
261
+
262
+ ```
263
+ 1. Call list_local_screenshots to see available screenshots
264
+ 2. Call view_local_screenshot with a path to view and analyze it
265
+ 3. The image is returned to the AI (if the client supports images) AND displayed to the user
266
+ ```
267
+
268
+ This is useful for:
269
+ - Debugging test failures by examining saved screenshots
270
+ - Reviewing test execution history
271
+ - Comparing current screen state to previous runs
272
+
273
+ ## Workflow
274
+
275
+ 1. **Start Session**: `session_start` provisions a sandbox with browser/app
276
+ 2. **Interact**: Use `find`, `click`, `type` etc. - each action returns generated code
277
+ 3. **Build Test**: Append the generated code from each action to your test file
278
+ 4. **Assert**: Use `assert` to verify expected state
279
+ 5. **Run Test**: Use the CLI (`vitest run <testFile>`) to run the test from scratch
280
+
281
+ Each tool returns a screenshot showing the result AND the code to add to your test file.
282
+
283
+ ## Architecture
284
+
285
+ ```
286
+ ┌─────────────────────────────────────────────────────┐
287
+ │ MCP Server │
288
+ ├─────────────────────────────────────────────────────┤
289
+ │ │
290
+ │ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ │
291
+ │ │ Tools │ │ Session │ │ CodeGen │ │
292
+ │ │ (find, │ │ Manager │ │ (inline │ │
293
+ │ │ click, │ │ (state, │ │ code │ │
294
+ │ │ type...) │ │ expiry) │ │ output) │ │
295
+ │ └──────┬──────┘ └──────┬──────┘ └─────┬──────┘ │
296
+ │ │ │ │ │
297
+ │ └────────────────┼───────────────┘ │
298
+ │ │ │
299
+ │ ┌───────────────────────┴───────────────────────┐ │
300
+ │ │ TestDriver SDK │ │
301
+ │ │ (sandbox control, AI vision) │ │
302
+ │ └───────────────────────────────────────────────┘ │
303
+ │ │ │
304
+ └──────────────────────────┼─────────────────────────┘
305
+
306
+
307
+ ┌──────────────┐
308
+ │ Sandbox │
309
+ │ (VM + app) │
310
+ └──────────────┘
311
+ ```
312
+
313
+ ## MCP Apps Integration
314
+
315
+ Every action tool returns a rich UI via MCP Apps showing:
316
+
317
+ - Screenshot of current screen
318
+ - Element highlights (for `find`)
319
+ - Click markers (for `click`)
320
+ - Scroll indicators (for `scroll`)
321
+ - Action status and duration
322
+ - Session info and time remaining
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Code generation for TestDriver test files
3
+ * Generates code snippets for inline responses
4
+ */
5
+ /**
6
+ * Generate code for a single action (for inline responses)
7
+ * Returns the code snippet that the agent should append to their test file
8
+ */
9
+ export declare function generateActionCode(action: string, args: Record<string, unknown>, result?: Record<string, unknown>): string;
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Code generation for TestDriver test files
3
+ * Generates code snippets for inline responses
4
+ */
5
+ /**
6
+ * Escape string for JavaScript
7
+ */
8
+ function escapeString(str) {
9
+ return str
10
+ .replace(/\\/g, "\\\\")
11
+ .replace(/"/g, '\\"')
12
+ .replace(/\n/g, "\\n")
13
+ .replace(/\r/g, "\\r")
14
+ .replace(/\t/g, "\\t");
15
+ }
16
+ /**
17
+ * Generate code for a single action (for inline responses)
18
+ * Returns the code snippet that the agent should append to their test file
19
+ */
20
+ export function generateActionCode(action, args, result) {
21
+ switch (action) {
22
+ case "provision.chrome": {
23
+ const url = args.url || "https://example.com";
24
+ const maximized = args.maximized;
25
+ const guest = args.guest;
26
+ const opts = [`url: "${escapeString(url)}"`];
27
+ if (maximized !== undefined)
28
+ opts.push(`maximized: ${maximized}`);
29
+ if (guest !== undefined)
30
+ opts.push(`guest: ${guest}`);
31
+ return `await testdriver.provision.chrome({ ${opts.join(", ")} });`;
32
+ }
33
+ case "provision.chromeExtension": {
34
+ const extensionPath = args.extensionPath;
35
+ const extensionId = args.extensionId;
36
+ const maximized = args.maximized;
37
+ const opts = [];
38
+ if (extensionPath)
39
+ opts.push(`extensionPath: "${escapeString(extensionPath)}"`);
40
+ if (extensionId)
41
+ opts.push(`extensionId: "${escapeString(extensionId)}"`);
42
+ if (maximized !== undefined)
43
+ opts.push(`maximized: ${maximized}`);
44
+ return `await testdriver.provision.chromeExtension({ ${opts.join(", ")} });`;
45
+ }
46
+ case "provision.vscode": {
47
+ const workspace = args.workspace;
48
+ const extensions = args.extensions;
49
+ const opts = [];
50
+ if (workspace)
51
+ opts.push(`workspace: "${escapeString(workspace)}"`);
52
+ if (extensions && extensions.length > 0) {
53
+ opts.push(`extensions: [${extensions.map(e => `"${escapeString(e)}"`).join(", ")}]`);
54
+ }
55
+ return `await testdriver.provision.vscode({ ${opts.join(", ")} });`;
56
+ }
57
+ case "provision.installer": {
58
+ const url = args.url;
59
+ const filename = args.filename;
60
+ const appName = args.appName;
61
+ const launch = args.launch;
62
+ const opts = [`url: "${escapeString(url)}"`];
63
+ if (filename)
64
+ opts.push(`filename: "${escapeString(filename)}"`);
65
+ if (appName)
66
+ opts.push(`appName: "${escapeString(appName)}"`);
67
+ if (launch !== undefined)
68
+ opts.push(`launch: ${launch}`);
69
+ return `await testdriver.provision.installer({ ${opts.join(", ")} });`;
70
+ }
71
+ case "provision.electron": {
72
+ const appPath = args.appPath;
73
+ const electronArgs = args.args;
74
+ const opts = [`appPath: "${escapeString(appPath)}"`];
75
+ if (electronArgs && electronArgs.length > 0) {
76
+ opts.push(`args: [${electronArgs.map(a => `"${escapeString(a)}"`).join(", ")}]`);
77
+ }
78
+ return `await testdriver.provision.electron({ ${opts.join(", ")} });`;
79
+ }
80
+ case "find": {
81
+ const description = args.description;
82
+ return `const element = await testdriver.find("${escapeString(description)}");`;
83
+ }
84
+ case "findall": {
85
+ const description = args.description;
86
+ return `const elements = await testdriver.findAll("${escapeString(description)}");`;
87
+ }
88
+ case "click": {
89
+ // When used after find, reference the element
90
+ const clickAction = args.action || "click";
91
+ if (clickAction === "click") {
92
+ return `await element.click();`;
93
+ }
94
+ else if (clickAction === "double-click") {
95
+ return `await element.doubleClick();`;
96
+ }
97
+ else if (clickAction === "right-click") {
98
+ return `await element.rightClick();`;
99
+ }
100
+ return `await element.click();`;
101
+ }
102
+ case "hover": {
103
+ return `await element.hover();`;
104
+ }
105
+ case "find_and_click": {
106
+ const description = args.description;
107
+ const clickAction = args.action || "click";
108
+ if (clickAction === "click") {
109
+ return `await testdriver.find("${escapeString(description)}").click();`;
110
+ }
111
+ else if (clickAction === "double-click") {
112
+ return `await testdriver.find("${escapeString(description)}").doubleClick();`;
113
+ }
114
+ else if (clickAction === "right-click") {
115
+ return `await testdriver.find("${escapeString(description)}").rightClick();`;
116
+ }
117
+ return `await testdriver.find("${escapeString(description)}").click();`;
118
+ }
119
+ case "type": {
120
+ const text = String(args.text);
121
+ const secret = args.secret;
122
+ if (secret) {
123
+ return `await testdriver.type(process.env.TD_SECRET || "", { secret: true });`;
124
+ }
125
+ return `await testdriver.type("${escapeString(text)}");`;
126
+ }
127
+ case "press_keys": {
128
+ const keys = args.keys;
129
+ return `await testdriver.pressKeys([${keys.map(k => `"${k}"`).join(", ")}]);`;
130
+ }
131
+ case "scroll": {
132
+ const direction = args.direction || "down";
133
+ const amount = args.amount;
134
+ if (amount) {
135
+ return `await testdriver.scroll("${direction}", { amount: ${amount} });`;
136
+ }
137
+ return `await testdriver.scroll("${direction}");`;
138
+ }
139
+ case "assert": {
140
+ const assertion = args.assertion;
141
+ return `const assertResult = await testdriver.assert("${escapeString(assertion)}");\nexpect(assertResult).toBeTruthy();`;
142
+ }
143
+ case "exec": {
144
+ const language = args.language || "sh";
145
+ const code = args.code;
146
+ const timeout = args.timeout;
147
+ if (code.includes("\n")) {
148
+ // Escape backticks and template literal interpolation syntax
149
+ const escapedCode = code.replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
150
+ return `await testdriver.exec("${language}", \`${escapedCode}\`${timeout ? `, ${timeout}` : ""});`;
151
+ }
152
+ return `await testdriver.exec("${language}", "${escapeString(code)}"${timeout ? `, ${timeout}` : ""});`;
153
+ }
154
+ case "wait": {
155
+ const timeout = args.timeout;
156
+ return `await testdriver.wait(${timeout});`;
157
+ }
158
+ case "focus_application": {
159
+ const name = args.name;
160
+ return `await testdriver.focusApplication("${escapeString(name)}");`;
161
+ }
162
+ default:
163
+ return `// Unknown action: ${action}`;
164
+ }
165
+ }