testdriverai 7.0.0 → 7.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (324) hide show
  1. package/.env.example +2 -0
  2. package/.github/workflows/linux-tests.yml +28 -0
  3. package/README.md +126 -0
  4. package/agent/index.js +7 -9
  5. package/agent/interface.js +13 -2
  6. package/agent/lib/commands.js +795 -136
  7. package/agent/lib/redraw.js +124 -39
  8. package/agent/lib/sandbox.js +40 -3
  9. package/agent/lib/sdk.js +21 -0
  10. package/agent/lib/valid-version.js +2 -2
  11. package/debugger/index.html +1 -1
  12. package/docs/docs.json +86 -71
  13. package/docs/guide/best-practices-polling.mdx +154 -0
  14. package/docs/v6/getting-started/self-hosting.mdx +3 -2
  15. package/docs/v7/_drafts/agents.mdx +852 -0
  16. package/docs/v7/_drafts/auto-cache-key.mdx +167 -0
  17. package/docs/v7/_drafts/best-practices.mdx +486 -0
  18. package/docs/v7/_drafts/caching-ai.mdx +215 -0
  19. package/docs/v7/_drafts/caching-selectors.mdx +400 -0
  20. package/docs/v7/_drafts/caching.mdx +366 -0
  21. package/docs/v7/_drafts/cli-to-sdk-migration.mdx +425 -0
  22. package/docs/v7/_drafts/core.mdx +459 -0
  23. package/docs/v7/_drafts/dashcam-title-feature.mdx +89 -0
  24. package/docs/v7/_drafts/debugging.mdx +349 -0
  25. package/docs/v7/_drafts/error-handling.mdx +501 -0
  26. package/docs/v7/_drafts/faq.mdx +393 -0
  27. package/docs/v7/_drafts/hooks.mdx +360 -0
  28. package/docs/v7/_drafts/implementation-plan.mdx +994 -0
  29. package/docs/v7/_drafts/init-command.mdx +95 -0
  30. package/docs/v7/_drafts/optimal-sdk-design.mdx +1348 -0
  31. package/docs/v7/_drafts/performance.mdx +517 -0
  32. package/docs/v7/_drafts/presets.mdx +210 -0
  33. package/docs/v7/_drafts/progressive-disclosure.mdx +230 -0
  34. package/docs/v7/_drafts/provision.mdx +266 -0
  35. package/docs/{QUICK_START_TEST_RECORDING.md → v7/_drafts/quick-start-test-recording.mdx} +3 -3
  36. package/docs/v7/_drafts/sdk-v7-complete.mdx +345 -0
  37. package/docs/v7/{guides → _drafts}/self-hosting.mdx +1 -1
  38. package/docs/v7/_drafts/troubleshooting.mdx +526 -0
  39. package/docs/v7/_drafts/vitest-plugin.mdx +477 -0
  40. package/docs/v7/_drafts/vitest.mdx +535 -0
  41. package/docs/v7/api/{ai.mdx → act.mdx} +24 -24
  42. package/docs/v7/api/client.mdx +1 -1
  43. package/docs/v7/api/dashcam.mdx +497 -0
  44. package/docs/v7/api/doubleClick.mdx +102 -0
  45. package/docs/v7/api/elements.mdx +143 -41
  46. package/docs/v7/api/find.mdx +258 -0
  47. package/docs/v7/api/mouseDown.mdx +161 -0
  48. package/docs/v7/api/mouseUp.mdx +164 -0
  49. package/docs/v7/api/rightClick.mdx +123 -0
  50. package/docs/v7/api/type.mdx +51 -7
  51. package/docs/v7/features/ai-native.mdx +427 -0
  52. package/docs/v7/features/easy-to-write.mdx +351 -0
  53. package/docs/v7/features/enterprise.mdx +540 -0
  54. package/docs/v7/features/fast.mdx +424 -0
  55. package/docs/v7/features/observable.mdx +623 -0
  56. package/docs/v7/features/powerful.mdx +531 -0
  57. package/docs/v7/features/scalable.mdx +417 -0
  58. package/docs/v7/features/stable.mdx +514 -0
  59. package/docs/v7/getting-started/configuration.mdx +380 -0
  60. package/docs/v7/getting-started/generating-tests.mdx +525 -0
  61. package/docs/v7/getting-started/installation.mdx +486 -0
  62. package/docs/v7/getting-started/quickstart.mdx +320 -141
  63. package/docs/v7/getting-started/running-and-debugging.mdx +511 -0
  64. package/docs/v7/getting-started/setting-up-in-ci.mdx +612 -0
  65. package/docs/v7/getting-started/writing-tests.mdx +535 -0
  66. package/docs/v7/overview/what-is-testdriver.mdx +398 -0
  67. package/docs/v7/platforms/linux.mdx +308 -0
  68. package/docs/v7/platforms/macos.mdx +433 -0
  69. package/docs/v7/platforms/windows.mdx +430 -0
  70. package/docs/v7/playwright.mdx +3 -3
  71. package/docs/v7/presets/chrome-extension.mdx +223 -0
  72. package/docs/v7/presets/chrome.mdx +303 -0
  73. package/docs/v7/presets/electron.mdx +453 -0
  74. package/docs/v7/presets/vscode.mdx +417 -0
  75. package/docs/v7/presets/webapp.mdx +396 -0
  76. package/examples/run-tests-with-recording.sh +2 -2
  77. package/interfaces/cli/commands/init.js +358 -0
  78. package/interfaces/vitest-plugin.mjs +393 -103
  79. package/lib/core/Dashcam.js +506 -0
  80. package/lib/core/index.d.ts +150 -0
  81. package/lib/core/index.js +12 -0
  82. package/lib/presets/index.mjs +331 -0
  83. package/lib/vitest/hooks.d.ts +119 -0
  84. package/lib/vitest/hooks.mjs +316 -0
  85. package/lib/vitest/setup.mjs +44 -0
  86. package/package.json +13 -3
  87. package/sdk.d.ts +350 -44
  88. package/sdk.js +818 -105
  89. package/{self-hosted.yml → setup/aws/self-hosted.yml} +1 -1
  90. package/test/manual/test-console-logs.test.mjs +42 -0
  91. package/test/manual/test-init.sh +54 -0
  92. package/test/manual/test-provision-auth.mjs +22 -0
  93. package/test/testdriver/assert.test.mjs +41 -0
  94. package/test/testdriver/auto-cache-key-demo.test.mjs +56 -0
  95. package/test/testdriver/chrome-extension.test.mjs +89 -0
  96. package/{testdriver/acceptance-sdk → test/testdriver}/drag-and-drop.test.mjs +7 -19
  97. package/{testdriver/acceptance-sdk → test/testdriver}/element-not-found.test.mjs +6 -19
  98. package/{testdriver/acceptance-sdk → test/testdriver}/exec-js.test.mjs +6 -18
  99. package/{testdriver/acceptance-sdk → test/testdriver}/exec-output.test.mjs +9 -21
  100. package/{testdriver/acceptance-sdk → test/testdriver}/exec-pwsh.test.mjs +14 -26
  101. package/{testdriver/acceptance-sdk → test/testdriver}/focus-window.test.mjs +8 -20
  102. package/{testdriver/acceptance-sdk → test/testdriver}/formatted-logging.test.mjs +5 -20
  103. package/{testdriver/acceptance-sdk → test/testdriver}/hover-image.test.mjs +10 -19
  104. package/{testdriver/acceptance-sdk → test/testdriver}/hover-text-with-description.test.mjs +7 -19
  105. package/{testdriver/acceptance-sdk → test/testdriver}/hover-text.test.mjs +5 -19
  106. package/{testdriver/acceptance-sdk → test/testdriver}/match-image.test.mjs +7 -19
  107. package/{testdriver/acceptance-sdk → test/testdriver}/press-keys.test.mjs +5 -19
  108. package/{testdriver/acceptance-sdk → test/testdriver}/prompt.test.mjs +7 -19
  109. package/{testdriver/acceptance-sdk → test/testdriver}/scroll-keyboard.test.mjs +6 -20
  110. package/{testdriver/acceptance-sdk → test/testdriver}/scroll-until-image.test.mjs +6 -18
  111. package/test/testdriver/scroll-until-text.test.mjs +28 -0
  112. package/{testdriver/acceptance-sdk → test/testdriver}/scroll.test.mjs +12 -21
  113. package/test/testdriver/setup/lifecycleHelpers.mjs +262 -0
  114. package/{testdriver/acceptance-sdk → test/testdriver}/setup/testHelpers.mjs +25 -20
  115. package/test/testdriver/type.test.mjs +45 -0
  116. package/vitest.config.mjs +11 -56
  117. package/.github/dependabot.yml +0 -11
  118. package/.github/workflows/acceptance-linux.yml +0 -75
  119. package/.github/workflows/acceptance-sdk-tests.yml +0 -133
  120. package/.github/workflows/acceptance-tests.yml +0 -130
  121. package/.github/workflows/lint.yml +0 -27
  122. package/.github/workflows/publish-canary.yml +0 -40
  123. package/.github/workflows/publish-latest.yml +0 -61
  124. package/.github/workflows/test-install.yml +0 -29
  125. package/.vscode/extensions.json +0 -3
  126. package/.vscode/launch.json +0 -22
  127. package/.vscode/mcp.json +0 -9
  128. package/.vscode/settings.json +0 -14
  129. package/CODEOWNERS +0 -3
  130. package/MIGRATION.md +0 -389
  131. package/SDK_README.md +0 -1122
  132. package/_testdriver/acceptance/assert.yaml +0 -7
  133. package/_testdriver/acceptance/dashcam.yaml +0 -9
  134. package/_testdriver/acceptance/drag-and-drop.yaml +0 -49
  135. package/_testdriver/acceptance/embed.yaml +0 -9
  136. package/_testdriver/acceptance/exec-js.yaml +0 -29
  137. package/_testdriver/acceptance/exec-output.yaml +0 -43
  138. package/_testdriver/acceptance/exec-shell.yaml +0 -40
  139. package/_testdriver/acceptance/focus-window.yaml +0 -16
  140. package/_testdriver/acceptance/hover-image.yaml +0 -18
  141. package/_testdriver/acceptance/hover-text-with-description.yaml +0 -29
  142. package/_testdriver/acceptance/hover-text.yaml +0 -14
  143. package/_testdriver/acceptance/if-else.yaml +0 -31
  144. package/_testdriver/acceptance/match-image.yaml +0 -15
  145. package/_testdriver/acceptance/press-keys.yaml +0 -35
  146. package/_testdriver/acceptance/prompt.yaml +0 -11
  147. package/_testdriver/acceptance/remember.yaml +0 -27
  148. package/_testdriver/acceptance/screenshots/cart.png +0 -0
  149. package/_testdriver/acceptance/scroll-keyboard.yaml +0 -34
  150. package/_testdriver/acceptance/scroll-until-image.yaml +0 -26
  151. package/_testdriver/acceptance/scroll-until-text.yaml +0 -20
  152. package/_testdriver/acceptance/scroll.yaml +0 -33
  153. package/_testdriver/acceptance/snippets/login.yaml +0 -29
  154. package/_testdriver/acceptance/snippets/match-cart.yaml +0 -8
  155. package/_testdriver/acceptance/type.yaml +0 -29
  156. package/_testdriver/behavior/failure.yaml +0 -7
  157. package/_testdriver/behavior/hover-text.yaml +0 -13
  158. package/_testdriver/behavior/lifecycle/postrun.yaml +0 -10
  159. package/_testdriver/behavior/lifecycle/prerun.yaml +0 -8
  160. package/_testdriver/behavior/lifecycle/provision.yaml +0 -8
  161. package/_testdriver/behavior/secrets.yaml +0 -7
  162. package/_testdriver/edge-cases/dashcam-chrome.yaml +0 -8
  163. package/_testdriver/edge-cases/exec-pwsh-multiline.yaml +0 -10
  164. package/_testdriver/edge-cases/js-exception.yaml +0 -8
  165. package/_testdriver/edge-cases/js-promise.yaml +0 -19
  166. package/_testdriver/edge-cases/lifecycle/postrun.yaml +0 -10
  167. package/_testdriver/edge-cases/prompt-in-middle.yaml +0 -23
  168. package/_testdriver/edge-cases/prompt-nested.yaml +0 -7
  169. package/_testdriver/edge-cases/success-test.yaml +0 -9
  170. package/_testdriver/examples/android/example.yaml +0 -12
  171. package/_testdriver/examples/android/lifecycle/postrun.yaml +0 -11
  172. package/_testdriver/examples/android/lifecycle/provision.yaml +0 -47
  173. package/_testdriver/examples/android/readme.md +0 -7
  174. package/_testdriver/examples/chrome-extension/lifecycle/provision.yaml +0 -74
  175. package/_testdriver/examples/desktop/lifecycle/prerun.yaml +0 -0
  176. package/_testdriver/examples/desktop/lifecycle/provision.yaml +0 -64
  177. package/_testdriver/examples/vscode-extension/lifecycle/provision.yaml +0 -73
  178. package/_testdriver/examples/web/lifecycle/postrun.yaml +0 -7
  179. package/_testdriver/examples/web/lifecycle/prerun.yaml +0 -22
  180. package/_testdriver/lifecycle/postrun.yaml +0 -8
  181. package/_testdriver/lifecycle/prerun.yaml +0 -15
  182. package/_testdriver/lifecycle/provision.yaml +0 -25
  183. package/debug-screenshot-1763401388589.png +0 -0
  184. package/mcp-server/AI_GUIDELINES.md +0 -57
  185. package/scripts/view-test-results.mjs +0 -96
  186. package/styles/.vale-config/2-MDX.ini +0 -5
  187. package/styles/Microsoft/AMPM.yml +0 -9
  188. package/styles/Microsoft/Accessibility.yml +0 -30
  189. package/styles/Microsoft/Acronyms.yml +0 -64
  190. package/styles/Microsoft/Adverbs.yml +0 -272
  191. package/styles/Microsoft/Auto.yml +0 -11
  192. package/styles/Microsoft/Avoid.yml +0 -14
  193. package/styles/Microsoft/Contractions.yml +0 -50
  194. package/styles/Microsoft/Dashes.yml +0 -13
  195. package/styles/Microsoft/DateFormat.yml +0 -8
  196. package/styles/Microsoft/DateNumbers.yml +0 -40
  197. package/styles/Microsoft/DateOrder.yml +0 -8
  198. package/styles/Microsoft/Ellipses.yml +0 -9
  199. package/styles/Microsoft/FirstPerson.yml +0 -16
  200. package/styles/Microsoft/Foreign.yml +0 -13
  201. package/styles/Microsoft/Gender.yml +0 -8
  202. package/styles/Microsoft/GenderBias.yml +0 -42
  203. package/styles/Microsoft/GeneralURL.yml +0 -11
  204. package/styles/Microsoft/HeadingAcronyms.yml +0 -7
  205. package/styles/Microsoft/HeadingColons.yml +0 -8
  206. package/styles/Microsoft/HeadingPunctuation.yml +0 -13
  207. package/styles/Microsoft/Headings.yml +0 -28
  208. package/styles/Microsoft/Hyphens.yml +0 -14
  209. package/styles/Microsoft/Negative.yml +0 -13
  210. package/styles/Microsoft/Ordinal.yml +0 -13
  211. package/styles/Microsoft/OxfordComma.yml +0 -8
  212. package/styles/Microsoft/Passive.yml +0 -183
  213. package/styles/Microsoft/Percentages.yml +0 -7
  214. package/styles/Microsoft/Plurals.yml +0 -7
  215. package/styles/Microsoft/Quotes.yml +0 -7
  216. package/styles/Microsoft/RangeTime.yml +0 -13
  217. package/styles/Microsoft/Semicolon.yml +0 -8
  218. package/styles/Microsoft/SentenceLength.yml +0 -6
  219. package/styles/Microsoft/Spacing.yml +0 -8
  220. package/styles/Microsoft/Suspended.yml +0 -7
  221. package/styles/Microsoft/Terms.yml +0 -42
  222. package/styles/Microsoft/URLFormat.yml +0 -9
  223. package/styles/Microsoft/Units.yml +0 -16
  224. package/styles/Microsoft/Vocab.yml +0 -25
  225. package/styles/Microsoft/We.yml +0 -11
  226. package/styles/Microsoft/Wordiness.yml +0 -127
  227. package/styles/Microsoft/meta.json +0 -4
  228. package/styles/alex/Ablist.yml +0 -274
  229. package/styles/alex/Condescending.yml +0 -16
  230. package/styles/alex/Gendered.yml +0 -110
  231. package/styles/alex/LGBTQ.yml +0 -55
  232. package/styles/alex/OCD.yml +0 -10
  233. package/styles/alex/Press.yml +0 -12
  234. package/styles/alex/ProfanityLikely.yml +0 -1289
  235. package/styles/alex/ProfanityMaybe.yml +0 -282
  236. package/styles/alex/ProfanityUnlikely.yml +0 -251
  237. package/styles/alex/README.md +0 -27
  238. package/styles/alex/Race.yml +0 -85
  239. package/styles/alex/Suicide.yml +0 -26
  240. package/styles/alex/meta.json +0 -4
  241. package/styles/config/vocabularies/Docs/accept.txt +0 -47
  242. package/styles/config/vocabularies/Docs/reject.txt +0 -4
  243. package/styles/proselint/Airlinese.yml +0 -8
  244. package/styles/proselint/AnimalLabels.yml +0 -48
  245. package/styles/proselint/Annotations.yml +0 -9
  246. package/styles/proselint/Apologizing.yml +0 -8
  247. package/styles/proselint/Archaisms.yml +0 -52
  248. package/styles/proselint/But.yml +0 -8
  249. package/styles/proselint/Cliches.yml +0 -782
  250. package/styles/proselint/CorporateSpeak.yml +0 -30
  251. package/styles/proselint/Currency.yml +0 -5
  252. package/styles/proselint/Cursing.yml +0 -15
  253. package/styles/proselint/DateCase.yml +0 -7
  254. package/styles/proselint/DateMidnight.yml +0 -7
  255. package/styles/proselint/DateRedundancy.yml +0 -10
  256. package/styles/proselint/DateSpacing.yml +0 -7
  257. package/styles/proselint/DenizenLabels.yml +0 -52
  258. package/styles/proselint/Diacritical.yml +0 -95
  259. package/styles/proselint/GenderBias.yml +0 -45
  260. package/styles/proselint/GroupTerms.yml +0 -39
  261. package/styles/proselint/Hedging.yml +0 -8
  262. package/styles/proselint/Hyperbole.yml +0 -6
  263. package/styles/proselint/Jargon.yml +0 -11
  264. package/styles/proselint/LGBTOffensive.yml +0 -13
  265. package/styles/proselint/LGBTTerms.yml +0 -15
  266. package/styles/proselint/Malapropisms.yml +0 -8
  267. package/styles/proselint/Needless.yml +0 -358
  268. package/styles/proselint/Nonwords.yml +0 -38
  269. package/styles/proselint/Oxymorons.yml +0 -22
  270. package/styles/proselint/P-Value.yml +0 -6
  271. package/styles/proselint/RASSyndrome.yml +0 -30
  272. package/styles/proselint/README.md +0 -12
  273. package/styles/proselint/Skunked.yml +0 -13
  274. package/styles/proselint/Spelling.yml +0 -17
  275. package/styles/proselint/Typography.yml +0 -11
  276. package/styles/proselint/Uncomparables.yml +0 -50
  277. package/styles/proselint/Very.yml +0 -6
  278. package/styles/proselint/meta.json +0 -15
  279. package/styles/write-good/Cliches.yml +0 -702
  280. package/styles/write-good/E-Prime.yml +0 -32
  281. package/styles/write-good/Illusions.yml +0 -11
  282. package/styles/write-good/Passive.yml +0 -183
  283. package/styles/write-good/README.md +0 -27
  284. package/styles/write-good/So.yml +0 -5
  285. package/styles/write-good/ThereIs.yml +0 -6
  286. package/styles/write-good/TooWordy.yml +0 -221
  287. package/styles/write-good/Weasel.yml +0 -29
  288. package/styles/write-good/meta.json +0 -4
  289. package/test/mcp-example-test.yaml +0 -27
  290. package/test/test_parser.js +0 -47
  291. package/testdriver/acceptance-sdk/QUICK_REFERENCE.md +0 -61
  292. package/testdriver/acceptance-sdk/README.md +0 -128
  293. package/testdriver/acceptance-sdk/TEST_REPORTING.md +0 -245
  294. package/testdriver/acceptance-sdk/assert.test.mjs +0 -44
  295. package/testdriver/acceptance-sdk/scroll-until-text.test.mjs +0 -42
  296. package/testdriver/acceptance-sdk/setup/lifecycleHelpers.mjs +0 -239
  297. package/testdriver/acceptance-sdk/type-checking-demo.js +0 -49
  298. package/testdriver/acceptance-sdk/type.test.mjs +0 -84
  299. package/vale.ini +0 -18
  300. package/vitest.config.example.js +0 -19
  301. package/vitest.config.mjs.bak +0 -44
  302. /package/docs/{ARCHITECTURE.md → v7/_drafts/architecture.mdx} +0 -0
  303. /package/docs/{AWESOME_LOGS_QUICK_REF.md → v7/_drafts/awesome-logs-quick-ref.mdx} +0 -0
  304. /package/{CONTRIBUTING.md → docs/v7/_drafts/contributing.mdx} +0 -0
  305. /package/docs/v7/{guides → _drafts}/migration.mdx +0 -0
  306. /package/{PLUGIN_MIGRATION.md → docs/v7/_drafts/plugin-migration.mdx} +0 -0
  307. /package/{PROMPT_CACHE.md → docs/v7/_drafts/prompt-cache.mdx} +0 -0
  308. /package/docs/{SDK_AWESOME_LOGS.md → v7/_drafts/sdk-awesome-logs.mdx} +0 -0
  309. /package/docs/{sdk-browser-rendering.md → v7/_drafts/sdk-browser-rendering.mdx} +0 -0
  310. /package/{SDK_LOGGING.md → docs/v7/_drafts/sdk-logging.mdx} +0 -0
  311. /package/{SDK_MIGRATION.md → docs/v7/_drafts/sdk-migration.mdx} +0 -0
  312. /package/docs/{TEST_RECORDING.md → v7/_drafts/test-recording.mdx} +0 -0
  313. /package/docs/v7/{README.md → overview/readme.mdx} +0 -0
  314. /package/{debug-locate-response.js → test/manual/debug-locate-response.js} +0 -0
  315. /package/{test-find-api.js → test/manual/test-find-api.js} +0 -0
  316. /package/{test-prompt-cache.js → test/manual/test-prompt-cache.js} +0 -0
  317. /package/{test-sandbox-render.js → test/manual/test-sandbox-render.js} +0 -0
  318. /package/{test-sdk-methods.js → test/manual/test-sdk-methods.js} +0 -0
  319. /package/{test-sdk-refactor.js → test/manual/test-sdk-refactor.js} +0 -0
  320. /package/{test-stack-trace.mjs → test/manual/test-stack-trace.mjs} +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}/setup/globalTeardown.mjs +0 -0
  324. /package/{testdriver/acceptance-sdk → test/testdriver}/setup/vitestSetup.mjs +0 -0
@@ -0,0 +1,366 @@
1
+ ---
2
+ title: "Caching"
3
+ sidebarTitle: "Caching"
4
+ description: "How TestDriver caches AI responses and element locations for faster tests"
5
+ icon: "bolt"
6
+ ---
7
+
8
+ ## Overview
9
+
10
+ TestDriver uses two types of caching to dramatically speed up your tests and reduce AI costs:
11
+
12
+ 1. **Prompt Cache** - Caches AI-generated commands (`.ai()` responses)
13
+ 2. **Selector Cache** - Caches element locations (`.find()` results)
14
+
15
+ Both caches are enabled by default and work automatically.
16
+
17
+ ## Prompt Cache
18
+
19
+ The Prompt Cache stores AI-generated YAML commands locally, so repeated `.ai()` calls with the same prompt skip the AI entirely.
20
+
21
+ ### How It Works
22
+
23
+ <Steps>
24
+ <Step title="First Call">
25
+ ```javascript
26
+ await testdriver.ai('click the submit button');
27
+ ```
28
+
29
+ - Sends prompt + screenshot to AI
30
+ - Receives YAML commands
31
+ - Saves to `.testdriver/.cache/{prompt-hash}.yaml`
32
+ </Step>
33
+
34
+ <Step title="Subsequent Calls">
35
+ ```javascript
36
+ await testdriver.ai('click the submit button');
37
+ ```
38
+
39
+ - Checks cache first
40
+ - Finds matching cached YAML
41
+ - Uses cached commands (no AI call)
42
+ - Shows `(using cached response)` in output
43
+ </Step>
44
+ </Steps>
45
+
46
+ ### Cache Location
47
+
48
+ Cached prompts are stored locally:
49
+
50
+ ```
51
+ .testdriver/
52
+ .cache/
53
+ click-the-submit-button-a1b2c3d4.yaml
54
+ find-login-form-e5f6a7b8.yaml
55
+ verify-dashboard-c9d0e1f2.yaml
56
+ ```
57
+
58
+ Files are named using:
59
+ - Sanitized prompt (first 50 chars, alphanumeric)
60
+ - MD5 hash of full prompt for uniqueness
61
+
62
+ ### Disabling Prompt Cache
63
+
64
+ Bypass the cache for a specific call:
65
+
66
+ ```javascript
67
+ // Force fresh AI call, bypass cache
68
+ await testdriver.ai('click the submit button', false);
69
+
70
+ // These use cache (default)
71
+ await testdriver.ai('click the submit button');
72
+ await testdriver.ai('click the submit button', true);
73
+ ```
74
+
75
+ ### Clearing Prompt Cache
76
+
77
+ Clear all cached prompts:
78
+
79
+ ```bash
80
+ rm -rf .testdriver/.cache/*.yaml
81
+ ```
82
+
83
+ Or programmatically:
84
+
85
+ ```javascript
86
+ const promptCache = require('testdriverai/agent/lib/cache.js');
87
+ promptCache.clearCache();
88
+ ```
89
+
90
+ ### Benefits
91
+
92
+ - ⚡ **Instant execution** - No AI call needed
93
+ - 💰 **Cost savings** - Reduces API usage
94
+ - 🔌 **Offline testing** - Works without network
95
+ - 🎯 **Deterministic** - Same prompt = same commands
96
+
97
+ ## Selector Cache
98
+
99
+ The Selector Cache stores element locations on the server, so `.find()` calls can skip the AI vision analysis.
100
+
101
+ ### How It Works
102
+
103
+ ```mermaid
104
+ sequenceDiagram
105
+ participant Test as Your Test
106
+ participant SDK as TestDriver SDK
107
+ participant API as TestDriver API
108
+ participant AI as Claude Vision
109
+ participant Cache as Selector Cache DB
110
+
111
+ Test->>SDK: testdriver.find('submit button')
112
+ SDK->>API: POST /locate (screenshot + prompt)
113
+
114
+ API->>Cache: Check for matching cache entry
115
+
116
+ alt Cache Hit (95%+ similar screenshot)
117
+ Cache-->>API: Return cached coordinates
118
+ API-->>SDK: {x, y, cacheHit: true}
119
+ SDK-->>Test: Element found (instant)
120
+ else Cache Miss
121
+ API->>AI: Analyze screenshot
122
+ AI-->>API: Element coordinates
123
+ API->>Cache: Save new cache entry
124
+ API-->>SDK: {x, y, cacheHit: false}
125
+ SDK-->>Test: Element found
126
+ end
127
+ ```
128
+
129
+ ### Cache Matching Strategy
130
+
131
+ The selector cache uses a three-tier matching system:
132
+
133
+ 1. **Exact Hash Match** (Fastest)
134
+ - Perceptual hash comparison
135
+ - Same screenshot = instant match
136
+ - 0% difference threshold
137
+
138
+ 2. **Pixel Diff Match** (Fast)
139
+ - 80%+ perceptual hash similarity
140
+ - Pixel-by-pixel comparison
141
+ - Default 5% difference threshold (95% similarity)
142
+ - Configurable per call
143
+
144
+ 3. **Template Match** (Fallback)
145
+ - Edge detection + template matching
146
+ - Finds visually similar UI elements
147
+ - 75%+ confidence threshold
148
+
149
+ ### Viewing Cache Entries
150
+
151
+ View all cached selectors at [console.testdriver.ai](https://console.testdriver.ai)
152
+
153
+ The console shows:
154
+ - Cached screenshots with green circles on found elements
155
+ - Original prompts
156
+ - Hit count (how many times cache was used)
157
+ - Similarity scores
158
+ - Cache age and last accessed time
159
+
160
+ ### Controlling Cache Threshold
161
+
162
+ Adjust similarity threshold per call:
163
+
164
+ ```javascript
165
+ // Default: 95% similarity (5% difference allowed)
166
+ await testdriver.find('submit button');
167
+
168
+ // Stricter: 99% similarity (1% difference allowed)
169
+ await testdriver.find('submit button', { threshold: 0.01 });
170
+
171
+ // More lenient: 90% similarity (10% difference allowed)
172
+ await testdriver.find('submit button', { threshold: 0.10 });
173
+
174
+ // Disable cache: force fresh AI analysis
175
+ await testdriver.find('submit button', { threshold: -1 });
176
+ ```
177
+
178
+ ### Cache Filtering
179
+
180
+ The selector cache automatically filters by:
181
+
182
+ - **Prompt** - Exact text match (case-insensitive)
183
+ - **Team** - Your team ID
184
+ - **OS** - Operating system (if specified)
185
+ - **Resolution** - Screen resolution (if specified)
186
+ - **Time Window** - Last 7 days by default
187
+
188
+ ### Cache Statistics
189
+
190
+ Each cache entry tracks:
191
+
192
+ - **Hit Count** - Number of times cache was used
193
+ - **Last Hit** - When cache was last accessed
194
+ - **Similarity** - Percentage match to original
195
+ - **Created At** - When entry was created
196
+ - **Element Type** - button, input, link, etc.
197
+ - **Element Bounds** - Bounding box coordinates
198
+
199
+ ### Benefits
200
+
201
+ - ⚡ **Up to 10x faster** - Skip AI vision analysis
202
+ - 💰 **Lower AI costs** - Fewer vision API calls
203
+ - 🎯 **Consistent results** - Same UI = same coordinates
204
+ - 📊 **Metrics tracking** - See cache hit rates in console
205
+
206
+ ## Cache Behavior Examples
207
+
208
+ ### Prompt Cache Example
209
+
210
+ ```javascript
211
+ import { test } from 'vitest';
212
+ import { chrome } from 'testdriverai/presets';
213
+
214
+ test('login flow', async (context) => {
215
+ const { testdriver } = await chrome(context, {
216
+ url: 'https://myapp.com/login'
217
+ });
218
+
219
+ // First call: AI generates commands, saves to cache
220
+ await testdriver.ai('click the login button');
221
+
222
+ // Run test again - uses cache (instant)
223
+ // Look for: "(using cached response)" in output
224
+ });
225
+ ```
226
+
227
+ ### Selector Cache Example
228
+
229
+ ```javascript
230
+ import { test } from 'vitest';
231
+ import { chrome } from 'testdriverai/presets';
232
+
233
+ test('find element', async (context) => {
234
+ const { testdriver } = await chrome(context, {
235
+ url: 'https://example.com'
236
+ });
237
+
238
+ // First call: AI vision analysis, saves to cache
239
+ const button = await testdriver.find('More information link');
240
+ console.log('Cache hit:', button.cacheHit); // false
241
+
242
+ // Second call: uses cache (instant)
243
+ const button2 = await testdriver.find('More information link');
244
+ console.log('Cache hit:', button2.cacheHit); // true
245
+ });
246
+ ```
247
+
248
+ ### Dynamic Threshold Example
249
+
250
+ ```javascript
251
+ test('strict vs lenient matching', async (context) => {
252
+ const { testdriver } = await chrome(context, { url });
253
+
254
+ // Strict: 99% similarity required
255
+ const elem1 = await testdriver.find('button', { threshold: 0.01 });
256
+
257
+ // Lenient: 90% similarity acceptable
258
+ const elem2 = await testdriver.find('button', { threshold: 0.10 });
259
+
260
+ // Bypass cache entirely
261
+ const elem3 = await testdriver.find('button', { threshold: -1 });
262
+ });
263
+ ```
264
+
265
+ ## Best Practices
266
+
267
+ ### 1. Use Consistent Prompts
268
+
269
+ ```javascript
270
+ // ✅ Good - consistent prompt
271
+ await testdriver.find('submit button');
272
+ await testdriver.find('submit button'); // Cache hit
273
+
274
+ // ❌ Bad - different prompts
275
+ await testdriver.find('submit button');
276
+ await testdriver.find('the submit button'); // Cache miss
277
+ ```
278
+
279
+ ### 2. Clear Cache When UI Changes
280
+
281
+ If your UI changes significantly, clear the cache:
282
+
283
+ ```bash
284
+ # Clear prompt cache
285
+ rm -rf .testdriver/.cache/*.yaml
286
+
287
+ # Clear selector cache
288
+ # Use console.testdriver.ai to delete entries
289
+ ```
290
+
291
+ ### 3. Use Appropriate Thresholds
292
+
293
+ ```javascript
294
+ // Stable UI: strict threshold
295
+ await testdriver.find('logo', { threshold: 0.01 });
296
+
297
+ // Dynamic UI: lenient threshold
298
+ await testdriver.find('news feed item', { threshold: 0.10 });
299
+
300
+ // Always fresh: disable cache
301
+ await testdriver.find('timestamp', { threshold: -1 });
302
+ ```
303
+
304
+ ### 4. Monitor Cache Performance
305
+
306
+ Check [console.testdriver.ai](https://console.testdriver.ai) regularly to:
307
+ - See cache hit rates
308
+ - Identify frequently used selectors
309
+ - Remove stale cache entries
310
+ - Optimize threshold settings
311
+
312
+ ## Cache Storage
313
+
314
+ | Cache Type | Location | Persistence |
315
+ |------------|----------|-------------|
316
+ | Prompt Cache | Local (`.testdriver/.cache/`) | Until manually cleared |
317
+ | Selector Cache | Server (MongoDB + S3) | 7 days default |
318
+
319
+ ## Important Notes
320
+
321
+ ### Prompt Cache
322
+
323
+ - Cache keys are **prompt text only** (no screenshot comparison)
324
+ - Case-insensitive, trimmed matching
325
+ - Safe to commit to version control (but not recommended)
326
+ - Never expires automatically
327
+
328
+ ### Selector Cache
329
+
330
+ - Cache matches by **screenshot similarity** + prompt
331
+ - Platform-specific (OS, resolution)
332
+ - Team-scoped (your cache entries only)
333
+ - 7-day rolling window by default
334
+
335
+ ## Troubleshooting
336
+
337
+ ### Prompt Cache Not Working
338
+
339
+ Check:
340
+ 1. Prompts match exactly (case-insensitive)
341
+ 2. `.testdriver/.cache/` directory exists and is writable
342
+ 3. `TD_NO_PROMPT_CACHE` environment variable is not set
343
+
344
+ ### Selector Cache Not Working
345
+
346
+ Check:
347
+ 1. Threshold isn't too strict (try 0.10 for 90% similarity)
348
+ 2. Screenshot hasn't changed significantly
349
+ 3. OS/resolution matches cached entry
350
+ 4. Cache entry isn't older than 7 days
351
+
352
+ ### Stale Cache Data
353
+
354
+ Clear prompt cache:
355
+ ```bash
356
+ rm -rf .testdriver/.cache/*.yaml
357
+ ```
358
+
359
+ Delete selector cache entries at [console.testdriver.ai](https://console.testdriver.ai)
360
+
361
+ ## See Also
362
+
363
+ - [Console Dashboard](https://console.testdriver.ai) - View and manage selector cache
364
+ - [`.ai()` Method](/v7/api/ai) - AI command generation
365
+ - [`.find()` Method](/v7/api/find) - Element location
366
+ - [Vitest Integration](/v7/guides/vitest) - Testing with TestDriver