testdriverai 7.1.0 → 7.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. package/.env.example +2 -0
  2. package/.github/workflows/linux-tests.yml +28 -0
  3. package/agent/index.js +18 -45
  4. package/agent/interface.js +13 -2
  5. package/agent/lib/commands.js +1 -1
  6. package/agent/lib/redraw.js +1 -1
  7. package/agent/lib/sandbox.js +30 -2
  8. package/agent/lib/valid-version.js +2 -2
  9. package/debugger/index.html +1 -1
  10. package/docs/docs.json +140 -131
  11. package/docs/v6/getting-started/self-hosting.mdx +3 -2
  12. package/docs/v7/_drafts/agents.mdx +852 -0
  13. package/docs/v7/_drafts/auto-cache-key.mdx +167 -0
  14. package/docs/v7/{guides → _drafts}/caching-selectors.mdx +125 -17
  15. package/docs/v7/_drafts/dashcam-title-feature.mdx +89 -0
  16. package/docs/v7/_drafts/error-handling.mdx +501 -0
  17. package/docs/v7/_drafts/implementation-plan.mdx +994 -0
  18. package/docs/v7/_drafts/init-command.mdx +95 -0
  19. package/docs/v7/_drafts/optimal-sdk-design.mdx +1348 -0
  20. package/docs/v7/_drafts/plugin-migration.mdx +222 -0
  21. package/docs/v7/_drafts/prompt-cache.mdx +200 -0
  22. package/docs/{QUICK_START_TEST_RECORDING.md → v7/_drafts/quick-start-test-recording.mdx} +3 -3
  23. package/docs/v7/_drafts/sdk-logging.mdx +222 -0
  24. package/docs/v7/_drafts/sdk-migration.mdx +474 -0
  25. package/docs/v7/_drafts/sdk-v7-complete.mdx +345 -0
  26. package/docs/v7/{guides → _drafts}/self-hosting.mdx +1 -1
  27. package/docs/v7/{guides → _drafts}/troubleshooting.mdx +2 -2
  28. package/docs/v7/{guides → _drafts}/vitest-plugin.mdx +4 -4
  29. package/docs/v7/api/{ai.mdx → act.mdx} +24 -24
  30. package/docs/v7/api/client.mdx +1 -1
  31. package/docs/v7/api/dashcam.mdx +2 -2
  32. package/docs/v7/api/elements.mdx +143 -41
  33. package/docs/v7/api/find.mdx +258 -0
  34. package/docs/v7/api/type.mdx +51 -7
  35. package/docs/v7/features/ai-native.mdx +427 -0
  36. package/docs/v7/features/easy-to-write.mdx +351 -0
  37. package/docs/v7/features/enterprise.mdx +540 -0
  38. package/docs/v7/features/fast.mdx +424 -0
  39. package/docs/v7/features/observable.mdx +623 -0
  40. package/docs/v7/features/powerful.mdx +531 -0
  41. package/docs/v7/features/scalable.mdx +417 -0
  42. package/docs/v7/features/stable.mdx +514 -0
  43. package/docs/v7/getting-started/configuration.mdx +1 -1
  44. package/docs/v7/getting-started/generating-tests.mdx +525 -0
  45. package/docs/v7/getting-started/installation.mdx +486 -0
  46. package/docs/v7/getting-started/quickstart.mdx +51 -5
  47. package/docs/v7/getting-started/running-and-debugging.mdx +511 -0
  48. package/docs/v7/getting-started/setting-up-in-ci.mdx +612 -0
  49. package/docs/v7/getting-started/writing-tests.mdx +535 -0
  50. package/docs/v7/overview/what-is-testdriver.mdx +398 -0
  51. package/docs/v7/playwright.mdx +3 -3
  52. package/docs/v7/presets/chrome.mdx +16 -0
  53. package/docs/v7/presets/electron.mdx +18 -0
  54. package/docs/v7/presets/vscode.mdx +19 -0
  55. package/examples/run-tests-with-recording.sh +70 -0
  56. package/examples/screenshot-example.js +63 -0
  57. package/examples/sdk-awesome-logs-demo.js +177 -0
  58. package/examples/sdk-cache-thresholds.js +96 -0
  59. package/examples/sdk-element-properties.js +155 -0
  60. package/examples/sdk-simple-example.js +65 -0
  61. package/examples/test-recording-example.test.js +166 -0
  62. package/interfaces/cli/commands/init.js +358 -0
  63. package/interfaces/vitest-plugin.mjs +214 -10
  64. package/{src → lib}/core/Dashcam.js +41 -4
  65. package/{src → lib}/vitest/hooks.mjs +118 -100
  66. package/lib/vitest/setup.mjs +44 -0
  67. package/package.json +9 -10
  68. package/sdk.d.ts +15 -2
  69. package/sdk.js +72 -17
  70. package/{self-hosted.yml → setup/aws/self-hosted.yml} +1 -1
  71. package/{testdriver/acceptance-sdk → test/manual}/test-console-logs.test.mjs +1 -1
  72. package/test/manual/test-find-api.js +73 -0
  73. package/test/manual/test-init.sh +54 -0
  74. package/test/manual/test-prompt-cache.js +96 -0
  75. package/test/manual/test-provision-auth.mjs +22 -0
  76. package/test/manual/test-sandbox-render.js +28 -0
  77. package/test/manual/test-sdk-methods.js +15 -0
  78. package/test/manual/test-sdk-refactor.js +53 -0
  79. package/test/manual/test-stack-trace.mjs +57 -0
  80. package/test/testdriver/assert.test.mjs +41 -0
  81. package/{testdriver/acceptance-sdk → test/testdriver}/auto-cache-key-demo.test.mjs +1 -1
  82. package/{testdriver/acceptance-sdk → test/testdriver}/drag-and-drop.test.mjs +1 -1
  83. package/{testdriver/acceptance-sdk → test/testdriver}/element-not-found.test.mjs +1 -1
  84. package/{testdriver/acceptance-sdk → test/testdriver}/exec-js.test.mjs +1 -1
  85. package/{testdriver/acceptance-sdk → test/testdriver}/exec-output.test.mjs +3 -3
  86. package/{testdriver/acceptance-sdk → test/testdriver}/exec-pwsh.test.mjs +3 -3
  87. package/{testdriver/acceptance-sdk → test/testdriver}/focus-window.test.mjs +1 -1
  88. package/{testdriver/acceptance-sdk → test/testdriver}/formatted-logging.test.mjs +1 -1
  89. package/{testdriver/acceptance-sdk → test/testdriver}/hover-image.test.mjs +1 -1
  90. package/{testdriver/acceptance-sdk → test/testdriver}/hover-text-with-description.test.mjs +1 -1
  91. package/{testdriver/acceptance-sdk → test/testdriver}/hover-text.test.mjs +1 -1
  92. package/{testdriver/acceptance-sdk → test/testdriver}/match-image.test.mjs +1 -1
  93. package/{testdriver/acceptance-sdk → test/testdriver}/press-keys.test.mjs +1 -1
  94. package/{testdriver/acceptance-sdk → test/testdriver}/prompt.test.mjs +2 -2
  95. package/{testdriver/acceptance-sdk → test/testdriver}/scroll-keyboard.test.mjs +1 -1
  96. package/{testdriver/acceptance-sdk → test/testdriver}/scroll-until-image.test.mjs +1 -1
  97. package/{testdriver/acceptance-sdk → test/testdriver}/scroll-until-text.test.mjs +1 -1
  98. package/{testdriver/acceptance-sdk → test/testdriver}/scroll.test.mjs +1 -1
  99. package/{src/vitest/lifecycle.mjs → test/testdriver/setup/lifecycleHelpers.mjs} +84 -99
  100. package/test/testdriver/setup/testHelpers.mjs +653 -0
  101. package/{testdriver/acceptance-sdk → test/testdriver}/type.test.mjs +1 -1
  102. package/vitest.config.mjs +8 -59
  103. package/.github/dependabot.yml +0 -11
  104. package/.github/workflows/acceptance-linux.yml +0 -75
  105. package/.github/workflows/acceptance-sdk-tests.yml +0 -133
  106. package/.github/workflows/acceptance-tests.yml +0 -130
  107. package/.github/workflows/lint.yml +0 -27
  108. package/.github/workflows/publish-canary.yml +0 -40
  109. package/.github/workflows/publish-latest.yml +0 -61
  110. package/.github/workflows/test-install.yml +0 -29
  111. package/.vscode/extensions.json +0 -3
  112. package/.vscode/launch.json +0 -22
  113. package/.vscode/settings.json +0 -14
  114. package/AGENTS.md +0 -550
  115. package/CODEOWNERS +0 -2
  116. package/_testdriver/acceptance/assert.yaml +0 -7
  117. package/_testdriver/acceptance/dashcam.yaml +0 -9
  118. package/_testdriver/acceptance/drag-and-drop.yaml +0 -49
  119. package/_testdriver/acceptance/embed.yaml +0 -9
  120. package/_testdriver/acceptance/exec-js.yaml +0 -29
  121. package/_testdriver/acceptance/exec-output.yaml +0 -43
  122. package/_testdriver/acceptance/exec-shell.yaml +0 -40
  123. package/_testdriver/acceptance/focus-window.yaml +0 -16
  124. package/_testdriver/acceptance/hover-image.yaml +0 -18
  125. package/_testdriver/acceptance/hover-text-with-description.yaml +0 -29
  126. package/_testdriver/acceptance/hover-text.yaml +0 -14
  127. package/_testdriver/acceptance/if-else.yaml +0 -31
  128. package/_testdriver/acceptance/match-image.yaml +0 -15
  129. package/_testdriver/acceptance/press-keys.yaml +0 -35
  130. package/_testdriver/acceptance/prompt.yaml +0 -11
  131. package/_testdriver/acceptance/remember.yaml +0 -27
  132. package/_testdriver/acceptance/screenshots/cart.png +0 -0
  133. package/_testdriver/acceptance/scroll-keyboard.yaml +0 -34
  134. package/_testdriver/acceptance/scroll-until-image.yaml +0 -26
  135. package/_testdriver/acceptance/scroll-until-text.yaml +0 -20
  136. package/_testdriver/acceptance/scroll.yaml +0 -33
  137. package/_testdriver/acceptance/snippets/login.yaml +0 -29
  138. package/_testdriver/acceptance/snippets/match-cart.yaml +0 -8
  139. package/_testdriver/acceptance/type.yaml +0 -29
  140. package/_testdriver/behavior/failure.yaml +0 -7
  141. package/_testdriver/behavior/hover-text.yaml +0 -13
  142. package/_testdriver/behavior/lifecycle/postrun.yaml +0 -10
  143. package/_testdriver/behavior/lifecycle/prerun.yaml +0 -8
  144. package/_testdriver/behavior/lifecycle/provision.yaml +0 -8
  145. package/_testdriver/behavior/secrets.yaml +0 -7
  146. package/_testdriver/edge-cases/dashcam-chrome.yaml +0 -8
  147. package/_testdriver/edge-cases/exec-pwsh-multiline.yaml +0 -10
  148. package/_testdriver/edge-cases/js-exception.yaml +0 -8
  149. package/_testdriver/edge-cases/js-promise.yaml +0 -19
  150. package/_testdriver/edge-cases/lifecycle/postrun.yaml +0 -10
  151. package/_testdriver/edge-cases/prompt-in-middle.yaml +0 -23
  152. package/_testdriver/edge-cases/prompt-nested.yaml +0 -7
  153. package/_testdriver/edge-cases/success-test.yaml +0 -9
  154. package/_testdriver/examples/android/example.yaml +0 -12
  155. package/_testdriver/examples/android/lifecycle/postrun.yaml +0 -11
  156. package/_testdriver/examples/android/lifecycle/provision.yaml +0 -47
  157. package/_testdriver/examples/android/readme.md +0 -7
  158. package/_testdriver/examples/chrome-extension/lifecycle/provision.yaml +0 -74
  159. package/_testdriver/examples/desktop/lifecycle/prerun.yaml +0 -0
  160. package/_testdriver/examples/desktop/lifecycle/provision.yaml +0 -64
  161. package/_testdriver/examples/vscode-extension/lifecycle/provision.yaml +0 -73
  162. package/_testdriver/examples/web/lifecycle/postrun.yaml +0 -7
  163. package/_testdriver/examples/web/lifecycle/prerun.yaml +0 -22
  164. package/_testdriver/lifecycle/postrun.yaml +0 -8
  165. package/_testdriver/lifecycle/prerun.yaml +0 -15
  166. package/_testdriver/lifecycle/provision.yaml +0 -25
  167. package/docs/v7/guides/ci-cd/azure.mdx +0 -587
  168. package/docs/v7/guides/ci-cd/circleci.mdx +0 -523
  169. package/docs/v7/guides/ci-cd/github-actions.mdx +0 -457
  170. package/docs/v7/guides/ci-cd/gitlab.mdx +0 -498
  171. package/docs/v7/guides/ci-cd/jenkins.mdx +0 -664
  172. package/docs/v7/guides/ci-cd/travis.mdx +0 -438
  173. package/scripts/view-test-results.mjs +0 -96
  174. package/src/vitest/extended.mjs +0 -108
  175. package/src/vitest/index.mjs +0 -64
  176. package/src/vitest/utils.mjs +0 -150
  177. package/styles/.vale-config/2-MDX.ini +0 -5
  178. package/styles/Microsoft/AMPM.yml +0 -9
  179. package/styles/Microsoft/Accessibility.yml +0 -30
  180. package/styles/Microsoft/Acronyms.yml +0 -64
  181. package/styles/Microsoft/Adverbs.yml +0 -272
  182. package/styles/Microsoft/Auto.yml +0 -11
  183. package/styles/Microsoft/Avoid.yml +0 -14
  184. package/styles/Microsoft/Contractions.yml +0 -50
  185. package/styles/Microsoft/Dashes.yml +0 -13
  186. package/styles/Microsoft/DateFormat.yml +0 -8
  187. package/styles/Microsoft/DateNumbers.yml +0 -40
  188. package/styles/Microsoft/DateOrder.yml +0 -8
  189. package/styles/Microsoft/Ellipses.yml +0 -9
  190. package/styles/Microsoft/FirstPerson.yml +0 -16
  191. package/styles/Microsoft/Foreign.yml +0 -13
  192. package/styles/Microsoft/Gender.yml +0 -8
  193. package/styles/Microsoft/GenderBias.yml +0 -42
  194. package/styles/Microsoft/GeneralURL.yml +0 -11
  195. package/styles/Microsoft/HeadingAcronyms.yml +0 -7
  196. package/styles/Microsoft/HeadingColons.yml +0 -8
  197. package/styles/Microsoft/HeadingPunctuation.yml +0 -13
  198. package/styles/Microsoft/Headings.yml +0 -28
  199. package/styles/Microsoft/Hyphens.yml +0 -14
  200. package/styles/Microsoft/Negative.yml +0 -13
  201. package/styles/Microsoft/Ordinal.yml +0 -13
  202. package/styles/Microsoft/OxfordComma.yml +0 -8
  203. package/styles/Microsoft/Passive.yml +0 -183
  204. package/styles/Microsoft/Percentages.yml +0 -7
  205. package/styles/Microsoft/Plurals.yml +0 -7
  206. package/styles/Microsoft/Quotes.yml +0 -7
  207. package/styles/Microsoft/RangeTime.yml +0 -13
  208. package/styles/Microsoft/Semicolon.yml +0 -8
  209. package/styles/Microsoft/SentenceLength.yml +0 -6
  210. package/styles/Microsoft/Spacing.yml +0 -8
  211. package/styles/Microsoft/Suspended.yml +0 -7
  212. package/styles/Microsoft/Terms.yml +0 -42
  213. package/styles/Microsoft/URLFormat.yml +0 -9
  214. package/styles/Microsoft/Units.yml +0 -16
  215. package/styles/Microsoft/Vocab.yml +0 -25
  216. package/styles/Microsoft/We.yml +0 -11
  217. package/styles/Microsoft/Wordiness.yml +0 -127
  218. package/styles/Microsoft/meta.json +0 -4
  219. package/styles/alex/Ablist.yml +0 -274
  220. package/styles/alex/Condescending.yml +0 -16
  221. package/styles/alex/Gendered.yml +0 -110
  222. package/styles/alex/LGBTQ.yml +0 -55
  223. package/styles/alex/OCD.yml +0 -10
  224. package/styles/alex/Press.yml +0 -12
  225. package/styles/alex/ProfanityLikely.yml +0 -1289
  226. package/styles/alex/ProfanityMaybe.yml +0 -282
  227. package/styles/alex/ProfanityUnlikely.yml +0 -251
  228. package/styles/alex/README.md +0 -27
  229. package/styles/alex/Race.yml +0 -85
  230. package/styles/alex/Suicide.yml +0 -26
  231. package/styles/alex/meta.json +0 -4
  232. package/styles/config/vocabularies/Docs/accept.txt +0 -47
  233. package/styles/config/vocabularies/Docs/reject.txt +0 -4
  234. package/styles/proselint/Airlinese.yml +0 -8
  235. package/styles/proselint/AnimalLabels.yml +0 -48
  236. package/styles/proselint/Annotations.yml +0 -9
  237. package/styles/proselint/Apologizing.yml +0 -8
  238. package/styles/proselint/Archaisms.yml +0 -52
  239. package/styles/proselint/But.yml +0 -8
  240. package/styles/proselint/Cliches.yml +0 -782
  241. package/styles/proselint/CorporateSpeak.yml +0 -30
  242. package/styles/proselint/Currency.yml +0 -5
  243. package/styles/proselint/Cursing.yml +0 -15
  244. package/styles/proselint/DateCase.yml +0 -7
  245. package/styles/proselint/DateMidnight.yml +0 -7
  246. package/styles/proselint/DateRedundancy.yml +0 -10
  247. package/styles/proselint/DateSpacing.yml +0 -7
  248. package/styles/proselint/DenizenLabels.yml +0 -52
  249. package/styles/proselint/Diacritical.yml +0 -95
  250. package/styles/proselint/GenderBias.yml +0 -45
  251. package/styles/proselint/GroupTerms.yml +0 -39
  252. package/styles/proselint/Hedging.yml +0 -8
  253. package/styles/proselint/Hyperbole.yml +0 -6
  254. package/styles/proselint/Jargon.yml +0 -11
  255. package/styles/proselint/LGBTOffensive.yml +0 -13
  256. package/styles/proselint/LGBTTerms.yml +0 -15
  257. package/styles/proselint/Malapropisms.yml +0 -8
  258. package/styles/proselint/Needless.yml +0 -358
  259. package/styles/proselint/Nonwords.yml +0 -38
  260. package/styles/proselint/Oxymorons.yml +0 -22
  261. package/styles/proselint/P-Value.yml +0 -6
  262. package/styles/proselint/RASSyndrome.yml +0 -30
  263. package/styles/proselint/README.md +0 -12
  264. package/styles/proselint/Skunked.yml +0 -13
  265. package/styles/proselint/Spelling.yml +0 -17
  266. package/styles/proselint/Typography.yml +0 -11
  267. package/styles/proselint/Uncomparables.yml +0 -50
  268. package/styles/proselint/Very.yml +0 -6
  269. package/styles/proselint/meta.json +0 -15
  270. package/styles/write-good/Cliches.yml +0 -702
  271. package/styles/write-good/E-Prime.yml +0 -32
  272. package/styles/write-good/Illusions.yml +0 -11
  273. package/styles/write-good/Passive.yml +0 -183
  274. package/styles/write-good/README.md +0 -27
  275. package/styles/write-good/So.yml +0 -5
  276. package/styles/write-good/ThereIs.yml +0 -6
  277. package/styles/write-good/TooWordy.yml +0 -221
  278. package/styles/write-good/Weasel.yml +0 -29
  279. package/styles/write-good/meta.json +0 -4
  280. package/test/dashcam.test.js +0 -137
  281. package/test/mcp-example-test.yaml +0 -27
  282. package/test/test_parser.js +0 -47
  283. package/testdriver/acceptance-sdk/QUICK_REFERENCE.md +0 -61
  284. package/testdriver/acceptance-sdk/README.md +0 -128
  285. package/testdriver/acceptance-sdk/TEST_REPORTING.md +0 -245
  286. package/testdriver/acceptance-sdk/assert.test.mjs +0 -26
  287. package/testdriver/acceptance-sdk/hooks-example.test.mjs +0 -38
  288. package/testdriver/acceptance-sdk/presets-example.test.mjs +0 -87
  289. package/testdriver/acceptance-sdk/setup/testHelpers.mjs +0 -420
  290. package/testdriver/acceptance-sdk/sully-ai.test.mjs +0 -234
  291. package/testdriver/acceptance-sdk/type-checking-demo.js +0 -49
  292. package/vale.ini +0 -18
  293. package/vitest.config.example.js +0 -19
  294. package/vitest.config.mjs.bak +0 -44
  295. /package/docs/{ARCHITECTURE.md → v7/_drafts/architecture.mdx} +0 -0
  296. /package/docs/{AWESOME_LOGS_QUICK_REF.md → v7/_drafts/awesome-logs-quick-ref.mdx} +0 -0
  297. /package/docs/v7/{guides → _drafts}/best-practices.mdx +0 -0
  298. /package/docs/v7/{guides → _drafts}/caching-ai.mdx +0 -0
  299. /package/docs/v7/{guides → _drafts}/caching.mdx +0 -0
  300. /package/docs/{MIGRATION.md → v7/_drafts/cli-to-sdk-migration.mdx} +0 -0
  301. /package/{CONTRIBUTING.md → docs/v7/_drafts/contributing.mdx} +0 -0
  302. /package/docs/v7/{progressive-apis/CORE.md → _drafts/core.mdx} +0 -0
  303. /package/docs/v7/{guides → _drafts}/debugging.mdx +0 -0
  304. /package/docs/v7/{guides → _drafts}/faq.mdx +0 -0
  305. /package/docs/v7/{progressive-apis/HOOKS.md → _drafts/hooks.mdx} +0 -0
  306. /package/docs/v7/{guides → _drafts}/migration.mdx +0 -0
  307. /package/docs/v7/{guides → _drafts}/performance.mdx +0 -0
  308. /package/docs/{PRESETS.md → v7/_drafts/presets.mdx} +0 -0
  309. /package/docs/v7/{progressive-apis/PROGRESSIVE_DISCLOSURE.md → _drafts/progressive-disclosure.mdx} +0 -0
  310. /package/docs/v7/{progressive-apis/PROVISION.md → _drafts/provision.mdx} +0 -0
  311. /package/docs/{SDK_AWESOME_LOGS.md → v7/_drafts/sdk-awesome-logs.mdx} +0 -0
  312. /package/docs/{sdk-browser-rendering.md → v7/_drafts/sdk-browser-rendering.mdx} +0 -0
  313. /package/docs/{TEST_RECORDING.md → v7/_drafts/test-recording.mdx} +0 -0
  314. /package/docs/v7/{guides → _drafts}/vitest.mdx +0 -0
  315. /package/docs/v7/{README.md → overview/readme.mdx} +0 -0
  316. /package/{src → lib}/core/index.d.ts +0 -0
  317. /package/{src → lib}/core/index.js +0 -0
  318. /package/{src → lib}/presets/index.mjs +0 -0
  319. /package/{src → lib}/vitest/hooks.d.ts +0 -0
  320. /package/{debug-locate-response.js → test/manual/debug-locate-response.js} +0 -0
  321. /package/{verify-element-api.js → test/manual/verify-element-api.js} +0 -0
  322. /package/{verify-types.js → test/manual/verify-types.js} +0 -0
  323. /package/{testdriver/acceptance-sdk → test/testdriver}/chrome-extension.test.mjs +0 -0
  324. /package/{testdriver/acceptance-sdk → test/testdriver}/setup/globalTeardown.mjs +0 -0
  325. /package/{testdriver/acceptance-sdk → test/testdriver}/setup/vitestSetup.mjs +0 -0
@@ -0,0 +1,222 @@
1
+ # Vitest Reporter → Plugin Migration
2
+
3
+ ## Summary
4
+
5
+ Converted the Vitest reporter to a plugin architecture with much simpler dashcam URL tracking.
6
+
7
+ ## Key Changes
8
+
9
+ ### 1. Plugin Architecture ✅
10
+
11
+ **Before (Reporter):**
12
+
13
+ ```javascript
14
+ class TestDriverReporter {
15
+ constructor(options = {}) {
16
+ this.options = options;
17
+ this.testRun = null;
18
+ // ... many instance properties
19
+ }
20
+ }
21
+ ```
22
+
23
+ **After (Plugin):**
24
+
25
+ ```javascript
26
+ const pluginState = {
27
+ testRun: null,
28
+ testRunId: null,
29
+ dashcamUrls: new Map(), // In-memory tracking!
30
+ // ... all state in one place
31
+ };
32
+
33
+ export default function testDriverPlugin(options = {}) {
34
+ return {
35
+ name: "testdriver-plugin",
36
+ // ... hooks
37
+ };
38
+ }
39
+ ```
40
+
41
+ ### 2. Dashcam URL Tracking (MUCH SIMPLER) ✅
42
+
43
+ **Before:**
44
+
45
+ - ❌ Write JSON to temp files in `/tmp/`
46
+ - ❌ Read temp files on test completion
47
+ - ❌ Complex matching logic (sessionId, taskId, filename patterns)
48
+ - ❌ Manual cleanup of temp files
49
+ - ❌ Race conditions with parallel tests
50
+ - ❌ Multiple fallback mechanisms (globalThis, registry, meta)
51
+
52
+ **After:**
53
+
54
+ - ✅ Simple in-memory Map (testId → dashcamUrl)
55
+ - ✅ Direct API: `registerDashcamUrl(testId, url, platform)`
56
+ - ✅ No file system operations
57
+ - ✅ No complex matching
58
+ - ✅ No cleanup needed
59
+ - ✅ Thread-safe for parallel tests
60
+
61
+ ### 3. Usage in Tests
62
+
63
+ **Before:**
64
+
65
+ ```javascript
66
+ // Tests had to write to temp files
67
+ const tempFile = path.join(
68
+ os.tmpdir(),
69
+ `testdriver-dashcam-${sessionId}-${taskId}-${Date.now()}.json`,
70
+ );
71
+ fs.writeFileSync(
72
+ tempFile,
73
+ JSON.stringify({
74
+ dashcamUrl,
75
+ replayObjectId,
76
+ platform: client.os,
77
+ timestamp: Date.now(),
78
+ pid: process.pid,
79
+ sessionId,
80
+ }),
81
+ );
82
+
83
+ // AND set global variables
84
+ globalThis.__testdriverMeta.__lastDashcamUrl__ = dashcamUrl;
85
+
86
+ // AND register in registry
87
+ globalThis.__testdriverRegistry.setClient(taskId, client);
88
+
89
+ // AND store in task.meta
90
+ task.meta.testdriverDashcamUrl = dashcamUrl;
91
+ ```
92
+
93
+ **After:**
94
+
95
+ ```javascript
96
+ // Just one simple call
97
+ globalThis.__testdriverPlugin.registerDashcamUrl(taskId, dashcamUrl, client.os);
98
+ ```
99
+
100
+ ### 4. Configuration
101
+
102
+ **Before:**
103
+
104
+ ```javascript
105
+ export default defineConfig({
106
+ test: {
107
+ reporters: [
108
+ "default",
109
+ [
110
+ "./interfaces/vitest-reporter.js",
111
+ {
112
+ apiKey: process.env.TD_API_KEY,
113
+ apiRoot: process.env.TD_API_ROOT,
114
+ },
115
+ ],
116
+ ],
117
+ },
118
+ });
119
+ ```
120
+
121
+ **After:**
122
+
123
+ ```javascript
124
+ export default defineConfig({
125
+ plugins: [
126
+ testDriverPlugin({
127
+ apiKey: process.env.TD_API_KEY,
128
+ apiRoot: process.env.TD_API_ROOT,
129
+ }),
130
+ ],
131
+ });
132
+ ```
133
+
134
+ ## Files Modified
135
+
136
+ ### Plugin
137
+
138
+ - ✅ **Created**: `interfaces/vitest-plugin.mjs` (new plugin)
139
+ - ✅ **Deleted**: `interfaces/vitest-reporter.js` (old reporter)
140
+ - ✅ **Updated**: `vitest.config.mjs` (uses plugin)
141
+ - ✅ **Updated**: `vitest.config.example.js` (uses plugin)
142
+
143
+ ### Test Helpers
144
+
145
+ - ✅ **Updated**: `testdriver/acceptance-sdk/setup/testHelpers.mjs`
146
+ - Removed temp file writing
147
+ - Removed `__testdriverRegistry` initialization
148
+ - Removed `__testdriverMeta` initialization
149
+ - Uses `globalThis.__testdriverPlugin.registerDashcamUrl()` instead
150
+
151
+ ### Documentation
152
+
153
+ - ✅ **Updated**: `docs/QUICK_START_TEST_RECORDING.md`
154
+ - ✅ **Updated**: `docs/TEST_RECORDING.md`
155
+ - ✅ **Updated**: `docs/ARCHITECTURE.md`
156
+
157
+ ## Code Removed
158
+
159
+ ### From Plugin (vs old reporter)
160
+
161
+ - ❌ ~200 lines of file system operations
162
+ - ❌ `indexDashcamFiles()` - complex temp file reading
163
+ - ❌ `findReplayForTest()` - complex sessionId matching
164
+ - ❌ `findReplayForTestInline()` - complex fallback logic
165
+ - ❌ Imports: `fs`, `os` (no longer needed!)
166
+
167
+ ### From Test Helpers
168
+
169
+ - ❌ ~60 lines of temp file writing
170
+ - ❌ Global registry setup
171
+ - ❌ Global meta initialization
172
+ - ❌ Multiple storage mechanisms
173
+
174
+ ## Benefits
175
+
176
+ 1. **Simpler**: ~300 fewer lines of complex code
177
+ 2. **Faster**: No file I/O overhead
178
+ 3. **More Reliable**: No file system race conditions
179
+ 4. **Better DX**: Single API call to register dashcam URLs
180
+ 5. **Easier to Debug**: All state in one place
181
+ 6. **Thread-Safe**: Map-based storage handles parallel tests
182
+ 7. **Cleaner**: No temp file cleanup needed
183
+
184
+ ## Testing
185
+
186
+ ```bash
187
+ # Verify plugin loads
188
+ node -e "import('./interfaces/vitest-plugin.mjs').then(m => console.log('Exports:', Object.keys(m)))"
189
+
190
+ # Run tests
191
+ TD_API_KEY=xxx npx vitest run
192
+ ```
193
+
194
+ ## Migration for Users
195
+
196
+ If you're using the TestDriver SDK in your tests:
197
+
198
+ **Old way (still works but deprecated):**
199
+
200
+ ```javascript
201
+ // Multiple places to set dashcam URL
202
+ globalThis.__testdriverMeta.__lastDashcamUrl__ = dashcamUrl;
203
+ ```
204
+
205
+ **New way:**
206
+
207
+ ```javascript
208
+ // Single plugin API
209
+ if (globalThis.__testdriverPlugin) {
210
+ globalThis.__testdriverPlugin.registerDashcamUrl(
211
+ testId,
212
+ dashcamUrl,
213
+ platform,
214
+ );
215
+ }
216
+ ```
217
+
218
+ ## Notes
219
+
220
+ - The plugin automatically makes itself available globally as `globalThis.__testdriverPlugin`
221
+ - Test helpers now use this API automatically
222
+ - No breaking changes for end users - just better internals!
@@ -0,0 +1,200 @@
1
+ # Prompt Cache System
2
+
3
+ ## Overview
4
+
5
+ The TestDriver SDK includes automatic caching of `.ai()` responses. When you use the SDK to execute natural language prompts, the YAML commands generated by the AI are cached locally to improve performance and reduce API calls.
6
+
7
+ **Caching is enabled by default** and can be controlled per-call using the `cache` parameter.
8
+
9
+ ## How It Works
10
+
11
+ 1. **First Call**: When you call `.ai('click the submit button')` for the first time:
12
+
13
+ - The SDK sends the prompt and screenshot to the API
14
+ - The API returns YAML commands in markdown format
15
+ - The response is cached to `.testdriver/.cache/{prompt-hash}.yaml`
16
+
17
+ 2. **Subsequent Calls**: When you call `.ai('click the submit button')` again:
18
+
19
+ - The SDK checks the cache first
20
+ - If found, it uses the cached YAML instead of calling the API
21
+ - You'll see `(using cached response)` in the output
22
+
23
+ 3. **Disable Caching**: Pass `false` as the second parameter:
24
+ - `.ai('click the submit button', false)` bypasses the cache
25
+ - Forces a fresh API call and updates the cache
26
+
27
+ ## Cache Location
28
+
29
+ Cached responses are stored in:
30
+
31
+ ```
32
+ .testdriver/.cache/
33
+ ```
34
+
35
+ Files are named using a combination of:
36
+
37
+ - Sanitized prompt (first 50 chars, alphanumeric only)
38
+ - MD5 hash of the full prompt for uniqueness
39
+
40
+ Example:
41
+
42
+ ```
43
+ .testdriver/.cache/click-the-submit-button-a1b2c3d4e5f6.yaml
44
+ ```
45
+
46
+ ## Benefits
47
+
48
+ - **Faster execution**: No API call needed for repeated prompts
49
+ - **Cost savings**: Reduces API usage for repeated operations
50
+ - **Offline testing**: Can rerun tests without network access
51
+ - **Deterministic tests**: Same prompt always produces same commands
52
+
53
+ ## Disabling Cache
54
+
55
+ To disable caching for a specific `.ai()` call, pass `false` as the second parameter:
56
+
57
+ ```javascript
58
+ // Force fresh API call, bypass cache
59
+ await client.ai("click the submit button", false);
60
+ ```
61
+
62
+ Caching is **enabled by default** (equivalent to passing `true`):
63
+
64
+ ```javascript
65
+ // These are equivalent
66
+ await client.ai("click the submit button");
67
+ await client.ai("click the submit button", true);
68
+ ```
69
+
70
+ ## Clearing Cache
71
+
72
+ To clear all cached prompts:
73
+
74
+ ```bash
75
+ rm -rf .testdriver/.cache/*.yaml
76
+ ```
77
+
78
+ Or programmatically:
79
+
80
+ ```javascript
81
+ const promptCache = require("testdriverai/agent/lib/cache.js");
82
+ promptCache.clearCache();
83
+ ```
84
+
85
+ ## Usage Examples
86
+
87
+ ### Basic Usage (Automatic Caching)
88
+
89
+ ```javascript
90
+ const TestDriver = require("testdriverai");
91
+
92
+ const client = new TestDriver(process.env.TD_API_KEY);
93
+ await client.connect();
94
+
95
+ // First call - makes API request and caches
96
+ await client.ai("click the login button");
97
+
98
+ // Second call - uses cache (instant)
99
+ await client.ai("click the login button");
100
+
101
+ // Force fresh API call, bypass cache
102
+ await client.ai("click the login button", false);
103
+ ```
104
+
105
+ ### Check Cache Status
106
+
107
+ ```javascript
108
+ const promptCache = require("testdriverai/agent/lib/cache.js");
109
+
110
+ // Check if a prompt is cached
111
+ if (promptCache.hasCache("click the login button")) {
112
+ console.log("This prompt is cached");
113
+ }
114
+
115
+ // Get cache statistics
116
+ const stats = promptCache.getCacheStats();
117
+ console.log(`Cached prompts: ${stats.count}`);
118
+ console.log(`Files: ${stats.files}`);
119
+ ```
120
+
121
+ ### Read Cached YAML
122
+
123
+ ```javascript
124
+ const promptCache = require("testdriverai/agent/lib/cache.js");
125
+
126
+ const yaml = promptCache.readCache("click the login button");
127
+ if (yaml) {
128
+ console.log("Cached YAML:", yaml);
129
+ }
130
+ ```
131
+
132
+ ### Manual Cache Control
133
+
134
+ ```javascript
135
+ const promptCache = require("testdriverai/agent/lib/cache.js");
136
+
137
+ // Write to cache manually
138
+ promptCache.writeCache("custom prompt", yamlContent);
139
+
140
+ // Clear entire cache
141
+ promptCache.clearCache();
142
+
143
+ // Get cache path for a prompt
144
+ const path = promptCache.getCachePath("my prompt");
145
+ console.log(`Cache file: ${path}`);
146
+ ```
147
+
148
+ ## Important Notes
149
+
150
+ 1. **Prompt Matching**: Cache keys are based on the exact prompt text (case-insensitive, trimmed)
151
+
152
+ - `'Click the button'` and `'click the button'` will match
153
+ - `'Click the button'` and `'Click the button '` will match (trailing space trimmed)
154
+ - `'Click button'` and `'Click the button'` will NOT match
155
+
156
+ 2. **No Screenshot Comparison**: The cache does NOT compare screenshots
157
+
158
+ - Cached responses assume the UI state is similar
159
+ - Use different prompts if the UI state has changed significantly
160
+
161
+ 3. **Manual Cache Management**: The cache never expires automatically
162
+
163
+ - Clear it periodically if needed
164
+ - Delete specific files if a prompt's behavior should change
165
+
166
+ 4. **Version Compatibility**: Cache files are plain YAML
167
+ - Compatible across TestDriver versions
168
+ - Safe to commit to version control (though not recommended)
169
+
170
+ ## Testing
171
+
172
+ Run the test suite to verify caching:
173
+
174
+ ```bash
175
+ node test-prompt-cache.js
176
+ ```
177
+
178
+ This will:
179
+
180
+ - Make an initial `.ai()` call that caches the response
181
+ - Make a second `.ai()` call that uses the cache
182
+ - Show cache statistics and file locations
183
+
184
+ ## Troubleshooting
185
+
186
+ ### Cache not being used
187
+
188
+ - Check that prompts match exactly (case-insensitive)
189
+ - Verify `TD_NO_PROMPT_CACHE` is not set
190
+ - Check `.testdriver/.cache/` directory exists and is writable
191
+
192
+ ### Stale cache data
193
+
194
+ - Clear the cache directory
195
+ - Or delete specific cached prompt files
196
+
197
+ ### Permission errors
198
+
199
+ - Ensure `.testdriver/.cache/` is writable
200
+ - Check file system permissions
@@ -33,7 +33,7 @@ export default defineConfig({
33
33
  export TD_API_KEY="your-api-key-here"
34
34
  ```
35
35
 
36
- Get your API key from: https://app.testdriver.ai/settings/api-keys
36
+ Get your API key from: https://console.testdriver.ai/settings/api-keys
37
37
 
38
38
  ### 3. Run Tests
39
39
 
@@ -42,7 +42,7 @@ npx vitest run
42
42
  ```
43
43
 
44
44
  That's it! Your tests are now being recorded. View results at:
45
- https://app.testdriver.ai/dashboard/test-runs
45
+ https://console.testdriver.ai/dashboard/test-runs
46
46
 
47
47
  ## With Dashcam (Optional)
48
48
 
@@ -211,5 +211,5 @@ await client.completeTestRun({
211
211
  ## Support
212
212
 
213
213
  - Documentation: https://docs.testdriver.ai
214
- - Dashboard: https://app.testdriver.ai
214
+ - Dashboard: https://console.testdriver.ai
215
215
  - API Reference: /cli/docs/TEST_RECORDING.md
@@ -0,0 +1,222 @@
1
+ # TestDriver SDK - Formatted Logging for Dashcam
2
+
3
+ The TestDriver SDK now includes clean, structured logging that makes logs easy to read when replayed in Dashcam.
4
+
5
+ ## Features
6
+
7
+ ✨ **Clean, structured formatting** with clear labels and timestamps
8
+ ⏱️ **Timestamp tracking** showing elapsed time from test start
9
+ 🎯 **Action-specific formatting** for find, click, type, hover, scroll, assert
10
+ ⚡ **Cache indicators** showing when elements are found from cache
11
+ 📊 **Test context integration** with Vitest test information
12
+ 🎥 **Dashcam-optimized** - no emojis or ANSI codes, pure text format
13
+
14
+ ## How It Works
15
+
16
+ All logs sent through the `log:log` event are automatically formatted before being sent to Dashcam. This means when you replay your test in Dashcam, you'll see beautiful, easy-to-read logs with:
17
+
18
+ - **Clear prefixes** like `[FIND]`, `[CLICK]`, `[ASSERT]` for different action types
19
+ - **Highlighted information** for element descriptions and coordinates
20
+ - **Elapsed timestamps** from test start like `[30.59s]`
21
+ - **Cache hit indicators** showing performance optimizations with `(cached)`
22
+ - **Duration information** for operations
23
+
24
+ ## Usage
25
+
26
+ ### Basic Setup
27
+
28
+ The formatter is automatically integrated into the SDK. Just use the SDK normally:
29
+
30
+ ```javascript
31
+ import { afterAll, beforeAll, describe, it } from "vitest";
32
+ import {
33
+ createTestClient,
34
+ setupTest,
35
+ teardownTest,
36
+ } from "./setup/testHelpers.mjs";
37
+
38
+ describe("My Test", () => {
39
+ let testdriver;
40
+
41
+ beforeAll(async () => {
42
+ testdriver = createTestClient();
43
+ await setupTest(testdriver);
44
+ });
45
+
46
+ afterAll(async () => {
47
+ await teardownTest(testdriver);
48
+ });
49
+
50
+ it("should have nice logs", async () => {
51
+ // Logs are automatically formatted!
52
+ const button = await testdriver.find("Submit button");
53
+ await button.click();
54
+ });
55
+ });
56
+ ```
57
+
58
+ ### Enhanced Logging with Test Context
59
+
60
+ For even better logging with timestamps, set the test context:
61
+
62
+ ```javascript
63
+ beforeAll(async () => {
64
+ testdriver = createTestClient();
65
+
66
+ // Set test context for enhanced logging
67
+ testdriver.setTestContext({
68
+ file: "my-test.spec.mjs",
69
+ test: "My Test Suite",
70
+ startTime: Date.now(),
71
+ });
72
+
73
+ await setupTest(testdriver);
74
+ });
75
+ ```
76
+
77
+ This enables elapsed time display like `[30.59s]` in your logs.
78
+
79
+ ## Log Format Examples
80
+
81
+ ### Element Found
82
+
83
+ ```
84
+ [30.59s] [FIND] Found "Submit button" at (682, 478) 1597ms (cached)
85
+ ```
86
+
87
+ ### Click Action
88
+
89
+ ```
90
+ [35.43s] [CLICK] Click "Submit button"
91
+ ```
92
+
93
+ ### Hover Action
94
+
95
+ ```
96
+ [12.15s] [HOVER] Hover "Menu item"
97
+ ```
98
+
99
+ ### Type Action
100
+
101
+ ```
102
+ [8.32s] [TYPE] Type "user@example.com"
103
+ ```
104
+
105
+ ### Assertion
106
+
107
+ ```
108
+ [42.10s] [ASSERT] "form submission successful" PASSED
109
+ ```
110
+
111
+ ### Error
112
+
113
+ ```
114
+ [15.23s] [FAIL] Failed to save debug image - Error: ENOENT: no such file or directory
115
+ ```
116
+
117
+ ## Formatter API
118
+
119
+ The formatter is available through the `sdk-log-formatter.js` module:
120
+
121
+ ```javascript
122
+ const { formatter } = require("./sdk-log-formatter");
123
+
124
+ // Format different types of messages
125
+ formatter.formatElementFound("Button", {
126
+ x: 100,
127
+ y: 200,
128
+ duration: "1500ms",
129
+ cacheHit: true,
130
+ });
131
+ formatter.formatAction("click", "Submit button");
132
+ formatter.formatAssertion("form is visible", true);
133
+ formatter.formatError("Connection failed", error);
134
+ ```
135
+
136
+ ### Available Methods
137
+
138
+ - `formatElementFound(description, meta)` - Format element discovery
139
+ - `formatAction(action, description, meta)` - Format user actions
140
+ - `formatAssertion(assertion, passed, meta)` - Format test assertions
141
+ - `formatError(message, error)` - Format error messages
142
+ - `formatHeader(title)` - Create section headers
143
+ - `formatSummary(stats)` - Format test summaries
144
+ - `setTestContext(context)` - Update test context for timing
145
+
146
+ ## Dashcam Compatibility
147
+
148
+ The formatter is designed specifically for Dashcam replay compatibility:
149
+
150
+ - **No emojis** - Uses text labels like `[FIND]`, `[CLICK]` instead of icons
151
+ - **No ANSI colors** - Plain text formatting that displays correctly in all environments
152
+ - **No special characters** - Simple ASCII characters only
153
+ - **Clean structure** - Easy to read in logs without terminal formatting
154
+
155
+ ## Integration with Dashcam
156
+
157
+ When you run tests with Dashcam recording:
158
+
159
+ 1. The SDK sends formatted logs to the `log:log` event
160
+ 2. These logs are forwarded to the sandbox via `_forwardLogToSandbox()`
161
+ 3. Dashcam captures and stores these logs with precise timestamps
162
+ 4. When you replay in Dashcam, you see beautifully formatted logs synchronized with the video
163
+
164
+ ### Example Workflow
165
+
166
+ ```bash
167
+ # Run tests with Dashcam
168
+ npx vitest run testdriver/acceptance-sdk/formatted-logging.test.mjs
169
+
170
+ # View the replay with formatted logs
171
+ # Open the Dashcam URL from the test output
172
+ ```
173
+
174
+ ## Customization
175
+
176
+ ### Custom Action Types
177
+
178
+ Add custom action types to the formatter:
179
+
180
+ ```javascript
181
+ // In sdk-log-formatter.js, add to getPrefix():
182
+ const prefixes = {
183
+ // ...existing prefixes
184
+ myAction: "[CUSTOM]",
185
+ };
186
+ ```
187
+
188
+ ### Custom Message Formatting
189
+
190
+ Override the `formatMessage` method for custom text highlighting:
191
+
192
+ ```javascript
193
+ formatMessage(type, message) {
194
+ // Add custom highlighting
195
+ message = message.replace(/\[custom\]/g, chalk.green('[custom]'));
196
+ return super.formatMessage(type, message);
197
+ }
198
+ ```
199
+
200
+ ## Examples
201
+
202
+ See `testdriver/acceptance-sdk/formatted-logging.test.mjs` for a complete example.
203
+
204
+ ## Benefits for Dashcam Replay
205
+
206
+ - **Better debugging**: Quickly identify what happened at each step
207
+ - **Professional appearance**: Share polished test recordings with stakeholders
208
+ - **Faster analysis**: Labeled actions make it easy to scan logs
209
+ - **Context awareness**: Timestamps help correlate logs with video timeline
210
+ - **Performance insights**: Cache indicators show optimization opportunities
211
+ - **Universal compatibility**: Works in any environment without terminal support
212
+
213
+ ## Technical Details
214
+
215
+ The formatter uses:
216
+
217
+ - **Plain text formatting** for universal compatibility
218
+ - **Event emitters** to intercept log events
219
+ - **Base64 encoding** for safe transmission to sandbox
220
+ - **Test context** from Vitest for timing information
221
+
222
+ Logs are sent through the existing `log:log` event system, ensuring compatibility with all existing TestDriver infrastructure.