testdriverai 7.1.0 → 7.1.2

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 (325) hide show
  1. package/.env.example +2 -0
  2. package/.github/workflows/linux-tests.yml +28 -0
  3. package/agent/index.js +18 -45
  4. package/agent/interface.js +13 -2
  5. package/agent/lib/commands.js +1 -1
  6. package/agent/lib/redraw.js +1 -1
  7. package/agent/lib/sandbox.js +30 -2
  8. package/agent/lib/valid-version.js +2 -2
  9. package/debugger/index.html +1 -1
  10. package/docs/docs.json +140 -131
  11. package/docs/v6/getting-started/self-hosting.mdx +3 -2
  12. package/docs/v7/_drafts/agents.mdx +852 -0
  13. package/docs/v7/_drafts/auto-cache-key.mdx +167 -0
  14. package/docs/v7/{guides → _drafts}/caching-selectors.mdx +125 -17
  15. package/docs/v7/_drafts/dashcam-title-feature.mdx +89 -0
  16. package/docs/v7/_drafts/error-handling.mdx +501 -0
  17. package/docs/v7/_drafts/implementation-plan.mdx +994 -0
  18. package/docs/v7/_drafts/init-command.mdx +95 -0
  19. package/docs/v7/_drafts/optimal-sdk-design.mdx +1348 -0
  20. package/docs/v7/_drafts/plugin-migration.mdx +222 -0
  21. package/docs/v7/_drafts/prompt-cache.mdx +200 -0
  22. package/docs/{QUICK_START_TEST_RECORDING.md → v7/_drafts/quick-start-test-recording.mdx} +3 -3
  23. package/docs/v7/_drafts/sdk-logging.mdx +222 -0
  24. package/docs/v7/_drafts/sdk-migration.mdx +474 -0
  25. package/docs/v7/_drafts/sdk-v7-complete.mdx +345 -0
  26. package/docs/v7/{guides → _drafts}/self-hosting.mdx +1 -1
  27. package/docs/v7/{guides → _drafts}/troubleshooting.mdx +2 -2
  28. package/docs/v7/{guides → _drafts}/vitest-plugin.mdx +4 -4
  29. package/docs/v7/api/{ai.mdx → act.mdx} +24 -24
  30. package/docs/v7/api/client.mdx +1 -1
  31. package/docs/v7/api/dashcam.mdx +2 -2
  32. package/docs/v7/api/elements.mdx +143 -41
  33. package/docs/v7/api/find.mdx +258 -0
  34. package/docs/v7/api/type.mdx +51 -7
  35. package/docs/v7/features/ai-native.mdx +427 -0
  36. package/docs/v7/features/easy-to-write.mdx +351 -0
  37. package/docs/v7/features/enterprise.mdx +540 -0
  38. package/docs/v7/features/fast.mdx +424 -0
  39. package/docs/v7/features/observable.mdx +623 -0
  40. package/docs/v7/features/powerful.mdx +531 -0
  41. package/docs/v7/features/scalable.mdx +417 -0
  42. package/docs/v7/features/stable.mdx +514 -0
  43. package/docs/v7/getting-started/configuration.mdx +1 -1
  44. package/docs/v7/getting-started/generating-tests.mdx +525 -0
  45. package/docs/v7/getting-started/installation.mdx +486 -0
  46. package/docs/v7/getting-started/quickstart.mdx +51 -5
  47. package/docs/v7/getting-started/running-and-debugging.mdx +511 -0
  48. package/docs/v7/getting-started/setting-up-in-ci.mdx +612 -0
  49. package/docs/v7/getting-started/writing-tests.mdx +535 -0
  50. package/docs/v7/overview/what-is-testdriver.mdx +398 -0
  51. package/docs/v7/playwright.mdx +3 -3
  52. package/docs/v7/presets/chrome.mdx +16 -0
  53. package/docs/v7/presets/electron.mdx +18 -0
  54. package/docs/v7/presets/vscode.mdx +19 -0
  55. package/examples/run-tests-with-recording.sh +70 -0
  56. package/examples/screenshot-example.js +63 -0
  57. package/examples/sdk-awesome-logs-demo.js +177 -0
  58. package/examples/sdk-cache-thresholds.js +96 -0
  59. package/examples/sdk-element-properties.js +155 -0
  60. package/examples/sdk-simple-example.js +65 -0
  61. package/examples/test-recording-example.test.js +166 -0
  62. package/interfaces/cli/commands/init.js +358 -0
  63. package/interfaces/vitest-plugin.mjs +214 -10
  64. package/{src → lib}/core/Dashcam.js +41 -4
  65. package/{src → lib}/vitest/hooks.mjs +118 -100
  66. package/lib/vitest/setup.mjs +44 -0
  67. package/package.json +9 -10
  68. package/sdk.d.ts +15 -2
  69. package/sdk.js +72 -17
  70. package/{self-hosted.yml → setup/aws/self-hosted.yml} +1 -1
  71. package/{testdriver/acceptance-sdk → test/manual}/test-console-logs.test.mjs +1 -1
  72. package/test/manual/test-find-api.js +73 -0
  73. package/test/manual/test-init.sh +54 -0
  74. package/test/manual/test-prompt-cache.js +96 -0
  75. package/test/manual/test-provision-auth.mjs +22 -0
  76. package/test/manual/test-sandbox-render.js +28 -0
  77. package/test/manual/test-sdk-methods.js +15 -0
  78. package/test/manual/test-sdk-refactor.js +53 -0
  79. package/test/manual/test-stack-trace.mjs +57 -0
  80. package/test/testdriver/assert.test.mjs +41 -0
  81. package/{testdriver/acceptance-sdk → test/testdriver}/auto-cache-key-demo.test.mjs +1 -1
  82. package/{testdriver/acceptance-sdk → test/testdriver}/drag-and-drop.test.mjs +1 -1
  83. package/{testdriver/acceptance-sdk → test/testdriver}/element-not-found.test.mjs +1 -1
  84. package/{testdriver/acceptance-sdk → test/testdriver}/exec-js.test.mjs +1 -1
  85. package/{testdriver/acceptance-sdk → test/testdriver}/exec-output.test.mjs +3 -3
  86. package/{testdriver/acceptance-sdk → test/testdriver}/exec-pwsh.test.mjs +3 -3
  87. package/{testdriver/acceptance-sdk → test/testdriver}/focus-window.test.mjs +1 -1
  88. package/{testdriver/acceptance-sdk → test/testdriver}/formatted-logging.test.mjs +1 -1
  89. package/{testdriver/acceptance-sdk → test/testdriver}/hover-image.test.mjs +1 -1
  90. package/{testdriver/acceptance-sdk → test/testdriver}/hover-text-with-description.test.mjs +1 -1
  91. package/{testdriver/acceptance-sdk → test/testdriver}/hover-text.test.mjs +1 -1
  92. package/{testdriver/acceptance-sdk → test/testdriver}/match-image.test.mjs +1 -1
  93. package/{testdriver/acceptance-sdk → test/testdriver}/press-keys.test.mjs +1 -1
  94. package/{testdriver/acceptance-sdk → test/testdriver}/prompt.test.mjs +2 -2
  95. package/{testdriver/acceptance-sdk → test/testdriver}/scroll-keyboard.test.mjs +1 -1
  96. package/{testdriver/acceptance-sdk → test/testdriver}/scroll-until-image.test.mjs +1 -1
  97. package/{testdriver/acceptance-sdk → test/testdriver}/scroll-until-text.test.mjs +1 -1
  98. package/{testdriver/acceptance-sdk → test/testdriver}/scroll.test.mjs +1 -1
  99. package/{src/vitest/lifecycle.mjs → test/testdriver/setup/lifecycleHelpers.mjs} +84 -99
  100. package/test/testdriver/setup/testHelpers.mjs +653 -0
  101. package/{testdriver/acceptance-sdk → test/testdriver}/type.test.mjs +1 -1
  102. package/vitest.config.mjs +8 -59
  103. package/.github/dependabot.yml +0 -11
  104. package/.github/workflows/acceptance-linux.yml +0 -75
  105. package/.github/workflows/acceptance-sdk-tests.yml +0 -133
  106. package/.github/workflows/acceptance-tests.yml +0 -130
  107. package/.github/workflows/lint.yml +0 -27
  108. package/.github/workflows/publish-canary.yml +0 -40
  109. package/.github/workflows/publish-latest.yml +0 -61
  110. package/.github/workflows/test-install.yml +0 -29
  111. package/.vscode/extensions.json +0 -3
  112. package/.vscode/launch.json +0 -22
  113. package/.vscode/settings.json +0 -14
  114. package/AGENTS.md +0 -550
  115. package/CODEOWNERS +0 -2
  116. package/_testdriver/acceptance/assert.yaml +0 -7
  117. package/_testdriver/acceptance/dashcam.yaml +0 -9
  118. package/_testdriver/acceptance/drag-and-drop.yaml +0 -49
  119. package/_testdriver/acceptance/embed.yaml +0 -9
  120. package/_testdriver/acceptance/exec-js.yaml +0 -29
  121. package/_testdriver/acceptance/exec-output.yaml +0 -43
  122. package/_testdriver/acceptance/exec-shell.yaml +0 -40
  123. package/_testdriver/acceptance/focus-window.yaml +0 -16
  124. package/_testdriver/acceptance/hover-image.yaml +0 -18
  125. package/_testdriver/acceptance/hover-text-with-description.yaml +0 -29
  126. package/_testdriver/acceptance/hover-text.yaml +0 -14
  127. package/_testdriver/acceptance/if-else.yaml +0 -31
  128. package/_testdriver/acceptance/match-image.yaml +0 -15
  129. package/_testdriver/acceptance/press-keys.yaml +0 -35
  130. package/_testdriver/acceptance/prompt.yaml +0 -11
  131. package/_testdriver/acceptance/remember.yaml +0 -27
  132. package/_testdriver/acceptance/screenshots/cart.png +0 -0
  133. package/_testdriver/acceptance/scroll-keyboard.yaml +0 -34
  134. package/_testdriver/acceptance/scroll-until-image.yaml +0 -26
  135. package/_testdriver/acceptance/scroll-until-text.yaml +0 -20
  136. package/_testdriver/acceptance/scroll.yaml +0 -33
  137. package/_testdriver/acceptance/snippets/login.yaml +0 -29
  138. package/_testdriver/acceptance/snippets/match-cart.yaml +0 -8
  139. package/_testdriver/acceptance/type.yaml +0 -29
  140. package/_testdriver/behavior/failure.yaml +0 -7
  141. package/_testdriver/behavior/hover-text.yaml +0 -13
  142. package/_testdriver/behavior/lifecycle/postrun.yaml +0 -10
  143. package/_testdriver/behavior/lifecycle/prerun.yaml +0 -8
  144. package/_testdriver/behavior/lifecycle/provision.yaml +0 -8
  145. package/_testdriver/behavior/secrets.yaml +0 -7
  146. package/_testdriver/edge-cases/dashcam-chrome.yaml +0 -8
  147. package/_testdriver/edge-cases/exec-pwsh-multiline.yaml +0 -10
  148. package/_testdriver/edge-cases/js-exception.yaml +0 -8
  149. package/_testdriver/edge-cases/js-promise.yaml +0 -19
  150. package/_testdriver/edge-cases/lifecycle/postrun.yaml +0 -10
  151. package/_testdriver/edge-cases/prompt-in-middle.yaml +0 -23
  152. package/_testdriver/edge-cases/prompt-nested.yaml +0 -7
  153. package/_testdriver/edge-cases/success-test.yaml +0 -9
  154. package/_testdriver/examples/android/example.yaml +0 -12
  155. package/_testdriver/examples/android/lifecycle/postrun.yaml +0 -11
  156. package/_testdriver/examples/android/lifecycle/provision.yaml +0 -47
  157. package/_testdriver/examples/android/readme.md +0 -7
  158. package/_testdriver/examples/chrome-extension/lifecycle/provision.yaml +0 -74
  159. package/_testdriver/examples/desktop/lifecycle/prerun.yaml +0 -0
  160. package/_testdriver/examples/desktop/lifecycle/provision.yaml +0 -64
  161. package/_testdriver/examples/vscode-extension/lifecycle/provision.yaml +0 -73
  162. package/_testdriver/examples/web/lifecycle/postrun.yaml +0 -7
  163. package/_testdriver/examples/web/lifecycle/prerun.yaml +0 -22
  164. package/_testdriver/lifecycle/postrun.yaml +0 -8
  165. package/_testdriver/lifecycle/prerun.yaml +0 -15
  166. package/_testdriver/lifecycle/provision.yaml +0 -25
  167. package/docs/v7/guides/ci-cd/azure.mdx +0 -587
  168. package/docs/v7/guides/ci-cd/circleci.mdx +0 -523
  169. package/docs/v7/guides/ci-cd/github-actions.mdx +0 -457
  170. package/docs/v7/guides/ci-cd/gitlab.mdx +0 -498
  171. package/docs/v7/guides/ci-cd/jenkins.mdx +0 -664
  172. package/docs/v7/guides/ci-cd/travis.mdx +0 -438
  173. package/scripts/view-test-results.mjs +0 -96
  174. package/src/vitest/extended.mjs +0 -108
  175. package/src/vitest/index.mjs +0 -64
  176. package/src/vitest/utils.mjs +0 -150
  177. package/styles/.vale-config/2-MDX.ini +0 -5
  178. package/styles/Microsoft/AMPM.yml +0 -9
  179. package/styles/Microsoft/Accessibility.yml +0 -30
  180. package/styles/Microsoft/Acronyms.yml +0 -64
  181. package/styles/Microsoft/Adverbs.yml +0 -272
  182. package/styles/Microsoft/Auto.yml +0 -11
  183. package/styles/Microsoft/Avoid.yml +0 -14
  184. package/styles/Microsoft/Contractions.yml +0 -50
  185. package/styles/Microsoft/Dashes.yml +0 -13
  186. package/styles/Microsoft/DateFormat.yml +0 -8
  187. package/styles/Microsoft/DateNumbers.yml +0 -40
  188. package/styles/Microsoft/DateOrder.yml +0 -8
  189. package/styles/Microsoft/Ellipses.yml +0 -9
  190. package/styles/Microsoft/FirstPerson.yml +0 -16
  191. package/styles/Microsoft/Foreign.yml +0 -13
  192. package/styles/Microsoft/Gender.yml +0 -8
  193. package/styles/Microsoft/GenderBias.yml +0 -42
  194. package/styles/Microsoft/GeneralURL.yml +0 -11
  195. package/styles/Microsoft/HeadingAcronyms.yml +0 -7
  196. package/styles/Microsoft/HeadingColons.yml +0 -8
  197. package/styles/Microsoft/HeadingPunctuation.yml +0 -13
  198. package/styles/Microsoft/Headings.yml +0 -28
  199. package/styles/Microsoft/Hyphens.yml +0 -14
  200. package/styles/Microsoft/Negative.yml +0 -13
  201. package/styles/Microsoft/Ordinal.yml +0 -13
  202. package/styles/Microsoft/OxfordComma.yml +0 -8
  203. package/styles/Microsoft/Passive.yml +0 -183
  204. package/styles/Microsoft/Percentages.yml +0 -7
  205. package/styles/Microsoft/Plurals.yml +0 -7
  206. package/styles/Microsoft/Quotes.yml +0 -7
  207. package/styles/Microsoft/RangeTime.yml +0 -13
  208. package/styles/Microsoft/Semicolon.yml +0 -8
  209. package/styles/Microsoft/SentenceLength.yml +0 -6
  210. package/styles/Microsoft/Spacing.yml +0 -8
  211. package/styles/Microsoft/Suspended.yml +0 -7
  212. package/styles/Microsoft/Terms.yml +0 -42
  213. package/styles/Microsoft/URLFormat.yml +0 -9
  214. package/styles/Microsoft/Units.yml +0 -16
  215. package/styles/Microsoft/Vocab.yml +0 -25
  216. package/styles/Microsoft/We.yml +0 -11
  217. package/styles/Microsoft/Wordiness.yml +0 -127
  218. package/styles/Microsoft/meta.json +0 -4
  219. package/styles/alex/Ablist.yml +0 -274
  220. package/styles/alex/Condescending.yml +0 -16
  221. package/styles/alex/Gendered.yml +0 -110
  222. package/styles/alex/LGBTQ.yml +0 -55
  223. package/styles/alex/OCD.yml +0 -10
  224. package/styles/alex/Press.yml +0 -12
  225. package/styles/alex/ProfanityLikely.yml +0 -1289
  226. package/styles/alex/ProfanityMaybe.yml +0 -282
  227. package/styles/alex/ProfanityUnlikely.yml +0 -251
  228. package/styles/alex/README.md +0 -27
  229. package/styles/alex/Race.yml +0 -85
  230. package/styles/alex/Suicide.yml +0 -26
  231. package/styles/alex/meta.json +0 -4
  232. package/styles/config/vocabularies/Docs/accept.txt +0 -47
  233. package/styles/config/vocabularies/Docs/reject.txt +0 -4
  234. package/styles/proselint/Airlinese.yml +0 -8
  235. package/styles/proselint/AnimalLabels.yml +0 -48
  236. package/styles/proselint/Annotations.yml +0 -9
  237. package/styles/proselint/Apologizing.yml +0 -8
  238. package/styles/proselint/Archaisms.yml +0 -52
  239. package/styles/proselint/But.yml +0 -8
  240. package/styles/proselint/Cliches.yml +0 -782
  241. package/styles/proselint/CorporateSpeak.yml +0 -30
  242. package/styles/proselint/Currency.yml +0 -5
  243. package/styles/proselint/Cursing.yml +0 -15
  244. package/styles/proselint/DateCase.yml +0 -7
  245. package/styles/proselint/DateMidnight.yml +0 -7
  246. package/styles/proselint/DateRedundancy.yml +0 -10
  247. package/styles/proselint/DateSpacing.yml +0 -7
  248. package/styles/proselint/DenizenLabels.yml +0 -52
  249. package/styles/proselint/Diacritical.yml +0 -95
  250. package/styles/proselint/GenderBias.yml +0 -45
  251. package/styles/proselint/GroupTerms.yml +0 -39
  252. package/styles/proselint/Hedging.yml +0 -8
  253. package/styles/proselint/Hyperbole.yml +0 -6
  254. package/styles/proselint/Jargon.yml +0 -11
  255. package/styles/proselint/LGBTOffensive.yml +0 -13
  256. package/styles/proselint/LGBTTerms.yml +0 -15
  257. package/styles/proselint/Malapropisms.yml +0 -8
  258. package/styles/proselint/Needless.yml +0 -358
  259. package/styles/proselint/Nonwords.yml +0 -38
  260. package/styles/proselint/Oxymorons.yml +0 -22
  261. package/styles/proselint/P-Value.yml +0 -6
  262. package/styles/proselint/RASSyndrome.yml +0 -30
  263. package/styles/proselint/README.md +0 -12
  264. package/styles/proselint/Skunked.yml +0 -13
  265. package/styles/proselint/Spelling.yml +0 -17
  266. package/styles/proselint/Typography.yml +0 -11
  267. package/styles/proselint/Uncomparables.yml +0 -50
  268. package/styles/proselint/Very.yml +0 -6
  269. package/styles/proselint/meta.json +0 -15
  270. package/styles/write-good/Cliches.yml +0 -702
  271. package/styles/write-good/E-Prime.yml +0 -32
  272. package/styles/write-good/Illusions.yml +0 -11
  273. package/styles/write-good/Passive.yml +0 -183
  274. package/styles/write-good/README.md +0 -27
  275. package/styles/write-good/So.yml +0 -5
  276. package/styles/write-good/ThereIs.yml +0 -6
  277. package/styles/write-good/TooWordy.yml +0 -221
  278. package/styles/write-good/Weasel.yml +0 -29
  279. package/styles/write-good/meta.json +0 -4
  280. package/test/dashcam.test.js +0 -137
  281. package/test/mcp-example-test.yaml +0 -27
  282. package/test/test_parser.js +0 -47
  283. package/testdriver/acceptance-sdk/QUICK_REFERENCE.md +0 -61
  284. package/testdriver/acceptance-sdk/README.md +0 -128
  285. package/testdriver/acceptance-sdk/TEST_REPORTING.md +0 -245
  286. package/testdriver/acceptance-sdk/assert.test.mjs +0 -26
  287. package/testdriver/acceptance-sdk/hooks-example.test.mjs +0 -38
  288. package/testdriver/acceptance-sdk/presets-example.test.mjs +0 -87
  289. package/testdriver/acceptance-sdk/setup/testHelpers.mjs +0 -420
  290. package/testdriver/acceptance-sdk/sully-ai.test.mjs +0 -234
  291. package/testdriver/acceptance-sdk/type-checking-demo.js +0 -49
  292. package/vale.ini +0 -18
  293. package/vitest.config.example.js +0 -19
  294. package/vitest.config.mjs.bak +0 -44
  295. /package/docs/{ARCHITECTURE.md → v7/_drafts/architecture.mdx} +0 -0
  296. /package/docs/{AWESOME_LOGS_QUICK_REF.md → v7/_drafts/awesome-logs-quick-ref.mdx} +0 -0
  297. /package/docs/v7/{guides → _drafts}/best-practices.mdx +0 -0
  298. /package/docs/v7/{guides → _drafts}/caching-ai.mdx +0 -0
  299. /package/docs/v7/{guides → _drafts}/caching.mdx +0 -0
  300. /package/docs/{MIGRATION.md → v7/_drafts/cli-to-sdk-migration.mdx} +0 -0
  301. /package/{CONTRIBUTING.md → docs/v7/_drafts/contributing.mdx} +0 -0
  302. /package/docs/v7/{progressive-apis/CORE.md → _drafts/core.mdx} +0 -0
  303. /package/docs/v7/{guides → _drafts}/debugging.mdx +0 -0
  304. /package/docs/v7/{guides → _drafts}/faq.mdx +0 -0
  305. /package/docs/v7/{progressive-apis/HOOKS.md → _drafts/hooks.mdx} +0 -0
  306. /package/docs/v7/{guides → _drafts}/migration.mdx +0 -0
  307. /package/docs/v7/{guides → _drafts}/performance.mdx +0 -0
  308. /package/docs/{PRESETS.md → v7/_drafts/presets.mdx} +0 -0
  309. /package/docs/v7/{progressive-apis/PROGRESSIVE_DISCLOSURE.md → _drafts/progressive-disclosure.mdx} +0 -0
  310. /package/docs/v7/{progressive-apis/PROVISION.md → _drafts/provision.mdx} +0 -0
  311. /package/docs/{SDK_AWESOME_LOGS.md → v7/_drafts/sdk-awesome-logs.mdx} +0 -0
  312. /package/docs/{sdk-browser-rendering.md → v7/_drafts/sdk-browser-rendering.mdx} +0 -0
  313. /package/docs/{TEST_RECORDING.md → v7/_drafts/test-recording.mdx} +0 -0
  314. /package/docs/v7/{guides → _drafts}/vitest.mdx +0 -0
  315. /package/docs/v7/{README.md → overview/readme.mdx} +0 -0
  316. /package/{src → lib}/core/index.d.ts +0 -0
  317. /package/{src → lib}/core/index.js +0 -0
  318. /package/{src → lib}/presets/index.mjs +0 -0
  319. /package/{src → lib}/vitest/hooks.d.ts +0 -0
  320. /package/{debug-locate-response.js → test/manual/debug-locate-response.js} +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}/chrome-extension.test.mjs +0 -0
  324. /package/{testdriver/acceptance-sdk → test/testdriver}/setup/globalTeardown.mjs +0 -0
  325. /package/{testdriver/acceptance-sdk → test/testdriver}/setup/vitestSetup.mjs +0 -0
@@ -0,0 +1,351 @@
1
+ ---
2
+ title: "Easy to Write"
3
+ description: "Natural language testing that feels like describing what you want, not programming"
4
+ icon: "feather"
5
+ ---
6
+
7
+ Writing tests with TestDriver is intuitive and straightforward. No more brittle CSS selectors or complex XPath expressions - just describe what you want in plain English.
8
+
9
+ ## Natural Language Selectors
10
+
11
+ Find elements the way humans think about them:
12
+
13
+ <CodeGroup>
14
+ ```javascript TestDriver - Natural Language
15
+ // ✅ Readable and maintainable
16
+ await testdriver.find('submit button').click();
17
+ await testdriver.find('email input in the login form').type('user@example.com');
18
+ await testdriver.find('delete button in the top right corner').click();
19
+ ```
20
+
21
+ ```javascript Traditional - CSS Selectors
22
+ // ❌ Fragile and cryptic
23
+ await page.locator('#root > div > form > div:nth-child(2) > button').click();
24
+ await page.locator('input[name="email"][data-testid="login-form-email"]').type('user@example.com');
25
+ await page.locator('.header-actions > .btn-danger:last-child').click();
26
+ ```
27
+ </CodeGroup>
28
+
29
+ <Tip>
30
+ Natural language selectors are resilient to UI changes. If a button moves or the DOM structure changes, the same description often still works.
31
+ </Tip>
32
+
33
+ ## Chainable API
34
+
35
+ Write cleaner, more readable test code with method chaining:
36
+
37
+ ```javascript
38
+ // Find and interact in one fluid motion
39
+ await testdriver.find('Login button').click();
40
+ await testdriver.find('username field').type('admin');
41
+ await testdriver.find('password field').type('secret', { secret: true });
42
+ await testdriver.find('submit').click();
43
+
44
+ // Also works with hover interactions
45
+ await testdriver.find('Products menu').hover();
46
+ await testdriver.find('Laptops submenu').click();
47
+
48
+ // And other actions
49
+ await testdriver.find('checkbox item').doubleClick();
50
+ await testdriver.find('context menu item').rightClick();
51
+ ```
52
+
53
+ All element methods are chainable:
54
+ - `.click()` - Click the element
55
+ - `.hover()` - Hover over the element
56
+ - `.doubleClick()` - Double-click the element
57
+ - `.rightClick()` - Right-click the element
58
+ - `.mouseDown()` - Press mouse button down
59
+ - `.mouseUp()` - Release mouse button
60
+ - `.type(text)` - Type text into the element
61
+
62
+ ## Familiar Syntax
63
+
64
+ TestDriver integrates seamlessly with the test frameworks you already know and love:
65
+
66
+ <Tabs>
67
+ <Tab title="Vitest">
68
+ ```javascript
69
+ import { test } from 'vitest';
70
+ import { chrome } from 'testdriverai/presets';
71
+
72
+ test('my test', async (context) => {
73
+ const { testdriver } = await chrome(context, {
74
+ url: 'https://example.com'
75
+ });
76
+
77
+ await testdriver.find('button').click();
78
+ });
79
+ ```
80
+ </Tab>
81
+
82
+ <Tab title="Jest">
83
+ ```javascript
84
+ import { chrome } from 'testdriverai/presets';
85
+
86
+ test('my test', async () => {
87
+ const { testdriver } = await chrome({
88
+ url: 'https://example.com'
89
+ });
90
+
91
+ await testdriver.find('button').click();
92
+ });
93
+ ```
94
+ </Tab>
95
+
96
+ <Tab title="Mocha">
97
+ ```javascript
98
+ import { chrome } from 'testdriverai/presets';
99
+
100
+ describe('My Suite', () => {
101
+ it('should work', async function() {
102
+ const { testdriver } = await chrome(this, {
103
+ url: 'https://example.com'
104
+ });
105
+
106
+ await testdriver.find('button').click();
107
+ });
108
+ });
109
+ ```
110
+ </Tab>
111
+ </Tabs>
112
+
113
+ No need to learn a new DSL or configuration format. TestDriver works with your existing test infrastructure.
114
+
115
+ ## Full TypeScript Support
116
+
117
+ First-class TypeScript support with complete IntelliSense and type safety:
118
+
119
+ ```typescript
120
+ import { test } from 'vitest';
121
+ import { chrome } from 'testdriverai/presets';
122
+
123
+ test('typed test', async (context) => {
124
+ const { testdriver } = await chrome(context, {
125
+ url: 'https://example.com'
126
+ });
127
+
128
+ const element = await testdriver.find('button');
129
+
130
+ // ✅ Autocomplete works perfectly
131
+ element.coordinates.x;
132
+ element.coordinates.y;
133
+ element.text;
134
+ element.confidence;
135
+
136
+ // ❌ TypeScript catches errors at compile time
137
+ element.invalidProperty; // Error: Property 'invalidProperty' does not exist
138
+ });
139
+ ```
140
+
141
+ <Card title="Type Definitions" icon="code">
142
+ TestDriver includes comprehensive TypeScript definitions for all APIs, methods, and return types. Your IDE will provide intelligent autocomplete and inline documentation.
143
+ </Card>
144
+
145
+ ## AI-Powered Assertions
146
+
147
+ Verify application state using natural language:
148
+
149
+ ```javascript
150
+ // Verify UI state
151
+ await testdriver.assert('the login page is displayed');
152
+ await testdriver.assert('submit button is visible and enabled');
153
+
154
+ // Verify content
155
+ await testdriver.assert('the page title is "Welcome"');
156
+ await testdriver.assert('success message says "Account created successfully"');
157
+
158
+ // Verify interactions
159
+ await testdriver.assert('the checkbox is checked');
160
+ await testdriver.assert('the dropdown shows "United States"');
161
+
162
+ // Verify visual state
163
+ await testdriver.assert('the button is blue');
164
+ await testdriver.assert('the loading spinner is not visible');
165
+ ```
166
+
167
+ No need to write complex selectors and assertions. Just describe what should be true.
168
+
169
+ ## Clean Test Code
170
+
171
+ Compare the readability of TestDriver vs traditional approaches:
172
+
173
+ <CodeGroup>
174
+ ```javascript TestDriver - Clean & Readable
175
+ test('user can login', async (context) => {
176
+ const { testdriver } = await chrome(context, {
177
+ url: 'https://myapp.com/login'
178
+ });
179
+
180
+ await testdriver.find('email input').type('user@example.com');
181
+ await testdriver.find('password input').type('secret', { secret: true });
182
+ await testdriver.find('Login button').click();
183
+
184
+ await testdriver.assert('Dashboard is visible');
185
+ });
186
+ ```
187
+
188
+ ```javascript Traditional - Verbose & Complex
189
+ test('user can login', async () => {
190
+ await page.goto('https://myapp.com/login');
191
+
192
+ const emailInput = await page.waitForSelector(
193
+ 'input[type="email"][name="email"]',
194
+ { state: 'visible', timeout: 30000 }
195
+ );
196
+ await emailInput.type('user@example.com');
197
+
198
+ const passwordInput = await page.waitForSelector(
199
+ 'input[type="password"][name="password"]',
200
+ { state: 'visible', timeout: 30000 }
201
+ );
202
+ await passwordInput.type('secret');
203
+
204
+ const loginButton = await page.waitForSelector(
205
+ 'button[type="submit"]',
206
+ { state: 'visible', timeout: 30000 }
207
+ );
208
+ await loginButton.click();
209
+
210
+ await page.waitForSelector('.dashboard', {
211
+ state: 'visible',
212
+ timeout: 30000
213
+ });
214
+ const dashboard = await page.$('.dashboard');
215
+ expect(dashboard).toBeTruthy();
216
+ });
217
+ ```
218
+ </CodeGroup>
219
+
220
+ ## Progressive Complexity
221
+
222
+ Choose your level of control:
223
+
224
+ <CardGroup cols={3}>
225
+ <Card title="Presets (Easiest)" icon="rocket">
226
+ One-line setup for common scenarios:
227
+
228
+ ```javascript
229
+ const { testdriver } = await chrome(context, {
230
+ url: 'https://example.com'
231
+ });
232
+ ```
233
+
234
+ [Learn more](/v7/progressive-apis/PROVISION)
235
+ </Card>
236
+
237
+ <Card title="Hooks (Flexible)" icon="link">
238
+ More control with composable hooks:
239
+
240
+ ```javascript
241
+ const client = useTestDriver(context);
242
+ const dashcam = useDashcam(context, client);
243
+ ```
244
+
245
+ [Learn more](/v7/progressive-apis/HOOKS)
246
+ </Card>
247
+
248
+ <Card title="Core (Full Control)" icon="code">
249
+ Manual control over everything:
250
+
251
+ ```javascript
252
+ const client = new TestDriver(apiKey);
253
+ await client.connect();
254
+ await client.find('button');
255
+ ```
256
+
257
+ [Learn more](/v7/progressive-apis/PROGRESSIVE_DISCLOSURE)
258
+ </Card>
259
+ </CardGroup>
260
+
261
+ ## Zero Boilerplate
262
+
263
+ Presets handle all the setup and teardown automatically:
264
+
265
+ ```javascript
266
+ test('minimal test', async (context) => {
267
+ // One line to set up everything:
268
+ // - Authentication
269
+ // - Sandbox provisioning
270
+ // - Browser launch
271
+ // - Navigation
272
+ // - Dashcam recording
273
+ // - Automatic cleanup
274
+ const { testdriver } = await chrome(context, {
275
+ url: 'https://example.com'
276
+ });
277
+
278
+ // Write your test
279
+ await testdriver.find('button').click();
280
+
281
+ // No cleanup needed - automatic!
282
+ });
283
+ ```
284
+
285
+ <Check>
286
+ The preset automatically disconnects and cleans up resources when your test completes, even if it fails.
287
+ </Check>
288
+
289
+ ## Real-World Example
290
+
291
+ Here's a complete, real-world test that showcases TestDriver's simplicity:
292
+
293
+ ```javascript
294
+ import { test, expect } from 'vitest';
295
+ import { chrome } from 'testdriverai/presets';
296
+
297
+ test('user can checkout', async (context) => {
298
+ const { testdriver } = await chrome(context, {
299
+ url: 'https://shop.example.com'
300
+ });
301
+
302
+ // Add items to cart
303
+ await testdriver.find('Add to Cart button on the first product').click();
304
+ await testdriver.assert('Cart badge shows 1 item');
305
+
306
+ // Go to checkout
307
+ await testdriver.find('Cart icon').click();
308
+ await testdriver.find('Checkout button').click();
309
+
310
+ // Fill shipping form
311
+ await testdriver.find('Full name input').type('John Doe');
312
+ await testdriver.find('Address input').type('123 Main St');
313
+ await testdriver.find('City input').type('Springfield');
314
+ await testdriver.find('State dropdown').click();
315
+ await testdriver.find('California option').click();
316
+
317
+ // Submit order
318
+ await testdriver.find('Place Order button').click();
319
+
320
+ // Verify success
321
+ await testdriver.assert('Order confirmation page is displayed');
322
+ await testdriver.assert('Thank you message is visible');
323
+ });
324
+ ```
325
+
326
+ Notice:
327
+ - No CSS selectors or IDs
328
+ - No explicit waits
329
+ - No manual setup/teardown
330
+ - Reads like a test plan
331
+ - Self-documenting code
332
+
333
+ ## Get Started
334
+
335
+ <CardGroup cols={2}>
336
+ <Card
337
+ title="Quick Start"
338
+ icon="rocket"
339
+ href="/v7/getting-started/quickstart"
340
+ >
341
+ Get up and running in 2 minutes
342
+ </Card>
343
+
344
+ <Card
345
+ title="API Reference"
346
+ icon="book"
347
+ href="/v7/api/client"
348
+ >
349
+ Complete API documentation
350
+ </Card>
351
+ </CardGroup>