@testdriverai/agent 7.11.239-test → 7.11.241-test
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/ai/skills/testdriver-agent/SKILL.md +174 -91
- package/ai/skills/testdriver-assert/SKILL.md +73 -269
- package/ai/skills/testdriver-aws-setup/SKILL.md +194 -312
- package/ai/skills/testdriver-bring-your-own-machine/SKILL.md +137 -204
- package/ai/skills/testdriver-cache/SKILL.md +142 -149
- package/ai/skills/testdriver-caching/SKILL.md +97 -87
- package/ai/skills/testdriver-captcha/SKILL.md +126 -111
- package/ai/skills/testdriver-ci-cd/SKILL.md +153 -542
- package/ai/skills/testdriver-click/SKILL.md +74 -229
- package/ai/skills/testdriver-client/SKILL.md +175 -229
- package/ai/skills/testdriver-customizing-devices/SKILL.md +72 -250
- package/ai/skills/testdriver-dashcam/SKILL.md +71 -404
- package/ai/skills/testdriver-debugging-with-screenshots/SKILL.md +103 -369
- package/ai/skills/testdriver-double-click/SKILL.md +46 -67
- package/ai/skills/testdriver-errors/SKILL.md +102 -176
- package/ai/skills/testdriver-events/SKILL.md +170 -327
- package/ai/skills/testdriver-exec/SKILL.md +92 -256
- package/ai/skills/testdriver-extract/SKILL.md +69 -170
- package/ai/skills/testdriver-find/SKILL.md +140 -736
- package/ai/skills/testdriver-focus-application/SKILL.md +69 -246
- package/ai/skills/testdriver-generating-tests/SKILL.md +102 -136
- package/ai/skills/testdriver-hosted/SKILL.md +79 -143
- package/ai/skills/testdriver-hover/SKILL.md +62 -235
- package/ai/skills/testdriver-locating-elements/SKILL.md +71 -366
- package/ai/skills/testdriver-making-assertions/SKILL.md +114 -72
- package/ai/skills/testdriver-mcp-setup/SKILL.md +79 -62
- package/ai/skills/testdriver-mouse-down/SKILL.md +46 -124
- package/ai/skills/testdriver-mouse-up/SKILL.md +45 -128
- package/ai/skills/testdriver-options/SKILL.md +73 -46
- package/ai/skills/testdriver-parse/SKILL.md +95 -184
- package/ai/skills/testdriver-performing-actions/SKILL.md +101 -91
- package/ai/skills/testdriver-press-keys/SKILL.md +59 -299
- package/ai/skills/testdriver-provision/SKILL.md +135 -179
- package/ai/skills/testdriver-quickstart/SKILL.md +24 -8
- package/ai/skills/testdriver-quickstart-claude/SKILL.md +84 -0
- package/ai/skills/testdriver-quickstart-github/SKILL.md +62 -32
- package/ai/skills/testdriver-quickstart-manual/SKILL.md +59 -32
- package/ai/skills/testdriver-quickstart-vscode/SKILL.md +96 -0
- package/ai/skills/testdriver-redraw/SKILL.md +100 -164
- package/ai/skills/testdriver-reusable-code/SKILL.md +95 -199
- package/ai/skills/testdriver-right-click/SKILL.md +45 -88
- package/ai/skills/testdriver-screenshot/SKILL.md +47 -201
- package/ai/skills/testdriver-screenshots/SKILL.md +86 -136
- package/ai/skills/testdriver-scroll/SKILL.md +71 -154
- package/ai/skills/testdriver-secrets/SKILL.md +94 -90
- package/ai/skills/testdriver-self-hosted/SKILL.md +82 -140
- package/ai/skills/testdriver-test-results-json/SKILL.md +165 -202
- package/ai/skills/testdriver-type/SKILL.md +56 -304
- package/ai/skills/testdriver-variables/SKILL.md +119 -80
- package/ai/skills/testdriver-wait/SKILL.md +31 -29
- package/ai/skills/testdriver-what-is-testdriver/SKILL.md +80 -32
- package/package.json +1 -1
|
@@ -1,81 +1,51 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: testdriver:cache
|
|
3
|
-
description:
|
|
3
|
+
description: Every option that controls how find() and assert() reuse cached results.
|
|
4
4
|
---
|
|
5
5
|
<!-- Generated from cache.mdx. DO NOT EDIT. -->
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
This page lists every cache option, its default, and where you can set it. The cache is on by default, so you only need these to tune or turn it off.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
The cache works at two levels:
|
|
12
|
-
- **Screen cache**: a pixel diff comparison between the present screenshot and the cached screenshot
|
|
13
|
-
- **Element cache**: OpenCV template matching to make sure that the cached element position is still correct
|
|
14
|
-
|
|
15
|
-
## How It Works
|
|
16
|
-
|
|
17
|
-
1. On `find()`, the SDK sends the present screenshot and the cache metadata to the API.
|
|
18
|
-
2. The API compares the screenshot against the cached results for the same `cacheKey`.
|
|
19
|
-
3. If the screen pixel diff is in the `screen` threshold AND the element template match is more than the `element` threshold, TestDriver returns the cached position.
|
|
20
|
-
4. If not, TestDriver makes a new AI call and caches the result.
|
|
21
|
-
|
|
22
|
-
```mermaid
|
|
23
|
-
flowchart LR
|
|
24
|
-
A[Screenshot + cacheKey] --> B{Screen Diff\n< threshold?}
|
|
25
|
-
B -- Yes --> C{Template\nMatch OK?}
|
|
26
|
-
C -- Yes --> D[Return cached position]
|
|
27
|
-
B -- No --> E[AI Call - fresh]
|
|
28
|
-
C -- No --> F[AI Call - fresh]
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Configuration
|
|
32
|
-
|
|
33
|
-
### Constructor Options
|
|
9
|
+
For how caching works and when it helps, see [Speed up reruns with caching](/caching).
|
|
34
10
|
|
|
35
11
|
```javascript
|
|
36
|
-
const testdriver =
|
|
12
|
+
const testdriver = TestDriver(context, {
|
|
37
13
|
cache: {
|
|
38
|
-
enabled: true,
|
|
39
14
|
thresholds: {
|
|
40
|
-
find: {
|
|
41
|
-
|
|
42
|
-
element: 0.8, // 80% OpenCV correlation required (default)
|
|
43
|
-
},
|
|
44
|
-
assert: 0.05, // 5% pixel diff for assertions (default)
|
|
15
|
+
find: { screen: 0.05, element: 0.8 },
|
|
16
|
+
assert: 0.05,
|
|
45
17
|
},
|
|
46
18
|
},
|
|
47
|
-
cacheKey: '
|
|
19
|
+
cacheKey: 'checkout-flow',
|
|
48
20
|
});
|
|
49
21
|
```
|
|
50
22
|
|
|
51
|
-
|
|
52
|
-
Cache configuration object, or `false` to disable entirely.
|
|
23
|
+
## Client options
|
|
53
24
|
|
|
54
|
-
|
|
55
|
-
<ParamField path="enabled" type="boolean" default={true}>
|
|
56
|
-
Enable or disable the cache system. Requires a valid `cacheKey` to actually activate.
|
|
57
|
-
</ParamField>
|
|
58
|
-
|
|
59
|
-
<ParamField path="thresholds" type="CacheThresholds">
|
|
60
|
-
Threshold configuration for different command types.
|
|
25
|
+
Pass these to `TestDriver(context, options)` or `new TestDriver(options)`. They apply to every call the client makes.
|
|
61
26
|
|
|
27
|
+
<ParamField path="cache" type="boolean | object" default="true">
|
|
28
|
+
Pass `false` to turn the cache off. Pass an object to change the match thresholds.
|
|
29
|
+
|
|
30
|
+
<Expandable title="properties">
|
|
31
|
+
<ParamField path="thresholds" type="object">
|
|
62
32
|
<Expandable title="properties">
|
|
63
|
-
<ParamField path="find" type="
|
|
33
|
+
<ParamField path="find" type="object">
|
|
64
34
|
Thresholds for `find()` and `findAll()`.
|
|
65
35
|
|
|
66
36
|
<Expandable title="properties">
|
|
67
|
-
<ParamField path="screen" type="number" default=
|
|
68
|
-
|
|
37
|
+
<ParamField path="screen" type="number" default="0.05">
|
|
38
|
+
The largest share of pixels that may differ between the current screen and the cached screen, from `0` to `1`. `0.05` allows a 5% difference. Lower values require a closer match.
|
|
69
39
|
</ParamField>
|
|
70
|
-
|
|
71
|
-
<ParamField path="element" type="number" default=
|
|
72
|
-
|
|
40
|
+
|
|
41
|
+
<ParamField path="element" type="number" default="0.8">
|
|
42
|
+
How closely the cached image of the element must match what's on screen now, from `0` to `1`. Higher values require a closer match. Used by `find()` only, not `findAll()`.
|
|
73
43
|
</ParamField>
|
|
74
44
|
</Expandable>
|
|
75
45
|
</ParamField>
|
|
76
|
-
|
|
77
|
-
<ParamField path="assert" type="number" default=
|
|
78
|
-
|
|
46
|
+
|
|
47
|
+
<ParamField path="assert" type="number" default="0.05">
|
|
48
|
+
The largest share of pixels that may differ for `assert()` to reuse a cached result, from `0` to `1`.
|
|
79
49
|
</ParamField>
|
|
80
50
|
</Expandable>
|
|
81
51
|
</ParamField>
|
|
@@ -83,139 +53,162 @@ const testdriver = new TestDriver({
|
|
|
83
53
|
</ParamField>
|
|
84
54
|
|
|
85
55
|
<ParamField path="cacheKey" type="string">
|
|
86
|
-
|
|
56
|
+
The key cache entries are stored under. By default, TestDriver generates one from the test file. See [Cache keys](#cache-keys).
|
|
57
|
+
</ParamField>
|
|
58
|
+
|
|
59
|
+
<ParamField path="cacheThreshold" type="object">
|
|
60
|
+
**Deprecated.** Use `cache.thresholds` instead.
|
|
87
61
|
</ParamField>
|
|
88
62
|
|
|
89
|
-
|
|
63
|
+
## Per-call options
|
|
90
64
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
65
|
+
Override the client settings for a single call.
|
|
66
|
+
|
|
67
|
+
### find()
|
|
94
68
|
|
|
95
|
-
|
|
96
|
-
|
|
69
|
+
```javascript
|
|
70
|
+
const priceLabel = await testdriver.find('Total price label', {
|
|
71
|
+
cacheKey: 'checkout-flow',
|
|
72
|
+
cache: { thresholds: { screen: 0.01, element: 0.95 } },
|
|
73
|
+
});
|
|
97
74
|
```
|
|
98
75
|
|
|
99
|
-
|
|
76
|
+
<ParamField path="cacheKey" type="string">
|
|
77
|
+
Use this key for this call instead of the client's key.
|
|
78
|
+
</ParamField>
|
|
100
79
|
|
|
101
|
-
|
|
80
|
+
<ParamField path="cache.thresholds.screen" type="number">
|
|
81
|
+
Overrides `cache.thresholds.find.screen` for this call.
|
|
82
|
+
</ParamField>
|
|
102
83
|
|
|
103
|
-
|
|
84
|
+
<ParamField path="cache.thresholds.element" type="number">
|
|
85
|
+
Overrides `cache.thresholds.find.element` for this call.
|
|
86
|
+
</ParamField>
|
|
87
|
+
|
|
88
|
+
### findAll()
|
|
89
|
+
|
|
90
|
+
`findAll()` takes `cacheKey` and `cache.thresholds.screen`. It doesn't use the `element` threshold.
|
|
104
91
|
|
|
105
92
|
```javascript
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
cache: {
|
|
109
|
-
thresholds: { screen: 0.01, element: 0.95 },
|
|
110
|
-
},
|
|
93
|
+
const productCards = await testdriver.findAll('Product card in the results grid', {
|
|
94
|
+
cache: { thresholds: { screen: 0.02 } },
|
|
111
95
|
});
|
|
96
|
+
```
|
|
112
97
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
98
|
+
### assert()
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
await testdriver.assert('the order confirmation is visible', {
|
|
102
|
+
cacheKey: 'checkout-flow',
|
|
103
|
+
threshold: 0.01,
|
|
117
104
|
});
|
|
118
105
|
```
|
|
119
106
|
|
|
120
|
-
|
|
107
|
+
<ParamField path="cacheKey" type="string">
|
|
108
|
+
Use this key for this call instead of the client's key.
|
|
109
|
+
</ParamField>
|
|
121
110
|
|
|
122
|
-
|
|
111
|
+
<ParamField path="threshold" type="number">
|
|
112
|
+
Overrides `cache.thresholds.assert` for this call.
|
|
113
|
+
</ParamField>
|
|
123
114
|
|
|
124
|
-
|
|
125
|
-
|----------|--------|---------|
|
|
126
|
-
| 1 (highest) | Per-command option | `find(desc, { cache: { thresholds: { screen: 0.1 } } })` |
|
|
127
|
-
| 2 | Legacy number argument | `find(desc, 0.1)` |
|
|
128
|
-
| 3 | Global constructor config | `new TestDriver({ cache: { thresholds: { find: { screen: 0.1 } } } })` |
|
|
129
|
-
| 4 (lowest) | Hard-coded defaults | `screen: 0.05`, `element: 0.8`, `assert: 0.05` |
|
|
115
|
+
## Threshold priority
|
|
130
116
|
|
|
131
|
-
|
|
117
|
+
When a threshold is set in more than one place, the most specific wins:
|
|
132
118
|
|
|
133
|
-
|
|
119
|
+
1. The per-call option, such as `find(description, { cache: { thresholds: { screen: 0.1 } } })`
|
|
120
|
+
2. A legacy number argument, such as `find(description, 0.1)`
|
|
121
|
+
3. The client option, `cache.thresholds`
|
|
122
|
+
4. The defaults: `screen` 0.05, `element` 0.8, `assert` 0.05
|
|
134
123
|
|
|
135
|
-
|
|
136
|
-
2. Reads the file content
|
|
137
|
-
3. Computes a **SHA-256 hash** of the content
|
|
138
|
-
4. Uses the **first 16 hex characters** as the cache key
|
|
124
|
+
## Cache keys
|
|
139
125
|
|
|
140
|
-
|
|
141
|
-
- **Same test file** → same cache key → cache hits
|
|
142
|
-
- **Modified test file** → different hash → automatic cache invalidation
|
|
143
|
-
- **Different test files** → different keys → isolated caches
|
|
126
|
+
Cache entries are stored under a key. By default, TestDriver generates the key from the test file:
|
|
144
127
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
128
|
+
- It hashes the contents of the file that creates the client (SHA-256, first 16 hex characters).
|
|
129
|
+
- Editing the file changes the hash, so the file starts with a fresh cache.
|
|
130
|
+
- Each test file gets its own cache.
|
|
131
|
+
|
|
132
|
+
Set `cacheKey` to keep a cache across edits, or to share one between files that use the same screens:
|
|
149
133
|
|
|
150
|
-
|
|
151
|
-
const testdriver =
|
|
134
|
+
```javascript
|
|
135
|
+
const testdriver = TestDriver(context, { cacheKey: 'checkout-flow' });
|
|
152
136
|
```
|
|
153
137
|
|
|
154
|
-
|
|
138
|
+
If TestDriver can't read the test file, it can't generate a key. `find()` and `findAll()` then skip the cache unless you set `cacheKey`.
|
|
155
139
|
|
|
156
|
-
|
|
140
|
+
## What must match
|
|
157
141
|
|
|
158
|
-
|
|
159
|
-
1. Load the cached element crop (needle) and current screenshot (haystack)
|
|
160
|
-
2. Run `cv.matchTemplate()` with `TM_CCOEFF_NORMED`
|
|
161
|
-
3. Binary threshold at the configured element threshold
|
|
162
|
-
4. Find contours to extract match positions
|
|
163
|
-
5. Return matches with `{ x, y, width, height, centerX, centerY }`
|
|
142
|
+
A cached entry is reused only when all of these match the run that created it:
|
|
164
143
|
|
|
165
|
-
|
|
166
|
-
|
|
144
|
+
- The cache key.
|
|
145
|
+
- The exact description passed to `find()`, or the exact assertion text.
|
|
146
|
+
- The sandbox OS and screen resolution.
|
|
167
147
|
|
|
168
|
-
|
|
148
|
+
Entries become usable only after the test that created them passes.
|
|
169
149
|
|
|
170
|
-
##
|
|
150
|
+
## Turn the cache off
|
|
171
151
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
152
|
+
Turn the cache off for one client:
|
|
153
|
+
|
|
154
|
+
```javascript
|
|
155
|
+
const testdriver = TestDriver(context, { cache: false });
|
|
156
|
+
```
|
|
176
157
|
|
|
177
|
-
|
|
158
|
+
Or for a whole run:
|
|
178
159
|
|
|
179
|
-
|
|
160
|
+
```bash
|
|
161
|
+
TD_NO_CACHE=true npx vitest run
|
|
162
|
+
```
|
|
180
163
|
|
|
181
|
-
|
|
164
|
+
<Warning>
|
|
165
|
+
`cache: { enabled: false }` doesn't turn the cache off. Use `cache: false` or `TD_NO_CACHE=true`.
|
|
166
|
+
</Warning>
|
|
182
167
|
|
|
183
|
-
|
|
184
|
-
|---|---|
|
|
185
|
-
| `cacheHit` | `true` if cache was used |
|
|
186
|
-
| `similarity` | Pixel diff percentage between screenshots |
|
|
187
|
-
| `cacheSimilarity` | OpenCV template match score |
|
|
168
|
+
## Inspect a result
|
|
188
169
|
|
|
189
|
-
|
|
170
|
+
Read the cache details from the element that `find()` returns:
|
|
190
171
|
|
|
191
172
|
```javascript
|
|
192
|
-
const
|
|
193
|
-
const
|
|
194
|
-
console.log(debug);
|
|
195
|
-
// { cacheHit: true, similarity: 0.02, cacheSimilarity: 0.92, ... }
|
|
173
|
+
const submitButton = await testdriver.find('Submit button');
|
|
174
|
+
const { cache } = submitButton.toJSON();
|
|
196
175
|
```
|
|
197
176
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
177
|
+
<ResponseField name="cache" type="object">
|
|
178
|
+
<Expandable title="properties">
|
|
179
|
+
<ResponseField name="hit" type="boolean">
|
|
180
|
+
`true` when the location came from the cache.
|
|
181
|
+
</ResponseField>
|
|
182
|
+
<ResponseField name="strategy" type="string">
|
|
183
|
+
How the cached entry was matched.
|
|
184
|
+
</ResponseField>
|
|
185
|
+
<ResponseField name="createdAt" type="string">
|
|
186
|
+
When the cached entry was created.
|
|
187
|
+
</ResponseField>
|
|
188
|
+
<ResponseField name="diffPercent" type="number">
|
|
189
|
+
The share of pixels that differed between the current screen and the cached screen, from `0` to `1`.
|
|
190
|
+
</ResponseField>
|
|
191
|
+
<ResponseField name="imageUrl" type="string">
|
|
192
|
+
A link to the cached screenshot.
|
|
193
|
+
</ResponseField>
|
|
194
|
+
</Expandable>
|
|
195
|
+
</ResponseField>
|
|
196
|
+
|
|
197
|
+
To browse or clear your team's cached entries, open the [Cache page in the TestDriver console](https://console.testdriver.ai/cache).
|
|
198
|
+
|
|
199
|
+
## Related
|
|
200
|
+
|
|
201
|
+
<CardGroup cols={2}>
|
|
202
|
+
<Card title="Caching" icon="brain" href="/caching">
|
|
203
|
+
How the cache works and when it helps.
|
|
204
|
+
</Card>
|
|
205
|
+
<Card title="Options" icon="sliders" href="/options">
|
|
206
|
+
Every client option, with its default.
|
|
207
|
+
</Card>
|
|
208
|
+
<Card title="find()" icon="magnifying-glass" href="/find">
|
|
209
|
+
Locate an element by describing it.
|
|
210
|
+
</Card>
|
|
211
|
+
<Card title="assert()" icon="check" href="/assert">
|
|
212
|
+
Check the screen with an AI assertion.
|
|
213
|
+
</Card>
|
|
214
|
+
</CardGroup>
|
|
@@ -1,132 +1,142 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: testdriver:caching
|
|
3
|
-
description:
|
|
3
|
+
description: Reuse element locations from passing runs to skip the AI when the screen is unchanged.
|
|
4
4
|
---
|
|
5
5
|
<!-- Generated from caching.mdx. DO NOT EDIT. -->
|
|
6
6
|
|
|
7
|
-
After
|
|
7
|
+
After a test passes, TestDriver remembers where it found each element.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
- When the screen looks the same on a later run, `find()` reuses that location instead of asking the AI.
|
|
10
|
+
- The step is faster, cheaper, and gives the same result every time.
|
|
11
|
+
- When the screen changes, TestDriver falls back to the AI and learns the new location.
|
|
10
12
|
|
|
13
|
+
Caching is on by default. You don't need to configure anything.
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
// First run: builds cache
|
|
14
|
-
await testdriver.find('submit button');
|
|
15
|
+
## How caching works
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
1. **The first run learns.** Each `find()` asks the AI to locate the element. TestDriver saves the result with an image of the screen and of the element.
|
|
18
|
+
2. **A passing run confirms.** Saved entries become usable only once the test passes. A failing run never teaches TestDriver a wrong location.
|
|
19
|
+
3. **Later runs reuse.** On the next run, `find()` compares the current screen with the saved one. TestDriver returns the saved location without calling the AI when both are true:
|
|
20
|
+
- The screen differs by no more than 5% of its pixels.
|
|
21
|
+
- The saved image of the element still matches what's at that spot.
|
|
19
22
|
|
|
20
|
-
|
|
23
|
+
Otherwise, it asks the AI and saves a new entry.
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
`assert()` is cached the same way. When the screen matches a confirmed earlier run, the saved result is reused.
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
- **Selector prompt**: The exact text description that you give to `find()`
|
|
26
|
-
- **Screenshot context**: The perceptual hash of the present screen state
|
|
27
|
-
- **Platform**: The operating system and the browser version
|
|
27
|
+
## What has to match
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
A saved entry is reused only when all of these match the run that created it:
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
- **The test file.** The cache is keyed on a hash of the test file's contents, so editing the file starts a fresh cache. A changed test can't reuse results that no longer apply.
|
|
32
|
+
- **The description.** The text you pass to `find()` must match exactly.
|
|
33
|
+
- **The OS and screen resolution** of the sandbox.
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
const { testdriver } = await chrome(context, {
|
|
37
|
-
url: 'https://example.com'
|
|
38
|
-
});
|
|
35
|
+
## Keep changing values out of descriptions
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
await testdriver.find('More information link'); // 2.1s
|
|
37
|
+
The description must match exactly. A description with a value that changes between runs misses the cache every time:
|
|
42
38
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
});
|
|
39
|
+
```javascript
|
|
40
|
+
// Misses the cache whenever the email changes
|
|
41
|
+
const emailField = await testdriver.find(`input next to ${email}`);
|
|
46
42
|
```
|
|
47
43
|
|
|
48
|
-
|
|
44
|
+
Describe the element itself, and pass the changing value to the action instead:
|
|
49
45
|
|
|
50
|
-
|
|
46
|
+
```javascript
|
|
47
|
+
// Same description every run, so it can be cached
|
|
48
|
+
const emailField = await testdriver.find('Email input field');
|
|
49
|
+
await emailField.click();
|
|
50
|
+
await testdriver.type(email);
|
|
51
|
+
```
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
Manage and clear your test cache from the TestDriver console.
|
|
54
|
-
</Card>
|
|
53
|
+
## Choose your own cache key
|
|
55
54
|
|
|
56
|
-
|
|
55
|
+
By default, each test file has its own cache, which resets when you edit the file.
|
|
57
56
|
|
|
58
|
-
|
|
57
|
+
Set a `cacheKey` when you create the client to keep the cache across edits, or to share it between files that use the same screens:
|
|
59
58
|
|
|
60
59
|
```javascript
|
|
61
|
-
|
|
62
|
-
const { testdriver } = await chrome(context, { url });
|
|
63
|
-
|
|
64
|
-
const element = await testdriver.find('submit button');
|
|
65
|
-
|
|
66
|
-
if (element.cacheHit) {
|
|
67
|
-
console.log('✅ Cache hit - instant response');
|
|
68
|
-
console.log('Strategy:', element.cacheStrategy); // 'exact', 'pixeldiff', or 'template'
|
|
69
|
-
console.log('Similarity:', `${(element.similarity * 100).toFixed(1)}%`);
|
|
70
|
-
console.log('Cache age:', element.cacheCreatedAt);
|
|
71
|
-
} else {
|
|
72
|
-
console.log('⏱️ Cache miss - AI analysis performed');
|
|
73
|
-
console.log('New cache entry created');
|
|
74
|
-
}
|
|
75
|
-
});
|
|
60
|
+
const testdriver = TestDriver(context, { cacheKey: 'checkout-flow' });
|
|
76
61
|
```
|
|
77
62
|
|
|
78
|
-
|
|
63
|
+
You can also pass `cacheKey` to a single `find()` call.
|
|
64
|
+
|
|
65
|
+
A stable key doesn't make TestDriver reuse a location for a changed page. Entries are still reused only when the description, OS, and resolution match and the screen looks the same.
|
|
66
|
+
|
|
67
|
+
## Adjust how closely the screen must match
|
|
79
68
|
|
|
80
|
-
|
|
69
|
+
Two thresholds control when a saved location is reused:
|
|
70
|
+
|
|
71
|
+
| Threshold | Default | Meaning |
|
|
72
|
+
| --- | --- | --- |
|
|
73
|
+
| `screen` | `0.05` | The largest share of pixels that may differ from the saved screen (5%) |
|
|
74
|
+
| `element` | `0.8` | How closely the saved element image must match what's on screen now (0 to 1) |
|
|
75
|
+
|
|
76
|
+
Set them for every call when you create the client:
|
|
81
77
|
|
|
82
78
|
```javascript
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
79
|
+
const testdriver = TestDriver(context, {
|
|
80
|
+
cache: {
|
|
81
|
+
thresholds: {
|
|
82
|
+
find: { screen: 0.02, element: 0.9 },
|
|
83
|
+
assert: 0.02,
|
|
84
|
+
},
|
|
85
|
+
},
|
|
91
86
|
});
|
|
92
87
|
```
|
|
93
88
|
|
|
94
|
-
|
|
89
|
+
Or override them for one call:
|
|
95
90
|
|
|
96
91
|
```javascript
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
// Explicit strict threshold
|
|
101
|
-
await testdriver.find('submit button', {
|
|
102
|
-
cacheThreshold: 0.01 // 99% similarity
|
|
92
|
+
const priceLabel = await testdriver.find('Total price label', {
|
|
93
|
+
cache: { thresholds: { screen: 0.01 } },
|
|
103
94
|
});
|
|
104
95
|
```
|
|
105
96
|
|
|
106
|
-
|
|
97
|
+
Lower `screen` and higher `element` values make reuse stricter. That helps on screens where small details matter, but costs more AI calls.
|
|
107
98
|
|
|
108
|
-
|
|
99
|
+
For every cache option, see [Configure the cache](/cache).
|
|
100
|
+
|
|
101
|
+
## Turn caching off
|
|
102
|
+
|
|
103
|
+
Disable caching for a client with `cache: false`, or for a whole run with `TD_NO_CACHE`:
|
|
109
104
|
|
|
110
105
|
```javascript
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
await testdriver.find(`input for ${email}`); // Cache miss every time
|
|
114
|
-
|
|
115
|
-
// ✅ With cache key - reuses cache regardless of variable
|
|
116
|
-
const email = 'user@example.com';
|
|
117
|
-
await testdriver.find(`input for ${email}`, {
|
|
118
|
-
cacheKey: 'email-input'
|
|
119
|
-
});
|
|
106
|
+
const testdriver = TestDriver(context, { cache: false });
|
|
107
|
+
```
|
|
120
108
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
await testdriver.find(`order ${orderId} status`, {
|
|
124
|
-
cacheKey: 'order-status' // Same cache for all orders
|
|
125
|
-
});
|
|
109
|
+
```bash
|
|
110
|
+
TD_NO_CACHE=true npx vitest run
|
|
126
111
|
```
|
|
127
112
|
|
|
128
|
-
##
|
|
113
|
+
## See what's cached
|
|
114
|
+
|
|
115
|
+
The [Cache page in the TestDriver console](https://console.testdriver.ai/cache) lists your team's cached elements and assertions. It shows a preview and the description for each, and lets you clear entries.
|
|
116
|
+
|
|
117
|
+
To check a single `find()` in your test, read the cache details from the element:
|
|
118
|
+
|
|
119
|
+
```javascript
|
|
120
|
+
const submitButton = await testdriver.find('Submit button');
|
|
121
|
+
const { cache } = submitButton.toJSON();
|
|
122
|
+
|
|
123
|
+
console.log(cache.hit); // true when the location came from the cache
|
|
124
|
+
console.log(cache.strategy); // how the cached entry was matched
|
|
125
|
+
```
|
|
129
126
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
127
|
+
## Next steps
|
|
128
|
+
|
|
129
|
+
<CardGroup cols={2}>
|
|
130
|
+
<Card title="Configure the cache" icon="sliders" href="/cache">
|
|
131
|
+
Every cache option, threshold, and override.
|
|
132
|
+
</Card>
|
|
133
|
+
<Card title="Locate elements" icon="crosshairs" href="/locating-elements">
|
|
134
|
+
Write descriptions that find the right element and cache well.
|
|
135
|
+
</Card>
|
|
136
|
+
<Card title="Run tests" icon="play" href="/copilot/running-tests">
|
|
137
|
+
Run your tests locally and in parallel.
|
|
138
|
+
</Card>
|
|
139
|
+
<Card title="Run in CI/CD" icon="code-branch" href="/ci-cd">
|
|
140
|
+
Run cached tests on every pull request.
|
|
141
|
+
</Card>
|
|
142
|
+
</CardGroup>
|