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