@testdriverai/agent 7.11.150-test → 7.11.151-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 (38) hide show
  1. package/ai/skills/testdriver-agent/SKILL.md +15 -15
  2. package/ai/skills/testdriver-aws-setup/SKILL.md +6 -6
  3. package/ai/skills/testdriver-cache/SKILL.md +8 -8
  4. package/ai/skills/testdriver-caching/SKILL.md +10 -9
  5. package/ai/skills/testdriver-captcha/SKILL.md +7 -7
  6. package/ai/skills/testdriver-ci-cd/SKILL.md +10 -10
  7. package/ai/skills/testdriver-claude-mcp-plugin/SKILL.md +37 -0
  8. package/ai/skills/testdriver-client/SKILL.md +3 -166
  9. package/ai/skills/testdriver-customizing-devices/SKILL.md +1 -1
  10. package/ai/skills/testdriver-dashcam/SKILL.md +3 -3
  11. package/ai/skills/testdriver-debugging-with-screenshots/SKILL.md +5 -5
  12. package/ai/skills/testdriver-elements/SKILL.md +5 -5
  13. package/ai/skills/testdriver-errors/SKILL.md +3 -3
  14. package/ai/skills/testdriver-events/SKILL.md +3 -3
  15. package/ai/skills/testdriver-extract/SKILL.md +5 -5
  16. package/ai/skills/testdriver-find/SKILL.md +1 -1
  17. package/ai/skills/testdriver-generating-tests/SKILL.md +6 -6
  18. package/ai/skills/testdriver-hosted/SKILL.md +4 -4
  19. package/ai/skills/testdriver-interacting-with-your-app/SKILL.md +197 -0
  20. package/ai/skills/testdriver-locating-elements/SKILL.md +390 -39
  21. package/ai/skills/testdriver-making-assertions/SKILL.md +4 -4
  22. package/ai/skills/testdriver-options/SKILL.md +319 -0
  23. package/ai/skills/testdriver-parse/SKILL.md +8 -8
  24. package/ai/skills/testdriver-performing-actions/SKILL.md +7 -7
  25. package/ai/skills/testdriver-provision/SKILL.md +7 -7
  26. package/ai/skills/testdriver-quickstart/SKILL.md +15 -441
  27. package/ai/skills/testdriver-quickstart-cli/SKILL.md +436 -0
  28. package/ai/skills/testdriver-quickstart-github/SKILL.md +53 -0
  29. package/ai/skills/testdriver-quickstart-manual/SKILL.md +134 -0
  30. package/ai/skills/testdriver-redraw/SKILL.md +6 -6
  31. package/ai/skills/testdriver-reusable-code/SKILL.md +3 -3
  32. package/ai/skills/testdriver-screenshots/SKILL.md +3 -3
  33. package/ai/skills/testdriver-secrets/SKILL.md +4 -4
  34. package/ai/skills/testdriver-self-hosted/SKILL.md +6 -6
  35. package/ai/skills/testdriver-test-results-json/SKILL.md +4 -4
  36. package/ai/skills/testdriver-variables/SKILL.md +2 -2
  37. package/ai/skills/testdriver-wait/SKILL.md +2 -2
  38. package/package.json +1 -1
@@ -1,71 +1,422 @@
1
1
  ---
2
2
  name: testdriver:locating-elements
3
- description: Find UI elements using natural language descriptions
3
+ description: Locate UI elements using AI
4
4
  ---
5
5
  <!-- Generated from locating-elements.mdx. DO NOT EDIT. -->
6
6
 
7
- ## Locating Single Elements
7
+ ## Overview
8
8
 
9
- Use natural language to describe elements. Descriptions should be specific enough to locate the element, but not too-specific that they break with minor UI changes. For example:
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
10
 
11
+ ## Finding Elements
12
+
13
+ ### find()
14
+
15
+ Find an element on the screen with a natural language description.
16
+
17
+ ```javascript
18
+ const element = await testdriver.find(description)
19
+ ```
20
+
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).
45
+
46
+ ### Methods
47
+
48
+ #### found()
49
+
50
+ Check if the element was successfully located.
51
+
52
+ ```javascript
53
+ element.found()
54
+ ```
55
+
56
+ **Returns:** `boolean` - True if element coordinates were found
57
+
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
+ }
66
+ ```
67
+
68
+ #### find()
69
+
70
+ Re-locate the element, optionally with a new description.
71
+
72
+ ```javascript
73
+ await element.find(newDescription)
74
+ ```
75
+
76
+ **Parameters:**
77
+ - `newDescription` (string, optional) - New description to search for
78
+
79
+ **Returns:** `Promise<Element>` - This element instance
80
+
81
+ **Example:**
82
+ ```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:**
11
109
  ```javascript
12
- await testdriver.find('email input field');
13
- await testdriver.find('first product card in the grid');
14
- await testdriver.find('dropdown menu labeled "Country"');
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})`);
116
+ }
15
117
  ```
16
118
 
17
- <Info>TestDriver will cache found elements for improved performance on subsequent calls. Learn more about [element caching here](/v7/caching).</Info>
119
+ #### x, y, centerX, centerY
18
120
 
19
- ## Debugging Found Elements
121
+ Direct access to coordinate values. Always available after successful `find()`.
20
122
 
21
- After finding an element, you can inspect its properties for debugging:
123
+ ```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)
128
+ ```
22
129
 
130
+ **Example:**
23
131
  ```javascript
24
132
  const button = await testdriver.find('submit button');
25
- console.log(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);
26
138
  ```
27
139
 
28
- This outputs all element properties:
140
+ #### width, height
141
+
142
+ Element dimensions in pixels. Available when AI detects element bounds.
29
143
 
30
144
  ```javascript
145
+ element.width // Width in pixels (number | null)
146
+ element.height // Height in pixels (number | null)
147
+ ```
148
+
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
+ ```
162
+
163
+ #### boundingBox
164
+
165
+ Complete bounding box information including position and dimensions.
166
+
167
+ ```javascript
168
+ element.boundingBox
169
+ ```
170
+
171
+ **Returns:** `Object | null` - Bounding box with all dimension data
172
+
173
+ ```typescript
31
174
  {
32
- description: 'submit button',
33
- found: true,
34
- x: 150,
35
- y: 300,
36
- coordinates: { x: 150, y: 300, centerX: 200, centerY: 320 },
37
- threshold: 0.8,
38
- confidence: 0.95,
39
- similarity: 0.92,
40
- selector: 'button[type="submit"]',
41
- cache: {
42
- hit: true,
43
- strategy: 'pixel-diff',
44
- createdAt: '2025-01-15T10:30:00Z',
45
- diffPercent: 0.02,
46
- imageUrl: 'https://...'
175
+ x: number, // Top-left X
176
+ y: number, // Top-left Y
177
+ width: number, // Width in pixels
178
+ height: number // Height in pixels
179
+ }
180
+ ```
181
+
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
+ ```
196
+
197
+ #### screenshot
198
+
199
+ Base64-encoded PNG screenshot of the screen when element was found. Only available in DEBUG mode or when an error occurs.
200
+
201
+ ```javascript
202
+ element.screenshot
203
+ ```
204
+
205
+ **Returns:** `string | null` - Base64-encoded PNG image
206
+
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
+ }
218
+ ```
219
+
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');
47
244
  }
48
245
  }
246
+
247
+ // Another example - extracting button label
248
+ const button = await testdriver.find('blue button');
249
+ console.log('Button text:', button.text); // "Submit"
49
250
  ```
50
251
 
51
- ## Working with Multiple Elements
252
+ #### label
52
253
 
53
- Find and interact with multiple elements:
254
+ Accessible label or name of the element (if available). Useful for verifying accessibility.
54
255
 
55
256
  ```javascript
56
- // Find all matching elements
57
- const products = await testdriver.findAll('product card');
58
- console.log(`Found ${products.length} products`);
257
+ element.label
258
+ ```
259
+
260
+ **Returns:** `string | null` - Accessible label
59
261
 
60
- // Interact with each
61
- for (const product of products) {
62
- const title = await product.find('title text');
63
- console.log('Product:', title.text);
262
+ **Example:**
263
+ ```javascript
264
+ const input = await testdriver.find('first input field');
64
265
 
65
- await product.find('add to cart button').click();
266
+ if (input.label) {
267
+ console.log('Input label:', input.label); // "Email Address"
66
268
  }
269
+ ```
67
270
 
68
- // Or find specific element
69
- const firstProduct = products[0];
70
- await firstProduct.click();
271
+ #### confidence
272
+
273
+ AI confidence score for the element match (0-1, where 1 is perfect confidence).
274
+
275
+ ```javascript
276
+ element.confidence
71
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:
321
+
322
+ ```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
+ }
351
+ ```
352
+
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
+ ```
391
+
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>
@@ -4,13 +4,13 @@ description: Locate elements and verify app state with AI-powered assertions
4
4
  ---
5
5
  <!-- Generated from making-assertions.mdx. DO NOT EDIT. -->
6
6
 
7
- Once a test runs, validate that the app did what it should. Validation has two parts: locating the elements you want to check, and making assertions about the state of your app. TestDriver uses AI as a judge, returning a boolean plus reasoning about whether your app is in the expected state.
7
+ After a test runs, make sure that the app did the correct thing. Validation has two parts: to find the elements that you want to check, and to make assertions about the state of your app. TestDriver uses the AI as a judge. It returns a boolean and the reason. This shows if your app is in the correct state.
8
8
 
9
9
  ## Locating Elements
10
10
 
11
11
  ### Locating Single Elements
12
12
 
13
- Use natural language to describe elements. Descriptions should be specific enough to locate the element, but not too-specific that they break with minor UI changes. For example:
13
+ Use natural language to describe elements. A description must be specific enough to find the element. But it must not be so specific that it breaks with small UI changes. For example:
14
14
 
15
15
  ```javascript
16
16
  await testdriver.find('email input field');
@@ -18,11 +18,11 @@ await testdriver.find('first product card in the grid');
18
18
  await testdriver.find('dropdown menu labeled "Country"');
19
19
  ```
20
20
 
21
- <Info>TestDriver will cache found elements for improved performance on subsequent calls. Learn more about [element caching here](/caching).</Info>
21
+ <Info>TestDriver caches the found elements for better performance on later calls. Read more about [element caching here](/caching).</Info>
22
22
 
23
23
  ### Debugging Found Elements
24
24
 
25
- After finding an element, you can inspect its properties for debugging:
25
+ After TestDriver finds an element, you can look at its properties for debug:
26
26
 
27
27
  ```javascript
28
28
  const button = await testdriver.find('submit button');