@testdriverai/agent 7.11.229-canary → 7.11.231-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.
Files changed (100) hide show
  1. package/docs/_data/examples-manifest.json +16 -16
  2. package/docs/_scripts/generate-examples.js +38 -45
  3. package/docs/agent.mdx +174 -93
  4. package/docs/assert.mdx +73 -269
  5. package/docs/aws-setup.mdx +196 -314
  6. package/docs/bring-your-own-machine.mdx +139 -206
  7. package/docs/cache.mdx +144 -151
  8. package/docs/caching.mdx +99 -89
  9. package/docs/captcha.mdx +126 -111
  10. package/docs/ci-cd.mdx +154 -543
  11. package/docs/click.mdx +74 -229
  12. package/docs/client.mdx +177 -231
  13. package/docs/copilot/auto-healing.mdx +86 -370
  14. package/docs/copilot/running-tests.mdx +121 -930
  15. package/docs/customizing-devices.mdx +74 -251
  16. package/docs/dashcam.mdx +72 -405
  17. package/docs/debugging-with-screenshots.mdx +105 -371
  18. package/docs/docs.json +75 -18
  19. package/docs/double-click.mdx +48 -68
  20. package/docs/errors.mdx +102 -176
  21. package/docs/events.mdx +170 -327
  22. package/docs/examples/{hover-text-with-description.mdx → add-to-cart.mdx} +30 -35
  23. package/docs/examples/assert.mdx +28 -41
  24. package/docs/examples/click-button.mdx +71 -0
  25. package/docs/examples/{hover-image.mdx → click-icon.mdx} +32 -28
  26. package/docs/examples/element-not-found.mdx +27 -26
  27. package/docs/examples/findall-coffee-icons.mdx +28 -32
  28. package/docs/examples/installer.mdx +61 -25
  29. package/docs/examples/launch-vscode-linux.mdx +28 -51
  30. package/docs/examples/navigate-and-scroll.mdx +82 -0
  31. package/docs/examples/parse.mdx +24 -28
  32. package/docs/examples/press-keys.mdx +28 -25
  33. package/docs/examples/scroll.mdx +25 -27
  34. package/docs/examples/type.mdx +26 -21
  35. package/docs/exec.mdx +92 -256
  36. package/docs/extract.mdx +69 -170
  37. package/docs/find.mdx +140 -736
  38. package/docs/focus-application.mdx +69 -246
  39. package/docs/generating-tests.mdx +103 -137
  40. package/docs/guide/best-practices-polling.mdx +65 -141
  41. package/docs/hosted.mdx +80 -144
  42. package/docs/hover.mdx +62 -235
  43. package/docs/locating-elements.mdx +74 -369
  44. package/docs/making-assertions.mdx +116 -74
  45. package/docs/mcp-setup.mdx +80 -63
  46. package/docs/mouse-down.mdx +48 -125
  47. package/docs/mouse-up.mdx +47 -129
  48. package/docs/options.mdx +75 -48
  49. package/docs/parse.mdx +95 -184
  50. package/docs/performing-actions.mdx +104 -94
  51. package/docs/press-keys.mdx +59 -299
  52. package/docs/provision.mdx +137 -182
  53. package/docs/quickstart-claude.mdx +85 -0
  54. package/docs/quickstart-github.mdx +62 -32
  55. package/docs/quickstart-manual.mdx +60 -33
  56. package/docs/quickstart-vscode.mdx +97 -0
  57. package/docs/quickstart.mdx +25 -9
  58. package/docs/redraw.mdx +101 -165
  59. package/docs/reusable-code.mdx +97 -200
  60. package/docs/right-click.mdx +47 -89
  61. package/docs/screenshot.mdx +47 -201
  62. package/docs/screenshots.mdx +87 -137
  63. package/docs/scroll.mdx +71 -154
  64. package/docs/secrets.mdx +96 -91
  65. package/docs/self-hosted.mdx +83 -142
  66. package/docs/snippets/enterprise.mdx +15 -0
  67. package/docs/styles.css +68 -0
  68. package/docs/test-results-json.mdx +167 -204
  69. package/docs/type.mdx +56 -304
  70. package/docs/variables.mdx +121 -81
  71. package/docs/wait.mdx +33 -31
  72. package/docs/what-is-testdriver.mdx +80 -32
  73. package/examples/{hover-text-with-description.test.mjs → add-to-cart.test.mjs} +4 -5
  74. package/examples/assert.test.mjs +3 -20
  75. package/examples/{hover-text.test.mjs → click-button.test.mjs} +3 -4
  76. package/examples/{hover-image.test.mjs → click-icon.test.mjs} +5 -6
  77. package/examples/element-not-found.test.mjs +3 -5
  78. package/examples/findall-coffee-icons.test.mjs +3 -3
  79. package/examples/installer.test.mjs +1 -1
  80. package/examples/launch-vscode-linux.test.mjs +6 -33
  81. package/examples/{scroll-keyboard.test.mjs → navigate-and-scroll.test.mjs} +4 -5
  82. package/examples/parse.test.mjs +1 -2
  83. package/examples/press-keys.test.mjs +4 -4
  84. package/examples/scroll.test.mjs +3 -6
  85. package/examples/type.test.mjs +5 -2
  86. package/lib/provision.js +6 -2
  87. package/package.json +1 -1
  88. package/sdk.d.ts +4 -2
  89. package/sdk.js +1 -1
  90. package/docs/claude-mcp-plugin.mdx +0 -244
  91. package/docs/elements.mdx +0 -606
  92. package/docs/examples/ai.mdx +0 -78
  93. package/docs/examples/captcha-api.mdx +0 -92
  94. package/docs/examples/chrome-extension.mdx +0 -156
  95. package/docs/examples/drag-and-drop.mdx +0 -100
  96. package/docs/examples/formatted-logging.mdx +0 -74
  97. package/docs/examples/hover-text.mdx +0 -70
  98. package/docs/examples/match-image.mdx +0 -97
  99. package/docs/examples/scroll-keyboard.mdx +0 -80
  100. package/docs/examples/scroll-until-text.mdx +0 -109
@@ -1,423 +1,128 @@
1
1
  ---
2
- title: "Locating Elements"
3
- sidebarTitle: "Locating Elements"
4
- description: "Locate UI elements using AI"
5
- icon: "mouse-pointer"
2
+ title: "Locate elements"
3
+ sidebarTitle: "Locating elements"
4
+ description: "Find elements on screen by describing them in plain language, and make the match reliable."
5
+ icon: "magnifying-glass"
6
6
  ---
7
7
 
8
- ## Overview
9
-
10
- The TestDriver element finding system uses AI. It finds elements on the screen with natural language descriptions. The `find()` method returns an `Element` object. You can [interact with the object](/interacting-with-your-app).
11
-
12
- ## Finding Elements
13
-
14
- ### find()
15
-
16
- Find an element on the screen with a natural language description.
8
+ Describe an element the way a person would, and `find()` locates it on screen. No selectors, IDs, or DOM access.
17
9
 
18
10
  ```javascript
19
- const element = await testdriver.find(description)
11
+ const signInButton = await testdriver.find('Sign in button below the password field');
12
+ await signInButton.click();
20
13
  ```
21
14
 
22
- **Parameters:**
23
- - `description` (string) - A natural language description of the element to find
24
-
25
- **Returns:** `Promise<Element>` - The Element instance that TestDriver found
26
-
27
- **Example:**
28
- ```javascript
29
- // Find a button
30
- const submitButton = await testdriver.find('the submit button');
31
-
32
- // Find an input field with context
33
- const emailField = await testdriver.find('email input field in the login form');
34
-
35
- // Find an element by visual characteristics
36
- const redButton = await testdriver.find('red button in the top right corner');
37
- ```
38
-
39
- <Tip>
40
- Be specific in your descriptions. Include visual details, location context, or nearby text to make the accuracy better.
41
- </Tip>
42
-
43
- ## Element Class
44
-
45
- The `Element` class represents a located (or to-be-located) UI element. It provides methods for interaction and properties for element information. For interaction methods like `click()` and `hover()`, see [Interacting With Your App](/interacting-with-your-app).
15
+ `find()` returns an element. You can act on it with methods like `click()` and `hover()`. See [Perform actions](/performing-actions).
46
16
 
47
- ### Methods
17
+ ## Describe the element
48
18
 
49
- #### found()
19
+ A good description has up to three parts:
50
20
 
51
- Check if the element was successfully located.
21
+ 1. **What it says.** The visible label or text, such as "Sign in" or "Add to cart".
22
+ 2. **What it is.** A button, an input field, an icon, a link, a checkbox.
23
+ 3. **Where it is,** when there's more than one match. A position, a color, or a nearby element.
52
24
 
53
25
  ```javascript
54
- element.found()
55
- ```
56
-
57
- **Returns:** `boolean` - True if element coordinates were found
26
+ // Too vague: several things on the page could match
27
+ await testdriver.find('button');
58
28
 
59
- **Example:**
60
- ```javascript
61
- const element = await testdriver.find('login button');
62
- if (element.found()) {
63
- await element.click();
64
- } else {
65
- console.log('Element not found');
66
- }
29
+ // Specific: label, type, and position
30
+ await testdriver.find('Add to cart button under the TestDriver Hat');
67
31
  ```
68
32
 
69
- #### find()
70
-
71
- Re-locate the element, optionally with a new description.
33
+ A few more tips:
72
34
 
73
- ```javascript
74
- await element.find(newDescription)
75
- ```
35
+ - **Lead with visible text.** Text on screen is the most reliable thing to match.
36
+ - **Describe icons by how they look.** "Shopping cart icon in the top right corner" works better than "cart link".
37
+ - **Keep changing values out.** A description with a changing name or ID never reuses the [cache](/caching). Describe the element itself instead.
38
+ - **Describe one element.** For a list of matches, use [`findAll()`](#find-every-match).
76
39
 
77
- **Parameters:**
78
- - `newDescription` (string, optional) - New description to search for
40
+ ## Check whether it was found
79
41
 
80
- **Returns:** `Promise<Element>` - This element instance
42
+ `find()` keeps checking the screen every 5 seconds for up to 10 seconds. If nothing matches, it doesn't throw. It returns an element whose `found()` is `false`:
81
43
 
82
- **Example:**
83
44
  ```javascript
84
- // Re-locate if the UI changed
85
- const element = await testdriver.find('submit button');
86
- // ... page updates ...
87
- await element.find(); // Re-locate with same description
88
-
89
- // Or update the description
90
- await element.find('blue submit button'); // Now looking for blue button
91
- ```
92
-
93
- ### Properties
94
-
95
- Element properties provide additional information about located elements. Properties are available after a successful `find()` call.
96
-
97
- #### coordinates
98
-
99
- Get the element's coordinates object containing all position information.
100
-
101
- ```javascript
102
- const coords = element.getCoordinates()
103
- // or access directly
104
- element.coordinates
105
- ```
106
-
107
- **Returns:** `Object | null` - Coordinate object with `{ x, y, centerX, centerY }`
108
-
109
- **Example:**
110
- ```javascript
111
- const button = await testdriver.find('submit button');
112
- const coords = button.coordinates;
113
-
114
- if (coords) {
115
- console.log(`Top-left: (${coords.x}, ${coords.y})`);
116
- console.log(`Center: (${coords.centerX}, ${coords.centerY})`);
45
+ const banner = await testdriver.find('cookie consent banner', { timeout: 0 });
46
+ if (banner.found()) {
47
+ await testdriver.find('Accept all cookies button').click();
117
48
  }
118
49
  ```
119
50
 
120
- #### x, y, centerX, centerY
51
+ Acting on an element that wasn't found throws an `ElementNotFoundError`.
121
52
 
122
- Direct access to coordinate values. Always available after successful `find()`.
53
+ For something slow to appear, raise the `timeout`:
123
54
 
124
55
  ```javascript
125
- element.x // Top-left X coordinate (number)
126
- element.y // Top-left Y coordinate (number)
127
- element.centerX // Center X coordinate (number)
128
- element.centerY // Center Y coordinate (number)
56
+ const confirmation = await testdriver.find('Order confirmation message', { timeout: 30000 });
129
57
  ```
130
58
 
131
- **Example:**
132
- ```javascript
133
- const button = await testdriver.find('submit button');
134
- console.log(`Button at: (${button.x}, ${button.y})`);
135
- console.log(`Button center: (${button.centerX}, ${button.centerY})`);
136
-
137
- // Use for custom mouse operations
138
- await testdriver.click(button.centerX, button.centerY);
139
- ```
59
+ ## Make the match stricter
140
60
 
141
- #### width, height
61
+ When finding the wrong element is costly, `find()` has options to tighten the match:
142
62
 
143
- Element dimensions in pixels. Available when AI detects element bounds.
63
+ | Option | What it does |
64
+ | --- | --- |
65
+ | `confidence` | Treat a match below this score (0 to 1) as not found |
66
+ | `verify` | Double-check the result with a second AI call, and retry once if it's wrong |
67
+ | `zoom` | Locate in two passes, for small targets or crowded screens |
68
+ | `type` | Hint that you mean `text`, an `image`, or a `ui` element |
144
69
 
145
70
  ```javascript
146
- element.width // Width in pixels (number | null)
147
- element.height // Height in pixels (number | null)
71
+ const deleteButton = await testdriver.find('Delete account button', {
72
+ confidence: 0.9,
73
+ verify: true,
74
+ });
148
75
  ```
149
76
 
150
- **Example:**
151
- ```javascript
152
- const button = await testdriver.find('submit button');
153
-
154
- if (button.width && button.height) {
155
- console.log(`Button size: ${button.width}x${button.height}px`);
156
-
157
- // Check if button is large enough
158
- if (button.width < 50) {
159
- console.warn('Button might be too small');
160
- }
161
- }
162
- ```
77
+ Each option adds time or makes a miss more likely, so use them where accuracy matters most. See [find()](/find) for details.
163
78
 
164
- #### boundingBox
79
+ ## Find every match
165
80
 
166
- Complete bounding box information including position and dimensions.
81
+ `findAll()` returns an array with one element per match:
167
82
 
168
83
  ```javascript
169
- element.boundingBox
170
- ```
84
+ const coffeeIcons = await testdriver.findAll('coffee cup icon');
171
85
 
172
- **Returns:** `Object | null` - Bounding box with all dimension data
173
-
174
- ```typescript
175
- {
176
- x: number, // Top-left X
177
- y: number, // Top-left Y
178
- width: number, // Width in pixels
179
- height: number // Height in pixels
86
+ for (const icon of coffeeIcons) {
87
+ await icon.click();
180
88
  }
181
89
  ```
182
90
 
183
- **Example:**
184
- ```javascript
185
- const element = await testdriver.find('dialog box');
186
-
187
- if (element.boundingBox) {
188
- const { x, y, width, height } = element.boundingBox;
189
- console.log(`Dialog: ${width}x${height} at (${x}, ${y})`);
190
-
191
- // Calculate if element is in viewport
192
- const rightEdge = x + width;
193
- const bottomEdge = y + height;
194
- console.log(`Element extends to (${rightEdge}, ${bottomEdge})`);
195
- }
196
- ```
91
+ See the [find all example](/examples/findall-coffee-icons) for a complete test.
197
92
 
198
- #### screenshot
93
+ ## Inspect a result
199
94
 
200
- Base64-encoded PNG screenshot of the screen when element was found. Only available in DEBUG mode or when an error occurs.
95
+ An element tells you where it was found and how sure the AI was:
201
96
 
202
97
  ```javascript
203
- element.screenshot
204
- ```
205
-
206
- **Returns:** `string | null` - Base64-encoded PNG image
98
+ const submitButton = await testdriver.find('Submit button');
207
99
 
208
- **Example:**
209
- ```javascript
210
- const element = await testdriver.find('error message');
211
-
212
- if (element.screenshot) {
213
- // Save screenshot to file
214
- const fs = require('fs');
215
- const base64Data = element.screenshot.replace(/^data:image\/\w+;base64,/, '');
216
- fs.writeFileSync('element-screenshot.png', Buffer.from(base64Data, 'base64'));
217
- console.log('Screenshot saved');
218
- }
100
+ console.log(submitButton.found()); // true
101
+ console.log(submitButton.x, submitButton.y); // the point TestDriver clicks
102
+ console.log(submitButton.confidence); // the AI's confidence, from 0 to 1
219
103
  ```
220
104
 
221
- <Warning>
222
- Screenshots can be large. They're automatically excluded from error messages to prevent memory issues.
223
- </Warning>
224
-
225
- #### text
226
-
227
- Text content extracted from the element by AI (if available).
228
-
229
- ```javascript
230
- element.text
231
- ```
232
-
233
- **Returns:** `string | null` - Element's text content
234
-
235
- **Example:**
236
- ```javascript
237
- const message = await testdriver.find('notification message');
238
-
239
- if (message.text) {
240
- console.log('Message says:', message.text);
241
-
242
- // Use text content in assertions
243
- if (message.text.includes('success')) {
244
- console.log('Success message detected');
245
- }
246
- }
247
-
248
- // Another example - extracting button label
249
- const button = await testdriver.find('blue button');
250
- console.log('Button text:', button.text); // "Submit"
251
- ```
252
-
253
- #### label
254
-
255
- Accessible label or name of the element (if available). Useful for verifying accessibility.
256
-
257
- ```javascript
258
- element.label
259
- ```
260
-
261
- **Returns:** `string | null` - Accessible label
262
-
263
- **Example:**
264
- ```javascript
265
- const input = await testdriver.find('first input field');
266
-
267
- if (input.label) {
268
- console.log('Input label:', input.label); // "Email Address"
269
- }
270
- ```
271
-
272
- #### confidence
273
-
274
- AI confidence score for the element match (0-1, where 1 is perfect confidence).
275
-
276
- ```javascript
277
- element.confidence
278
- ```
279
-
280
- **Returns:** `number | null` - Confidence score between 0 and 1
281
-
282
- **Example:**
283
- ```javascript
284
- const element = await testdriver.find('submit button');
285
-
286
- if (element.confidence !== null) {
287
- const percentage = (element.confidence * 100).toFixed(1);
288
- console.log(`Match confidence: ${percentage}%`);
289
-
290
- if (element.confidence < 0.8) {
291
- console.warn('⚠️ Low confidence match - element might not be correct');
292
- } else if (element.confidence > 0.95) {
293
- console.log('✅ High confidence match');
294
- }
295
- }
296
- ```
297
-
298
- <Tip>
299
- Confidence scores below 0.8 may indicate the element description was ambiguous or the wrong element was found.
300
- </Tip>
301
-
302
- ### Property Availability
303
-
304
- | Property | When Available |
305
- |----------|---------------|
306
- | `x`, `y`, `centerX`, `centerY` | ✅ Always after successful `find()` |
307
- | `coordinates` | ✅ Always after successful `find()` |
308
- | `width`, `height` | ⚠️ When AI detects element bounds |
309
- | `boundingBox` | ⚠️ When AI detects element bounds |
310
- | `text` | ⚠️ When AI extracts text content |
311
- | `label` | ⚠️ When element has accessible label |
312
- | `confidence` | ✅ Always after AI element finding |
313
- | `screenshot` | ⚠️ Only in DEBUG mode or on errors |
314
-
315
- <Note>
316
- Properties marked with ⚠️ may be `null` depending on what the AI could detect from the screenshot.
317
- </Note>
318
-
319
- ## JSON Serialization
320
-
321
- Element objects can be safely serialized using `JSON.stringify()` for logging, debugging, and data storage. Circular references are automatically removed:
105
+ For more detail, serialize the element. `toJSON()` adds the AI's reasoning and whether the result came from the cache:
322
106
 
323
107
  ```javascript
324
- const element = await testdriver.find('login button');
325
-
326
- // Safe to stringify - no circular reference errors!
327
- console.log(JSON.stringify(element, null, 2));
328
- ```
329
-
330
- **Serialized output includes:**
331
-
332
- ```json
333
- {
334
- "description": "login button",
335
- "coordinates": { "x": 100, "y": 200, "centerX": 150, "centerY": 225 },
336
- "found": true,
337
- "threshold": 0.01,
338
- "x": 100,
339
- "y": 200,
340
- "cache": {
341
- "hit": true,
342
- "strategy": "pixel-diff",
343
- "createdAt": "2025-12-09T10:30:00.000Z",
344
- "diffPercent": 0.0023,
345
- "imageUrl": "https://cache.testdriver.ai/..."
346
- },
347
- "similarity": 0.98,
348
- "confidence": 0.95,
349
- "selector": "button#login",
350
- "aiResponse": "Found the blue login button in the center of the form..."
351
- }
108
+ const { reasoning, cache } = submitButton.toJSON();
109
+ console.log(reasoning); // why the AI picked this element
110
+ console.log(cache.hit); // true when the position came from the cache
352
111
  ```
353
112
 
354
- **Serialized properties:**
355
-
356
- | Property | Type | Description |
357
- |----------|------|-------------|
358
- | `description` | string | Element search description |
359
- | `coordinates` | object | Full coordinate object `{x, y, centerX, centerY}` |
360
- | `found` | boolean | Whether element was located |
361
- | `threshold` | number | Cache threshold used for this find |
362
- | `x`, `y` | number | Top-left coordinates |
363
- | `cache.hit` | boolean | Whether cache was used |
364
- | `cache.strategy` | string | Cache strategy (e.g., "pixel-diff") |
365
- | `cache.createdAt` | string | ISO timestamp when cache was created |
366
- | `cache.diffPercent` | number | Pixel difference from cached image |
367
- | `cache.imageUrl` | string | URL to cached screenshot |
368
- | `similarity` | number | Similarity score (0-1) |
369
- | `confidence` | number | AI confidence score (0-1) |
370
- | `selector` | string | CSS/XPath selector if available |
371
- | `aiResponse` | string | AI's explanation of what it found |
372
-
373
- **Use cases:**
374
-
375
- ```javascript
376
- // Debugging element detection
377
- const element = await testdriver.find('submit button');
378
- if (!element.found()) {
379
- console.error('Element not found:', JSON.stringify(element, null, 2));
380
- }
381
-
382
- // Logging cache performance
383
- const data = JSON.parse(JSON.stringify(element));
384
- if (data.cache.hit) {
385
- console.log(`Cache hit! Diff: ${(data.cache.diffPercent * 100).toFixed(2)}%`);
386
- }
387
-
388
- // Sharing element data across processes
389
- const elementData = JSON.stringify(element);
390
- // Send to another process, log to file, etc.
391
- ```
113
+ ## Next steps
392
114
 
393
- <Tip>
394
- Use JSON serialization when you need to log element data or when debugging why an element wasn't found. The serialized output excludes large binary data (screenshots) and circular references.
395
- </Tip>
396
-
397
- ## Best Practices
398
-
399
- <AccordionGroup>
400
- <Accordion title="Be specific with descriptions">
401
- Include visual details, position context, and nearby text:
402
-
403
- ```javascript
404
- // ❌ Too vague
405
- await testdriver.find('button');
406
-
407
- // ✅ Specific
408
- await testdriver.find('blue submit button below the email field');
409
- ```
410
- </Accordion>
411
-
412
- <Accordion title="Check if element was found">
413
- Always verify elements were located before interacting:
414
-
415
- ```javascript
416
- const element = await testdriver.find('submit button');
417
- if (!element.found()) {
418
- throw new Error('Submit button not found');
419
- }
420
- await element.click();
421
- ```
422
- </Accordion>
423
- </AccordionGroup>
115
+ <CardGroup cols={2}>
116
+ <Card title="find()" icon="magnifying-glass" href="/find">
117
+ Every option, with examples.
118
+ </Card>
119
+ <Card title="Perform actions" icon="arrow-pointer" href="/performing-actions">
120
+ Click, type, and scroll once you've found an element.
121
+ </Card>
122
+ <Card title="Caching" icon="brain" href="/caching">
123
+ Reuse element positions from passing runs.
124
+ </Card>
125
+ <Card title="Debug a failing test" icon="bug" href="/debugging-with-screenshots">
126
+ See what the screen showed when find() missed.
127
+ </Card>
128
+ </CardGroup>