@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,31 @@
1
+ {
2
+ "name": "testdriver-mcp-server",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for TestDriver AI - enables AI agents to build tests iteratively",
5
+ "type": "module",
6
+ "main": "dist/server.js",
7
+ "scripts": {
8
+ "build": "npm run build:ui && npm run build:server",
9
+ "build:server": "tsc && mv dist/server.js dist/server.mjs && echo '{\"type\":\"module\"}' > dist/package.json",
10
+ "build:ui": "cross-env INPUT=mcp-app.html vite build",
11
+ "dev": "tsx watch src/server.ts",
12
+ "serve": "tsx src/server.ts",
13
+ "start": "node dist/server.js"
14
+ },
15
+ "dependencies": {
16
+ "@modelcontextprotocol/ext-apps": "^1.0.0",
17
+ "@modelcontextprotocol/sdk": "^1.24.0",
18
+ "@sentry/node": "^9.0.0",
19
+ "semver": "^7.7.4",
20
+ "zod": "^3.24.0"
21
+ },
22
+ "devDependencies": {
23
+ "@types/node": "^22.0.0",
24
+ "@types/semver": "^7.7.1",
25
+ "cross-env": "^7.0.3",
26
+ "tsx": "^4.19.0",
27
+ "typescript": "^5.6.0",
28
+ "vite": "^6.0.0",
29
+ "vite-plugin-singlefile": "^2.3.0"
30
+ }
31
+ }
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Code generation for TestDriver test files
3
+ * Generates code snippets for inline responses
4
+ */
5
+
6
+ /**
7
+ * Escape string for JavaScript
8
+ */
9
+ function escapeString(str: string): string {
10
+ return str
11
+ .replace(/\\/g, "\\\\")
12
+ .replace(/"/g, '\\"')
13
+ .replace(/\n/g, "\\n")
14
+ .replace(/\r/g, "\\r")
15
+ .replace(/\t/g, "\\t");
16
+ }
17
+
18
+ /**
19
+ * Generate code for a single action (for inline responses)
20
+ * Returns the code snippet that the agent should append to their test file
21
+ */
22
+ export function generateActionCode(
23
+ action: string,
24
+ args: Record<string, unknown>,
25
+ result?: Record<string, unknown>
26
+ ): string {
27
+ switch (action) {
28
+ case "provision.chrome": {
29
+ const url = (args.url as string) || "https://example.com";
30
+ const maximized = args.maximized as boolean | undefined;
31
+ const guest = args.guest as boolean | undefined;
32
+
33
+ const opts: string[] = [`url: "${escapeString(url)}"`];
34
+ if (maximized !== undefined) opts.push(`maximized: ${maximized}`);
35
+ if (guest !== undefined) opts.push(`guest: ${guest}`);
36
+
37
+ return `await testdriver.provision.chrome({ ${opts.join(", ")} });`;
38
+ }
39
+
40
+ case "provision.chromeExtension": {
41
+ const extensionPath = args.extensionPath as string | undefined;
42
+ const extensionId = args.extensionId as string | undefined;
43
+ const maximized = args.maximized as boolean | undefined;
44
+
45
+ const opts: string[] = [];
46
+ if (extensionPath) opts.push(`extensionPath: "${escapeString(extensionPath)}"`);
47
+ if (extensionId) opts.push(`extensionId: "${escapeString(extensionId)}"`);
48
+ if (maximized !== undefined) opts.push(`maximized: ${maximized}`);
49
+
50
+ return `await testdriver.provision.chromeExtension({ ${opts.join(", ")} });`;
51
+ }
52
+
53
+ case "provision.vscode": {
54
+ const workspace = args.workspace as string | undefined;
55
+ const extensions = args.extensions as string[] | undefined;
56
+
57
+ const opts: string[] = [];
58
+ if (workspace) opts.push(`workspace: "${escapeString(workspace)}"`);
59
+ if (extensions && extensions.length > 0) {
60
+ opts.push(`extensions: [${extensions.map(e => `"${escapeString(e)}"`).join(", ")}]`);
61
+ }
62
+
63
+ return `await testdriver.provision.vscode({ ${opts.join(", ")} });`;
64
+ }
65
+
66
+ case "provision.installer": {
67
+ const url = args.url as string;
68
+ const filename = args.filename as string | undefined;
69
+ const appName = args.appName as string | undefined;
70
+ const launch = args.launch as boolean | undefined;
71
+
72
+ const opts: string[] = [`url: "${escapeString(url)}"`];
73
+ if (filename) opts.push(`filename: "${escapeString(filename)}"`);
74
+ if (appName) opts.push(`appName: "${escapeString(appName)}"`);
75
+ if (launch !== undefined) opts.push(`launch: ${launch}`);
76
+
77
+ return `await testdriver.provision.installer({ ${opts.join(", ")} });`;
78
+ }
79
+
80
+ case "provision.electron": {
81
+ const appPath = args.appPath as string;
82
+ const electronArgs = args.args as string[] | undefined;
83
+
84
+ const opts: string[] = [`appPath: "${escapeString(appPath)}"`];
85
+ if (electronArgs && electronArgs.length > 0) {
86
+ opts.push(`args: [${electronArgs.map(a => `"${escapeString(a)}"`).join(", ")}]`);
87
+ }
88
+
89
+ return `await testdriver.provision.electron({ ${opts.join(", ")} });`;
90
+ }
91
+
92
+ case "find": {
93
+ const description = args.description as string;
94
+ return `const element = await testdriver.find("${escapeString(description)}");`;
95
+ }
96
+
97
+ case "findall": {
98
+ const description = args.description as string;
99
+ return `const elements = await testdriver.findAll("${escapeString(description)}");`;
100
+ }
101
+
102
+ case "click": {
103
+ // When used after find, reference the element
104
+ const clickAction = args.action as string || "click";
105
+ if (clickAction === "click") {
106
+ return `await element.click();`;
107
+ } else if (clickAction === "double-click") {
108
+ return `await element.doubleClick();`;
109
+ } else if (clickAction === "right-click") {
110
+ return `await element.rightClick();`;
111
+ }
112
+ return `await element.click();`;
113
+ }
114
+
115
+ case "hover": {
116
+ return `await element.hover();`;
117
+ }
118
+
119
+ case "find_and_click": {
120
+ const description = args.description as string;
121
+ const clickAction = args.action as string || "click";
122
+
123
+ if (clickAction === "click") {
124
+ return `await testdriver.find("${escapeString(description)}").click();`;
125
+ } else if (clickAction === "double-click") {
126
+ return `await testdriver.find("${escapeString(description)}").doubleClick();`;
127
+ } else if (clickAction === "right-click") {
128
+ return `await testdriver.find("${escapeString(description)}").rightClick();`;
129
+ }
130
+ return `await testdriver.find("${escapeString(description)}").click();`;
131
+ }
132
+
133
+ case "type": {
134
+ const text = String(args.text);
135
+ const secret = args.secret as boolean;
136
+
137
+ if (secret) {
138
+ return `await testdriver.type(process.env.TD_SECRET || "", { secret: true });`;
139
+ }
140
+ return `await testdriver.type("${escapeString(text)}");`;
141
+ }
142
+
143
+ case "press_keys": {
144
+ const keys = args.keys as string[];
145
+ return `await testdriver.pressKeys([${keys.map(k => `"${k}"`).join(", ")}]);`;
146
+ }
147
+
148
+ case "scroll": {
149
+ const direction = (args.direction as string) || "down";
150
+ const amount = args.amount as number | undefined;
151
+
152
+ if (amount) {
153
+ return `await testdriver.scroll("${direction}", { amount: ${amount} });`;
154
+ }
155
+ return `await testdriver.scroll("${direction}");`;
156
+ }
157
+
158
+ case "assert": {
159
+ const assertion = args.assertion as string;
160
+ return `const assertResult = await testdriver.assert("${escapeString(assertion)}");\nexpect(assertResult).toBeTruthy();`;
161
+ }
162
+
163
+ case "exec": {
164
+ const language = (args.language as string) || "sh";
165
+ const code = args.code as string;
166
+ const timeout = args.timeout as number | undefined;
167
+
168
+ if (code.includes("\n")) {
169
+ // Escape backticks and template literal interpolation syntax
170
+ const escapedCode = code.replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
171
+ return `await testdriver.exec("${language}", \`${escapedCode}\`${timeout ? `, ${timeout}` : ""});`;
172
+ }
173
+ return `await testdriver.exec("${language}", "${escapeString(code)}"${timeout ? `, ${timeout}` : ""});`;
174
+ }
175
+
176
+ case "wait": {
177
+ const timeout = args.timeout as number;
178
+ return `await testdriver.wait(${timeout});`;
179
+ }
180
+
181
+ case "focus_application": {
182
+ const name = args.name as string;
183
+ return `await testdriver.focusApplication("${escapeString(name)}");`;
184
+ }
185
+
186
+ default:
187
+ return `// Unknown action: ${action}`;
188
+ }
189
+ }
@@ -0,0 +1,360 @@
1
+ * {
2
+ box-sizing: border-box;
3
+ margin: 0;
4
+ padding: 0;
5
+ }
6
+
7
+ html, body {
8
+ font-family: var(--font-sans, system-ui, -apple-system, sans-serif);
9
+ font-size: var(--font-text-sm-size, 14px);
10
+ line-height: var(--font-text-sm-line-height, 1.5);
11
+ background: var(--color-background-primary, #fff);
12
+ color: var(--color-text-primary, #1a1a1a);
13
+ overflow: hidden;
14
+ margin: 0;
15
+ padding: 0;
16
+ }
17
+
18
+ body {
19
+ height: 100%;
20
+ display: flex;
21
+ flex-direction: column;
22
+ }
23
+
24
+ .main {
25
+ width: 100%;
26
+ max-width: 100%;
27
+ display: flex;
28
+ flex-direction: column;
29
+ overflow: hidden;
30
+ }
31
+
32
+ .screenshot-wrapper {
33
+ position: relative;
34
+ width: 100%;
35
+ flex: 1;
36
+ min-height: 0;
37
+ background: var(--color-background-secondary, #f5f5f5);
38
+ border-radius: var(--border-radius-md, 8px);
39
+ overflow: hidden;
40
+ display: flex;
41
+ flex-direction: column;
42
+ }
43
+
44
+ /* Loading overlay */
45
+ .loading-overlay {
46
+ display: flex;
47
+ flex-direction: column;
48
+ align-items: center;
49
+ justify-content: center;
50
+ gap: 12px;
51
+ padding: 40px;
52
+ flex: 1;
53
+ min-height: 100px;
54
+ background: var(--color-background-secondary, #f5f5f5);
55
+ }
56
+
57
+ .loading-overlay.hidden {
58
+ display: none;
59
+ }
60
+
61
+ .loading-spinner {
62
+ width: 32px;
63
+ height: 32px;
64
+ border: 3px solid var(--color-border-primary, #e5e5e5);
65
+ border-top-color: #3b82f6;
66
+ border-radius: 50%;
67
+ animation: spin 0.8s linear infinite;
68
+ }
69
+
70
+ @keyframes spin {
71
+ to { transform: rotate(360deg); }
72
+ }
73
+
74
+ .loading-text {
75
+ font-size: var(--font-text-sm-size, 14px);
76
+ color: var(--color-text-secondary, #666);
77
+ }
78
+
79
+ .screenshot-container {
80
+ position: relative;
81
+ width: 100%;
82
+ flex: 1;
83
+ min-height: 0;
84
+ display: flex;
85
+ align-items: center;
86
+ justify-content: center;
87
+ }
88
+
89
+ #screenshot {
90
+ display: block;
91
+ max-width: 100%;
92
+ max-height: 100%;
93
+ width: auto;
94
+ height: auto;
95
+ object-fit: contain;
96
+ }
97
+
98
+ #overlays {
99
+ position: absolute;
100
+ top: 0;
101
+ left: 0;
102
+ width: 100%;
103
+ height: 100%;
104
+ pointer-events: none;
105
+ }
106
+
107
+ /* Element click target */
108
+ .element-target {
109
+ position: absolute;
110
+ width: 24px;
111
+ height: 24px;
112
+ margin-left: -12px;
113
+ margin-top: -12px;
114
+ background: rgba(59, 130, 246, 0.3);
115
+ border: 3px solid #3b82f6;
116
+ border-radius: 50%;
117
+ box-shadow: 0 0 0 2px white, 0 2px 8px rgba(0, 0, 0, 0.3);
118
+ animation: target-pulse 1.5s ease-in-out infinite;
119
+ }
120
+
121
+ @keyframes target-pulse {
122
+ 0%, 100% {
123
+ transform: scale(1);
124
+ border-color: #3b82f6;
125
+ box-shadow: 0 0 0 2px white, 0 2px 8px rgba(0, 0, 0, 0.3);
126
+ }
127
+ 50% {
128
+ transform: scale(1.1);
129
+ border-color: #60a5fa;
130
+ box-shadow: 0 0 0 2px white, 0 0 12px rgba(59, 130, 246, 0.5);
131
+ }
132
+ }
133
+
134
+ /* Crosshair lines for element target */
135
+ .crosshair-h,
136
+ .crosshair-v {
137
+ position: absolute;
138
+ background: #3b82f6;
139
+ }
140
+
141
+ .crosshair-h {
142
+ width: 40px;
143
+ height: 2px;
144
+ left: 50%;
145
+ top: 50%;
146
+ margin-left: -20px;
147
+ margin-top: -1px;
148
+ }
149
+
150
+ .crosshair-v {
151
+ width: 2px;
152
+ height: 40px;
153
+ left: 50%;
154
+ top: 50%;
155
+ margin-left: -1px;
156
+ margin-top: -20px;
157
+ }
158
+
159
+ .element-label {
160
+ position: absolute;
161
+ top: 100%;
162
+ left: 50%;
163
+ transform: translateX(-50%);
164
+ margin-top: 24px;
165
+ background: #3b82f6;
166
+ color: white;
167
+ font-size: 11px;
168
+ padding: 4px 8px;
169
+ border-radius: 4px;
170
+ white-space: nowrap;
171
+ max-width: 300px;
172
+ overflow: hidden;
173
+ text-overflow: ellipsis;
174
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
175
+ }
176
+
177
+ /* Click marker */
178
+ .click-marker {
179
+ position: absolute;
180
+ width: 16px;
181
+ height: 16px;
182
+ margin-left: -8px;
183
+ margin-top: -8px;
184
+ background: #ef4444;
185
+ border: 2px solid white;
186
+ border-radius: 50%;
187
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
188
+ }
189
+
190
+ .click-ripple {
191
+ position: absolute;
192
+ top: 50%;
193
+ left: 50%;
194
+ width: 40px;
195
+ height: 40px;
196
+ margin-left: -20px;
197
+ margin-top: -20px;
198
+ border: 2px solid #ef4444;
199
+ border-radius: 50%;
200
+ animation: ripple 1s ease-out infinite;
201
+ }
202
+
203
+ @keyframes ripple {
204
+ 0% { transform: scale(0.5); opacity: 1; }
205
+ 100% { transform: scale(2); opacity: 0; }
206
+ }
207
+
208
+ /* Scroll indicator */
209
+ .scroll-indicator {
210
+ position: absolute;
211
+ font-size: 48px;
212
+ color: #3b82f6;
213
+ text-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
214
+ animation: scroll-bounce 0.5s ease-in-out;
215
+ }
216
+
217
+ .scroll-up { top: 20px; left: 50%; transform: translateX(-50%); }
218
+ .scroll-down { bottom: 20px; left: 50%; transform: translateX(-50%); }
219
+ .scroll-left { left: 20px; top: 50%; transform: translateY(-50%); }
220
+ .scroll-right { right: 20px; top: 50%; transform: translateY(-50%); }
221
+
222
+ @keyframes scroll-bounce {
223
+ 0%, 100% { opacity: 1; }
224
+ 50% { opacity: 0.5; }
225
+ }
226
+
227
+ /* Status bar */
228
+ .status-bar {
229
+ display: flex;
230
+ justify-content: space-between;
231
+ align-items: center;
232
+ padding: 8px 12px;
233
+ background: var(--color-background-secondary, #f5f5f5);
234
+ border-top: 1px solid var(--color-border-primary, #e5e5e5);
235
+ font-size: var(--font-text-xs-size, 12px);
236
+ }
237
+
238
+ #action-status {
239
+ font-weight: var(--font-weight-medium, 500);
240
+ }
241
+
242
+ #action-status.success { color: #10b981; }
243
+ #action-status.error { color: #ef4444; }
244
+ #action-status.loading { color: var(--color-text-secondary, #666); }
245
+
246
+ #session-info {
247
+ color: var(--color-text-secondary, #666);
248
+ }
249
+
250
+ #session-info.warning { color: #f59e0b; }
251
+
252
+ /* Debugger link */
253
+ .debugger-link {
254
+ color: #3b82f6;
255
+ text-decoration: none;
256
+ transition: color 0.15s ease;
257
+ }
258
+
259
+ .debugger-link:hover {
260
+ color: #2563eb;
261
+ text-decoration: underline;
262
+ }
263
+
264
+ /* Target info section */
265
+ .target-info {
266
+ padding: 8px 12px;
267
+ background: var(--color-background-secondary, #f5f5f5);
268
+ border-bottom: 1px solid var(--color-border-primary, #e5e5e5);
269
+ font-size: var(--font-text-sm-size, 14px);
270
+ color: var(--color-text-primary, #1a1a1a);
271
+ }
272
+
273
+ .target-info.hidden {
274
+ display: none;
275
+ }
276
+
277
+ .target-info strong {
278
+ color: #3b82f6;
279
+ font-weight: var(--font-weight-medium, 500);
280
+ }
281
+
282
+ .target-coords {
283
+ color: var(--color-text-secondary, #666);
284
+ font-family: var(--font-mono, ui-monospace, monospace);
285
+ font-size: var(--font-text-xs-size, 12px);
286
+ margin-left: 4px;
287
+ }
288
+
289
+ .target-confidence {
290
+ display: inline-block;
291
+ padding: 1px 6px;
292
+ border-radius: 10px;
293
+ font-size: var(--font-text-xs-size, 11px);
294
+ font-weight: var(--font-weight-medium, 500);
295
+ margin-left: 6px;
296
+ }
297
+
298
+ .target-confidence.high {
299
+ background: #dcfce7;
300
+ color: #166534;
301
+ }
302
+
303
+ .target-confidence.medium {
304
+ background: #fef3c7;
305
+ color: #92400e;
306
+ }
307
+
308
+ .target-confidence.low {
309
+ background: #fee2e2;
310
+ color: #991b1b;
311
+ }
312
+
313
+ /* Dark mode overrides for elements without CSS vars */
314
+ @media (prefers-color-scheme: dark) {
315
+ html:not([data-theme="light"]) {
316
+ .element-target {
317
+ border-color: #60a5fa;
318
+ background: rgba(96, 165, 250, 0.2);
319
+ box-shadow: 0 0 0 2px #1f2937, 0 2px 8px rgba(0, 0, 0, 0.5);
320
+ }
321
+ .crosshair-h,
322
+ .crosshair-v {
323
+ background: #60a5fa;
324
+ }
325
+ .element-label {
326
+ background: #2563eb;
327
+ }
328
+ .click-marker {
329
+ background: #f87171;
330
+ border-color: #1f2937;
331
+ }
332
+ .click-ripple {
333
+ border-color: #f87171;
334
+ }
335
+ .scroll-indicator {
336
+ color: #60a5fa;
337
+ }
338
+ .debugger-link {
339
+ color: #60a5fa;
340
+ }
341
+ .debugger-link:hover {
342
+ color: #93c5fd;
343
+ }
344
+ .target-info strong {
345
+ color: #60a5fa;
346
+ }
347
+ .target-confidence.high {
348
+ background: #166534;
349
+ color: #dcfce7;
350
+ }
351
+ .target-confidence.medium {
352
+ background: #92400e;
353
+ color: #fef3c7;
354
+ }
355
+ .target-confidence.low {
356
+ background: #991b1b;
357
+ color: #fee2e2;
358
+ }
359
+ }
360
+ }