@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,266 @@
1
+ # GitHub Integration Setup
2
+
3
+ TestDriver automatically posts beautiful test result comments to GitHub Pull Requests, including:
4
+ - ✅ Test results summary with pass/fail counts
5
+ - 🎥 Dashcam GIF replays embedded directly in comments
6
+ - 📊 Detailed test statistics and duration
7
+ - 🔴 Exception details with stack traces
8
+ - 📋 Links to full test runs
9
+
10
+ This guide explains how to configure GitHub authentication so TestDriver can post these comments.
11
+
12
+ ## How It Works
13
+
14
+ TestDriver's Vitest plugin automatically detects GitHub context and posts comments when tests complete. Here's what it needs:
15
+
16
+ ### Required Environment Variables
17
+
18
+ 1. **GITHUB_TOKEN** or **GH_TOKEN** - GitHub Personal Access Token for authentication
19
+ 2. **GITHUB_REPOSITORY** - Repository in `owner/repo` format (auto-detected in GitHub Actions)
20
+ 3. **GITHUB_PR_NUMBER** - Pull Request number (auto-detected in GitHub Actions)
21
+ 4. **GITHUB_SHA** - Commit SHA (optional, auto-detected in GitHub Actions)
22
+
23
+ ### Auto-Detection in GitHub Actions
24
+
25
+ When running in GitHub Actions, most variables are automatically available:
26
+ - `GITHUB_REPOSITORY` - Set automatically
27
+ - `GITHUB_SHA` - Set automatically
28
+ - `GITHUB_REF` - Used to detect PR number
29
+ - Pull request info extracted from event data
30
+
31
+ You only need to configure the token permissions!
32
+
33
+ ### Method 1: GitHub Actions (Recommended)
34
+
35
+ GitHub Actions provides automatic authentication. TestDriver will detect the context automatically.
36
+
37
+ **Required Permissions:**
38
+
39
+ In your workflow file, use the built-in `GITHUB_TOKEN` with write permissions:
40
+
41
+ ```yaml
42
+ name: TestDriver Tests
43
+
44
+ on:
45
+ pull_request:
46
+ types: [opened, synchronize]
47
+
48
+ jobs:
49
+ test:
50
+ runs-on: ubuntu-latest
51
+ permissions:
52
+ contents: read
53
+ pull-requests: write # Required to post comments
54
+
55
+ steps:
56
+ - uses: actions/checkout@v4
57
+
58
+ - name: Setup Node.js
59
+ uses: actions/setup-node@v4
60
+ with:
61
+ node-version: '20'
62
+
63
+ - name: Install dependencies
64
+ run: npm ci
65
+
66
+ - name: Run TestDriver tests
67
+ env:
68
+ TD_API_KEY: ${{ secrets.TD_API_KEY }}
69
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Automatically provided
70
+ run: vitest run
71
+ ```
72
+
73
+ **What happens automatically:**
74
+ - `GITHUB_TOKEN`: Provided by GitHub Actions
75
+ - `GITHUB_REPOSITORY`: Automatically set (e.g., `testdriverai/testdriverai`)
76
+ - `GITHUB_REF`: Automatically set (e.g., `refs/pull/123/merge`)
77
+ - PR number: Extracted automatically from `GITHUB_REF` or event data
78
+
79
+ ### Method 2: Manual Setup (Local or Other CI)
80
+
81
+ For local development or other CI systems, set these environment variables:
82
+
83
+ ```bash
84
+ # .env or export in your shell
85
+ GITHUB_TOKEN=ghp_your_personal_access_token_here
86
+ GITHUB_PR_NUMBER=123
87
+ # GITHUB_REPOSITORY is auto-detected from git if not set
88
+ ```
89
+
90
+ **Creating a Personal Access Token:**
91
+
92
+ 1. Go to [GitHub Settings → Developer settings → Personal access tokens](https://github.com/settings/tokens)
93
+ 2. Click "Generate new token" → "Generate new token (classic)"
94
+ 3. Give it a descriptive name (e.g., "TestDriver CI")
95
+ 4. Select scopes:
96
+ - ✅ `repo` (Full control of private repositories)
97
+ - Or just ✅ `public_repo` (for public repositories only)
98
+ 5. Click "Generate token"
99
+ 6. Copy the token immediately (you won't see it again!)
100
+ 7. Store it securely:
101
+ - **In GitHub Actions**: Add as repository secret (`Settings → Secrets and variables → Actions → New repository secret`)
102
+ - **Locally**: Add to `.env` file (and add `.env` to `.gitignore`!)
103
+
104
+ ### Method 3: Other CI Systems
105
+
106
+ #### CircleCI
107
+ ```yaml
108
+ environment:
109
+ GITHUB_TOKEN: $GITHUB_TOKEN
110
+ GITHUB_REPOSITORY: $CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME
111
+ GITHUB_PR_NUMBER: $CIRCLE_PR_NUMBER
112
+ ```
113
+
114
+ #### GitLab CI
115
+ ```yaml
116
+ variables:
117
+ GITHUB_TOKEN: $GITHUB_TOKEN
118
+ GITHUB_REPOSITORY: "your-org/your-repo"
119
+ GITHUB_PR_NUMBER: $CI_MERGE_REQUEST_IID
120
+ ```
121
+
122
+ #### Jenkins
123
+ ```groovy
124
+ environment {
125
+ GITHUB_TOKEN = credentials('github-token')
126
+ GITHUB_REPOSITORY = "${env.GITHUB_ORG}/${env.GITHUB_REPO}"
127
+ GITHUB_PR_NUMBER = "${env.CHANGE_ID}"
128
+ }
129
+ ```
130
+
131
+ ## Environment Variables Reference
132
+
133
+ | Variable | Priority | Description | Example | Source |
134
+ |----------|----------|-------------|---------|--------|
135
+ | `GITHUB_TOKEN` | 1 | GitHub personal access token | `ghp_abc...` | Auto-provided in GitHub Actions |
136
+ | `GH_TOKEN` | 2 | Alternative GitHub token | `ghp_xyz...` | Manual setup |
137
+ | `GITHUB_REPOSITORY` | - | Repository in `owner/repo` format | `testdriverai/testdriverai` | Auto-set in GitHub Actions |
138
+ | `GITHUB_PR_NUMBER` | - | Pull request number | `123` | Must be set manually or by CI |
139
+ | `GITHUB_SHA` | - | Commit SHA | `abc1234def...` | Auto-set in GitHub Actions |
140
+ | `TESTDRIVER_SKIP_GITHUB_COMMENT` | - | Disable comment posting | `true` | Set to skip comments |
141
+
142
+ **Note**: Git repository info (owner/repo, branch, commit) is auto-detected from your local `.git` directory if not provided via environment variables.
143
+
144
+ ## Disabling GitHub Comments
145
+
146
+ To disable GitHub comments:
147
+
148
+ ```bash
149
+ # Method 1: Set environment variable
150
+ TESTDRIVER_SKIP_GITHUB_COMMENT=true npm run test
151
+
152
+ # Method 2: Remove/unset the GitHub token
153
+ unset GITHUB_TOKEN
154
+ unset GH_TOKEN
155
+ ```
156
+
157
+ In GitHub Actions workflow:
158
+ ```yaml
159
+ - name: Run tests without GitHub comments
160
+ env:
161
+ TD_API_KEY: ${{ secrets.TD_API_KEY }}
162
+ TESTDRIVER_SKIP_GITHUB_COMMENT: true
163
+ run: vitest run
164
+ ```
165
+
166
+ ## Troubleshooting
167
+
168
+ ### "GitHub token not found, skipping comment posting"
169
+
170
+ Check that the token is set:
171
+ ```bash
172
+ echo $GITHUB_TOKEN # or GH_TOKEN
173
+ ```
174
+
175
+ ### "Neither PR number nor commit SHA found"
176
+
177
+ Set the PR number:
178
+ ```bash
179
+ export GITHUB_PR_NUMBER=123
180
+ ```
181
+
182
+ Or ensure `GITHUB_SHA` is set (auto-set in GitHub Actions).
183
+
184
+ ### "Repository info not available"
185
+
186
+ The plugin auto-detects repo info from your `.git` directory. If that fails, set:
187
+ ```bash
188
+ export GITHUB_REPOSITORY=owner/repo
189
+ ```
190
+
191
+ ### "Resource not accessible by integration"
192
+
193
+ Your token doesn't have `pull-requests: write` permission. Check:
194
+ - GitHub Actions: Add `permissions.pull-requests: write` to workflow
195
+ - Personal token: Ensure it has `repo` or `public_repo` scope
196
+
197
+ ### "Not Found" or "403 Forbidden"
198
+
199
+ - Token doesn't have access to the repository
200
+ - Repository name format is incorrect (must be `owner/repo`)
201
+ - PR number is invalid
202
+
203
+ ### Comments not appearing
204
+
205
+ - Check that tests are running in the context of a pull request
206
+ - Verify the token has write access
207
+ - Look for error messages in the test output
208
+ - Run with `DEBUG=testdriver:github` for verbose logging
209
+
210
+ ## Security Best Practices
211
+
212
+ 1. **Never commit tokens** to git repositories
213
+ 2. **Use GitHub Actions secrets** for CI/CD
214
+ 3. **Use fine-grained tokens** with minimum required permissions
215
+ 4. **Rotate tokens regularly** (at least every 90 days)
216
+ 5. **Revoke tokens** immediately if compromised
217
+ 6. **Use organization secrets** for shared tokens across repos
218
+
219
+ ## Example Comment Output
220
+
221
+ When properly configured, TestDriver will post comments like:
222
+
223
+ ```markdown
224
+ # 🟢 TestDriver Test Results
225
+
226
+ **Status:** ✅ PASSED
227
+ **Duration:** 45.23s
228
+ **Platform:** linux
229
+ **Branch:** `feature/new-login`
230
+ **Commit:** `abc1234`
231
+
232
+ ## 📊 Test Summary
233
+
234
+ Total: 3
235
+ Passed: 3 ✅
236
+ Failed: 0 ❌
237
+ Skipped: 0 ⏭️
238
+
239
+ ### [📋 View Full Test Run](https://app.testdriver.ai/runs/...)
240
+
241
+ ## 📝 Test Results
242
+
243
+ | Status | Test | File | Duration | Replay |
244
+ |--------|------|------|----------|--------|
245
+ | ✅ | should log in successfully | `login.test.mjs` | 12.34s | [🎥 View](https://app.testdriver.ai/replay/...) |
246
+ | ✅ | should navigate to dashboard | `navigation.test.mjs` | 8.91s | [🎥 View](https://app.testdriver.ai/replay/...) |
247
+
248
+ ## 🎥 Dashcam Replays
249
+
250
+ ### should log in successfully
251
+
252
+ [![Login test](https://app.testdriver.ai/api/replay/.../gif)](https://app.testdriver.ai/replay/...)
253
+
254
+ [🎬 View Full Replay](https://app.testdriver.ai/replay/...)
255
+
256
+ ---
257
+ <sub>Generated by [TestDriver](https://testdriver.ai) • Run ID: `run_abc123`</sub>
258
+ ```
259
+
260
+ The GIF replays are automatically embedded so reviewers can see what happened without leaving GitHub!
261
+
262
+ ## Getting Help
263
+
264
+ - 📚 [Full Documentation](https://docs.testdriver.ai)
265
+ - 💬 [Discord Community](https://discord.gg/testdriver)
266
+ - 🐛 [Report Issues](https://github.com/testdriverai/testdriverai/issues)
@@ -0,0 +1,174 @@
1
+ # Best Practices: Element Polling
2
+
3
+ **When waiting for elements to appear, prefer `find()` with a `timeout` option over `wait()`.**
4
+
5
+ ## When to Use `wait()` vs `find()` with Timeout
6
+
7
+ `wait()` is useful for **simple pauses** — after actions, for animations, or for state changes to settle:
8
+
9
+ ```javascript
10
+ await testdriver.find('submit button').click();
11
+ await testdriver.wait(2000); // Wait for animation to complete
12
+ ```
13
+
14
+ However, **don't use `wait()` to wait for elements to appear**. For that, use `find()` with a `timeout`:
15
+
16
+ ```javascript
17
+ // ✅ GOOD: Polls until the element appears (up to 30s)
18
+ const element = await testdriver.find('success message', { timeout: 30000 });
19
+
20
+ // ❌ BAD: Arbitrary wait then hope the element is there
21
+ await testdriver.wait(5000);
22
+ const element = await testdriver.find('success message');
23
+ ```
24
+
25
+ ## Why Prefer `find()` with Timeout for Element Waiting?
26
+
27
+ Using arbitrary waits for element detection has problems:
28
+
29
+ 1. **Brittle**: Fixed timeouts may be too short (causing flaky tests) or too long (wasting time)
30
+ 2. **Slow**: You always wait the full duration, even if the element appears sooner
31
+ 3. **Unreliable**: Network conditions, system load, and other factors affect timing
32
+ 4. **Hard to debug**: When tests fail, you don't know if it was a timing issue or actual failure
33
+
34
+ ## The Right Way: Element Polling with `find()`
35
+
36
+ TestDriver's `find()` method is designed for element detection. Use it in a polling loop to wait for elements:
37
+
38
+ ### Basic Polling Pattern
39
+
40
+ ```javascript
41
+ // ❌ WRONG: Using wait()
42
+ await testdriver.wait(2000);
43
+ const button = await testdriver.find("Submit button");
44
+
45
+ // ✅ CORRECT: Polling with find()
46
+ let button;
47
+ for (let i = 0; i < 10; i++) {
48
+ try {
49
+ button = await testdriver.find("Submit button");
50
+ if (button.found()) break;
51
+ } catch (e) {
52
+ if (i === 9) throw e; // Re-throw on last attempt
53
+ }
54
+ await new Promise(resolve => setTimeout(resolve, 1000));
55
+ }
56
+ ```
57
+
58
+ ### Helper Function for Polling
59
+
60
+ Create a reusable helper function:
61
+
62
+ ```javascript
63
+ async function waitForElement(testdriver, description, maxAttempts = 10, delayMs = 1000) {
64
+ for (let i = 0; i < maxAttempts; i++) {
65
+ try {
66
+ const element = await testdriver.find(description);
67
+ if (element.found()) {
68
+ return element;
69
+ }
70
+ } catch (e) {
71
+ if (i === maxAttempts - 1) throw e;
72
+ }
73
+ await new Promise(resolve => setTimeout(resolve, delayMs));
74
+ }
75
+ throw new Error(`Element not found after ${maxAttempts} attempts: ${description}`);
76
+ }
77
+
78
+ // Usage
79
+ const emailField = await waitForElement(testdriver, "Email input field");
80
+ await emailField.click();
81
+ ```
82
+
83
+ ## When to Use Polling
84
+
85
+ Use element polling in these scenarios:
86
+
87
+ - **After navigation**: Waiting for a new page to load
88
+ - **After user action**: Waiting for UI updates (form submission, modal opening, etc.)
89
+ - **Dynamic content**: Waiting for AJAX-loaded elements
90
+ - **State transitions**: Waiting for loading spinners to disappear or success messages to appear
91
+
92
+ ## Example: Complete Login Flow
93
+
94
+ ```javascript
95
+ import { chrome } from "testdriverai/presets";
96
+
97
+ // Helper function
98
+ async function waitForElement(testdriver, description, maxAttempts = 10, delayMs = 1000) {
99
+ for (let i = 0; i < maxAttempts; i++) {
100
+ try {
101
+ const element = await testdriver.find(description);
102
+ if (element.found()) return element;
103
+ } catch (e) {
104
+ if (i === maxAttempts - 1) throw e;
105
+ }
106
+ await new Promise(resolve => setTimeout(resolve, delayMs));
107
+ }
108
+ throw new Error(`Element not found after ${maxAttempts} attempts: ${description}`);
109
+ }
110
+
111
+ it("should log in successfully", async (context) => {
112
+ const { testdriver } = await chrome(context, {
113
+ url: 'https://example.com/login',
114
+ });
115
+
116
+ // Wait for login page to load
117
+ const emailField = await waitForElement(testdriver, "Email input field");
118
+ await emailField.click();
119
+ await testdriver.type("user@example.com");
120
+
121
+ const passwordField = await testdriver.find("Password input field");
122
+ await passwordField.click();
123
+ await testdriver.type("password123");
124
+
125
+ const loginButton = await testdriver.find("Login button");
126
+ await loginButton.click();
127
+
128
+ // Wait for dashboard to load after login
129
+ await waitForElement(testdriver, "Dashboard welcome message");
130
+
131
+ // Verify login successful
132
+ const isLoggedIn = await testdriver.assert("user is logged in to dashboard");
133
+ expect(isLoggedIn).toBeTruthy();
134
+ });
135
+ ```
136
+
137
+ ## Advanced: Conditional Polling
138
+
139
+ For elements that may or may not appear (like dialogs or notifications):
140
+
141
+ ```javascript
142
+ // Try to find and dismiss optional dialog
143
+ try {
144
+ const dialog = await waitForElement(testdriver, "Cookie consent dialog", 3, 500);
145
+ const acceptButton = await testdriver.find("Accept button");
146
+ await acceptButton.click();
147
+ console.log("Dismissed cookie dialog");
148
+ } catch {
149
+ console.log("No cookie dialog found, continuing...");
150
+ }
151
+ ```
152
+
153
+ ## Configuration
154
+
155
+ Adjust polling parameters based on your needs:
156
+
157
+ ```javascript
158
+ // Quick polling for fast UI updates (check every 300ms, up to 3 seconds)
159
+ await waitForElement(testdriver, "Success message", 10, 300);
160
+
161
+ // Patient polling for slow operations (check every 2s, up to 20 seconds)
162
+ await waitForElement(testdriver, "Processing complete indicator", 10, 2000);
163
+ ```
164
+
165
+ ## Summary
166
+
167
+ | Pattern | Use Case |
168
+ |---------|----------|
169
+ | **Polling with `find()`** | ✅ Waiting for UI elements to appear or disappear |
170
+ | **`wait()`** | ✅ Simple delays (animations, state changes) — ❌ Don't use for element waiting |
171
+ | **Helper function** | ✅ Recommended for cleaner, reusable code |
172
+ | **Conditional polling** | ✅ For optional elements (dialogs, notifications) |
173
+
174
+ Remember: **If you're waiting for something to appear on screen, use `find()` with a `timeout` option, not `wait()`. Use `wait()` for simple pauses between actions.**