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/.env.example CHANGED
@@ -0,0 +1,2 @@
1
+ TD_API_KEY=
2
+ TD_API_ROOT=
@@ -0,0 +1,28 @@
1
+ name: Linux Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [ main, develop ]
6
+ pull_request:
7
+ branches: [ main, develop ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Setup Node.js
17
+ uses: actions/setup-node@v4
18
+ with:
19
+ node-version: '20'
20
+ cache: 'npm'
21
+
22
+ - name: Install dependencies
23
+ run: npm ci
24
+
25
+ - name: Run Linux tests
26
+ run: npx vitest run test/testdriver/assert.test.mjs
27
+ env:
28
+ TD_API_KEY: ${{ secrets.TD_API_KEY }}
package/agent/index.js CHANGED
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env node
2
-
3
1
  // disable depreciation warnings
4
2
  process.removeAllListeners("warning");
5
3
 
@@ -226,13 +224,12 @@ class TestDriverAgent extends EventEmitter2 {
226
224
  this.emitter.emit(events.error.fatal, errorContext);
227
225
  } else {
228
226
  this.emitter.emit(
229
- events.error.fatal,
230
- theme.red("Fatal Error") + `\n${error}`,
227
+ events.error.fatal,error,
231
228
  );
232
229
  }
233
230
 
234
231
  if (skipPostrun) {
235
- this.exit(true);
232
+ return await this.exit(true);
236
233
  } else {
237
234
  try {
238
235
  await this.summarize(error.message);
@@ -1711,28 +1708,12 @@ ${regression}
1711
1708
  this.emitter.emit(events.log.log, `${inputFile} (end)`);
1712
1709
  }
1713
1710
 
1714
- // Returns the path to the sandbox file (project-local first, then global)
1715
- getSandboxFilePath(preferProjectLocal = true) {
1716
- const projectLocalFile = path.join(process.cwd(), ".testdriver-sandbox.json");
1717
- const globalFile = path.join(os.homedir(), ".testdriverai-last-sandbox");
1718
-
1719
- if (preferProjectLocal) {
1720
- // For reading: check project-local first, then global
1721
- if (fs.existsSync(projectLocalFile)) {
1722
- return projectLocalFile;
1723
- }
1724
- if (fs.existsSync(globalFile)) {
1725
- return globalFile;
1726
- }
1727
- // For writing: default to project-local
1728
- return projectLocalFile;
1729
- }
1730
- return globalFile;
1731
- }
1732
-
1733
1711
  // Returns sandboxId to use (either from file if recent, or null)
1734
1712
  getRecentSandboxId() {
1735
- const lastSandboxFile = this.getSandboxFilePath(true);
1713
+ const lastSandboxFile = path.join(
1714
+ os.homedir(),
1715
+ ".testdriverai-last-sandbox",
1716
+ );
1736
1717
 
1737
1718
  if (fs.existsSync(lastSandboxFile)) {
1738
1719
  try {
@@ -1778,8 +1759,10 @@ ${regression}
1778
1759
  }
1779
1760
 
1780
1761
  saveLastSandboxId(sandboxId, osType = "linux") {
1781
- // Save to project-local .testdriver-sandbox.json
1782
- const projectLocalFile = path.join(process.cwd(), ".testdriver-sandbox.json");
1762
+ const lastSandboxFile = path.join(
1763
+ os.homedir(),
1764
+ ".testdriverai-last-sandbox",
1765
+ );
1783
1766
  try {
1784
1767
  const sandboxInfo = {
1785
1768
  sandboxId: sandboxId,
@@ -1788,7 +1771,7 @@ ${regression}
1788
1771
  instanceType: this.sandboxInstance || null,
1789
1772
  timestamp: new Date().toISOString(),
1790
1773
  };
1791
- fs.writeFileSync(projectLocalFile, JSON.stringify(sandboxInfo, null, 2), {
1774
+ fs.writeFileSync(lastSandboxFile, JSON.stringify(sandboxInfo), {
1792
1775
  encoding: "utf-8",
1793
1776
  });
1794
1777
  } catch {
@@ -1797,16 +1780,13 @@ ${regression}
1797
1780
  }
1798
1781
 
1799
1782
  clearRecentSandboxId() {
1800
- // Clear project-local file first, then global
1801
- const projectLocalFile = path.join(process.cwd(), ".testdriver-sandbox.json");
1802
- const globalFile = path.join(os.homedir(), ".testdriverai-last-sandbox");
1803
-
1783
+ const lastSandboxFile = path.join(
1784
+ os.homedir(),
1785
+ ".testdriverai-last-sandbox",
1786
+ );
1804
1787
  try {
1805
- if (fs.existsSync(projectLocalFile)) {
1806
- fs.unlinkSync(projectLocalFile);
1807
- }
1808
- if (fs.existsSync(globalFile)) {
1809
- fs.unlinkSync(globalFile);
1788
+ if (fs.existsSync(lastSandboxFile)) {
1789
+ fs.unlinkSync(lastSandboxFile);
1810
1790
  }
1811
1791
  } catch {
1812
1792
  // ignore errors
@@ -1862,9 +1842,6 @@ ${regression}
1862
1842
  await this.connectToSandboxService();
1863
1843
 
1864
1844
  const recentId = createNew ? null : this.getRecentSandboxId();
1865
-
1866
- // Track whether we reconnected to an existing sandbox or created a new one
1867
- this.isReconnected = false;
1868
1845
 
1869
1846
  // Set sandbox ID for reconnection (only if not creating new and recent ID exists)
1870
1847
  if (this.ip) {
@@ -1878,7 +1855,6 @@ ${regression}
1878
1855
  this.emitter.emit(events.sandbox.connected);
1879
1856
 
1880
1857
  this.instance = instance.instance;
1881
- this.isReconnected = false; // Direct IP is considered new
1882
1858
  await this.renderSandbox(this.instance, headless);
1883
1859
  await this.newSession();
1884
1860
  await this.runLifecycle("provision");
@@ -1899,7 +1875,6 @@ ${regression}
1899
1875
  );
1900
1876
 
1901
1877
  this.instance = instance;
1902
- this.isReconnected = true; // Successfully reconnected to existing sandbox
1903
1878
 
1904
1879
  await this.renderSandbox(instance, headless);
1905
1880
  await this.newSession();
@@ -1932,7 +1907,6 @@ ${regression}
1932
1907
  );
1933
1908
 
1934
1909
  this.instance = instance;
1935
- this.isReconnected = true; // Successfully reconnected to existing sandbox
1936
1910
 
1937
1911
  await this.renderSandbox(instance, headless);
1938
1912
  await this.newSession();
@@ -1949,7 +1923,6 @@ ${regression}
1949
1923
 
1950
1924
  // Create new sandbox (either because createNew is true, or no existing sandbox to connect to)
1951
1925
  if (!this.instance) {
1952
- this.isReconnected = false; // Creating new sandbox
1953
1926
  this.emitter.emit(
1954
1927
  events.log.narration,
1955
1928
  theme.dim(`creating new sandbox...`),
@@ -2186,7 +2159,7 @@ Please check your network connection, TD_API_KEY, or the service status.`,
2186
2159
  type: "create",
2187
2160
  resolution: this.config.TD_RESOLUTION,
2188
2161
  ci: this.config.CI,
2189
- os: this.sandboxOs || "windows",
2162
+ os: this.sandboxOs || "linux",
2190
2163
  };
2191
2164
 
2192
2165
  // Add AMI and instance type if specified
@@ -69,7 +69,7 @@ function createCommandDefinitions(agent) {
69
69
  os: Flags.string({
70
70
  description: "Operating system for the sandbox (windows or linux)",
71
71
  options: ["windows", "linux"],
72
- default: "windows",
72
+ default: "linux",
73
73
  }),
74
74
  },
75
75
  handler: async (args, flags) => {
@@ -246,7 +246,7 @@ function createCommandDefinitions(agent) {
246
246
  os: Flags.string({
247
247
  description: "Operating system for the sandbox (windows or linux)",
248
248
  options: ["windows", "linux"],
249
- default: "windows",
249
+ default: "linux",
250
250
  }),
251
251
  },
252
252
  handler: async (args, flags) => {
@@ -254,6 +254,17 @@ function createCommandDefinitions(agent) {
254
254
  await agent.generate(flags.count || 3, args.prompt);
255
255
  },
256
256
  },
257
+
258
+ init: {
259
+ description: "Initialize a new TestDriver project with Vitest SDK examples",
260
+ args: {},
261
+ flags: {},
262
+ handler: async () => {
263
+ // This handler is special - it doesn't need an agent instance
264
+ // It just scaffolds files, so it will be handled by the CLI command
265
+ throw new Error("Init mode should be handled by CLI interface");
266
+ },
267
+ },
257
268
  };
258
269
  }
259
270
 
@@ -81,7 +81,7 @@ const createCommands = (
81
81
  config,
82
82
  sessionInstance,
83
83
  getCurrentFilePath,
84
- redrawThreshold = 0.1,
84
+ redrawThreshold = 0.01,
85
85
  getDashcamElapsedTime = null,
86
86
  ) => {
87
87
  // Create SDK instance with emitter, config, and session
@@ -8,7 +8,7 @@ const DEFAULT_REDRAW_OPTIONS = {
8
8
  enabled: true, // Master switch to enable/disable redraw detection
9
9
  screenRedraw: true, // Enable screen redraw detection
10
10
  networkMonitor: true, // Enable network activity monitoring
11
- diffThreshold: 0.1, // Percentage threshold for screen diff (0.1 = 0.1%)
11
+ diffThreshold: 0.01, // Percentage threshold for screen diff (0.01 = 0.01%)
12
12
  };
13
13
 
14
14
  // Factory function that creates redraw functionality with the provided system instance
@@ -123,8 +123,8 @@ const createSandbox = (emitter, analytics, sessionInstance) => {
123
123
  this.socket.on("open", async () => {
124
124
  this.apiSocketConnected = true;
125
125
 
126
- setInterval(() => {
127
- if (this.socket.readyState === WebSocket.OPEN) {
126
+ this.heartbeat = setInterval(() => {
127
+ if (this.socket && this.socket.readyState === WebSocket.OPEN) {
128
128
  this.socket.ping();
129
129
  }
130
130
  }, 5000);
@@ -175,6 +175,34 @@ const createSandbox = (emitter, analytics, sessionInstance) => {
175
175
  });
176
176
  });
177
177
  }
178
+
179
+ /**
180
+ * Close the WebSocket connection and clean up resources
181
+ */
182
+ close() {
183
+ if (this.heartbeat) {
184
+ clearInterval(this.heartbeat);
185
+ this.heartbeat = null;
186
+ }
187
+
188
+ if (this.socket) {
189
+ try {
190
+ this.socket.close();
191
+ } catch (err) {
192
+ // Ignore close errors
193
+ }
194
+ this.socket = null;
195
+ }
196
+
197
+ this.apiSocketConnected = false;
198
+ this.instanceSocketConnected = false;
199
+ this.authenticated = false;
200
+ this.instance = null;
201
+
202
+ // Silently clear pending promises without rejecting
203
+ // (rejecting causes unhandled promise rejections during cleanup)
204
+ this.ps = {};
205
+ }
178
206
  }
179
207
 
180
208
  return new Sandbox();
@@ -1,9 +1,9 @@
1
1
  const semver = require("semver");
2
- const package = require("../../package.json");
2
+ const packageJson = require("../../package.json");
3
3
 
4
4
  // Function to check if the new version's minor version is >= current version's minor version
5
5
  module.exports = (inputVersion) => {
6
- const currentParsed = semver.parse(package.version);
6
+ const currentParsed = semver.parse(packageJson.version);
7
7
  const inputParsed = semver.parse(inputVersion.replace("v", ""));
8
8
 
9
9
  if (!currentParsed || !inputParsed) {
@@ -8,7 +8,7 @@
8
8
  rel="stylesheet"
9
9
  />
10
10
  <link rel="icon" type="image/png" href="icon.png" />
11
- <title>TestDriver</title>
11
+ <title>TestDriver - Debugger</title>
12
12
  <style>
13
13
  body {
14
14
  background-color: #111;
package/docs/docs.json CHANGED
@@ -17,121 +17,7 @@
17
17
  "tab": "Computer-Use SDK",
18
18
  "versions": [
19
19
  {
20
- "version": "7.0.0 (SDK)",
21
- "groups": [
22
- {
23
- "group": "Getting Started",
24
- "pages": [
25
- "/v7/getting-started/quickstart",
26
- {
27
- "group": "Configuration",
28
- "icon": "gear",
29
- "pages": [
30
- "/v7/getting-started/configuration",
31
- {
32
- "group": "Platforms",
33
- "icon": "server",
34
- "pages": [
35
- "/v7/platforms/linux",
36
- "/v7/platforms/windows",
37
- "/v7/platforms/macos"
38
- ]
39
- }
40
- ]
41
- }
42
- ]
43
- },
44
- {
45
- "group": "Examples",
46
- "icon": "code",
47
- "pages": [
48
- "/v7/presets/chrome",
49
- "/v7/presets/chrome-extension",
50
- "/v7/presets/vscode",
51
- "/v7/presets/electron"
52
- ]
53
- },
54
- {
55
- "group": "Interactions",
56
- "icon": "bolt",
57
- "pages": [
58
- "/v7/api/find",
59
- "/v7/api/ai",
60
- "/v7/api/click",
61
- "/v7/api/doubleClick",
62
- "/v7/api/rightClick",
63
- "/v7/api/hover",
64
- "/v7/api/mouseDown",
65
- "/v7/api/mouseUp",
66
- "/v7/api/type",
67
- "/v7/api/pressKeys",
68
- "/v7/api/scroll",
69
- "/v7/api/focusApplication",
70
- "/v7/api/assert",
71
- "/v7/api/exec"
72
- ]
73
- },
74
- {
75
- "group": "Core Concepts",
76
- "icon": "book",
77
- "pages": [
78
- "/v7/api/client",
79
- "/v7/api/sandbox",
80
- "/v7/api/elements",
81
- "/v7/api/dashcam",
82
- "/v7/api/assertions"
83
- ]
84
- },
85
- {
86
- "group": "Progressive APIs",
87
- "icon": "layer-group",
88
- "pages": [
89
- "/v7/progressive-apis/PROGRESSIVE_DISCLOSURE",
90
- "/v7/progressive-apis/PROVISION",
91
- "/v7/progressive-apis/HOOKS"
92
- ]
93
- },
94
-
95
- {
96
- "group": "Guides",
97
- "icon": "book-open",
98
- "pages": [
99
- "/v7/guides/vitest",
100
- "/v7/guides/vitest-plugin",
101
- "/v7/guides/debugging",
102
- "/v7/guides/best-practices",
103
- "/v7/guides/troubleshooting",
104
- "/v7/guides/faq",
105
- {
106
- "group": "Caching",
107
- "icon": "bolt",
108
- "pages": [
109
- "/v7/guides/caching-ai",
110
- "/v7/guides/caching-selectors"
111
- ]
112
- },
113
- {
114
- "group": "CI/CD Integration",
115
- "icon": "arrows-spin",
116
- "pages": [
117
- "/v7/guides/ci-cd/overview",
118
- "/v7/guides/ci-cd/github-actions",
119
- "/v7/guides/ci-cd/gitlab",
120
- "/v7/guides/ci-cd/circleci",
121
- "/v7/guides/ci-cd/jenkins",
122
- "/v7/guides/ci-cd/azure",
123
- "/v7/guides/ci-cd/travis"
124
- ]
125
- },
126
- "/v7/guides/performance",
127
- "/v7/guides/self-hosting",
128
- "/v7/guides/migration"
129
- ]
130
- }
131
- ]
132
- },
133
- {
134
- "version": "6.X.X (YAML)",
20
+ "version": "v6 (YAML)",
135
21
  "groups": [
136
22
  {
137
23
  "group": "Overview",
@@ -303,18 +189,93 @@
303
189
  ]
304
190
  }
305
191
  ]
192
+ },
193
+ {
194
+ "version": "v7 (JS Beta)",
195
+ "groups": [
196
+ {
197
+ "group": "Overview",
198
+ "icon": "circle-info",
199
+ "pages": [
200
+ "/v7/overview/what-is-testdriver",
201
+ {
202
+ "group": "Features",
203
+ "icon": "star",
204
+ "pages": [
205
+ "/v7/features/easy-to-write",
206
+ "/v7/features/fast",
207
+ "/v7/features/stable",
208
+ "/v7/features/scalable",
209
+ "/v7/features/ai-native",
210
+ "/v7/features/powerful",
211
+ "/v7/features/observable",
212
+ "/v7/features/enterprise"
213
+ ]
214
+ }
215
+ ]
216
+ },
217
+ {
218
+ "group": "Getting Started",
219
+ "icon": "rocket",
220
+ "pages": [
221
+ "/v7/getting-started/installation",
222
+ "/v7/getting-started/writing-tests",
223
+ "/v7/getting-started/generating-tests",
224
+ "/v7/getting-started/running-and-debugging",
225
+ "/v7/getting-started/setting-up-in-ci"
226
+ ]
227
+ },
228
+ {
229
+ "group": "Examples",
230
+ "icon": "code",
231
+ "pages": [
232
+ "/v7/presets/chrome",
233
+ "/v7/presets/chrome-extension",
234
+ "/v7/presets/vscode",
235
+ "/v7/presets/electron",
236
+ "/v7/presets/webapp"
237
+ ]
238
+ },
239
+ {
240
+ "group": "API Reference",
241
+ "icon": "book",
242
+ "pages": [
243
+ "/v7/api/client",
244
+ "/v7/api/sandbox",
245
+ {
246
+ "group": "Interactions",
247
+ "icon": "bolt",
248
+ "pages": [
249
+ "/v7/api/find",
250
+ "/v7/api/elements",
251
+ "/v7/api/click",
252
+ "/v7/api/doubleClick",
253
+ "/v7/api/rightClick",
254
+ "/v7/api/hover",
255
+ "/v7/api/mouseDown",
256
+ "/v7/api/mouseUp",
257
+ "/v7/api/type",
258
+ "/v7/api/pressKeys",
259
+ "/v7/api/scroll",
260
+ "/v7/api/focusApplication"
261
+ ]
262
+ },
263
+ {
264
+ "group": "AI & Assertions",
265
+ "icon": "wand-magic-sparkles",
266
+ "pages": [
267
+ "/v7/api/act",
268
+ "/v7/api/assert",
269
+ "/v7/api/assertions"
270
+ ]
271
+ },
272
+ "/v7/api/exec",
273
+ "/v7/api/dashcam"
274
+ ]
275
+ }
276
+ ]
306
277
  }
307
278
  ]
308
- },
309
- {
310
- "tab": "Playwright SDK",
311
- "pages": ["v7/playwright"]
312
- },
313
- {
314
- "tab": "Playwright Studio"
315
- },
316
- {
317
- "tab": "Dashcam CLI"
318
279
  }
319
280
  ]
320
281
  },
@@ -352,16 +313,64 @@
352
313
  },
353
314
  "redirects": [
354
315
  {
355
- "source": "/guides/github-actions",
356
- "destination": "/action/setup"
316
+ "source": "/overview/:slug*",
317
+ "destination": "/v6/overview/:slug*"
318
+ },
319
+ {
320
+ "source": "/features/:slug*",
321
+ "destination": "/v6/features/:slug*"
322
+ },
323
+ {
324
+ "source": "/account/:slug*",
325
+ "destination": "/v6/account/:slug*"
326
+ },
327
+ {
328
+ "source": "/cli/:slug*",
329
+ "destination": "/v6/cli/:slug*"
330
+ },
331
+ {
332
+ "source": "/interactive/:slug*",
333
+ "destination": "/v6/interactive/:slug*"
334
+ },
335
+ {
336
+ "source": "/getting-started/:slug*",
337
+ "destination": "/v6/getting-started/:slug*"
338
+ },
339
+ {
340
+ "source": "/apps/:slug*",
341
+ "destination": "/v6/apps/:slug*"
342
+ },
343
+ {
344
+ "source": "/scenarios/:slug*",
345
+ "destination": "/v6/scenarios/:slug*"
346
+ },
347
+ {
348
+ "source": "/integrations/:slug*",
349
+ "destination": "/v6/integrations/:slug*"
350
+ },
351
+ {
352
+ "source": "/guide/:slug*",
353
+ "destination": "/v6/guide/:slug*"
354
+ },
355
+ {
356
+ "source": "/action/:slug*",
357
+ "destination": "/v6/action/:slug*"
358
+ },
359
+ {
360
+ "source": "/importing/:slug*",
361
+ "destination": "/v6/importing/:slug*"
362
+ },
363
+ {
364
+ "source": "/exporting/:slug*",
365
+ "destination": "/v6/exporting/:slug*"
357
366
  },
358
367
  {
359
- "source": "/reference/test-steps",
360
- "destination": "/features/selectorless"
368
+ "source": "/bugs/:slug*",
369
+ "destination": "/v6/bugs/:slug*"
361
370
  },
362
371
  {
363
- "source": "/guides/debugging-test-runs",
364
- "destination": "/getting-started/editing"
372
+ "source": "/commands/:slug*",
373
+ "destination": "/v6/commands/:slug*"
365
374
  }
366
375
  ],
367
376
  "integrations": {
@@ -46,7 +46,7 @@ The setup process involves three main steps:
46
46
  <Tip>
47
47
  Be sure to run `aws configure` with your credentials
48
48
  </Tip>
49
- - Access to the TestDriver AMI (Golden Image is `ami-055cd47506a2f39bb`)\
49
+ - Access to the TestDriver AMI (Golden Image is `ami-086b5b4b86d78987c`)\
50
50
  [Contact us with your preferred AWS Region for access](https://form.typeform.com/to/UECf9rDx?typeform-source=testdriver.ai).
51
51
  - A GitHub repository for committing your tests & workflow.
52
52
 
@@ -244,7 +244,7 @@ Configure these secrets in your GitHub repository:
244
244
  | `AWS_REGION` | AWS Region | `us-east-2` |
245
245
  | `AWS_SECRET_ACCESS_KEY` | AWS secret key | `wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY` |
246
246
  | `AWS_LAUNCH_TEMPLATE_ID` | Launch template from CloudFormation | `lt-07c53ce8349b958d1` |
247
- | `AMI_ID` | TestDriver AMI ID | `ami-085f872ca0cd80fed` |
247
+ | `AMI_ID` | TestDriver AMI ID | `ami-086b5b4b86d78987c` |
248
248
  | `TD_API_KEY` | TestDriver API key | Your API key from [the dashboard](https://app.testdriver.ai) |
249
249
 
250
250
  ## AMI Customization
@@ -291,6 +291,7 @@ Before doing anything else, change the default password:
291
291
 
292
292
  1. Open PowerShell on the instance
293
293
  2. Run the password rotation script:
294
+
294
295
  ```powershell
295
296
  C:\testdriver\RotateLocalPasswords.ps1
296
297
  ```