testdriverai 7.1.4 → 7.2.2

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 (72) hide show
  1. package/.github/workflows/acceptance.yaml +81 -0
  2. package/.github/workflows/publish.yaml +44 -0
  3. package/agent/index.js +18 -19
  4. package/agent/interface.js +4 -0
  5. package/agent/lib/commands.js +321 -121
  6. package/agent/lib/redraw.js +99 -39
  7. package/agent/lib/sandbox.js +98 -6
  8. package/agent/lib/sdk.js +25 -0
  9. package/agent/lib/system.js +2 -1
  10. package/agent/lib/validation.js +6 -6
  11. package/docs/docs.json +211 -101
  12. package/docs/snippets/tests/type-repeated-replay.mdx +1 -1
  13. package/docs/v7/_drafts/caching-selectors.mdx +24 -0
  14. package/docs/v7/api/act.mdx +1 -1
  15. package/docs/v7/api/assert.mdx +1 -1
  16. package/docs/v7/api/assertions.mdx +7 -7
  17. package/docs/v7/api/elements.mdx +78 -0
  18. package/docs/v7/api/find.mdx +38 -0
  19. package/docs/v7/api/focusApplication.mdx +2 -2
  20. package/docs/v7/api/hover.mdx +2 -2
  21. package/docs/v7/features/ai-native.mdx +57 -71
  22. package/docs/v7/features/application-logs.mdx +353 -0
  23. package/docs/v7/features/browser-logs.mdx +414 -0
  24. package/docs/v7/features/cache-management.mdx +402 -0
  25. package/docs/v7/features/continuous-testing.mdx +346 -0
  26. package/docs/v7/features/coverage.mdx +508 -0
  27. package/docs/v7/features/data-driven-testing.mdx +441 -0
  28. package/docs/v7/features/easy-to-write.mdx +2 -73
  29. package/docs/v7/features/enterprise.mdx +155 -39
  30. package/docs/v7/features/fast.mdx +63 -81
  31. package/docs/v7/features/managed-sandboxes.mdx +384 -0
  32. package/docs/v7/features/network-monitoring.mdx +568 -0
  33. package/docs/v7/features/observable.mdx +3 -22
  34. package/docs/v7/features/parallel-execution.mdx +381 -0
  35. package/docs/v7/features/powerful.mdx +1 -1
  36. package/docs/v7/features/reports.mdx +414 -0
  37. package/docs/v7/features/sandbox-customization.mdx +229 -0
  38. package/docs/v7/features/scalable.mdx +217 -2
  39. package/docs/v7/features/stable.mdx +106 -147
  40. package/docs/v7/features/system-performance.mdx +616 -0
  41. package/docs/v7/features/test-analytics.mdx +373 -0
  42. package/docs/v7/features/test-cases.mdx +393 -0
  43. package/docs/v7/features/test-replays.mdx +408 -0
  44. package/docs/v7/features/test-reports.mdx +308 -0
  45. package/docs/v7/getting-started/{running-and-debugging.mdx → debugging-tests.mdx} +12 -142
  46. package/docs/v7/getting-started/quickstart.mdx +22 -305
  47. package/docs/v7/getting-started/running-tests.mdx +173 -0
  48. package/docs/v7/overview/what-is-testdriver.mdx +2 -14
  49. package/docs/v7/presets/chrome-extension.mdx +147 -122
  50. package/interfaces/cli/commands/init.js +3 -3
  51. package/interfaces/cli/lib/base.js +3 -2
  52. package/interfaces/logger.js +0 -2
  53. package/interfaces/shared-test-state.mjs +0 -5
  54. package/interfaces/vitest-plugin.mjs +70 -50
  55. package/lib/core/Dashcam.js +60 -85
  56. package/lib/vitest/hooks.mjs +42 -50
  57. package/package.json +1 -1
  58. package/sdk-log-formatter.js +350 -175
  59. package/sdk.d.ts +36 -3
  60. package/sdk.js +431 -116
  61. package/setup/aws/cloudformation.yaml +2 -2
  62. package/setup/aws/self-hosted.yml +1 -1
  63. package/test/testdriver/chrome-extension.test.mjs +55 -72
  64. package/test/testdriver/element-not-found.test.mjs +2 -1
  65. package/test/testdriver/hover-image.test.mjs +1 -1
  66. package/test/testdriver/scroll-until-text.test.mjs +10 -6
  67. package/test/testdriver/setup/lifecycleHelpers.mjs +19 -24
  68. package/test/testdriver/setup/testHelpers.mjs +18 -23
  69. package/vitest.config.mjs +3 -3
  70. package/.github/workflows/linux-tests.yml +0 -28
  71. package/docs/v7/getting-started/generating-tests.mdx +0 -525
  72. package/test/testdriver/auto-cache-key-demo.test.mjs +0 -56
package/docs/docs.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://mintlify.com/docs.json",
3
- "theme": "willow",
3
+ "theme": "aspen",
4
4
  "name": "TestDriver",
5
5
  "colors": {
6
6
  "primary": "#b3d334",
@@ -12,12 +12,9 @@
12
12
  },
13
13
  "favicon": "/images/template/icon.png",
14
14
  "navigation": {
15
- "tabs": [
16
- {
17
- "tab": "Computer-Use SDK",
18
15
  "versions": [
19
16
  {
20
- "version": "v6 (YAML)",
17
+ "version": "v6",
21
18
  "groups": [
22
19
  {
23
20
  "group": "Overview",
@@ -68,24 +65,24 @@
68
65
  "group": "Apps",
69
66
  "icon": "laptop",
70
67
  "pages": [
71
- "apps/static-websites",
72
- "apps/desktop-apps",
73
- "apps/chrome-extensions",
74
- "apps/mobile-apps",
75
- "apps/tauri-apps"
68
+ "/v6/apps/static-websites",
69
+ "/v6/apps/desktop-apps",
70
+ "/v6/apps/chrome-extensions",
71
+ "/v6/apps/mobile-apps",
72
+ "/v6/apps/tauri-apps"
76
73
  ]
77
74
  },
78
75
  {
79
76
  "group": "Scenarios",
80
77
  "icon": "computer-mouse",
81
78
  "pages": [
82
- "scenarios/ai-chatbot",
83
- "scenarios/cookie-banner",
84
- "scenarios/file-upload",
85
- "scenarios/form-filling",
86
- "scenarios/log-in",
87
- "scenarios/pdf-generation",
88
- "scenarios/spell-check"
79
+ "/v6/scenarios/ai-chatbot",
80
+ "/v6/scenarios/cookie-banner",
81
+ "/v6/scenarios/file-upload",
82
+ "/v6/scenarios/form-filling",
83
+ "/v6/scenarios/log-in",
84
+ "/v6/scenarios/pdf-generation",
85
+ "/v6/scenarios/spell-check"
89
86
  ]
90
87
  },
91
88
  {
@@ -156,7 +153,7 @@
156
153
  {
157
154
  "group": "Reporting",
158
155
  "icon": "chart-simple",
159
- "pages": ["exporting/junit", "/v6/bugs/jira"]
156
+ "pages": ["/v6/exporting/junit", "/v6/bugs/jira"]
160
157
  }
161
158
  ]
162
159
  },
@@ -190,87 +187,140 @@
190
187
  }
191
188
  ]
192
189
  },
193
- {
194
- "version": "v7 (JS Beta)",
195
- "groups": [
196
- {
197
- "group": "Overview",
198
- "icon": "circle-info",
199
- "pages": [
200
- "/v7/overview/what-is-testdriver",
201
- {
202
- "group": "Features",
203
- "icon": "star",
204
- "pages": [
205
- "/v7/features/easy-to-write",
206
- "/v7/features/fast",
207
- "/v7/features/stable",
208
- "/v7/features/scalable",
209
- "/v7/features/ai-native",
210
- "/v7/features/powerful",
211
- "/v7/features/observable",
212
- "/v7/features/enterprise"
213
- ]
214
- }
215
- ]
216
- },
217
- {
218
- "group": "Getting Started",
219
- "icon": "rocket",
220
- "pages": [
221
- "/v7/getting-started/installation",
222
- "/v7/getting-started/writing-tests",
223
- "/v7/getting-started/generating-tests",
224
- "/v7/getting-started/running-and-debugging",
225
- "/v7/getting-started/setting-up-in-ci"
226
- ]
227
- },
228
- {
229
- "group": "Examples",
230
- "icon": "code",
231
- "pages": [
232
- "/v7/presets/chrome",
233
- "/v7/presets/chrome-extension",
234
- "/v7/presets/vscode",
235
- "/v7/presets/electron"
236
- ]
237
- },
238
- {
239
- "group": "Actions",
240
- "icon": "bolt",
241
- "pages": [
242
- "/v7/api/act",
243
- "/v7/api/assert",
244
- "/v7/api/assertions",
245
- "/v7/api/click",
246
- "/v7/api/doubleClick",
247
- "/v7/api/exec",
248
- "/v7/api/find",
249
- "/v7/api/focusApplication",
250
- "/v7/api/hover",
251
- "/v7/api/mouseDown",
252
- "/v7/api/mouseUp",
253
- "/v7/api/pressKeys",
254
- "/v7/api/rightClick",
255
- "/v7/api/type",
256
- "/v7/api/scroll"
257
- ]
258
- },
259
- {
260
- "group": "API Reference",
261
- "icon": "book",
262
- "pages": [
263
- "/v7/api/client",
264
- "/v7/api/elements",
265
- "/v7/api/sandbox",
266
- "/v7/api/dashcam"
267
- ]
268
- }
269
- ]
270
- }
190
+ {
191
+ "version": "v7",
192
+ "groups": [
193
+ {
194
+ "group": "Getting Started",
195
+ "icon": "rocket",
196
+ "pages": [
197
+ "/v7/getting-started/quickstart"
198
+ ]
199
+ },
200
+ {
201
+ "group": "Guides",
202
+ "icon": "book",
203
+ "pages": [
204
+ "/v7/getting-started/writing-tests",
205
+ "/v7/getting-started/running-tests",
206
+ "/v7/getting-started/debugging-tests",
207
+ "/v7/getting-started/setting-up-in-ci"
208
+ ]
209
+ },
210
+ {
211
+ "group": "Examples",
212
+ "icon": "code",
213
+ "pages": [
214
+ "/v7/presets/chrome",
215
+ "/v7/presets/chrome-extension",
216
+ "/v7/presets/vscode",
217
+ "/v7/presets/electron"
218
+ ]
219
+ },
220
+ {
221
+ "group": "Features",
222
+ "icon": "layer-group",
223
+ "pages": [
224
+ {
225
+ "group": "Selectorless Testing",
226
+ "icon": "sparkles",
227
+ "pages": [
228
+ "/v7/features/easy-to-write",
229
+ "/v7/features/coverage",
230
+ "/v7/features/powerful",
231
+ "/v7/features/ai-native"
232
+ ]
233
+ },
234
+ {
235
+ "group": "Sandbox Environments",
236
+ "icon": "cube",
237
+ "pages": [
238
+ "/v7/features/managed-sandboxes",
239
+ "/v7/features/sandbox-customization",
240
+ "/v7/features/enterprise"
241
+ ]
242
+ },
243
+ {
244
+ "group": "Test Observability",
245
+ "icon": "microscope",
246
+ "pages": [
247
+ "/v7/features/application-logs",
248
+ "/v7/features/browser-logs",
249
+ "/v7/features/network-monitoring",
250
+ "/v7/features/system-performance"
251
+ ]
252
+ },
253
+ {
254
+ "group": "Performance & Reliability",
255
+ "icon": "gauge-high",
256
+ "pages": [
257
+ "/v7/features/fast",
258
+ "/v7/features/stable",
259
+ "/v7/features/parallel-execution",
260
+ "/v7/features/cache-management"
261
+ ]
262
+ },
263
+ {
264
+ "group": "Testing at Scale",
265
+ "icon": "arrow-up-right-dots",
266
+ "pages": [
267
+ "/v7/features/data-driven-testing",
268
+ "/v7/features/continuous-testing"
269
+ ]
270
+ },
271
+ {
272
+ "group": "Reports & Analytics",
273
+ "icon": "chart-line",
274
+ "pages": [
275
+ "/v7/features/test-reports",
276
+ "/v7/features/test-analytics",
277
+ "/v7/features/test-cases",
278
+ "/v7/features/test-replays"
279
+ ]
280
+ }
281
+ ]
282
+ },
283
+ {
284
+ "group": "Reference",
285
+ "icon": "book",
286
+ "pages": [
287
+ {
288
+ "group": "Actions",
289
+ "icon": "bolt",
290
+ "pages": [
291
+ "/v7/api/act",
292
+ "/v7/api/assert",
293
+ "/v7/api/assertions",
294
+ "/v7/api/click",
295
+ "/v7/api/doubleClick",
296
+ "/v7/api/exec",
297
+ "/v7/api/find",
298
+ "/v7/api/focusApplication",
299
+ "/v7/api/hover",
300
+ "/v7/api/mouseDown",
301
+ "/v7/api/mouseUp",
302
+ "/v7/api/pressKeys",
303
+ "/v7/api/rightClick",
304
+ "/v7/api/type",
305
+ "/v7/api/scroll"
306
+ ]
307
+ },
308
+ {
309
+ "group": "Client SDK",
310
+ "icon": "code",
311
+ "pages": [
312
+ "/v7/api/client",
313
+ "/v7/api/elements",
314
+ "/v7/api/sandbox",
315
+ "/v7/api/dashcam"
316
+ ]
317
+ }
318
+ ]
319
+ }
320
+ ]
321
+ }
322
+
271
323
  ]
272
- }
273
- ]
274
324
  },
275
325
  "logo": {
276
326
  "light": "/images/template/light.png",
@@ -307,15 +357,75 @@
307
357
  "redirects": [
308
358
  {
309
359
  "source": "/guides/github-actions",
310
- "destination": "/action/setup"
360
+ "destination": "/v6/action/setup"
311
361
  },
312
362
  {
313
363
  "source": "/reference/test-steps",
314
- "destination": "/features/selectorless"
364
+ "destination": "/v6/features/selectorless"
315
365
  },
316
366
  {
317
367
  "source": "/guides/debugging-test-runs",
318
- "destination": "/getting-started/editing"
368
+ "destination": "/v6/getting-started/editing"
369
+ },
370
+ {
371
+ "source": "/overview/:slug*",
372
+ "destination": "/v6/overview/:slug*"
373
+ },
374
+ {
375
+ "source": "/features/:slug*",
376
+ "destination": "/v6/features/:slug*"
377
+ },
378
+ {
379
+ "source": "/getting-started/:slug*",
380
+ "destination": "/v6/getting-started/:slug*"
381
+ },
382
+ {
383
+ "source": "/cli/:slug*",
384
+ "destination": "/v6/cli/:slug*"
385
+ },
386
+ {
387
+ "source": "/interactive/:slug*",
388
+ "destination": "/v6/interactive/:slug*"
389
+ },
390
+ {
391
+ "source": "/guide/:slug*",
392
+ "destination": "/v6/guide/:slug*"
393
+ },
394
+ {
395
+ "source": "/action/:slug*",
396
+ "destination": "/v6/action/:slug*"
397
+ },
398
+ {
399
+ "source": "/account/:slug*",
400
+ "destination": "/v6/account/:slug*"
401
+ },
402
+ {
403
+ "source": "/apps/:slug*",
404
+ "destination": "/v6/apps/:slug*"
405
+ },
406
+ {
407
+ "source": "/scenarios/:slug*",
408
+ "destination": "/v6/scenarios/:slug*"
409
+ },
410
+ {
411
+ "source": "/integrations/:slug*",
412
+ "destination": "/v6/integrations/:slug*"
413
+ },
414
+ {
415
+ "source": "/importing/:slug*",
416
+ "destination": "/v6/importing/:slug*"
417
+ },
418
+ {
419
+ "source": "/exporting/:slug*",
420
+ "destination": "/v6/exporting/:slug*"
421
+ },
422
+ {
423
+ "source": "/bugs/:slug*",
424
+ "destination": "/v6/bugs/:slug*"
425
+ },
426
+ {
427
+ "source": "/commands/:slug*",
428
+ "destination": "/v6/commands/:slug*"
319
429
  }
320
430
  ],
321
431
  "integrations": {
@@ -1,4 +1,4 @@
1
- <div className="replay-block">
1
+ st<div className="replay-block">
2
2
  <iframe
3
3
  src="https://app.dashcam.io/replay/683f9c23dc453b7caa0e0d0c?share=gIH46G6NMy3tV8V0KssxA&embed=true&timestamp=90000&playbackRate=5"
4
4
  width="1000"
@@ -51,6 +51,30 @@ const button = await testdriver.find('submit button', {
51
51
  });
52
52
  ```
53
53
 
54
+ **Use Case - Variables in Test Steps:**
55
+
56
+ Custom cache keys are especially useful when you use variables in your test steps, ensuring consistent caching regardless of the variable values:
57
+
58
+ ```javascript
59
+ // Without custom cache key - each variable value creates a new cache entry
60
+ const userName = 'john.doe@example.com';
61
+ await testdriver.find(`input field for ${userName}`); // Cache miss every time
62
+
63
+ // With custom cache key - all values share the same cache
64
+ const userName = 'john.doe@example.com';
65
+ await testdriver.find(`input field for ${userName}`, {
66
+ cacheKey: 'email-input-field' // Same cache key regardless of userName value
67
+ });
68
+
69
+ // Another example with dynamic data
70
+ const productId = '12345';
71
+ await testdriver.find(`product card for ${productId}`, {
72
+ cacheKey: 'product-card' // Reuses cache for any productId
73
+ });
74
+ ```
75
+
76
+ This prevents cache pollution and improves cache hit rates when your prompts include dynamic values.
77
+
54
78
  ### Global Cache Key
55
79
 
56
80
  Enable caching for all finds in your test:
@@ -184,7 +184,7 @@ describe('E-commerce Flow with AI', () => {
184
184
  const cartIcon = await testdriver.find('shopping cart icon');
185
185
  await cartIcon.click();
186
186
 
187
- const total = await testdriver.remember('the cart total amount');
187
+ const total = await testdriver.extract('the cart total amount');
188
188
  console.log('Cart total:', total);
189
189
 
190
190
  // Use AI for checkout flow
@@ -98,7 +98,7 @@ await testdriver.assert('the modal dialog is open');
98
98
  expect(result).toBeTruthy();
99
99
 
100
100
  // Extract for detailed comparison
101
- const message = await testdriver.remember('the success message text');
101
+ const message = await testdriver.extract('the success message text');
102
102
  expect(message).toContain('successfully');
103
103
  ```
104
104
  </Check>
@@ -264,9 +264,9 @@ describe('E2E Shopping Flow', () => {
264
264
  // Verify cart updated
265
265
  await testdriver.assert('cart badge shows 1 item');
266
266
 
267
- // Remember product details
268
- const productName = await testdriver.remember('the name of the product just added');
269
- const price = await testdriver.remember('the price of the product');
267
+ // Extract product details
268
+ const productName = await testdriver.extract('the name of the product just added');
269
+ const price = await testdriver.extract('the price of the product');
270
270
 
271
271
  console.log(`Added ${productName} at ${price}`);
272
272
 
@@ -302,7 +302,7 @@ describe('E2E Shopping Flow', () => {
302
302
  await testdriver.assert('success message is shown');
303
303
 
304
304
  // Extract order number
305
- const orderNumber = await testdriver.remember('the order number');
305
+ const orderNumber = await testdriver.extract('the order number');
306
306
  console.log('Order placed:', orderNumber);
307
307
  expect(orderNumber).toBeTruthy();
308
308
  });
@@ -377,10 +377,10 @@ describe('E2E Shopping Flow', () => {
377
377
  </Accordion>
378
378
 
379
379
  <Accordion title="Extract before comparing">
380
- Use `remember()` to extract values for detailed comparisons:
380
+ Use `extract()` to extract values for detailed comparisons:
381
381
 
382
382
  ```javascript
383
- const actualTotal = await testdriver.remember('the cart total');
383
+ const actualTotal = await testdriver.extract('the cart total');
384
384
  const expectedTotal = '$99.99';
385
385
 
386
386
  expect(actualTotal).toBe(expectedTotal);
@@ -395,7 +395,7 @@ describe('E2E Shopping Flow', () => {
395
395
  await testdriver.assert('success message is displayed');
396
396
 
397
397
  // Extract and use traditional assertion for exact values
398
- const message = await testdriver.remember('the success message text');
398
+ const message = await testdriver.extract('the success message text');
399
399
  expect(message).toContain('successfully');
400
400
  expect(message).toMatch(/order #\d+/i);
401
401
  ```
@@ -418,6 +418,84 @@ if (element.confidence !== null) {
418
418
  Properties marked with ⚠️ may be `null` depending on what the AI could detect from the screenshot.
419
419
  </Note>
420
420
 
421
+ ## JSON Serialization
422
+
423
+ Element objects can be safely serialized using `JSON.stringify()` for logging, debugging, and data storage. Circular references are automatically removed:
424
+
425
+ ```javascript
426
+ const element = await testdriver.find('login button');
427
+
428
+ // Safe to stringify - no circular reference errors!
429
+ console.log(JSON.stringify(element, null, 2));
430
+ ```
431
+
432
+ **Serialized output includes:**
433
+
434
+ ```json
435
+ {
436
+ "description": "login button",
437
+ "coordinates": { "x": 100, "y": 200, "centerX": 150, "centerY": 225 },
438
+ "found": true,
439
+ "threshold": 0.01,
440
+ "x": 100,
441
+ "y": 200,
442
+ "cache": {
443
+ "hit": true,
444
+ "strategy": "pixel-diff",
445
+ "createdAt": "2025-12-09T10:30:00.000Z",
446
+ "diffPercent": 0.0023,
447
+ "imageUrl": "https://cache.testdriver.ai/..."
448
+ },
449
+ "similarity": 0.98,
450
+ "confidence": 0.95,
451
+ "selector": "button#login",
452
+ "aiResponse": "Found the blue login button in the center of the form..."
453
+ }
454
+ ```
455
+
456
+ **Serialized properties:**
457
+
458
+ | Property | Type | Description |
459
+ |----------|------|-------------|
460
+ | `description` | string | Element search description |
461
+ | `coordinates` | object | Full coordinate object `{x, y, centerX, centerY}` |
462
+ | `found` | boolean | Whether element was located |
463
+ | `threshold` | number | Cache threshold used for this find |
464
+ | `x`, `y` | number | Top-left coordinates |
465
+ | `cache.hit` | boolean | Whether cache was used |
466
+ | `cache.strategy` | string | Cache strategy (e.g., "pixel-diff") |
467
+ | `cache.createdAt` | string | ISO timestamp when cache was created |
468
+ | `cache.diffPercent` | number | Pixel difference from cached image |
469
+ | `cache.imageUrl` | string | URL to cached screenshot |
470
+ | `similarity` | number | Similarity score (0-1) |
471
+ | `confidence` | number | AI confidence score (0-1) |
472
+ | `selector` | string | CSS/XPath selector if available |
473
+ | `aiResponse` | string | AI's explanation of what it found |
474
+
475
+ **Use cases:**
476
+
477
+ ```javascript
478
+ // Debugging element detection
479
+ const element = await testdriver.find('submit button');
480
+ if (!element.found()) {
481
+ console.error('Element not found:', JSON.stringify(element, null, 2));
482
+ }
483
+
484
+ // Logging cache performance
485
+ const data = JSON.parse(JSON.stringify(element));
486
+ if (data.cache.hit) {
487
+ console.log(`Cache hit! Diff: ${(data.cache.diffPercent * 100).toFixed(2)}%`);
488
+ }
489
+
490
+ // Sharing element data across processes
491
+ const elementData = JSON.stringify(element);
492
+ // Send to another process, log to file, etc.
493
+ ```
494
+
495
+ <Tip>
496
+ 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.
497
+ </Tip>
498
+
421
499
  ## Polling for Elements
422
500
 
423
501
  Use polling to wait for elements that may not be immediately visible:
@@ -103,6 +103,44 @@ The returned `Element` object provides:
103
103
 
104
104
  See [Elements Reference](/v7/api/elements) for complete details.
105
105
 
106
+ ### JSON Serialization
107
+
108
+ Elements can be safely serialized using `JSON.stringify()` for logging and debugging. Circular references are automatically removed:
109
+
110
+ ```javascript
111
+ const element = await testdriver.find('login button');
112
+
113
+ // Safe to stringify - no circular reference errors
114
+ console.log(JSON.stringify(element, null, 2));
115
+
116
+ // Output includes useful debugging info:
117
+ // {
118
+ // "description": "login button",
119
+ // "coordinates": { "x": 100, "y": 200, "centerX": 150, "centerY": 225 },
120
+ // "found": true,
121
+ // "threshold": 0.01,
122
+ // "x": 100,
123
+ // "y": 200,
124
+ // "cache": {
125
+ // "hit": true,
126
+ // "strategy": "pixel-diff",
127
+ // "createdAt": "2025-12-09T10:30:00Z",
128
+ // "diffPercent": 0.0023,
129
+ // "imageUrl": "https://..."
130
+ // },
131
+ // "similarity": 0.98,
132
+ // "confidence": 0.95,
133
+ // "selector": "button#login",
134
+ // "aiResponse": "Found the blue login button..."
135
+ // }
136
+ ```
137
+
138
+ This is useful for:
139
+ - Debugging element detection issues
140
+ - Logging test execution details
141
+ - Sharing element information across processes
142
+ - Analyzing cache performance
143
+
106
144
  ## Best Practices
107
145
 
108
146
  <Check>
@@ -113,7 +113,7 @@ await testdriver.focusApplication('Google Chrome');
113
113
  ```javascript
114
114
  // Test workflow across multiple apps
115
115
  await testdriver.focusApplication('Google Chrome');
116
- const data = await testdriver.remember('the order number');
116
+ const data = await testdriver.extract('the order number');
117
117
 
118
118
  await testdriver.focusApplication('Notepad');
119
119
  await testdriver.type(data);
@@ -221,7 +221,7 @@ describe('Multi-Application Workflow', () => {
221
221
  await testdriver.focusApplication('Google Chrome');
222
222
 
223
223
  // Get data from web page
224
- const orderNumber = await testdriver.remember('the order number');
224
+ const orderNumber = await testdriver.extract('the order number');
225
225
  console.log('Order:', orderNumber);
226
226
 
227
227
  // Open Notepad
@@ -130,7 +130,7 @@ await new Promise(r => setTimeout(r, 1000));
130
130
  await new Promise(r => setTimeout(r, 1000));
131
131
 
132
132
  // Read tooltip content
133
- const tooltipText = await testdriver.remember('the tooltip text');
133
+ const tooltipText = await testdriver.extract('the tooltip text');
134
134
  console.log('Tooltip:', tooltipText);
135
135
  ```
136
136
  </Accordion>
@@ -225,7 +225,7 @@ describe('Hover Interactions', () => {
225
225
  await testdriver.assert('tooltip is displayed');
226
226
 
227
227
  // Extract tooltip text
228
- const tooltipText = await testdriver.remember('the tooltip message');
228
+ const tooltipText = await testdriver.extract('the tooltip message');
229
229
  console.log('Tooltip says:', tooltipText);
230
230
  });
231
231