testdriverai 7.3.11 → 7.3.13

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 (133) hide show
  1. package/.github/skills/testdriver:ai/SKILL.md +204 -0
  2. package/.github/skills/testdriver:assert/SKILL.md +284 -0
  3. package/.github/skills/testdriver:aws-setup/SKILL.md +515 -0
  4. package/.github/skills/testdriver:caching/SKILL.md +124 -0
  5. package/.github/skills/testdriver:captcha/SKILL.md +159 -0
  6. package/.github/skills/testdriver:ci-cd/SKILL.md +602 -0
  7. package/.github/skills/testdriver:click/SKILL.md +286 -0
  8. package/.github/skills/testdriver:client/SKILL.md +339 -0
  9. package/.github/skills/testdriver:cloud/SKILL.md +119 -0
  10. package/.github/skills/testdriver:customizing-devices/SKILL.md +153 -0
  11. package/.github/skills/testdriver:dashcam/SKILL.md +418 -0
  12. package/.github/skills/testdriver:debugging-with-screenshots/SKILL.md +271 -0
  13. package/.github/skills/testdriver:device-config/SKILL.md +317 -0
  14. package/.github/skills/testdriver:double-click/SKILL.md +102 -0
  15. package/.github/skills/testdriver:elements/SKILL.md +605 -0
  16. package/.github/skills/testdriver:enterprise/SKILL.md +114 -0
  17. package/.github/skills/testdriver:examples/SKILL.md +7 -0
  18. package/.github/skills/testdriver:exec/SKILL.md +345 -0
  19. package/.github/skills/testdriver:find/SKILL.md +721 -0
  20. package/.github/skills/testdriver:focus-application/SKILL.md +293 -0
  21. package/.github/skills/testdriver:generating-tests/SKILL.md +36 -0
  22. package/.github/skills/testdriver:hover/SKILL.md +278 -0
  23. package/.github/skills/testdriver:locating-elements/SKILL.md +71 -0
  24. package/.github/skills/testdriver:making-assertions/SKILL.md +32 -0
  25. package/.github/skills/testdriver:mcp-workflow/SKILL.md +410 -0
  26. package/.github/skills/testdriver:mouse-down/SKILL.md +161 -0
  27. package/.github/skills/testdriver:mouse-up/SKILL.md +164 -0
  28. package/.github/skills/testdriver:performing-actions/SKILL.md +51 -0
  29. package/.github/skills/testdriver:press-keys/SKILL.md +348 -0
  30. package/.github/skills/testdriver:quickstart/SKILL.md +161 -0
  31. package/.github/skills/testdriver:reusable-code/SKILL.md +240 -0
  32. package/.github/skills/testdriver:right-click/SKILL.md +123 -0
  33. package/.github/skills/testdriver:running-tests/SKILL.md +181 -0
  34. package/.github/skills/testdriver:screenshot/SKILL.md +167 -0
  35. package/.github/skills/testdriver:scroll/SKILL.md +299 -0
  36. package/.github/skills/testdriver:secrets/SKILL.md +115 -0
  37. package/.github/skills/testdriver:self-hosted/SKILL.md +65 -0
  38. package/.github/skills/testdriver:test-writer/SKILL.md +451 -0
  39. package/.github/skills/testdriver:testdriver/SKILL.md +523 -0
  40. package/.github/skills/testdriver:testdriver-mechanic/SKILL.md +165 -0
  41. package/.github/skills/testdriver:type/SKILL.md +357 -0
  42. package/.github/skills/testdriver:variables/SKILL.md +111 -0
  43. package/.github/skills/testdriver:waiting-for-elements/SKILL.md +66 -0
  44. package/.github/skills/testdriver:what-is-testdriver/SKILL.md +54 -0
  45. package/.github/workflows/acceptance-windows-scheduled.yaml +6 -1
  46. package/.github/workflows/acceptance.yaml +0 -36
  47. package/.github/workflows/update-examples.yaml +53 -0
  48. package/CHANGELOG.md +8 -0
  49. package/agent/events.js +1 -0
  50. package/agent/index.js +8 -0
  51. package/agent/lib/commands.js +48 -29
  52. package/agent/lib/redraw.js +3 -1
  53. package/agent/lib/sandbox.js +166 -14
  54. package/agent/lib/sdk.js +142 -3
  55. package/agent/lib/system.js +4 -6
  56. package/ai/skills/testdriver:ai/SKILL.md +204 -0
  57. package/ai/skills/testdriver:assert/SKILL.md +315 -0
  58. package/ai/skills/testdriver:aws-setup/SKILL.md +448 -0
  59. package/ai/skills/testdriver:caching/SKILL.md +124 -0
  60. package/ai/skills/testdriver:captcha/SKILL.md +159 -0
  61. package/ai/skills/testdriver:ci-cd/SKILL.md +602 -0
  62. package/ai/skills/testdriver:click/SKILL.md +286 -0
  63. package/ai/skills/testdriver:client/SKILL.md +372 -0
  64. package/ai/skills/testdriver:cloud/SKILL.md +119 -0
  65. package/ai/skills/testdriver:customizing-devices/SKILL.md +153 -0
  66. package/ai/skills/testdriver:dashcam/SKILL.md +418 -0
  67. package/ai/skills/testdriver:debugging-with-screenshots/SKILL.md +401 -0
  68. package/ai/skills/testdriver:device-config/SKILL.md +317 -0
  69. package/ai/skills/testdriver:double-click/SKILL.md +102 -0
  70. package/ai/skills/testdriver:elements/SKILL.md +605 -0
  71. package/ai/skills/testdriver:enterprise/SKILL.md +114 -0
  72. package/ai/skills/testdriver:examples/SKILL.md +7 -0
  73. package/ai/skills/testdriver:exec/SKILL.md +345 -0
  74. package/ai/skills/testdriver:find/SKILL.md +745 -0
  75. package/ai/skills/testdriver:focus-application/SKILL.md +293 -0
  76. package/ai/skills/testdriver:generating-tests/SKILL.md +36 -0
  77. package/ai/skills/testdriver:hover/SKILL.md +278 -0
  78. package/ai/skills/testdriver:locating-elements/SKILL.md +71 -0
  79. package/ai/skills/testdriver:making-assertions/SKILL.md +32 -0
  80. package/ai/skills/testdriver:mcp-workflow/SKILL.md +410 -0
  81. package/ai/skills/testdriver:mouse-down/SKILL.md +161 -0
  82. package/ai/skills/testdriver:mouse-up/SKILL.md +164 -0
  83. package/ai/skills/testdriver:ocr/SKILL.md +235 -0
  84. package/ai/skills/testdriver:performing-actions/SKILL.md +51 -0
  85. package/ai/skills/testdriver:press-keys/SKILL.md +348 -0
  86. package/ai/skills/testdriver:quickstart/SKILL.md +146 -0
  87. package/ai/skills/testdriver:reusable-code/SKILL.md +240 -0
  88. package/ai/skills/testdriver:right-click/SKILL.md +123 -0
  89. package/ai/skills/testdriver:running-tests/SKILL.md +185 -0
  90. package/ai/skills/testdriver:screenshot/SKILL.md +248 -0
  91. package/ai/skills/testdriver:scroll/SKILL.md +335 -0
  92. package/ai/skills/testdriver:secrets/SKILL.md +115 -0
  93. package/ai/skills/testdriver:self-hosted/SKILL.md +65 -0
  94. package/ai/skills/testdriver:test-writer/SKILL.md +451 -0
  95. package/ai/skills/testdriver:testdriver/SKILL.md +631 -0
  96. package/ai/skills/testdriver:testdriver-mechanic/SKILL.md +165 -0
  97. package/ai/skills/testdriver:type/SKILL.md +357 -0
  98. package/ai/skills/testdriver:variables/SKILL.md +111 -0
  99. package/ai/skills/testdriver:waiting-for-elements/SKILL.md +66 -0
  100. package/ai/skills/testdriver:what-is-testdriver/SKILL.md +54 -0
  101. package/debugger/index.html +12 -2
  102. package/docs/v7/examples/scroll-keyboard.mdx +1 -1
  103. package/docs/v7/find.mdx +1 -0
  104. package/examples/config.mjs +1 -1
  105. package/examples/findall-coffee-icons.test.mjs +42 -0
  106. package/examples/flake-diffthreshold-001.test.mjs +9 -0
  107. package/examples/flake-diffthreshold-01.test.mjs +9 -0
  108. package/examples/flake-diffthreshold-05.test.mjs +9 -0
  109. package/examples/{z_flake-noredraw-cache.test.mjs → flake-noredraw-cache.test.mjs} +2 -2
  110. package/examples/{z_flake-noredraw-nocache.test.mjs → flake-noredraw-nocache.test.mjs} +2 -2
  111. package/examples/{z_flake-redraw-cache.test.mjs → flake-redraw-cache.test.mjs} +2 -2
  112. package/examples/{z_flake-redraw-nocache.test.mjs → flake-redraw-nocache.test.mjs} +2 -2
  113. package/examples/flake-rocket-match.test.mjs +30 -0
  114. package/examples/{z_flake-shared.mjs → flake-shared.mjs} +2 -2
  115. package/examples/parse.test.mjs +19 -0
  116. package/examples/scroll-keyboard.test.mjs +1 -1
  117. package/interfaces/cli/lib/base.js +6 -0
  118. package/interfaces/logger.js +51 -13
  119. package/interfaces/vitest-plugin.mjs +137 -0
  120. package/lib/core/index.d.ts +22 -0
  121. package/lib/init-project.js +105 -6
  122. package/lib/vitest/hooks.mjs +2 -5
  123. package/lib/vitest/setup-disable-defender.mjs +52 -0
  124. package/package.json +2 -1
  125. package/sdk-log-formatter.js +90 -0
  126. package/sdk.d.ts +88 -51
  127. package/sdk.js +128 -21
  128. package/setup/aws/disable-defender.sh +42 -0
  129. package/vitest.config.mjs +1 -3
  130. package/examples/z_flake-diffthreshold-001.test.mjs +0 -9
  131. package/examples/z_flake-diffthreshold-01.test.mjs +0 -9
  132. package/examples/z_flake-diffthreshold-05.test.mjs +0 -9
  133. /package/{examples → manual}/captcha-api.test.mjs +0 -0
@@ -0,0 +1,605 @@
1
+ ---
2
+ name: testdriver:elements
3
+ description: Locate and interact with UI elements using AI
4
+ ---
5
+ <!-- Generated from elements.mdx. DO NOT EDIT. -->
6
+
7
+ ## Overview
8
+
9
+ TestDriver's element finding system uses AI to locate elements on screen using natural language descriptions. The `find()` method returns an `Element` object that you can interact with.
10
+
11
+ ## Finding Elements
12
+
13
+ ### find()
14
+
15
+ Locate an element on screen using a natural language description.
16
+
17
+ ```javascript
18
+ const element = await testdriver.find(description)
19
+ ```
20
+
21
+ **Parameters:**
22
+ - `description` (string) - Natural language description of the element to find
23
+
24
+ **Returns:** `Promise<Element>` - Element instance that has been located
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 improve accuracy.
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.
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
+ #### click()
93
+
94
+ Click on the element.
95
+
96
+ ```javascript
97
+ await element.click(action)
98
+ ```
99
+
100
+ **Parameters:**
101
+ - `action` (string, optional) - Type of click: `'click'` (default), `'double-click'`, `'right-click'`, `'hover'`, `'mouseDown'`, `'mouseUp'`
102
+
103
+ **Returns:** `Promise<void>`
104
+
105
+ **Example:**
106
+ ```javascript
107
+ const button = await testdriver.find('submit button');
108
+ await button.click(); // Regular click
109
+
110
+ const file = await testdriver.find('document.txt');
111
+ await file.click('double-click'); // Double-click
112
+
113
+ const menu = await testdriver.find('settings icon');
114
+ await menu.click('right-click'); // Right-click
115
+ ```
116
+
117
+ <Note>
118
+ The element must be found before clicking. The `find()` method automatically locates the element.
119
+ </Note>
120
+
121
+ #### hover()
122
+
123
+ Hover over the element without clicking.
124
+
125
+ ```javascript
126
+ await element.hover()
127
+ ```
128
+
129
+ **Returns:** `Promise<void>`
130
+
131
+ **Example:**
132
+ ```javascript
133
+ const tooltip = await testdriver.find('info icon');
134
+ await tooltip.hover();
135
+ // Wait to see tooltip
136
+ await new Promise(resolve => setTimeout(resolve, 1000));
137
+ ```
138
+
139
+ #### doubleClick()
140
+
141
+ Double-click on the element.
142
+
143
+ ```javascript
144
+ await element.doubleClick()
145
+ ```
146
+
147
+ **Returns:** `Promise<void>`
148
+
149
+ **Example:**
150
+ ```javascript
151
+ const file = await testdriver.find('README.txt file icon');
152
+ await file.doubleClick();
153
+ ```
154
+
155
+ #### rightClick()
156
+
157
+ Right-click on the element to open context menu.
158
+
159
+ ```javascript
160
+ await element.rightClick()
161
+ ```
162
+
163
+ **Returns:** `Promise<void>`
164
+
165
+ **Example:**
166
+ ```javascript
167
+ const folder = await testdriver.find('Documents folder');
168
+ await folder.rightClick();
169
+ ```
170
+
171
+ #### mouseDown() / mouseUp()
172
+
173
+ Press or release mouse button on the element (for drag operations).
174
+
175
+ ```javascript
176
+ await element.mouseDown()
177
+ await element.mouseUp()
178
+ ```
179
+
180
+ **Returns:** `Promise<void>`
181
+
182
+ **Example:**
183
+ ```javascript
184
+ // Drag and drop
185
+ const item = await testdriver.find('draggable item');
186
+ await item.mouseDown();
187
+
188
+ // Move to drop target (using coordinates or another element)
189
+ const target = await testdriver.find('drop zone');
190
+ await target.hover();
191
+ await target.mouseUp();
192
+ ```
193
+
194
+ ### Properties
195
+
196
+ Element properties provide additional information about located elements. Properties are available after a successful `find()` call.
197
+
198
+ #### coordinates
199
+
200
+ Get the element's coordinates object containing all position information.
201
+
202
+ ```javascript
203
+ const coords = element.getCoordinates()
204
+ // or access directly
205
+ element.coordinates
206
+ ```
207
+
208
+ **Returns:** `Object | null` - Coordinate object with `{ x, y, centerX, centerY }`
209
+
210
+ **Example:**
211
+ ```javascript
212
+ const button = await testdriver.find('submit button');
213
+ const coords = button.coordinates;
214
+
215
+ if (coords) {
216
+ console.log(`Top-left: (${coords.x}, ${coords.y})`);
217
+ console.log(`Center: (${coords.centerX}, ${coords.centerY})`);
218
+ }
219
+ ```
220
+
221
+ #### x, y, centerX, centerY
222
+
223
+ Direct access to coordinate values. Always available after successful `find()`.
224
+
225
+ ```javascript
226
+ element.x // Top-left X coordinate (number)
227
+ element.y // Top-left Y coordinate (number)
228
+ element.centerX // Center X coordinate (number)
229
+ element.centerY // Center Y coordinate (number)
230
+ ```
231
+
232
+ **Example:**
233
+ ```javascript
234
+ const button = await testdriver.find('submit button');
235
+ console.log(`Button at: (${button.x}, ${button.y})`);
236
+ console.log(`Button center: (${button.centerX}, ${button.centerY})`);
237
+
238
+ // Use for custom mouse operations
239
+ await testdriver.click(button.centerX, button.centerY);
240
+ ```
241
+
242
+ #### width, height
243
+
244
+ Element dimensions in pixels. Available when AI detects element bounds.
245
+
246
+ ```javascript
247
+ element.width // Width in pixels (number | null)
248
+ element.height // Height in pixels (number | null)
249
+ ```
250
+
251
+ **Example:**
252
+ ```javascript
253
+ const button = await testdriver.find('submit button');
254
+
255
+ if (button.width && button.height) {
256
+ console.log(`Button size: ${button.width}x${button.height}px`);
257
+
258
+ // Check if button is large enough
259
+ if (button.width < 50) {
260
+ console.warn('Button might be too small');
261
+ }
262
+ }
263
+ ```
264
+
265
+ #### boundingBox
266
+
267
+ Complete bounding box information including position and dimensions.
268
+
269
+ ```javascript
270
+ element.boundingBox
271
+ ```
272
+
273
+ **Returns:** `Object | null` - Bounding box with all dimension data
274
+
275
+ ```typescript
276
+ {
277
+ x: number, // Top-left X
278
+ y: number, // Top-left Y
279
+ width: number, // Width in pixels
280
+ height: number // Height in pixels
281
+ }
282
+ ```
283
+
284
+ **Example:**
285
+ ```javascript
286
+ const element = await testdriver.find('dialog box');
287
+
288
+ if (element.boundingBox) {
289
+ const { x, y, width, height } = element.boundingBox;
290
+ console.log(`Dialog: ${width}x${height} at (${x}, ${y})`);
291
+
292
+ // Calculate if element is in viewport
293
+ const rightEdge = x + width;
294
+ const bottomEdge = y + height;
295
+ console.log(`Element extends to (${rightEdge}, ${bottomEdge})`);
296
+ }
297
+ ```
298
+
299
+ #### screenshot
300
+
301
+ Base64-encoded PNG screenshot of the screen when element was found. Only available in DEBUG mode or when an error occurs.
302
+
303
+ ```javascript
304
+ element.screenshot
305
+ ```
306
+
307
+ **Returns:** `string | null` - Base64-encoded PNG image
308
+
309
+ **Example:**
310
+ ```javascript
311
+ const element = await testdriver.find('error message');
312
+
313
+ if (element.screenshot) {
314
+ // Save screenshot to file
315
+ const fs = require('fs');
316
+ const base64Data = element.screenshot.replace(/^data:image\/\w+;base64,/, '');
317
+ fs.writeFileSync('element-screenshot.png', Buffer.from(base64Data, 'base64'));
318
+ console.log('Screenshot saved');
319
+ }
320
+ ```
321
+
322
+ <Warning>
323
+ Screenshots can be large. They're automatically excluded from error messages to prevent memory issues.
324
+ </Warning>
325
+
326
+ #### text
327
+
328
+ Text content extracted from the element by AI (if available).
329
+
330
+ ```javascript
331
+ element.text
332
+ ```
333
+
334
+ **Returns:** `string | null` - Element's text content
335
+
336
+ **Example:**
337
+ ```javascript
338
+ const message = await testdriver.find('notification message');
339
+
340
+ if (message.text) {
341
+ console.log('Message says:', message.text);
342
+
343
+ // Use text content in assertions
344
+ if (message.text.includes('success')) {
345
+ console.log('Success message detected');
346
+ }
347
+ }
348
+
349
+ // Another example - extracting button label
350
+ const button = await testdriver.find('blue button');
351
+ console.log('Button text:', button.text); // "Submit"
352
+ ```
353
+
354
+ #### label
355
+
356
+ Accessible label or name of the element (if available). Useful for verifying accessibility.
357
+
358
+ ```javascript
359
+ element.label
360
+ ```
361
+
362
+ **Returns:** `string | null` - Accessible label
363
+
364
+ **Example:**
365
+ ```javascript
366
+ const input = await testdriver.find('first input field');
367
+
368
+ if (input.label) {
369
+ console.log('Input label:', input.label); // "Email Address"
370
+ }
371
+ ```
372
+
373
+ #### confidence
374
+
375
+ AI confidence score for the element match (0-1, where 1 is perfect confidence).
376
+
377
+ ```javascript
378
+ element.confidence
379
+ ```
380
+
381
+ **Returns:** `number | null` - Confidence score between 0 and 1
382
+
383
+ **Example:**
384
+ ```javascript
385
+ const element = await testdriver.find('submit button');
386
+
387
+ if (element.confidence !== null) {
388
+ const percentage = (element.confidence * 100).toFixed(1);
389
+ console.log(`Match confidence: ${percentage}%`);
390
+
391
+ if (element.confidence < 0.8) {
392
+ console.warn('⚠️ Low confidence match - element might not be correct');
393
+ } else if (element.confidence > 0.95) {
394
+ console.log('✅ High confidence match');
395
+ }
396
+ }
397
+ ```
398
+
399
+ <Tip>
400
+ Confidence scores below 0.8 may indicate the element description was ambiguous or the wrong element was found.
401
+ </Tip>
402
+
403
+ ### Property Availability
404
+
405
+ | Property | When Available |
406
+ |----------|---------------|
407
+ | `x`, `y`, `centerX`, `centerY` | ✅ Always after successful `find()` |
408
+ | `coordinates` | ✅ Always after successful `find()` |
409
+ | `width`, `height` | ⚠️ When AI detects element bounds |
410
+ | `boundingBox` | ⚠️ When AI detects element bounds |
411
+ | `text` | ⚠️ When AI extracts text content |
412
+ | `label` | ⚠️ When element has accessible label |
413
+ | `confidence` | ✅ Always after AI element finding |
414
+ | `screenshot` | ⚠️ Only in DEBUG mode or on errors |
415
+
416
+ <Note>
417
+ Properties marked with ⚠️ may be `null` depending on what the AI could detect from the screenshot.
418
+ </Note>
419
+
420
+ ## JSON Serialization
421
+
422
+ Element objects can be safely serialized using `JSON.stringify()` for logging, debugging, and data storage. Circular references are automatically removed:
423
+
424
+ ```javascript
425
+ const element = await testdriver.find('login button');
426
+
427
+ // Safe to stringify - no circular reference errors!
428
+ console.log(JSON.stringify(element, null, 2));
429
+ ```
430
+
431
+ **Serialized output includes:**
432
+
433
+ ```json
434
+ {
435
+ "description": "login button",
436
+ "coordinates": { "x": 100, "y": 200, "centerX": 150, "centerY": 225 },
437
+ "found": true,
438
+ "threshold": 0.01,
439
+ "x": 100,
440
+ "y": 200,
441
+ "cache": {
442
+ "hit": true,
443
+ "strategy": "pixel-diff",
444
+ "createdAt": "2025-12-09T10:30:00.000Z",
445
+ "diffPercent": 0.0023,
446
+ "imageUrl": "https://cache.testdriver.ai/..."
447
+ },
448
+ "similarity": 0.98,
449
+ "confidence": 0.95,
450
+ "selector": "button#login",
451
+ "aiResponse": "Found the blue login button in the center of the form..."
452
+ }
453
+ ```
454
+
455
+ **Serialized properties:**
456
+
457
+ | Property | Type | Description |
458
+ |----------|------|-------------|
459
+ | `description` | string | Element search description |
460
+ | `coordinates` | object | Full coordinate object `{x, y, centerX, centerY}` |
461
+ | `found` | boolean | Whether element was located |
462
+ | `threshold` | number | Cache threshold used for this find |
463
+ | `x`, `y` | number | Top-left coordinates |
464
+ | `cache.hit` | boolean | Whether cache was used |
465
+ | `cache.strategy` | string | Cache strategy (e.g., "pixel-diff") |
466
+ | `cache.createdAt` | string | ISO timestamp when cache was created |
467
+ | `cache.diffPercent` | number | Pixel difference from cached image |
468
+ | `cache.imageUrl` | string | URL to cached screenshot |
469
+ | `similarity` | number | Similarity score (0-1) |
470
+ | `confidence` | number | AI confidence score (0-1) |
471
+ | `selector` | string | CSS/XPath selector if available |
472
+ | `aiResponse` | string | AI's explanation of what it found |
473
+
474
+ **Use cases:**
475
+
476
+ ```javascript
477
+ // Debugging element detection
478
+ const element = await testdriver.find('submit button');
479
+ if (!element.found()) {
480
+ console.error('Element not found:', JSON.stringify(element, null, 2));
481
+ }
482
+
483
+ // Logging cache performance
484
+ const data = JSON.parse(JSON.stringify(element));
485
+ if (data.cache.hit) {
486
+ console.log(`Cache hit! Diff: ${(data.cache.diffPercent * 100).toFixed(2)}%`);
487
+ }
488
+
489
+ // Sharing element data across processes
490
+ const elementData = JSON.stringify(element);
491
+ // Send to another process, log to file, etc.
492
+ ```
493
+
494
+ <Tip>
495
+ 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.
496
+ </Tip>
497
+
498
+ ## Examples
499
+
500
+ ### Basic Element Interaction
501
+
502
+ ```javascript
503
+ // Find and click
504
+ const submitButton = await testdriver.find('submit button');
505
+ await submitButton.click();
506
+
507
+ // Find, verify, then interact
508
+ const emailInput = await testdriver.find('email input field');
509
+ if (emailInput.found()) {
510
+ await emailInput.click();
511
+ await testdriver.type('user@example.com');
512
+ }
513
+ ```
514
+
515
+ ### Working with Forms
516
+
517
+ ```javascript
518
+ // Fill out a multi-field form
519
+ const nameField = await testdriver.find('name input field');
520
+ await nameField.click();
521
+ await testdriver.type('John Doe');
522
+
523
+ const emailField = await testdriver.find('email input field');
524
+ await emailField.click();
525
+ await testdriver.type('john@example.com');
526
+
527
+ const submitButton = await testdriver.find('submit button');
528
+ await submitButton.click();
529
+ ```
530
+
531
+ ### Conditional Interactions
532
+
533
+ ```javascript
534
+ // Check if element exists before interacting
535
+ const closeButton = await testdriver.find('close popup button');
536
+
537
+ if (closeButton.found()) {
538
+ await closeButton.click();
539
+ console.log('Popup closed');
540
+ } else {
541
+ console.log('No popup to close');
542
+ }
543
+ ```
544
+
545
+ ### Re-locating Dynamic Elements
546
+
547
+ ```javascript
548
+ // Element that moves or changes
549
+ const notification = await testdriver.find('success notification');
550
+
551
+ // Do something that might cause it to move
552
+ await testdriver.scroll('down', 300);
553
+
554
+ // Re-locate the element
555
+ await notification.find();
556
+
557
+ if (notification.found()) {
558
+ await notification.click();
559
+ }
560
+ ```
561
+
562
+ ## Best Practices
563
+
564
+ <AccordionGroup>
565
+ <Accordion title="Be specific with descriptions">
566
+ Include visual details, position context, and nearby text:
567
+
568
+ ```javascript
569
+ // ❌ Too vague
570
+ await testdriver.find('button');
571
+
572
+ // ✅ Specific
573
+ await testdriver.find('blue submit button below the email field');
574
+ ```
575
+ </Accordion>
576
+
577
+ <Accordion title="Check if element was found">
578
+ Always verify elements were located before interacting:
579
+
580
+ ```javascript
581
+ const element = await testdriver.find('submit button');
582
+ if (!element.found()) {
583
+ throw new Error('Submit button not found');
584
+ }
585
+ await element.click();
586
+ ```
587
+ </Accordion>
588
+
589
+
590
+ <Accordion title="Reuse element references when possible">
591
+ If you need to interact with the same element multiple times, reuse the reference:
592
+
593
+ ```javascript
594
+ const input = await testdriver.find('search input');
595
+ await input.click();
596
+ await testdriver.type('first search');
597
+ await testdriver.pressKeys(['enter']);
598
+
599
+ // Re-use the same element reference
600
+ await input.click();
601
+ await testdriver.pressKeys(['ctrl', 'a']); // Select all
602
+ await testdriver.type('second search');
603
+ ```
604
+ </Accordion>
605
+ </AccordionGroup>
@@ -0,0 +1,114 @@
1
+ ---
2
+ name: testdriver:enterprise
3
+ description: Air-gapped security and full customization for demanding environments
4
+ ---
5
+ <!-- Generated from enterprise.mdx. DO NOT EDIT. -->
6
+
7
+ ## Why Enterprise?
8
+
9
+ <CardGroup cols={2}>
10
+ <Card title="Air-Gapped Security" icon="shield-check">
11
+ Deploy everything in your environment. No data leaves your network. Complete isolation from external services.
12
+ </Card>
13
+ <Card title="Full Customization" icon="gear">
14
+ Custom integrations, dedicated infrastructure, and tailored solutions for your unique requirements.
15
+ </Card>
16
+ <Card title="Self-Hosted Dashboard & API" icon="server">
17
+ Run the entire TestDriver stack — dashboard, API, and test infrastructure — within your own environment.
18
+ </Card>
19
+ <Card title="Dedicated Support" icon="headset">
20
+ Direct access to our engineering team for implementation, customization, and ongoing support.
21
+ </Card>
22
+ </CardGroup>
23
+
24
+ ## Who Needs Enterprise?
25
+
26
+ Enterprise is designed for organizations that:
27
+
28
+ - **Require air-gapped deployments** — Regulated industries, government, defense, or strict compliance requirements
29
+ - **Cannot use external APIs** — Data must never leave your network perimeter
30
+ - **Need custom integrations** — Unique CI/CD systems, internal tools, or specialized workflows
31
+ - **Want dedicated support** — Direct engineering support for complex implementations
32
+
33
+ ## What's Included
34
+
35
+ ### Fully Self-Hosted Stack
36
+
37
+ Unlike [Self-Hosted](/v7/self-hosted) (which uses TestDriver's hosted dashboard and API), Enterprise deploys everything in your environment:
38
+
39
+ | Component | Self-Hosted | Enterprise |
40
+ |-----------|-------------|------------|
41
+ | Test Sandboxes | Your infrastructure | Your infrastructure |
42
+ | Dashboard | TestDriver hosted | Your infrastructure |
43
+ | API | TestDriver hosted | Your infrastructure |
44
+ | AI Processing | Your API keys | Your infrastructure |
45
+ | Data Storage | Your AWS account | Your infrastructure |
46
+
47
+ ### Custom Contract Terms
48
+
49
+ - Volume-based pricing
50
+ - Custom SLAs
51
+ - Dedicated support channels
52
+ - Professional services for implementation
53
+ - Training for your team
54
+
55
+ ## Implementation Process
56
+
57
+ <Steps>
58
+ <Step title="Discovery Call">
59
+ Discuss your requirements, security constraints, and integration needs with our team.
60
+ </Step>
61
+
62
+ <Step title="Architecture Review">
63
+ Our engineers design a deployment architecture that meets your security and compliance requirements.
64
+ </Step>
65
+
66
+ <Step title="Deployment">
67
+ We work with your team to deploy TestDriver within your environment, including dashboard, API, and test infrastructure.
68
+ </Step>
69
+
70
+ <Step title="Integration">
71
+ Connect TestDriver to your CI/CD pipelines, internal tools, and workflows.
72
+ </Step>
73
+
74
+ <Step title="Training & Handoff">
75
+ Comprehensive training for your team on operating and maintaining the deployment.
76
+ </Step>
77
+ </Steps>
78
+
79
+ ## Security & Compliance
80
+
81
+ Enterprise deployments support:
82
+
83
+ - **SOC 2** compliance requirements
84
+ - **HIPAA** for healthcare applications
85
+ - **FedRAMP** for government deployments
86
+ - **PCI DSS** for payment processing
87
+ - **Custom compliance frameworks** as needed
88
+
89
+ <Note>
90
+ All data remains within your network perimeter. TestDriver has no access to your test results, application data, or infrastructure.
91
+ </Note>
92
+
93
+ ## Comparison: Self-Hosted vs Enterprise
94
+
95
+ | Feature | Self-Hosted | Enterprise |
96
+ |---------|-------------|------------|
97
+ | **Test Infrastructure** | Your AWS | Your infrastructure (any) |
98
+ | **Dashboard** | TestDriver cloud | Your infrastructure |
99
+ | **API** | TestDriver cloud | Your infrastructure |
100
+ | **Data Location** | Your AWS + TestDriver | 100% your infrastructure |
101
+ | **Network Requirements** | Internet access | Can be fully air-gapped |
102
+ | **Cloud Providers** | AWS only | Any (AWS, Azure, GCP, on-prem) |
103
+ | **Support** | Standard | Dedicated engineering |
104
+ | **Contract** | Standard licensing | Custom terms |
105
+
106
+ ## Get Started
107
+
108
+ <Card
109
+ title="Schedule a Consultation"
110
+ icon="calendar"
111
+ href="https://calendly.com/d/cq23-qyn-3v6/testdriver-ai-demo"
112
+ >
113
+ Discuss your requirements with our team and get a custom proposal for your Enterprise deployment.
114
+ </Card>