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