testdriverai 7.1.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 (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 +86 -125
  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 +70 -18
  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 +11 -57
  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
package/sdk.js CHANGED
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env node
2
-
3
1
  const fs = require("fs");
4
2
  const path = require("path");
5
3
  const os = require("os");
@@ -1123,8 +1121,8 @@ class TestDriverSDK {
1123
1121
  ? options.redrawThreshold
1124
1122
  : { diffThreshold: options.redrawThreshold };
1125
1123
  } else {
1126
- // Default: disabled
1127
- this.redrawOptions = { enabled: false };
1124
+ // Default: enabled (as of v7.2)
1125
+ this.redrawOptions = { enabled: true };
1128
1126
  }
1129
1127
  // Keep redrawThreshold for backwards compatibility in connect()
1130
1128
  this.redrawThreshold = this.redrawOptions;
@@ -1178,7 +1176,7 @@ class TestDriverSDK {
1178
1176
  */
1179
1177
  get dashcam() {
1180
1178
  if (!this._dashcam) {
1181
- const { Dashcam } = require("./src/core/index.js");
1179
+ const { Dashcam } = require("./lib/core/index.js");
1182
1180
  // Don't pass apiKey - let Dashcam use its default key
1183
1181
  this._dashcam = new Dashcam(this);
1184
1182
  }
@@ -1222,6 +1220,19 @@ class TestDriverSDK {
1222
1220
 
1223
1221
  // If dashcam is available and recording, add web logs for this domain
1224
1222
  if (this._dashcam) {
1223
+
1224
+ // Create the log file on the remote machine
1225
+ const shell = this.os === "windows" ? "pwsh" : "sh";
1226
+ const logPath = this.os === "windows"
1227
+ ? "C:\\Users\\testdriver\\Documents\\testdriver.log"
1228
+ : "/tmp/testdriver.log";
1229
+
1230
+ const createLogCmd = this.os === "windows"
1231
+ ? `New-Item -ItemType File -Path "${logPath}" -Force | Out-Null`
1232
+ : `touch ${logPath}`;
1233
+
1234
+ await this.exec(shell, createLogCmd, 10000, true);
1235
+
1225
1236
  console.log('[provision.chrome] Adding web logs to dashcam...');
1226
1237
  try {
1227
1238
  const urlObj = new URL(url);
@@ -1229,6 +1240,9 @@ class TestDriverSDK {
1229
1240
  const pattern = `*${domain}*`;
1230
1241
  await this._dashcam.addWebLog(pattern, 'Web Logs');
1231
1242
  console.log(`[provision.chrome] ✅ Web logs added to dashcam (pattern: ${pattern})`);
1243
+
1244
+ await this._dashcam.addFileLog(logPath, "TestDriver Log");
1245
+
1232
1246
  } catch (error) {
1233
1247
  console.warn('[provision.chrome] ⚠️ Failed to add web logs:', error.message);
1234
1248
  }
@@ -1472,6 +1486,9 @@ class TestDriverSDK {
1472
1486
  this.agent.sandboxOs = connectOptions.os;
1473
1487
  } else if (this.sandboxOs) {
1474
1488
  this.agent.sandboxOs = this.sandboxOs;
1489
+ } else {
1490
+ // Fall back to this.os (which defaults to "linux")
1491
+ this.agent.sandboxOs = this.os;
1475
1492
  }
1476
1493
 
1477
1494
  // Set redrawThreshold on agent's cliArgs.options
@@ -1506,13 +1523,8 @@ class TestDriverSDK {
1506
1523
  this._setupCommandMethods();
1507
1524
 
1508
1525
  this.connected = true;
1509
-
1510
- // Expose whether we reconnected to an existing sandbox or created a new one
1511
- this.isReconnected = this.agent.isReconnected || false;
1512
-
1513
1526
  this.analytics.track("sdk.connect", {
1514
1527
  sandboxId: this.instance?.instanceId,
1515
- isReconnected: this.isReconnected,
1516
1528
  });
1517
1529
 
1518
1530
  return this.instance;
@@ -1525,13 +1537,19 @@ class TestDriverSDK {
1525
1537
  * @returns {Promise<void>}
1526
1538
  */
1527
1539
  async disconnect() {
1540
+ // Track disconnect event if we were connected
1528
1541
  if (this.connected && this.instance) {
1529
- // Track disconnect event
1530
1542
  this.analytics.track("sdk.disconnect");
1543
+ }
1531
1544
 
1532
- this.connected = false;
1533
- this.instance = null;
1545
+ // Always close the sandbox WebSocket connection to clean up resources
1546
+ // This ensures we don't leave orphaned connections even if connect() failed
1547
+ if (this.sandbox && typeof this.sandbox.close === 'function') {
1548
+ this.sandbox.close();
1534
1549
  }
1550
+
1551
+ this.connected = false;
1552
+ this.instance = null;
1535
1553
  }
1536
1554
 
1537
1555
  /**
@@ -2197,6 +2215,9 @@ class TestDriverSDK {
2197
2215
  * @private
2198
2216
  */
2199
2217
  _setupLogging() {
2218
+ // Track the last fatal error message to throw on exit
2219
+ let lastFatalError = null;
2220
+
2200
2221
  // Set up markdown logger
2201
2222
  createMarkdownLogger(this.emitter);
2202
2223
 
@@ -2219,6 +2240,11 @@ class TestDriverSDK {
2219
2240
  if (this.loggingEnabled) {
2220
2241
  const event = this.emitter.event;
2221
2242
  console.error(event, ":", data);
2243
+
2244
+ // Capture fatal errors
2245
+ if (event === events.error.fatal) {
2246
+ lastFatalError = data;
2247
+ }
2222
2248
  }
2223
2249
  });
2224
2250
 
@@ -2245,6 +2271,19 @@ class TestDriverSDK {
2245
2271
  }
2246
2272
  });
2247
2273
 
2274
+ // Handle exit events - throw error with meaningful message instead of calling process.exit
2275
+ // This allows test frameworks like Vitest to properly catch and display the error
2276
+ this.emitter.on(events.exit, (exitCode) => {
2277
+ if (exitCode !== 0) {
2278
+ // Create an error with the fatal error message if available
2279
+ const errorMessage = lastFatalError || 'TestDriver fatal error';
2280
+ const error = new Error(errorMessage);
2281
+ error.name = 'TestDriverFatalError';
2282
+ error.exitCode = exitCode;
2283
+ throw error;
2284
+ }
2285
+ });
2286
+
2248
2287
  // Handle show window events for sandbox visualization
2249
2288
  this.emitter.on("show-window", async (url) => {
2250
2289
  if (this.loggingEnabled) {
@@ -2380,7 +2419,7 @@ class TestDriverSDK {
2380
2419
  );
2381
2420
  await sdk.auth();
2382
2421
 
2383
- const platform = options.platform || this.config.TD_PLATFORM || "windows";
2422
+ const platform = options.platform || this.config.TD_PLATFORM || "linux";
2384
2423
 
2385
2424
  // Auto-detect sandbox ID from the active sandbox if not provided
2386
2425
  const sandboxId = options.sandboxId || this.agent?.sandbox?.id || null;
@@ -2545,21 +2584,34 @@ class TestDriverSDK {
2545
2584
  *
2546
2585
  * @example
2547
2586
  * // Simple execution
2548
- * await client.ai('Click the submit button');
2587
+ * await client.act('Click the submit button');
2549
2588
  *
2550
2589
  * @example
2551
2590
  * // With validation loop
2552
- * const result = await client.ai('Fill out the contact form', { validateAndLoop: true });
2591
+ * const result = await client.act('Fill out the contact form', { validateAndLoop: true });
2553
2592
  * console.log(result); // AI's final assessment
2554
2593
  */
2555
- async ai(task) {
2594
+ async act(task) {
2556
2595
  this._ensureConnected();
2557
2596
 
2558
- this.analytics.track("sdk.ai", { task });
2597
+ this.analytics.track("sdk.act", { task });
2559
2598
 
2560
2599
  // Use the agent's exploratoryLoop method directly
2561
2600
  return await this.agent.exploratoryLoop(task, false, true, false);
2562
2601
  }
2602
+
2603
+ /**
2604
+ * @deprecated Use act() instead
2605
+ * Execute a natural language task using AI
2606
+ *
2607
+ * @param {string} task - Natural language description of what to do
2608
+ * @param {Object} options - Execution options
2609
+ * @param {boolean} [options.validateAndLoop=false] - Whether to validate completion and retry if incomplete
2610
+ * @returns {Promise<string|void>} Final AI response if validateAndLoop is true
2611
+ */
2612
+ async ai(task) {
2613
+ return await this.act(task);
2614
+ }
2563
2615
  }
2564
2616
 
2565
2617
  module.exports = TestDriverSDK;
@@ -78,7 +78,7 @@ jobs:
78
78
  AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
79
79
  AWS_REGION: us-east-2
80
80
  AWS_LAUNCH_TEMPLATE_ID: lt-00d02f31cfc602f27
81
- AMI_ID: ami-055cd47506a2f39bb
81
+ AMI_ID: ami-086b5b4b86d78987c
82
82
  RESOLUTION: 1920x1080
83
83
  - name: Run TestDriver
84
84
  run: node bin/testdriverai.js run testdriver/acceptance/${{ matrix.test }} --ip="${{ steps.aws-setup.outputs.public-ip }}" --junit=out.xml
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../src/vitest/hooks.mjs";
7
+ import { TestDriver } from "../../lib/vitest/hooks.mjs";
8
8
 
9
9
  describe("Console Log Test", () => {
10
10
  it("should capture console logs and send them to dashcam", async (context) => {
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Quick test of the new find() API
5
+ * This is a simple smoke test to verify the Element class works
6
+ */
7
+
8
+ const TestDriver = require("../sdk");
9
+
10
+ async function testFindAPI() {
11
+ console.log("Testing new find() API...\n");
12
+
13
+ const client = new TestDriver("test-key", {
14
+ logging: false,
15
+ });
16
+
17
+ // Test 1: Create element without connecting
18
+ console.log("✓ Test 1: Creating Element instance");
19
+ const element = client.find("test element");
20
+ console.log(" Element description:", element.description);
21
+ console.log(" Element found():", element.found());
22
+ console.log(" Element coordinates:", element.getCoordinates());
23
+
24
+ // Test 2: Verify element methods exist
25
+ console.log("\n✓ Test 2: Verifying Element methods");
26
+ console.log(" Has find():", typeof element.find === "function");
27
+ console.log(" Has click():", typeof element.click === "function");
28
+ console.log(" Has hover():", typeof element.hover === "function");
29
+ console.log(
30
+ " Has doubleClick():",
31
+ typeof element.doubleClick === "function",
32
+ );
33
+ console.log(" Has rightClick():", typeof element.rightClick === "function");
34
+ console.log(" Has mouseDown():", typeof element.mouseDown === "function");
35
+ console.log(" Has mouseUp():", typeof element.mouseUp === "function");
36
+ console.log(" Has found():", typeof element.found === "function");
37
+ console.log(
38
+ " Has getCoordinates():",
39
+ typeof element.getCoordinates === "function",
40
+ );
41
+
42
+ // Test 3: Verify error handling for clicking unfound element
43
+ console.log("\n✓ Test 3: Error handling for unfound element");
44
+ try {
45
+ await element.click();
46
+ console.log(" ❌ Should have thrown error");
47
+ } catch (error) {
48
+ console.log(" ✓ Correctly throws error:", error.message);
49
+ }
50
+
51
+ // Test 4: Verify TypeScript types exist (if running from TypeScript)
52
+ console.log("\n✓ Test 4: SDK methods");
53
+ console.log(" Has find():", typeof client.find === "function");
54
+ console.log(
55
+ " Has deprecated hoverText():",
56
+ typeof client.hoverText === "undefined" ? "not yet connected" : "exists",
57
+ );
58
+ console.log(
59
+ " Has deprecated waitForText():",
60
+ typeof client.waitForText === "undefined" ? "not yet connected" : "exists",
61
+ );
62
+
63
+ console.log("\n✅ All basic tests passed!");
64
+ console.log(
65
+ "\nNote: Full integration tests require connection to TestDriver sandbox.",
66
+ );
67
+ console.log("See examples/sdk-find-example.js for complete usage examples.");
68
+ }
69
+
70
+ testFindAPI().catch((error) => {
71
+ console.error("Test failed:", error);
72
+ process.exit(1);
73
+ });
@@ -0,0 +1,54 @@
1
+ #!/bin/bash
2
+
3
+ # Test script for the init command
4
+ # Usage: ./test-init.sh
5
+
6
+ set -e
7
+
8
+ echo "🧪 Testing testdriverai init command..."
9
+ echo ""
10
+
11
+ # Cleanup function
12
+ cleanup() {
13
+ echo "🧹 Cleaning up test directories..."
14
+ rm -rf /tmp/testdriver-test-*
15
+ }
16
+
17
+ trap cleanup EXIT
18
+
19
+ # Test 1: Full init with all features
20
+ echo "1️⃣ Testing full initialization (package.json, tests, workflow, npm install)..."
21
+ cd /tmp
22
+ mkdir -p testdriver-test-init
23
+ cd testdriver-test-init
24
+ node /Users/ianjennings/Development/cli/bin/testdriverai.js init
25
+ echo ""
26
+ echo "✅ Files created:"
27
+ find . -type f -not -path "./node_modules/*" | sort
28
+ echo ""
29
+ echo "📄 package.json:"
30
+ cat package.json
31
+ echo ""
32
+ echo "📄 vitest.config.js:"
33
+ cat vitest.config.js
34
+ echo ""
35
+ echo "📄 GitHub workflow:"
36
+ cat .github/workflows/testdriver.yml
37
+ echo ""
38
+ echo "📄 First 15 lines of tests/example.test.js:"
39
+ head -15 tests/example.test.js
40
+ echo ""
41
+ echo "📦 Installed dependencies:"
42
+ npm list --depth=0
43
+ echo ""
44
+ echo "---"
45
+ echo ""
46
+
47
+ # Test 2: Help command
48
+ echo "2️⃣ Testing help command..."
49
+ node /Users/ianjennings/Development/cli/bin/testdriverai.js init --help
50
+ echo ""
51
+ echo "---"
52
+ echo ""
53
+
54
+ echo "✅ All tests passed!"
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Simple test to verify prompt caching functionality
5
+ *
6
+ * This test demonstrates that:
7
+ * 1. First .prompt() call makes an API request and caches the YAML response
8
+ * 2. Second .prompt() call with the same prompt uses the cached YAML
9
+ * 3. Cache can be disabled with TD_NO_PROMPT_CACHE=true
10
+ */
11
+
12
+ const TestDriver = require("./sdk.js");
13
+ const promptCache = require("./agent/lib/cache.js");
14
+
15
+ async function testPromptCache() {
16
+ console.log("Testing prompt caching functionality...\n");
17
+
18
+ const client = new TestDriver(process.env.TD_API_KEY, {
19
+ os: "linux",
20
+ logging: true,
21
+ });
22
+
23
+ try {
24
+ // Connect to sandbox
25
+ console.log("Connecting to sandbox...");
26
+ await client.connect();
27
+ console.log("Connected!\n");
28
+
29
+ const testPrompt = "click the search button";
30
+
31
+ // Clear cache for this prompt to start fresh
32
+ const cachePath = promptCache.getCachePath(testPrompt);
33
+ console.log(`Cache path for "${testPrompt}": ${cachePath}\n`);
34
+
35
+ // Test 1: First call (should make API request and cache)
36
+ console.log("Test 1: First .ai() call (should cache the response)");
37
+ const stats1 = promptCache.getCacheStats();
38
+ console.log(`Cache before: ${stats1.count} files`);
39
+
40
+ await client.ai(testPrompt);
41
+
42
+ const stats2 = promptCache.getCacheStats();
43
+ console.log(`Cache after: ${stats2.count} files`);
44
+ console.log(
45
+ `Cache hit: ${promptCache.hasCache(testPrompt) ? "YES" : "NO"}\n`,
46
+ );
47
+
48
+ // Test 2: Second call (should use cache)
49
+ console.log(
50
+ "Test 2: Second .ai() call with same prompt (should use cache)",
51
+ );
52
+ console.log('Look for "(using cached response)" message above...\n');
53
+ await client.ai(testPrompt);
54
+
55
+ // Test 3: Third call with cache disabled (should make API call)
56
+ console.log(
57
+ "\nTest 3: Third .ai() call with cache=false (should bypass cache)",
58
+ );
59
+ await client.ai(testPrompt, false);
60
+
61
+ // Test 4: Show cache contents
62
+ console.log("\nTest 4: Cache contents");
63
+ const cachedYaml = promptCache.readCache(testPrompt);
64
+ if (cachedYaml) {
65
+ console.log("Cached YAML preview (first 500 chars):");
66
+ console.log(cachedYaml.substring(0, 500));
67
+ console.log("...\n");
68
+ }
69
+
70
+ // Test 5: Cache statistics
71
+ console.log("Test 5: Cache statistics");
72
+ const finalStats = promptCache.getCacheStats();
73
+ console.log(`Total cached prompts: ${finalStats.count}`);
74
+ console.log(`Cache files:`, finalStats.files.slice(0, 5));
75
+
76
+ console.log("\n✅ Prompt caching test completed!");
77
+ console.log("\nTo disable caching, pass false: client.ai(prompt, false)");
78
+ console.log("To clear cache, delete .testdriver/.cache/*.yaml files");
79
+ } catch (error) {
80
+ console.error("❌ Test failed:", error.message);
81
+ throw error;
82
+ } finally {
83
+ // Disconnect
84
+ await client.disconnect();
85
+ }
86
+ }
87
+
88
+ // Run the test
89
+ if (require.main === module) {
90
+ testPromptCache().catch((error) => {
91
+ console.error("Test error:", error);
92
+ process.exit(1);
93
+ });
94
+ }
95
+
96
+ module.exports = testPromptCache;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Quick test to verify provision() authentication works
3
+ */
4
+
5
+ import { test } from 'vitest';
6
+ import { provision } from '../../lib/presets/index.mjs';
7
+
8
+ test('provision auth test', async (context) => {
9
+ console.log('Starting provision...');
10
+
11
+ const { testdriver, dashcam } = await provision('chrome', {
12
+ url: 'http://testdriver-sandbox.vercel.app/',
13
+ }, context);
14
+
15
+ console.log('✅ Provision complete!');
16
+ console.log('TestDriver:', testdriver);
17
+ console.log('Dashcam:', dashcam);
18
+
19
+ // Try a simple find
20
+ const result = await testdriver.find('any element');
21
+ console.log('Find result:', result);
22
+ });
@@ -0,0 +1,28 @@
1
+ const TestDriver = require("./sdk.js");
2
+
3
+ async function test() {
4
+ console.log("Testing sandbox rendering...");
5
+
6
+ const client = new TestDriver(process.env.TD_API_KEY, {
7
+ os: process.env.TEST_PLATFORM || "linux",
8
+ headless: false, // Should open browser
9
+ logging: true,
10
+ });
11
+
12
+ try {
13
+ console.log("Connecting to sandbox...");
14
+ const instance = await client.connect();
15
+ console.log("Connected to instance:", instance);
16
+
17
+ // Wait a bit to see if browser opens
18
+ await new Promise((resolve) => setTimeout(resolve, 5000));
19
+
20
+ await client.disconnect();
21
+ console.log("Test completed successfully");
22
+ } catch (error) {
23
+ console.error("Test failed:", error);
24
+ process.exit(1);
25
+ }
26
+ }
27
+
28
+ test();
@@ -0,0 +1,15 @@
1
+ const SDK = require("./sdk.js");
2
+
3
+ const client = new SDK("test-key");
4
+
5
+ // Get all public methods (non-private, non-constructor)
6
+ const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(client))
7
+ .filter((m) => !m.startsWith("_") && m !== "constructor")
8
+ .sort();
9
+
10
+ console.log("Public SDK Methods:");
11
+ console.log(methods.join(", "));
12
+ console.log("\nTotal:", methods.length, "methods");
13
+
14
+ // Check if commands will be set up after connect
15
+ console.log("\nCommands before connect:", client.commands);
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Quick test to verify SDK refactoring works correctly
5
+ */
6
+
7
+ const TestDriver = require("./sdk.js");
8
+
9
+ async function test() {
10
+ console.log("Testing SDK refactor...\n");
11
+
12
+ // Test 1: SDK construction
13
+ console.log("✓ Test 1: Creating SDK instance");
14
+ const client = new TestDriver(process.env.TD_API_KEY || "test-key", {
15
+ logging: false,
16
+ });
17
+
18
+ console.log(" - agent exists:", !!client.agent);
19
+ console.log(" - emitter exists:", !!client.emitter);
20
+ console.log(" - config exists:", !!client.config);
21
+ console.log(" - session exists:", !!client.session);
22
+ console.log(" - apiClient exists:", !!client.apiClient);
23
+ console.log(" - analytics exists:", !!client.analytics);
24
+ console.log(" - sandbox exists:", !!client.sandbox);
25
+ console.log(" - system exists:", !!client.system);
26
+
27
+ // Test 2: Check agent methods are accessible
28
+ console.log("\n✓ Test 2: Checking agent methods");
29
+ console.log(
30
+ " - agent.exploratoryLoop exists:",
31
+ typeof client.agent.exploratoryLoop,
32
+ );
33
+ console.log(" - agent.buildEnv exists:", typeof client.agent.buildEnv);
34
+ console.log(
35
+ " - agent.getRecentSandboxId exists:",
36
+ typeof client.agent.getRecentSandboxId,
37
+ );
38
+
39
+ // Test 3: Check SDK methods
40
+ console.log("\n✓ Test 3: Checking SDK methods");
41
+ console.log(" - ai() exists:", typeof client.ai);
42
+ console.log(" - auth() exists:", typeof client.auth);
43
+ console.log(" - connect() exists:", typeof client.connect);
44
+ console.log(" - disconnect() exists:", typeof client.disconnect);
45
+
46
+ console.log("\n✅ All basic tests passed!");
47
+ }
48
+
49
+ test().catch((error) => {
50
+ console.error("\n❌ Test failed:", error.message);
51
+ console.error(error.stack);
52
+ process.exit(1);
53
+ });
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Quick test to verify stack trace filtering works
3
+ */
4
+
5
+ // Mock the MatchError similar to commands.js
6
+ class MatchError extends Error {
7
+ constructor(message, fatal = false) {
8
+ super(message);
9
+ this.fatal = fatal;
10
+ this.attachScreenshot = true;
11
+ }
12
+ }
13
+
14
+ // Simulate SDK wrapper with stack filtering (improved version)
15
+ class TestSDK {
16
+ constructor() {
17
+ const command = async (message) => {
18
+ // Simulate the command throwing an error
19
+ throw new MatchError(`AI Assertion failed: ${message}`, true);
20
+ };
21
+
22
+ // Wrap the method with proper stack trace handling
23
+ this.assert = async function (...args) {
24
+ // Capture the call site for better error reporting
25
+ const callSite = {};
26
+ Error.captureStackTrace(callSite, this.assert);
27
+
28
+ try {
29
+ return await command(...args);
30
+ } catch (error) {
31
+ // Replace the stack trace to point to the actual caller
32
+ if (Error.captureStackTrace && callSite.stack) {
33
+ const errorMessage = error.stack?.split("\n")[0];
34
+ const callerStack = callSite.stack?.split("\n").slice(1);
35
+ error.stack = errorMessage + "\n" + callerStack.join("\n");
36
+ }
37
+ throw error;
38
+ }
39
+ }.bind(this);
40
+ }
41
+ }
42
+
43
+ // Test it
44
+ async function runTest() {
45
+ const client = new TestSDK();
46
+
47
+ try {
48
+ console.log("Testing stack trace...\n");
49
+ await client.assert("home page appears"); // Line 42 - this should show in stack
50
+ } catch (error) {
51
+ console.log("Error caught!");
52
+ console.log("Stack trace:");
53
+ console.log(error.stack);
54
+ }
55
+ }
56
+
57
+ runTest();
@@ -0,0 +1,41 @@
1
+ /**
2
+ * TestDriver SDK - Assert Test (Vitest)
3
+ * Converted from: testdriver/acceptance/assert.yaml
4
+ */
5
+
6
+ import { describe, expect, it } from "vitest";
7
+ import { TestDriver } from "../../lib/vitest/hooks.mjs";
8
+
9
+ describe("Assert Test", () => {
10
+ it("should assert the testdriver login page shows", async (context) => {
11
+ const testdriver = TestDriver(context, { newSandbox: true });
12
+
13
+ // provision.chrome() automatically calls ready() and starts dashcam
14
+ await testdriver.provision.chrome({
15
+ url: 'http://testdriver-sandbox.vercel.app/login',
16
+ });
17
+
18
+ // Assert the TestDriver.ai Sandbox login page is displayed
19
+ const result = await testdriver.assert(
20
+ "the TestDriver.ai Sandbox login page is displayed",
21
+ );
22
+
23
+ expect(result).toBeTruthy();
24
+ });
25
+ // it("should assert the testdriver login page shows 2", async (context) => {
26
+ // const testdriver = TestDriver(context, { newSandbox: true });
27
+
28
+ // // provision.chrome() automatically calls ready() and starts dashcam
29
+ // await testdriver.provision.chrome({
30
+ // url: 'http://testdriver-sandbox.vercel.app/login',
31
+ // });
32
+
33
+ // // Assert the TestDriver.ai Sandbox login page is displayed
34
+ // const result = await testdriver.assert(
35
+ // "the TestDriver.ai Sandbox login page is displayed",
36
+ // );
37
+
38
+ // expect(result).toBeTruthy();
39
+ // });
40
+ });
41
+
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  import { describe, expect, it } from "vitest";
10
- import { TestDriver } from "../../src/vitest/hooks.mjs";
10
+ import { TestDriver } from "../../lib/vitest/hooks.mjs";
11
11
 
12
12
  describe("Auto Cache Key Demo", () => {
13
13
  it("should use auto-generated cache key based on file hash", async (context) => {
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../src/vitest/hooks.mjs";
7
+ import { TestDriver } from "../../lib/vitest/hooks.mjs";
8
8
 
9
9
  const isLinux = (process.env.TD_OS || "linux") === "linux";
10
10
 
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../src/vitest/hooks.mjs";
7
+ import { TestDriver } from "../../lib/vitest/hooks.mjs";
8
8
 
9
9
  describe("Element Not Found Test", () => {
10
10
  it("should handle non-existent element gracefully without timing out", async (context) => {