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
package/sdk.js CHANGED
@@ -1,4 +1,5 @@
1
- #!/usr/bin/env node
1
+ // Auto-load environment variables from .env file if it exists
2
+ require("dotenv").config();
2
3
 
3
4
  const fs = require("fs");
4
5
  const path = require("path");
@@ -1123,8 +1124,8 @@ class TestDriverSDK {
1123
1124
  ? options.redrawThreshold
1124
1125
  : { diffThreshold: options.redrawThreshold };
1125
1126
  } else {
1126
- // Default: disabled
1127
- this.redrawOptions = { enabled: false };
1127
+ // Default: enabled (as of v7.2)
1128
+ this.redrawOptions = { enabled: true };
1128
1129
  }
1129
1130
  // Keep redrawThreshold for backwards compatibility in connect()
1130
1131
  this.redrawThreshold = this.redrawOptions;
@@ -1178,7 +1179,7 @@ class TestDriverSDK {
1178
1179
  */
1179
1180
  get dashcam() {
1180
1181
  if (!this._dashcam) {
1181
- const { Dashcam } = require("./src/core/index.js");
1182
+ const { Dashcam } = require("./lib/core/index.js");
1182
1183
  // Don't pass apiKey - let Dashcam use its default key
1183
1184
  this._dashcam = new Dashcam(this);
1184
1185
  }
@@ -1222,6 +1223,19 @@ class TestDriverSDK {
1222
1223
 
1223
1224
  // If dashcam is available and recording, add web logs for this domain
1224
1225
  if (this._dashcam) {
1226
+
1227
+ // Create the log file on the remote machine
1228
+ const shell = this.os === "windows" ? "pwsh" : "sh";
1229
+ const logPath = this.os === "windows"
1230
+ ? "C:\\Users\\testdriver\\Documents\\testdriver.log"
1231
+ : "/tmp/testdriver.log";
1232
+
1233
+ const createLogCmd = this.os === "windows"
1234
+ ? `New-Item -ItemType File -Path "${logPath}" -Force | Out-Null`
1235
+ : `touch ${logPath}`;
1236
+
1237
+ await this.exec(shell, createLogCmd, 10000, true);
1238
+
1225
1239
  console.log('[provision.chrome] Adding web logs to dashcam...');
1226
1240
  try {
1227
1241
  const urlObj = new URL(url);
@@ -1229,6 +1243,9 @@ class TestDriverSDK {
1229
1243
  const pattern = `*${domain}*`;
1230
1244
  await this._dashcam.addWebLog(pattern, 'Web Logs');
1231
1245
  console.log(`[provision.chrome] ✅ Web logs added to dashcam (pattern: ${pattern})`);
1246
+
1247
+ await this._dashcam.addFileLog(logPath, "TestDriver Log");
1248
+
1232
1249
  } catch (error) {
1233
1250
  console.warn('[provision.chrome] ⚠️ Failed to add web logs:', error.message);
1234
1251
  }
@@ -1472,6 +1489,9 @@ class TestDriverSDK {
1472
1489
  this.agent.sandboxOs = connectOptions.os;
1473
1490
  } else if (this.sandboxOs) {
1474
1491
  this.agent.sandboxOs = this.sandboxOs;
1492
+ } else {
1493
+ // Fall back to this.os (which defaults to "linux")
1494
+ this.agent.sandboxOs = this.os;
1475
1495
  }
1476
1496
 
1477
1497
  // Set redrawThreshold on agent's cliArgs.options
@@ -1506,13 +1526,8 @@ class TestDriverSDK {
1506
1526
  this._setupCommandMethods();
1507
1527
 
1508
1528
  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
1529
  this.analytics.track("sdk.connect", {
1514
1530
  sandboxId: this.instance?.instanceId,
1515
- isReconnected: this.isReconnected,
1516
1531
  });
1517
1532
 
1518
1533
  return this.instance;
@@ -1525,13 +1540,19 @@ class TestDriverSDK {
1525
1540
  * @returns {Promise<void>}
1526
1541
  */
1527
1542
  async disconnect() {
1543
+ // Track disconnect event if we were connected
1528
1544
  if (this.connected && this.instance) {
1529
- // Track disconnect event
1530
1545
  this.analytics.track("sdk.disconnect");
1546
+ }
1531
1547
 
1532
- this.connected = false;
1533
- this.instance = null;
1548
+ // Always close the sandbox WebSocket connection to clean up resources
1549
+ // This ensures we don't leave orphaned connections even if connect() failed
1550
+ if (this.sandbox && typeof this.sandbox.close === 'function') {
1551
+ this.sandbox.close();
1534
1552
  }
1553
+
1554
+ this.connected = false;
1555
+ this.instance = null;
1535
1556
  }
1536
1557
 
1537
1558
  /**
@@ -2197,6 +2218,9 @@ class TestDriverSDK {
2197
2218
  * @private
2198
2219
  */
2199
2220
  _setupLogging() {
2221
+ // Track the last fatal error message to throw on exit
2222
+ let lastFatalError = null;
2223
+
2200
2224
  // Set up markdown logger
2201
2225
  createMarkdownLogger(this.emitter);
2202
2226
 
@@ -2219,6 +2243,11 @@ class TestDriverSDK {
2219
2243
  if (this.loggingEnabled) {
2220
2244
  const event = this.emitter.event;
2221
2245
  console.error(event, ":", data);
2246
+
2247
+ // Capture fatal errors
2248
+ if (event === events.error.fatal) {
2249
+ lastFatalError = data;
2250
+ }
2222
2251
  }
2223
2252
  });
2224
2253
 
@@ -2245,6 +2274,19 @@ class TestDriverSDK {
2245
2274
  }
2246
2275
  });
2247
2276
 
2277
+ // Handle exit events - throw error with meaningful message instead of calling process.exit
2278
+ // This allows test frameworks like Vitest to properly catch and display the error
2279
+ this.emitter.on(events.exit, (exitCode) => {
2280
+ if (exitCode !== 0) {
2281
+ // Create an error with the fatal error message if available
2282
+ const errorMessage = lastFatalError || 'TestDriver fatal error';
2283
+ const error = new Error(errorMessage);
2284
+ error.name = 'TestDriverFatalError';
2285
+ error.exitCode = exitCode;
2286
+ throw error;
2287
+ }
2288
+ });
2289
+
2248
2290
  // Handle show window events for sandbox visualization
2249
2291
  this.emitter.on("show-window", async (url) => {
2250
2292
  if (this.loggingEnabled) {
@@ -2380,7 +2422,7 @@ class TestDriverSDK {
2380
2422
  );
2381
2423
  await sdk.auth();
2382
2424
 
2383
- const platform = options.platform || this.config.TD_PLATFORM || "windows";
2425
+ const platform = options.platform || this.config.TD_PLATFORM || "linux";
2384
2426
 
2385
2427
  // Auto-detect sandbox ID from the active sandbox if not provided
2386
2428
  const sandboxId = options.sandboxId || this.agent?.sandbox?.id || null;
@@ -2545,21 +2587,34 @@ class TestDriverSDK {
2545
2587
  *
2546
2588
  * @example
2547
2589
  * // Simple execution
2548
- * await client.ai('Click the submit button');
2590
+ * await client.act('Click the submit button');
2549
2591
  *
2550
2592
  * @example
2551
2593
  * // With validation loop
2552
- * const result = await client.ai('Fill out the contact form', { validateAndLoop: true });
2594
+ * const result = await client.act('Fill out the contact form', { validateAndLoop: true });
2553
2595
  * console.log(result); // AI's final assessment
2554
2596
  */
2555
- async ai(task) {
2597
+ async act(task) {
2556
2598
  this._ensureConnected();
2557
2599
 
2558
- this.analytics.track("sdk.ai", { task });
2600
+ this.analytics.track("sdk.act", { task });
2559
2601
 
2560
2602
  // Use the agent's exploratoryLoop method directly
2561
2603
  return await this.agent.exploratoryLoop(task, false, true, false);
2562
2604
  }
2605
+
2606
+ /**
2607
+ * @deprecated Use act() instead
2608
+ * Execute a natural language task using AI
2609
+ *
2610
+ * @param {string} task - Natural language description of what to do
2611
+ * @param {Object} options - Execution options
2612
+ * @param {boolean} [options.validateAndLoop=false] - Whether to validate completion and retry if incomplete
2613
+ * @returns {Promise<string|void>} Final AI response if validateAndLoop is true
2614
+ */
2615
+ async ai(task) {
2616
+ return await this.act(task);
2617
+ }
2563
2618
  }
2564
2619
 
2565
2620
  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