testdriverai 7.0.0 → 7.1.1

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 (324) hide show
  1. package/.env.example +2 -0
  2. package/.github/workflows/linux-tests.yml +28 -0
  3. package/README.md +126 -0
  4. package/agent/index.js +7 -9
  5. package/agent/interface.js +13 -2
  6. package/agent/lib/commands.js +795 -136
  7. package/agent/lib/redraw.js +124 -39
  8. package/agent/lib/sandbox.js +40 -3
  9. package/agent/lib/sdk.js +21 -0
  10. package/agent/lib/valid-version.js +2 -2
  11. package/debugger/index.html +1 -1
  12. package/docs/docs.json +86 -71
  13. package/docs/guide/best-practices-polling.mdx +154 -0
  14. package/docs/v6/getting-started/self-hosting.mdx +3 -2
  15. package/docs/v7/_drafts/agents.mdx +852 -0
  16. package/docs/v7/_drafts/auto-cache-key.mdx +167 -0
  17. package/docs/v7/_drafts/best-practices.mdx +486 -0
  18. package/docs/v7/_drafts/caching-ai.mdx +215 -0
  19. package/docs/v7/_drafts/caching-selectors.mdx +400 -0
  20. package/docs/v7/_drafts/caching.mdx +366 -0
  21. package/docs/v7/_drafts/cli-to-sdk-migration.mdx +425 -0
  22. package/docs/v7/_drafts/core.mdx +459 -0
  23. package/docs/v7/_drafts/dashcam-title-feature.mdx +89 -0
  24. package/docs/v7/_drafts/debugging.mdx +349 -0
  25. package/docs/v7/_drafts/error-handling.mdx +501 -0
  26. package/docs/v7/_drafts/faq.mdx +393 -0
  27. package/docs/v7/_drafts/hooks.mdx +360 -0
  28. package/docs/v7/_drafts/implementation-plan.mdx +994 -0
  29. package/docs/v7/_drafts/init-command.mdx +95 -0
  30. package/docs/v7/_drafts/optimal-sdk-design.mdx +1348 -0
  31. package/docs/v7/_drafts/performance.mdx +517 -0
  32. package/docs/v7/_drafts/presets.mdx +210 -0
  33. package/docs/v7/_drafts/progressive-disclosure.mdx +230 -0
  34. package/docs/v7/_drafts/provision.mdx +266 -0
  35. package/docs/{QUICK_START_TEST_RECORDING.md → v7/_drafts/quick-start-test-recording.mdx} +3 -3
  36. package/docs/v7/_drafts/sdk-v7-complete.mdx +345 -0
  37. package/docs/v7/{guides → _drafts}/self-hosting.mdx +1 -1
  38. package/docs/v7/_drafts/troubleshooting.mdx +526 -0
  39. package/docs/v7/_drafts/vitest-plugin.mdx +477 -0
  40. package/docs/v7/_drafts/vitest.mdx +535 -0
  41. package/docs/v7/api/{ai.mdx → act.mdx} +24 -24
  42. package/docs/v7/api/client.mdx +1 -1
  43. package/docs/v7/api/dashcam.mdx +497 -0
  44. package/docs/v7/api/doubleClick.mdx +102 -0
  45. package/docs/v7/api/elements.mdx +143 -41
  46. package/docs/v7/api/find.mdx +258 -0
  47. package/docs/v7/api/mouseDown.mdx +161 -0
  48. package/docs/v7/api/mouseUp.mdx +164 -0
  49. package/docs/v7/api/rightClick.mdx +123 -0
  50. package/docs/v7/api/type.mdx +51 -7
  51. package/docs/v7/features/ai-native.mdx +427 -0
  52. package/docs/v7/features/easy-to-write.mdx +351 -0
  53. package/docs/v7/features/enterprise.mdx +540 -0
  54. package/docs/v7/features/fast.mdx +424 -0
  55. package/docs/v7/features/observable.mdx +623 -0
  56. package/docs/v7/features/powerful.mdx +531 -0
  57. package/docs/v7/features/scalable.mdx +417 -0
  58. package/docs/v7/features/stable.mdx +514 -0
  59. package/docs/v7/getting-started/configuration.mdx +380 -0
  60. package/docs/v7/getting-started/generating-tests.mdx +525 -0
  61. package/docs/v7/getting-started/installation.mdx +486 -0
  62. package/docs/v7/getting-started/quickstart.mdx +320 -141
  63. package/docs/v7/getting-started/running-and-debugging.mdx +511 -0
  64. package/docs/v7/getting-started/setting-up-in-ci.mdx +612 -0
  65. package/docs/v7/getting-started/writing-tests.mdx +535 -0
  66. package/docs/v7/overview/what-is-testdriver.mdx +398 -0
  67. package/docs/v7/platforms/linux.mdx +308 -0
  68. package/docs/v7/platforms/macos.mdx +433 -0
  69. package/docs/v7/platforms/windows.mdx +430 -0
  70. package/docs/v7/playwright.mdx +3 -3
  71. package/docs/v7/presets/chrome-extension.mdx +223 -0
  72. package/docs/v7/presets/chrome.mdx +303 -0
  73. package/docs/v7/presets/electron.mdx +453 -0
  74. package/docs/v7/presets/vscode.mdx +417 -0
  75. package/docs/v7/presets/webapp.mdx +396 -0
  76. package/examples/run-tests-with-recording.sh +2 -2
  77. package/interfaces/cli/commands/init.js +358 -0
  78. package/interfaces/vitest-plugin.mjs +393 -103
  79. package/lib/core/Dashcam.js +506 -0
  80. package/lib/core/index.d.ts +150 -0
  81. package/lib/core/index.js +12 -0
  82. package/lib/presets/index.mjs +331 -0
  83. package/lib/vitest/hooks.d.ts +119 -0
  84. package/lib/vitest/hooks.mjs +316 -0
  85. package/lib/vitest/setup.mjs +44 -0
  86. package/package.json +13 -3
  87. package/sdk.d.ts +350 -44
  88. package/sdk.js +818 -105
  89. package/{self-hosted.yml → setup/aws/self-hosted.yml} +1 -1
  90. package/test/manual/test-console-logs.test.mjs +42 -0
  91. package/test/manual/test-init.sh +54 -0
  92. package/test/manual/test-provision-auth.mjs +22 -0
  93. package/test/testdriver/assert.test.mjs +41 -0
  94. package/test/testdriver/auto-cache-key-demo.test.mjs +56 -0
  95. package/test/testdriver/chrome-extension.test.mjs +89 -0
  96. package/{testdriver/acceptance-sdk → test/testdriver}/drag-and-drop.test.mjs +7 -19
  97. package/{testdriver/acceptance-sdk → test/testdriver}/element-not-found.test.mjs +6 -19
  98. package/{testdriver/acceptance-sdk → test/testdriver}/exec-js.test.mjs +6 -18
  99. package/{testdriver/acceptance-sdk → test/testdriver}/exec-output.test.mjs +9 -21
  100. package/{testdriver/acceptance-sdk → test/testdriver}/exec-pwsh.test.mjs +14 -26
  101. package/{testdriver/acceptance-sdk → test/testdriver}/focus-window.test.mjs +8 -20
  102. package/{testdriver/acceptance-sdk → test/testdriver}/formatted-logging.test.mjs +5 -20
  103. package/{testdriver/acceptance-sdk → test/testdriver}/hover-image.test.mjs +10 -19
  104. package/{testdriver/acceptance-sdk → test/testdriver}/hover-text-with-description.test.mjs +7 -19
  105. package/{testdriver/acceptance-sdk → test/testdriver}/hover-text.test.mjs +5 -19
  106. package/{testdriver/acceptance-sdk → test/testdriver}/match-image.test.mjs +7 -19
  107. package/{testdriver/acceptance-sdk → test/testdriver}/press-keys.test.mjs +5 -19
  108. package/{testdriver/acceptance-sdk → test/testdriver}/prompt.test.mjs +7 -19
  109. package/{testdriver/acceptance-sdk → test/testdriver}/scroll-keyboard.test.mjs +6 -20
  110. package/{testdriver/acceptance-sdk → test/testdriver}/scroll-until-image.test.mjs +6 -18
  111. package/test/testdriver/scroll-until-text.test.mjs +28 -0
  112. package/{testdriver/acceptance-sdk → test/testdriver}/scroll.test.mjs +12 -21
  113. package/test/testdriver/setup/lifecycleHelpers.mjs +262 -0
  114. package/{testdriver/acceptance-sdk → test/testdriver}/setup/testHelpers.mjs +25 -20
  115. package/test/testdriver/type.test.mjs +45 -0
  116. package/vitest.config.mjs +11 -56
  117. package/.github/dependabot.yml +0 -11
  118. package/.github/workflows/acceptance-linux.yml +0 -75
  119. package/.github/workflows/acceptance-sdk-tests.yml +0 -133
  120. package/.github/workflows/acceptance-tests.yml +0 -130
  121. package/.github/workflows/lint.yml +0 -27
  122. package/.github/workflows/publish-canary.yml +0 -40
  123. package/.github/workflows/publish-latest.yml +0 -61
  124. package/.github/workflows/test-install.yml +0 -29
  125. package/.vscode/extensions.json +0 -3
  126. package/.vscode/launch.json +0 -22
  127. package/.vscode/mcp.json +0 -9
  128. package/.vscode/settings.json +0 -14
  129. package/CODEOWNERS +0 -3
  130. package/MIGRATION.md +0 -389
  131. package/SDK_README.md +0 -1122
  132. package/_testdriver/acceptance/assert.yaml +0 -7
  133. package/_testdriver/acceptance/dashcam.yaml +0 -9
  134. package/_testdriver/acceptance/drag-and-drop.yaml +0 -49
  135. package/_testdriver/acceptance/embed.yaml +0 -9
  136. package/_testdriver/acceptance/exec-js.yaml +0 -29
  137. package/_testdriver/acceptance/exec-output.yaml +0 -43
  138. package/_testdriver/acceptance/exec-shell.yaml +0 -40
  139. package/_testdriver/acceptance/focus-window.yaml +0 -16
  140. package/_testdriver/acceptance/hover-image.yaml +0 -18
  141. package/_testdriver/acceptance/hover-text-with-description.yaml +0 -29
  142. package/_testdriver/acceptance/hover-text.yaml +0 -14
  143. package/_testdriver/acceptance/if-else.yaml +0 -31
  144. package/_testdriver/acceptance/match-image.yaml +0 -15
  145. package/_testdriver/acceptance/press-keys.yaml +0 -35
  146. package/_testdriver/acceptance/prompt.yaml +0 -11
  147. package/_testdriver/acceptance/remember.yaml +0 -27
  148. package/_testdriver/acceptance/screenshots/cart.png +0 -0
  149. package/_testdriver/acceptance/scroll-keyboard.yaml +0 -34
  150. package/_testdriver/acceptance/scroll-until-image.yaml +0 -26
  151. package/_testdriver/acceptance/scroll-until-text.yaml +0 -20
  152. package/_testdriver/acceptance/scroll.yaml +0 -33
  153. package/_testdriver/acceptance/snippets/login.yaml +0 -29
  154. package/_testdriver/acceptance/snippets/match-cart.yaml +0 -8
  155. package/_testdriver/acceptance/type.yaml +0 -29
  156. package/_testdriver/behavior/failure.yaml +0 -7
  157. package/_testdriver/behavior/hover-text.yaml +0 -13
  158. package/_testdriver/behavior/lifecycle/postrun.yaml +0 -10
  159. package/_testdriver/behavior/lifecycle/prerun.yaml +0 -8
  160. package/_testdriver/behavior/lifecycle/provision.yaml +0 -8
  161. package/_testdriver/behavior/secrets.yaml +0 -7
  162. package/_testdriver/edge-cases/dashcam-chrome.yaml +0 -8
  163. package/_testdriver/edge-cases/exec-pwsh-multiline.yaml +0 -10
  164. package/_testdriver/edge-cases/js-exception.yaml +0 -8
  165. package/_testdriver/edge-cases/js-promise.yaml +0 -19
  166. package/_testdriver/edge-cases/lifecycle/postrun.yaml +0 -10
  167. package/_testdriver/edge-cases/prompt-in-middle.yaml +0 -23
  168. package/_testdriver/edge-cases/prompt-nested.yaml +0 -7
  169. package/_testdriver/edge-cases/success-test.yaml +0 -9
  170. package/_testdriver/examples/android/example.yaml +0 -12
  171. package/_testdriver/examples/android/lifecycle/postrun.yaml +0 -11
  172. package/_testdriver/examples/android/lifecycle/provision.yaml +0 -47
  173. package/_testdriver/examples/android/readme.md +0 -7
  174. package/_testdriver/examples/chrome-extension/lifecycle/provision.yaml +0 -74
  175. package/_testdriver/examples/desktop/lifecycle/prerun.yaml +0 -0
  176. package/_testdriver/examples/desktop/lifecycle/provision.yaml +0 -64
  177. package/_testdriver/examples/vscode-extension/lifecycle/provision.yaml +0 -73
  178. package/_testdriver/examples/web/lifecycle/postrun.yaml +0 -7
  179. package/_testdriver/examples/web/lifecycle/prerun.yaml +0 -22
  180. package/_testdriver/lifecycle/postrun.yaml +0 -8
  181. package/_testdriver/lifecycle/prerun.yaml +0 -15
  182. package/_testdriver/lifecycle/provision.yaml +0 -25
  183. package/debug-screenshot-1763401388589.png +0 -0
  184. package/mcp-server/AI_GUIDELINES.md +0 -57
  185. package/scripts/view-test-results.mjs +0 -96
  186. package/styles/.vale-config/2-MDX.ini +0 -5
  187. package/styles/Microsoft/AMPM.yml +0 -9
  188. package/styles/Microsoft/Accessibility.yml +0 -30
  189. package/styles/Microsoft/Acronyms.yml +0 -64
  190. package/styles/Microsoft/Adverbs.yml +0 -272
  191. package/styles/Microsoft/Auto.yml +0 -11
  192. package/styles/Microsoft/Avoid.yml +0 -14
  193. package/styles/Microsoft/Contractions.yml +0 -50
  194. package/styles/Microsoft/Dashes.yml +0 -13
  195. package/styles/Microsoft/DateFormat.yml +0 -8
  196. package/styles/Microsoft/DateNumbers.yml +0 -40
  197. package/styles/Microsoft/DateOrder.yml +0 -8
  198. package/styles/Microsoft/Ellipses.yml +0 -9
  199. package/styles/Microsoft/FirstPerson.yml +0 -16
  200. package/styles/Microsoft/Foreign.yml +0 -13
  201. package/styles/Microsoft/Gender.yml +0 -8
  202. package/styles/Microsoft/GenderBias.yml +0 -42
  203. package/styles/Microsoft/GeneralURL.yml +0 -11
  204. package/styles/Microsoft/HeadingAcronyms.yml +0 -7
  205. package/styles/Microsoft/HeadingColons.yml +0 -8
  206. package/styles/Microsoft/HeadingPunctuation.yml +0 -13
  207. package/styles/Microsoft/Headings.yml +0 -28
  208. package/styles/Microsoft/Hyphens.yml +0 -14
  209. package/styles/Microsoft/Negative.yml +0 -13
  210. package/styles/Microsoft/Ordinal.yml +0 -13
  211. package/styles/Microsoft/OxfordComma.yml +0 -8
  212. package/styles/Microsoft/Passive.yml +0 -183
  213. package/styles/Microsoft/Percentages.yml +0 -7
  214. package/styles/Microsoft/Plurals.yml +0 -7
  215. package/styles/Microsoft/Quotes.yml +0 -7
  216. package/styles/Microsoft/RangeTime.yml +0 -13
  217. package/styles/Microsoft/Semicolon.yml +0 -8
  218. package/styles/Microsoft/SentenceLength.yml +0 -6
  219. package/styles/Microsoft/Spacing.yml +0 -8
  220. package/styles/Microsoft/Suspended.yml +0 -7
  221. package/styles/Microsoft/Terms.yml +0 -42
  222. package/styles/Microsoft/URLFormat.yml +0 -9
  223. package/styles/Microsoft/Units.yml +0 -16
  224. package/styles/Microsoft/Vocab.yml +0 -25
  225. package/styles/Microsoft/We.yml +0 -11
  226. package/styles/Microsoft/Wordiness.yml +0 -127
  227. package/styles/Microsoft/meta.json +0 -4
  228. package/styles/alex/Ablist.yml +0 -274
  229. package/styles/alex/Condescending.yml +0 -16
  230. package/styles/alex/Gendered.yml +0 -110
  231. package/styles/alex/LGBTQ.yml +0 -55
  232. package/styles/alex/OCD.yml +0 -10
  233. package/styles/alex/Press.yml +0 -12
  234. package/styles/alex/ProfanityLikely.yml +0 -1289
  235. package/styles/alex/ProfanityMaybe.yml +0 -282
  236. package/styles/alex/ProfanityUnlikely.yml +0 -251
  237. package/styles/alex/README.md +0 -27
  238. package/styles/alex/Race.yml +0 -85
  239. package/styles/alex/Suicide.yml +0 -26
  240. package/styles/alex/meta.json +0 -4
  241. package/styles/config/vocabularies/Docs/accept.txt +0 -47
  242. package/styles/config/vocabularies/Docs/reject.txt +0 -4
  243. package/styles/proselint/Airlinese.yml +0 -8
  244. package/styles/proselint/AnimalLabels.yml +0 -48
  245. package/styles/proselint/Annotations.yml +0 -9
  246. package/styles/proselint/Apologizing.yml +0 -8
  247. package/styles/proselint/Archaisms.yml +0 -52
  248. package/styles/proselint/But.yml +0 -8
  249. package/styles/proselint/Cliches.yml +0 -782
  250. package/styles/proselint/CorporateSpeak.yml +0 -30
  251. package/styles/proselint/Currency.yml +0 -5
  252. package/styles/proselint/Cursing.yml +0 -15
  253. package/styles/proselint/DateCase.yml +0 -7
  254. package/styles/proselint/DateMidnight.yml +0 -7
  255. package/styles/proselint/DateRedundancy.yml +0 -10
  256. package/styles/proselint/DateSpacing.yml +0 -7
  257. package/styles/proselint/DenizenLabels.yml +0 -52
  258. package/styles/proselint/Diacritical.yml +0 -95
  259. package/styles/proselint/GenderBias.yml +0 -45
  260. package/styles/proselint/GroupTerms.yml +0 -39
  261. package/styles/proselint/Hedging.yml +0 -8
  262. package/styles/proselint/Hyperbole.yml +0 -6
  263. package/styles/proselint/Jargon.yml +0 -11
  264. package/styles/proselint/LGBTOffensive.yml +0 -13
  265. package/styles/proselint/LGBTTerms.yml +0 -15
  266. package/styles/proselint/Malapropisms.yml +0 -8
  267. package/styles/proselint/Needless.yml +0 -358
  268. package/styles/proselint/Nonwords.yml +0 -38
  269. package/styles/proselint/Oxymorons.yml +0 -22
  270. package/styles/proselint/P-Value.yml +0 -6
  271. package/styles/proselint/RASSyndrome.yml +0 -30
  272. package/styles/proselint/README.md +0 -12
  273. package/styles/proselint/Skunked.yml +0 -13
  274. package/styles/proselint/Spelling.yml +0 -17
  275. package/styles/proselint/Typography.yml +0 -11
  276. package/styles/proselint/Uncomparables.yml +0 -50
  277. package/styles/proselint/Very.yml +0 -6
  278. package/styles/proselint/meta.json +0 -15
  279. package/styles/write-good/Cliches.yml +0 -702
  280. package/styles/write-good/E-Prime.yml +0 -32
  281. package/styles/write-good/Illusions.yml +0 -11
  282. package/styles/write-good/Passive.yml +0 -183
  283. package/styles/write-good/README.md +0 -27
  284. package/styles/write-good/So.yml +0 -5
  285. package/styles/write-good/ThereIs.yml +0 -6
  286. package/styles/write-good/TooWordy.yml +0 -221
  287. package/styles/write-good/Weasel.yml +0 -29
  288. package/styles/write-good/meta.json +0 -4
  289. package/test/mcp-example-test.yaml +0 -27
  290. package/test/test_parser.js +0 -47
  291. package/testdriver/acceptance-sdk/QUICK_REFERENCE.md +0 -61
  292. package/testdriver/acceptance-sdk/README.md +0 -128
  293. package/testdriver/acceptance-sdk/TEST_REPORTING.md +0 -245
  294. package/testdriver/acceptance-sdk/assert.test.mjs +0 -44
  295. package/testdriver/acceptance-sdk/scroll-until-text.test.mjs +0 -42
  296. package/testdriver/acceptance-sdk/setup/lifecycleHelpers.mjs +0 -239
  297. package/testdriver/acceptance-sdk/type-checking-demo.js +0 -49
  298. package/testdriver/acceptance-sdk/type.test.mjs +0 -84
  299. package/vale.ini +0 -18
  300. package/vitest.config.example.js +0 -19
  301. package/vitest.config.mjs.bak +0 -44
  302. /package/docs/{ARCHITECTURE.md → v7/_drafts/architecture.mdx} +0 -0
  303. /package/docs/{AWESOME_LOGS_QUICK_REF.md → v7/_drafts/awesome-logs-quick-ref.mdx} +0 -0
  304. /package/{CONTRIBUTING.md → docs/v7/_drafts/contributing.mdx} +0 -0
  305. /package/docs/v7/{guides → _drafts}/migration.mdx +0 -0
  306. /package/{PLUGIN_MIGRATION.md → docs/v7/_drafts/plugin-migration.mdx} +0 -0
  307. /package/{PROMPT_CACHE.md → docs/v7/_drafts/prompt-cache.mdx} +0 -0
  308. /package/docs/{SDK_AWESOME_LOGS.md → v7/_drafts/sdk-awesome-logs.mdx} +0 -0
  309. /package/docs/{sdk-browser-rendering.md → v7/_drafts/sdk-browser-rendering.mdx} +0 -0
  310. /package/{SDK_LOGGING.md → docs/v7/_drafts/sdk-logging.mdx} +0 -0
  311. /package/{SDK_MIGRATION.md → docs/v7/_drafts/sdk-migration.mdx} +0 -0
  312. /package/docs/{TEST_RECORDING.md → v7/_drafts/test-recording.mdx} +0 -0
  313. /package/docs/v7/{README.md → overview/readme.mdx} +0 -0
  314. /package/{debug-locate-response.js → test/manual/debug-locate-response.js} +0 -0
  315. /package/{test-find-api.js → test/manual/test-find-api.js} +0 -0
  316. /package/{test-prompt-cache.js → test/manual/test-prompt-cache.js} +0 -0
  317. /package/{test-sandbox-render.js → test/manual/test-sandbox-render.js} +0 -0
  318. /package/{test-sdk-methods.js → test/manual/test-sdk-methods.js} +0 -0
  319. /package/{test-sdk-refactor.js → test/manual/test-sdk-refactor.js} +0 -0
  320. /package/{test-stack-trace.mjs → test/manual/test-stack-trace.mjs} +0 -0
  321. /package/{verify-element-api.js → test/manual/verify-element-api.js} +0 -0
  322. /package/{verify-types.js → test/manual/verify-types.js} +0 -0
  323. /package/{testdriver/acceptance-sdk → test/testdriver}/setup/globalTeardown.mjs +0 -0
  324. /package/{testdriver/acceptance-sdk → test/testdriver}/setup/vitestSetup.mjs +0 -0
@@ -0,0 +1,535 @@
1
+ ---
2
+ title: "Using TestDriver with Vitest"
3
+ sidebarTitle: "Vitest Integration"
4
+ description: "Complete guide to integrating TestDriver with Vitest"
5
+ icon: "flask-vial"
6
+ ---
7
+
8
+ ## Overview
9
+
10
+ TestDriver integrates seamlessly with Vitest, providing three levels of API complexity to match your needs. From simple preset functions to full manual control, choose the approach that works best for your project.
11
+
12
+ ## Quick Start
13
+
14
+ ### 1. Install TestDriver
15
+
16
+ ```bash
17
+ npm install --save-dev testdriverai
18
+ ```
19
+
20
+ ### 2. Create Vitest Config
21
+
22
+ ```javascript vitest.config.mjs
23
+ import { defineConfig } from 'vitest/config';
24
+
25
+ export default defineConfig({
26
+ test: {
27
+ // Optional: Configure test timeout
28
+ testTimeout: 120000,
29
+ hookTimeout: 120000,
30
+ },
31
+ });
32
+ ```
33
+
34
+ ### 3. Write Your First Test
35
+
36
+ ```javascript example.test.js
37
+ import { test } from 'vitest';
38
+ import { chrome } from 'testdriverai/presets';
39
+
40
+ test('my first test', async (context) => {
41
+ const { testdriver } = await chrome(context, {
42
+ url: 'https://example.com'
43
+ });
44
+
45
+ await testdriver.find('More information link').click();
46
+ await testdriver.assert('IANA information page is visible');
47
+ });
48
+ ```
49
+
50
+ ### 4. Run Your Tests
51
+
52
+ ```bash
53
+ npx vitest
54
+ ```
55
+
56
+ That's it! TestDriver automatically handles all setup and teardown.
57
+
58
+ ## Three Levels of Integration
59
+
60
+ <CardGroup cols={3}>
61
+ <Card title="Provision API" icon="rocket" href="/v7/progressive-apis/PROVISION">
62
+ **Easiest** - One-line setup
63
+ ```javascript
64
+ const { testdriver } = await provision('chrome', { url }, context);
65
+ ```
66
+ </Card>
67
+
68
+ <Card title="Hooks API" icon="link" href="/v7/progressive-apis/HOOKS">
69
+ **Flexible** - More control
70
+ ```javascript
71
+ const client = useTestDriver(context);
72
+ const dashcam = useDashcam(context, client);
73
+ ```
74
+ </Card>
75
+
76
+ <Card title="Core Classes" icon="code" href="/v7/progressive-apis/CORE">
77
+ **Full Control** - Manual everything
78
+ ```javascript
79
+ const client = new TestDriver(apiKey);
80
+ await client.connect();
81
+ ```
82
+ </Card>
83
+ </CardGroup>
84
+
85
+ ## Complete Examples
86
+
87
+ ### Web Application Testing
88
+
89
+ ```javascript login.test.js
90
+ import { describe, test, expect } from 'vitest';
91
+ import { chrome } from 'testdriverai/presets';
92
+
93
+ describe('User Login', () => {
94
+ test('successful login flow', async (context) => {
95
+ const { testdriver, dashcam } = await chrome(context, {
96
+ url: 'https://myapp.com/login',
97
+ maximized: true
98
+ });
99
+
100
+ // Fill login form
101
+ await testdriver.find('email input').type('user@example.com');
102
+ await testdriver.find('password input').type('password123');
103
+ await testdriver.find('Login button').click();
104
+
105
+ // Verify dashboard loads
106
+ const result = await testdriver.assert('Welcome message is visible');
107
+ expect(result).toBeTruthy();
108
+
109
+ // Dashcam automatically saves replay URL
110
+ console.log('Replay:', dashcam.url);
111
+ });
112
+
113
+ test('invalid credentials error', async (context) => {
114
+ const { testdriver } = await chrome(context, {
115
+ url: 'https://myapp.com/login'
116
+ });
117
+
118
+ await testdriver.find('email input').type('wrong@example.com');
119
+ await testdriver.find('password input').type('wrongpass');
120
+ await testdriver.find('Login button').click();
121
+
122
+ await testdriver.assert('Invalid credentials error appears');
123
+ });
124
+ });
125
+ ```
126
+
127
+ ### VS Code Extension Testing
128
+
129
+ ```javascript extension.test.js
130
+ import { test } from 'vitest';
131
+ import { vscode } from 'testdriverai/presets';
132
+
133
+ test('create new python file', async (context) => {
134
+ const { vscode } = await vscode(context, {
135
+ workspace: '/tmp/test-project',
136
+ extensions: ['ms-python.python']
137
+ });
138
+
139
+ // Open command palette
140
+ await vscode.pressKeys(['cmd', 'shift', 'p']);
141
+
142
+ // Create new Python file
143
+ await vscode.type('Python: Create New File');
144
+ await vscode.pressKeys(['enter']);
145
+
146
+ // Verify file created
147
+ await vscode.assert('Untitled Python file is open');
148
+ });
149
+ ```
150
+
151
+ ### Electron App Testing
152
+
153
+ ```javascript electron-app.test.js
154
+ import { test } from 'vitest';
155
+ import { electron } from 'testdriverai/presets';
156
+
157
+ test('file menu operations', async (context) => {
158
+ const { app } = await electron(context, {
159
+ appPath: './dist/my-app',
160
+ args: ['--enable-logging']
161
+ });
162
+
163
+ await app.find('File menu').click();
164
+ await app.find('New Document').click();
165
+
166
+ await app.assert('New document window opens');
167
+ });
168
+ ```
169
+
170
+ ### Using Multiple Presets
171
+
172
+ ```javascript multi-app.test.js
173
+ import { test } from 'vitest';
174
+ import { chrome, vscode } from 'testdriverai/presets';
175
+
176
+ test('test chrome and vscode together', async (context) => {
177
+ // Both share the same Vitest context for cleanup
178
+ const browser = await chrome(context, {
179
+ url: 'https://example.com'
180
+ });
181
+
182
+ const editor = await vscode(context, {
183
+ workspace: '/tmp/project'
184
+ });
185
+
186
+ // Use both in the same test
187
+ await browser.testdriver.find('link').click();
188
+ await editor.vscode.find('File').click();
189
+ });
190
+ ```
191
+
192
+ ## Test Lifecycle
193
+
194
+ TestDriver automatically manages the entire test lifecycle:
195
+
196
+ ```javascript
197
+ test('lifecycle example', async (context) => {
198
+ // 1. Setup happens automatically when you call preset
199
+ const { testdriver, dashcam } = await chrome(context, { url });
200
+
201
+ // 2. Your test code runs
202
+ await testdriver.find('button').click();
203
+
204
+ // 3. Teardown happens automatically after test completes
205
+ // - Dashcam stops and saves replay URL
206
+ // - TestDriver disconnects from sandbox
207
+ // - All resources are cleaned up
208
+ });
209
+ ```
210
+
211
+ ### Automatic Cleanup
212
+
213
+ Even if your test fails or throws an error, cleanup still happens:
214
+
215
+ ```javascript
216
+ test('error handling', async (context) => {
217
+ const { testdriver } = await chrome(context, { url });
218
+
219
+ try {
220
+ await testdriver.find('non-existent element').click();
221
+ } catch (error) {
222
+ // Cleanup STILL happens automatically via Vitest hooks
223
+ console.error('Test failed:', error);
224
+ throw error;
225
+ }
226
+ // No need for finally block or manual cleanup
227
+ });
228
+ ```
229
+
230
+ ## Configuration
231
+
232
+ ### Environment Variables
233
+
234
+ Create a `.env` file in your project root:
235
+
236
+ ```bash .env
237
+ TD_API_KEY=your-api-key-here
238
+ TD_API_ROOT=https://testdriver-api.onrender.com
239
+ ```
240
+
241
+ TestDriver automatically reads these when initializing.
242
+
243
+ ### Vitest Config Options
244
+
245
+ ```javascript vitest.config.mjs
246
+ import { defineConfig } from 'vitest/config';
247
+
248
+ export default defineConfig({
249
+ test: {
250
+ // Recommended: Increase timeouts for UI testing
251
+ testTimeout: 120000, // 2 minutes per test
252
+ hookTimeout: 120000, // 2 minutes for setup/teardown
253
+
254
+ // Optional: Run tests sequentially for resource-intensive tests
255
+ threads: false,
256
+
257
+ // Optional: Limit concurrent tests
258
+ maxConcurrency: 3,
259
+
260
+ // Optional: Enable file watching
261
+ watch: false,
262
+ },
263
+ });
264
+ ```
265
+
266
+ ### Per-Test Configuration
267
+
268
+ Override defaults for specific tests:
269
+
270
+ ```javascript
271
+ test('long running test', async (context) => {
272
+ const { testdriver } = await chrome(context, {
273
+ url: 'https://slow-app.com',
274
+ dashcam: false, // Disable recording for faster execution
275
+ maximized: false,
276
+ });
277
+
278
+ // Your test code
279
+ }, { timeout: 180000 }); // 3-minute timeout for this test only
280
+ ```
281
+
282
+ ## Running Tests
283
+
284
+ ### Basic Commands
285
+
286
+ ```bash
287
+ # Run all tests
288
+ npx vitest
289
+
290
+ # Run specific file
291
+ npx vitest login.test.js
292
+
293
+ # Run in watch mode
294
+ npx vitest --watch
295
+
296
+ # Run with coverage
297
+ npx vitest --coverage
298
+
299
+ # Run tests matching pattern
300
+ npx vitest --grep "login"
301
+ ```
302
+
303
+ ### CI/CD Integration
304
+
305
+ ```yaml .github/workflows/test.yml
306
+ name: TestDriver Tests
307
+
308
+ on: [push, pull_request]
309
+
310
+ jobs:
311
+ test:
312
+ runs-on: ubuntu-latest
313
+ steps:
314
+ - uses: actions/checkout@v3
315
+
316
+ - name: Setup Node.js
317
+ uses: actions/setup-node@v3
318
+ with:
319
+ node-version: '18'
320
+
321
+ - name: Install dependencies
322
+ run: npm install
323
+
324
+ - name: Run tests
325
+ env:
326
+ TD_API_KEY: ${{ secrets.TD_API_KEY }}
327
+ run: npx vitest --run
328
+ ```
329
+
330
+ ## Advanced Patterns
331
+
332
+ ### Shared Setup with beforeEach
333
+
334
+ ```javascript
335
+ import { describe, test, beforeEach } from 'vitest';
336
+ import { chrome } from 'testdriverai/presets';
337
+
338
+ describe('Dashboard Tests', () => {
339
+ let testdriver;
340
+
341
+ beforeEach(async (context) => {
342
+ // Setup runs before each test
343
+ const result = await chrome(context, {
344
+ url: 'https://myapp.com'
345
+ });
346
+ testdriver = result.testdriver;
347
+
348
+ // Shared login
349
+ await testdriver.find('email').type('user@example.com');
350
+ await testdriver.find('password').type('password');
351
+ await testdriver.find('Login').click();
352
+ });
353
+
354
+ test('view profile', async () => {
355
+ await testdriver.find('Profile link').click();
356
+ await testdriver.assert('Profile page loads');
357
+ });
358
+
359
+ test('view settings', async () => {
360
+ await testdriver.find('Settings link').click();
361
+ await testdriver.assert('Settings page loads');
362
+ });
363
+ });
364
+ ```
365
+
366
+ ### Parameterized Tests
367
+
368
+ ```javascript
369
+ import { test } from 'vitest';
370
+ import { chrome } from 'testdriverai/presets';
371
+
372
+ const testCases = [
373
+ { browser: 'chrome', os: 'linux' },
374
+ { browser: 'chrome', os: 'windows' },
375
+ { browser: 'chrome', os: 'mac' },
376
+ ];
377
+
378
+ testCases.forEach(({ browser, os }) => {
379
+ test(`login on ${os}`, async (context) => {
380
+ const { testdriver } = await chrome(context, {
381
+ url: 'https://myapp.com',
382
+ os
383
+ });
384
+
385
+ await testdriver.find('Login').click();
386
+ await testdriver.assert('Login successful');
387
+ });
388
+ });
389
+ ```
390
+
391
+ ### Custom Helpers
392
+
393
+ ```javascript helpers.js
394
+ import { chrome } from 'testdriverai/presets';
395
+
396
+ export async function loginAsUser(context, email, password) {
397
+ const { testdriver } = await chrome(context, {
398
+ url: 'https://myapp.com/login'
399
+ });
400
+
401
+ await testdriver.find('email input').type(email);
402
+ await testdriver.find('password input').type(password);
403
+ await testdriver.find('Login button').click();
404
+
405
+ return testdriver;
406
+ }
407
+ ```
408
+
409
+ ```javascript test.js
410
+ import { test } from 'vitest';
411
+ import { loginAsUser } from './helpers.js';
412
+
413
+ test('logged in user can view dashboard', async (context) => {
414
+ const testdriver = await loginAsUser(context, 'user@example.com', 'pass123');
415
+
416
+ await testdriver.find('Dashboard link').click();
417
+ await testdriver.assert('Dashboard is visible');
418
+ });
419
+ ```
420
+
421
+ ## Best Practices
422
+
423
+ ### 1. Use Descriptive Test Names
424
+
425
+ ```javascript
426
+ // ✅ Good
427
+ test('user can login with valid credentials and view dashboard', async (context) => {
428
+
429
+ // ❌ Bad
430
+ test('test1', async (context) => {
431
+ ```
432
+
433
+ ### 2. Enable Dashcam for Debugging
434
+
435
+ ```javascript
436
+ test('complex interaction', async (context) => {
437
+ const { testdriver, dashcam } = await chrome(context, {
438
+ url: 'https://myapp.com',
439
+ dashcam: true // Always enable for debugging
440
+ });
441
+
442
+ // If test fails, check dashcam.url for replay
443
+ });
444
+ ```
445
+
446
+ ### 3. Use Assertions Liberally
447
+
448
+ ```javascript
449
+ test('multi-step flow', async (context) => {
450
+ const { testdriver } = await chrome(context, { url });
451
+
452
+ await testdriver.find('Step 1').click();
453
+ await testdriver.assert('Step 1 completed'); // Verify each step
454
+
455
+ await testdriver.find('Step 2').click();
456
+ await testdriver.assert('Step 2 completed');
457
+ });
458
+ ```
459
+
460
+ ### 4. Keep Tests Focused
461
+
462
+ ```javascript
463
+ // ✅ Good - One test per scenario
464
+ test('user can login', async (context) => { /* ... */ });
465
+ test('user can logout', async (context) => { /* ... */ });
466
+
467
+ // ❌ Bad - Testing too many things
468
+ test('user can login and logout and change settings and...', async (context) => { /* ... */ });
469
+ ```
470
+
471
+ ### 5. Use Environment Variables for Secrets
472
+
473
+ ```javascript
474
+ // ✅ Good
475
+ await testdriver.find('password').type(process.env.TEST_PASSWORD);
476
+
477
+ // ❌ Bad
478
+ await testdriver.find('password').type('hardcoded-password');
479
+ ```
480
+
481
+ ## Troubleshooting
482
+
483
+ ### Tests Timeout
484
+
485
+ Increase timeout in vitest.config.mjs:
486
+
487
+ ```javascript
488
+ export default defineConfig({
489
+ test: {
490
+ testTimeout: 180000, // 3 minutes
491
+ },
492
+ });
493
+ ```
494
+
495
+ ### Cleanup Not Working
496
+
497
+ Make sure you're passing the `context` parameter:
498
+
499
+ ```javascript
500
+ // ✅ Correct
501
+ test('my test', async (context) => {
502
+ await chrome(context, { url });
503
+ });
504
+
505
+ // ❌ Wrong - cleanup won't work
506
+ test('my test', async () => {
507
+ await chrome({}, { url });
508
+ });
509
+ ```
510
+
511
+ ### Dashcam URL Not Available
512
+
513
+ Ensure Dashcam is enabled and check for errors:
514
+
515
+ ```javascript
516
+ const { testdriver, dashcam } = await chrome(context, {
517
+ url: 'https://example.com',
518
+ dashcam: true
519
+ });
520
+
521
+ if (dashcam) {
522
+ console.log('Replay URL:', dashcam.url);
523
+ } else {
524
+ console.error('Dashcam not initialized');
525
+ }
526
+ ```
527
+
528
+ ## See Also
529
+
530
+ - [Provision API](/v7/progressive-apis/PROVISION) - One-line setup for common apps
531
+ - [Hooks API](/v7/progressive-apis/HOOKS) - Flexible lifecycle control
532
+ - [Chrome Preset](/v7/presets/chrome) - Browser testing
533
+ - [VS Code Preset](/v7/presets/vscode) - Extension testing
534
+ - [Electron Preset](/v7/presets/electron) - Desktop app testing
535
+ - [Vitest Plugin](/v7/guides/vitest-plugin) - Test recording and reporting
@@ -1,18 +1,18 @@
1
1
  ---
2
- title: "ai()"
3
- sidebarTitle: "ai"
2
+ title: "act()"
3
+ sidebarTitle: "act"
4
4
  description: "Execute natural language tasks using AI"
5
5
  icon: "wand-magic-sparkles"
6
6
  ---
7
7
 
8
8
  ## Overview
9
9
 
10
- The `ai()` method allows you to execute complex tasks using natural language descriptions. TestDriver's AI will figure out the steps needed to accomplish the task.
10
+ The `act()` method allows you to execute complex tasks using natural language descriptions. TestDriver's AI will figure out the steps needed to accomplish the task.
11
11
 
12
12
  ## Syntax
13
13
 
14
14
  ```javascript
15
- await testdriver.ai(task, options)
15
+ await testdriver.act(task, options)
16
16
  ```
17
17
 
18
18
  ## Parameters
@@ -41,20 +41,20 @@ await testdriver.ai(task, options)
41
41
 
42
42
  ```javascript
43
43
  // Simple task execution
44
- await testdriver.ai('Click the submit button');
44
+ await testdriver.act('Click the submit button');
45
45
 
46
46
  // Complex multi-step task
47
- await testdriver.ai('Fill out the contact form and submit it');
47
+ await testdriver.act('Fill out the contact form and submit it');
48
48
 
49
49
  // Navigation task
50
- await testdriver.ai('Go to the settings page and enable notifications');
50
+ await testdriver.act('Go to the settings page and enable notifications');
51
51
  ```
52
52
 
53
53
  ### With Validation
54
54
 
55
55
  ```javascript
56
56
  // AI will verify the task completed successfully
57
- const result = await testdriver.ai('Complete the checkout process', {
57
+ const result = await testdriver.act('Complete the checkout process', {
58
58
  validateAndLoop: true
59
59
  });
60
60
 
@@ -65,10 +65,10 @@ console.log('Task result:', result);
65
65
 
66
66
  ```javascript
67
67
  // The AI will break down complex tasks
68
- await testdriver.ai('Search for "laptop", add the first result to cart, and proceed to checkout');
68
+ await testdriver.act('Search for "laptop", add the first result to cart, and proceed to checkout');
69
69
 
70
70
  // UI exploration
71
- await testdriver.ai('Find and click all menu items to explore the application');
71
+ await testdriver.act('Find and click all menu items to explore the application');
72
72
  ```
73
73
 
74
74
  ## Use Cases
@@ -78,8 +78,8 @@ await testdriver.ai('Find and click all menu items to explore the application');
78
78
  Use AI to explore unfamiliar applications:
79
79
 
80
80
  ```javascript
81
- await testdriver.ai('Explore the main navigation menu');
82
- await testdriver.ai('Try to find the user profile settings');
81
+ await testdriver.act('Explore the main navigation menu');
82
+ await testdriver.act('Try to find the user profile settings');
83
83
  ```
84
84
  </Accordion>
85
85
 
@@ -87,8 +87,8 @@ await testdriver.ai('Find and click all menu items to explore the application');
87
87
  Let AI handle multi-step processes:
88
88
 
89
89
  ```javascript
90
- await testdriver.ai('Complete the multi-step registration form');
91
- await testdriver.ai('Configure all the advanced settings to default values');
90
+ await testdriver.act('Complete the multi-step registration form');
91
+ await testdriver.act('Configure all the advanced settings to default values');
92
92
  ```
93
93
  </Accordion>
94
94
 
@@ -96,8 +96,8 @@ await testdriver.ai('Find and click all menu items to explore the application');
96
96
  When exact element locations aren't critical:
97
97
 
98
98
  ```javascript
99
- await testdriver.ai('Close any popup dialogs');
100
- await testdriver.ai('Accept the cookie consent if it appears');
99
+ await testdriver.act('Close any popup dialogs');
100
+ await testdriver.act('Accept the cookie consent if it appears');
101
101
  ```
102
102
  </Accordion>
103
103
  </AccordionGroup>
@@ -109,13 +109,13 @@ await testdriver.ai('Find and click all menu items to explore the application');
109
109
 
110
110
  ```javascript
111
111
  // ✅ Good
112
- await testdriver.ai('Add the first product to the shopping cart');
112
+ await testdriver.act('Add the first product to the shopping cart');
113
113
 
114
114
  // ❌ Too vague
115
- await testdriver.ai('do something');
115
+ await testdriver.act('do something');
116
116
 
117
117
  // ❌ Too specific (defeats the purpose)
118
- await testdriver.ai('click at coordinates 500, 300');
118
+ await testdriver.act('click at coordinates 500, 300');
119
119
  ```
120
120
  </Check>
121
121
 
@@ -124,7 +124,7 @@ await testdriver.ai('Find and click all menu items to explore the application');
124
124
 
125
125
  ```javascript
126
126
  // Use AI for setup
127
- await testdriver.ai('Navigate to the login page');
127
+ await testdriver.act('Navigate to the login page');
128
128
 
129
129
  // Use explicit methods for critical steps
130
130
  const usernameField = await testdriver.find('username input');
@@ -141,7 +141,7 @@ await testdriver.ai('Find and click all menu items to explore the application');
141
141
 
142
142
  ## When to Use AI vs Explicit Methods
143
143
 
144
- ### Use `ai()` when:
144
+ ### Use `act()` when:
145
145
  - Exploring unfamiliar applications
146
146
  - Handling optional UI elements (popups, cookies, etc.)
147
147
  - Prototyping tests quickly
@@ -177,8 +177,8 @@ describe('E-commerce Flow with AI', () => {
177
177
  await testdriver.focusApplication('Google Chrome');
178
178
 
179
179
  // Use AI for navigation and exploration
180
- await testdriver.ai('Browse to the electronics section');
181
- await testdriver.ai('Find and add a laptop to the cart');
180
+ await testdriver.act('Browse to the electronics section');
181
+ await testdriver.act('Find and add a laptop to the cart');
182
182
 
183
183
  // Use explicit methods for critical steps
184
184
  const cartIcon = await testdriver.find('shopping cart icon');
@@ -188,7 +188,7 @@ describe('E-commerce Flow with AI', () => {
188
188
  console.log('Cart total:', total);
189
189
 
190
190
  // Use AI for checkout flow
191
- await testdriver.ai('Proceed to checkout and fill in shipping details', {
191
+ await testdriver.act('Proceed to checkout and fill in shipping details', {
192
192
  validateAndLoop: true
193
193
  });
194
194
 
@@ -18,7 +18,7 @@ const testdriver = new TestDriver(apiKey, options)
18
18
  ### Parameters
19
19
 
20
20
  <ParamField path="apiKey" type="string" required>
21
- Your TestDriver API key from the [dashboard](https://app.testdriver.ai/team)
21
+ Your TestDriver API key from the [dashboard](https://console.testdriver.ai/team)
22
22
  </ParamField>
23
23
 
24
24
  <ParamField path="options" type="object">