testdriverai 7.3.32 → 7.3.34

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 (34) hide show
  1. package/.github/copilot-instructions.md +641 -0
  2. package/.github/skills/testdriver:assert/SKILL.md +31 -0
  3. package/.github/skills/testdriver:aws-setup/SKILL.md +1 -68
  4. package/.github/skills/testdriver:client/SKILL.md +33 -0
  5. package/.github/skills/testdriver:debugging-with-screenshots/SKILL.md +175 -45
  6. package/.github/skills/testdriver:find/SKILL.md +87 -0
  7. package/.github/skills/testdriver:parse/SKILL.md +124 -6
  8. package/.github/skills/testdriver:quickstart/SKILL.md +2 -17
  9. package/.github/skills/testdriver:reusable-code/SKILL.md +9 -0
  10. package/.github/skills/testdriver:running-tests/SKILL.md +4 -0
  11. package/.github/skills/testdriver:screenshot/SKILL.md +84 -3
  12. package/.github/skills/testdriver:scroll/SKILL.md +36 -0
  13. package/.github/skills/testdriver:testdriver/SKILL.md +194 -86
  14. package/CHANGELOG.md +8 -0
  15. package/docs/_data/examples-manifest.json +72 -64
  16. package/docs/v7/examples/ai.mdx +1 -1
  17. package/docs/v7/examples/assert.mdx +1 -1
  18. package/docs/v7/examples/chrome-extension.mdx +1 -1
  19. package/docs/v7/examples/drag-and-drop.mdx +1 -1
  20. package/docs/v7/examples/element-not-found.mdx +1 -1
  21. package/docs/v7/examples/hover-image.mdx +1 -1
  22. package/docs/v7/examples/hover-text.mdx +1 -1
  23. package/docs/v7/examples/installer.mdx +1 -1
  24. package/docs/v7/examples/launch-vscode-linux.mdx +1 -1
  25. package/docs/v7/examples/match-image.mdx +1 -1
  26. package/docs/v7/examples/press-keys.mdx +1 -1
  27. package/docs/v7/examples/scroll-keyboard.mdx +1 -1
  28. package/docs/v7/examples/scroll-until-image.mdx +1 -1
  29. package/docs/v7/examples/scroll-until-text.mdx +1 -1
  30. package/docs/v7/examples/scroll.mdx +1 -1
  31. package/docs/v7/examples/type.mdx +1 -1
  32. package/docs/v7/examples/windows-installer.mdx +1 -1
  33. package/package.json +1 -2
  34. package/sdk.js +1 -1
@@ -256,7 +256,7 @@ jobs:
256
256
  run: npm ci
257
257
 
258
258
  - name: Run Windows tests with self-hosted instances
259
- run: vitest run examples/*.test.mjs
259
+ run: npx vitest run examples/*.test.mjs
260
260
  env:
261
261
  TD_API_KEY: ${{ secrets.TD_API_KEY }}
262
262
  TD_OS: windows
@@ -393,73 +393,6 @@ You can customize the AMI to include additional software or configurations:
393
393
  **Security**: Never use the default password in production. Always rotate passwords before creating custom AMIs.
394
394
  </Warning>
395
395
 
396
- ## Custom Lifecycle Hooks
397
-
398
- You can run custom scripts after instance spawning by creating your own Vitest setup file. This is useful for:
399
-
400
- - Installing additional software via SSM before tests run
401
- - Configuring network settings or proxies
402
- - Running cleanup scripts after tests complete
403
- - Collecting logs or artifacts from instances
404
-
405
- ### Post-Spawn Hooks
406
-
407
- To run commands after the instance is ready but before the test executes, create a setup file positioned **after** `setup-aws`:
408
-
409
- ```javascript post-spawn-setup.mjs
410
- import { execSync } from 'child_process';
411
- import { beforeEach } from 'vitest';
412
-
413
- beforeEach(async (context) => {
414
- // context.ip is set by setup-aws
415
- if (!context.ip) return;
416
-
417
- console.log(`Instance ready at ${context.ip}, running post-spawn setup...`);
418
-
419
- // Run SSM commands on the instance
420
- execSync(`aws ssm send-command \
421
- --region "${process.env.AWS_REGION}" \
422
- --targets "Key=tag:Name,Values=td-*" \
423
- --document-name "AWS-RunPowerShellScript" \
424
- --parameters 'commands=["choco install my-software -y"]'`);
425
- });
426
- ```
427
-
428
- ```javascript vitest.config.mjs
429
- setupFiles: [
430
- 'testdriverai/vitest/setup',
431
- 'testdriverai/vitest/setup-aws', // Instance spawns here
432
- './post-spawn-setup.mjs' // Your hooks run AFTER instance is ready
433
- ]
434
- ```
435
-
436
- <Note>
437
- Vitest executes setup files in array order. By positioning your file after `setup-aws`, the `context.ip` is already available in your `beforeEach` hook.
438
- </Note>
439
-
440
- ### Post-Test Cleanup
441
-
442
- To run cleanup after each test completes (while the instance is still running):
443
-
444
- ```javascript post-spawn-setup.mjs
445
- import { execSync } from 'child_process';
446
- import { beforeEach, afterEach } from 'vitest';
447
-
448
- beforeEach(async (context) => {
449
- if (!context.ip) return;
450
- // ... post-spawn setup
451
- });
452
-
453
- afterEach(async (context) => {
454
- if (!context.ip) return;
455
-
456
- console.log('Running post-test cleanup...');
457
- execSync('./scripts/collect-logs.sh', {
458
- env: { ...process.env, INSTANCE_IP: context.ip }
459
- });
460
- });
461
- ```
462
-
463
396
  ## Security Best Practices
464
397
 
465
398
  ### Network Security
@@ -44,9 +44,37 @@ const testdriver = new TestDriver(apiKey, options)
44
44
  Enable or disable console logging
45
45
  </ParamField>
46
46
 
47
+ <ParamField path="autoScreenshots" type="boolean" default="true">
48
+ Automatically capture screenshots before and after each command. Screenshots are saved to `.testdriver/screenshots/<test>/` with descriptive filenames that include the line number and action name. Format: `<seq>-<action>-<phase>-L<line>-<description>.png`
49
+ </ParamField>
50
+
47
51
  <ParamField path="environment" type="object">
48
52
  Additional environment variables to pass to the sandbox
49
53
  </ParamField>
54
+
55
+ <ParamField path="ai" type="object">
56
+ Global AI sampling configuration. Controls how the AI model generates responses for `find()` verification and `assert()` calls. Can be overridden per call.
57
+
58
+ <Expandable title="properties">
59
+ <ParamField path="temperature" type="number">
60
+ Controls randomness in AI responses. `0` = deterministic (best for verification), higher values = more creative. Default: `0` for find verification, model default for assert.
61
+ </ParamField>
62
+
63
+ <ParamField path="top" type="object">
64
+ Nucleus and top-k sampling parameters
65
+
66
+ <Expandable title="properties">
67
+ <ParamField path="p" type="number">
68
+ Top-P (nucleus sampling). Limits token choices to the smallest set whose cumulative probability exceeds P. Lower values = more focused responses. Range: 0-1.
69
+ </ParamField>
70
+
71
+ <ParamField path="k" type="number">
72
+ Top-K sampling. Limits token choices to the top K most likely tokens. `1` = always pick the most likely token. `0` = disabled (consider all tokens).
73
+ </ParamField>
74
+ </Expandable>
75
+ </ParamField>
76
+ </Expandable>
77
+ </ParamField>
50
78
  </Expandable>
51
79
  </ParamField>
52
80
 
@@ -63,6 +91,11 @@ const testdriver = new TestDriver({
63
91
  analytics: true
64
92
  });
65
93
 
94
+ // With AI config for stricter verification
95
+ const testdriver = new TestDriver({
96
+ ai: { temperature: 0, top: { p: 0.9, k: 40 } }
97
+ });
98
+
66
99
  // Or pass API key explicitly
67
100
  const testdriver = new TestDriver('your-api-key', {
68
101
  os: 'windows'
@@ -8,20 +8,60 @@ description: View and analyze saved screenshots using MCP commands for test debu
8
8
 
9
9
  TestDriver MCP provides powerful commands to view and analyze screenshots saved during test execution. This enables rapid debugging, test development, and comparison workflows without manually opening image files.
10
10
 
11
+ <Note>
12
+ **Automatic Screenshots (Default: Enabled)**: TestDriver automatically captures screenshots before and after every command. Screenshots are named with the line number and action, making it easy to trace exactly which line of code produced each screenshot. For example: `001-click-before-L42-submit-button.png`
13
+ </Note>
14
+
11
15
  ## MCP Commands
12
16
 
13
17
  ### list_local_screenshots
14
18
 
15
- List all screenshots saved in the `.testdriver/screenshots/` directory:
19
+ List and filter screenshots saved in the `.testdriver/screenshots/` directory:
16
20
 
17
21
  ```
18
22
  list_local_screenshots()
19
23
  ```
20
24
 
21
- **Optional Parameters:**
25
+ **Filter Parameters:**
22
26
 
23
27
  <ParamField path="directory" type="string" optional>
24
- Filter screenshots by subdirectory (e.g., specific test file). If omitted, lists all screenshots.
28
+ Filter screenshots by test file or subdirectory (e.g., "login.test", "mcp-screenshots"). If omitted, lists all screenshots.
29
+ </ParamField>
30
+
31
+ <ParamField path="line" type="number" optional>
32
+ Filter by exact line number from test file (e.g., 42 matches L42 in filename).
33
+ </ParamField>
34
+
35
+ <ParamField path="lineRange" type="object" optional>
36
+ Filter by line number range. Example: `{ start: 10, end: 20 }` matches screenshots from lines 10-20.
37
+ </ParamField>
38
+
39
+ <ParamField path="action" type="string" optional>
40
+ Filter by action type: `click`, `find`, `type`, `assert`, `provision`, `scroll`, `hover`, etc.
41
+ </ParamField>
42
+
43
+ <ParamField path="phase" type="string" optional>
44
+ Filter by phase: `"before"` (state before action) or `"after"` (state after action).
45
+ </ParamField>
46
+
47
+ <ParamField path="pattern" type="string" optional>
48
+ Regex pattern to match against filename. Example: `"login|signin"` or `"button.*click"`.
49
+ </ParamField>
50
+
51
+ <ParamField path="sequence" type="number" optional>
52
+ Filter by exact sequence number.
53
+ </ParamField>
54
+
55
+ <ParamField path="sequenceRange" type="object" optional>
56
+ Filter by sequence range. Example: `{ start: 1, end: 10 }` matches first 10 screenshots.
57
+ </ParamField>
58
+
59
+ <ParamField path="limit" type="number" optional>
60
+ Maximum number of results to return (default: 50).
61
+ </ParamField>
62
+
63
+ <ParamField path="sortBy" type="string" optional>
64
+ Sort results by: `"modified"` (newest first, default), `"sequence"` (execution order), or `"line"` (line number).
25
65
  </ParamField>
26
66
 
27
67
  **Returns:**
@@ -29,24 +69,31 @@ list_local_screenshots()
29
69
  Array of screenshot metadata including:
30
70
  - `path` - Full absolute path to the screenshot file
31
71
  - `relativePath` - Path relative to `.testdriver/screenshots/`
32
- - `testFile` - The test file that created this screenshot
33
- - `filename` - Screenshot filename
34
- - `size` - File size in bytes
72
+ - `name` - Screenshot filename
73
+ - `sizeBytes` - File size in bytes
35
74
  - `modified` - Last modification timestamp
36
- - `created` - Creation timestamp
75
+ - `sequence` - Sequential number (from auto-screenshots)
76
+ - `action` - Action type (click, find, etc.)
77
+ - `phase` - Before/after phase
78
+ - `lineNumber` - Line number from test file
79
+ - `description` - Element or action description
37
80
 
38
- **Example Response:**
81
+ **Example Responses:**
39
82
 
40
83
  ```json
84
+ // Basic listing
41
85
  [
42
86
  {
43
- "path": "/Users/user/project/.testdriver/screenshots/login.test/screenshot-1737633600000.png",
44
- "relativePath": "login.test/screenshot-1737633600000.png",
45
- "testFile": "login.test",
46
- "filename": "screenshot-1737633600000.png",
47
- "size": 145632,
87
+ "path": "/Users/user/project/.testdriver/screenshots/login.test/001-click-before-L42-submit-button.png",
88
+ "relativePath": "login.test/001-click-before-L42-submit-button.png",
89
+ "name": "001-click-before-L42-submit-button.png",
90
+ "sizeBytes": 145632,
48
91
  "modified": "2026-01-23T10:00:00.000Z",
49
- "created": "2026-01-23T10:00:00.000Z"
92
+ "sequence": 1,
93
+ "action": "click",
94
+ "phase": "before",
95
+ "lineNumber": 42,
96
+ "description": "submit-button"
50
97
  }
51
98
  ]
52
99
  ```
@@ -75,34 +122,85 @@ view_local_screenshot({ path: "/full/path/to/screenshot.png" })
75
122
 
76
123
  ### Test Debugging After Failures
77
124
 
78
- When a test fails, view the saved screenshots to understand what went wrong:
125
+ When a test fails, use powerful filtering to quickly find relevant screenshots:
79
126
 
80
- 1. **List screenshots from the failed test:**
127
+ **1. Find screenshots at the failing line:**
81
128
 
82
129
  ```
83
- list_local_screenshots({ directory: "login.test" })
130
+ // If test failed at line 42
131
+ list_local_screenshots({ line: 42 })
132
+
133
+ // View before and after states at that line
134
+ view_local_screenshot({ path: ".testdriver/screenshots/login.test/005-click-before-L42-submit-button.png" })
135
+ view_local_screenshot({ path: ".testdriver/screenshots/login.test/006-click-after-L42-submit-button.png" })
84
136
  ```
85
137
 
86
- 2. **View screenshots in chronological order** (sorted by creation time) to trace the test execution:
138
+ **2. See what happened leading up to the failure:**
87
139
 
88
140
  ```
89
- view_local_screenshot({ path: ".testdriver/screenshots/login.test/screenshot-1737633600000.png" })
90
- view_local_screenshot({ path: ".testdriver/screenshots/login.test/screenshot-1737633610000.png" })
91
- view_local_screenshot({ path: ".testdriver/screenshots/login.test/screenshot-1737633620000.png" })
141
+ // Get screenshots from lines 35-45 to see context
142
+ list_local_screenshots({ directory: "login.test", lineRange: { start: 35, end: 45 } })
92
143
  ```
93
144
 
94
- 3. **Analyze the UI state** at each step to identify where things went wrong
145
+ **3. Find all assertion screenshots:**
146
+
147
+ ```
148
+ // See what the screen looked like during assertions
149
+ list_local_screenshots({ action: "assert" })
150
+ ```
151
+
152
+ **4. View the final state before failure:**
153
+
154
+ ```
155
+ // Get the last 5 screenshots in execution order
156
+ list_local_screenshots({ directory: "login.test", sortBy: "sequence", limit: 5 })
157
+ ```
95
158
 
96
- 4. **Compare expected vs actual** - if you added descriptive filenames with `screenshot("step-name")`, you can easily identify key moments
159
+ ### Finding Specific Actions
160
+
161
+ When debugging element interactions:
162
+
163
+ ```
164
+ // Find all click actions
165
+ list_local_screenshots({ action: "click" })
166
+
167
+ // Find what the screen looked like BEFORE each click
168
+ list_local_screenshots({ action: "click", phase: "before" })
169
+
170
+ // Find screenshots related to a specific element using regex
171
+ list_local_screenshots({ pattern: "submit|button" })
172
+
173
+ // Find all type actions (for form filling issues)
174
+ list_local_screenshots({ action: "type" })
175
+ ```
176
+
177
+ ### Understanding Test Flow
178
+
179
+ View screenshots in execution order to trace test behavior:
180
+
181
+ ```
182
+ // Get screenshots in execution order
183
+ list_local_screenshots({ directory: "checkout.test", sortBy: "sequence" })
184
+
185
+ // Get just the first 10 actions
186
+ list_local_screenshots({ sequenceRange: { start: 1, end: 10 }, sortBy: "sequence" })
187
+
188
+ // Get just the last 10 actions
189
+ list_local_screenshots({ directory: "checkout.test", sortBy: "sequence", limit: 10 })
190
+ ```
97
191
 
98
192
  ### Interactive Test Development
99
193
 
100
194
  While building tests using MCP tools, view screenshots to verify your test logic:
101
195
 
102
- 1. **After a test run**, list screenshots to see what was captured:
196
+ 1. **After a test run**, filter screenshots to see specific actions:
103
197
 
104
198
  ```
105
- list_local_screenshots()
199
+ // See all assertions
200
+ list_local_screenshots({ action: "assert" })
201
+
202
+ // See what happened at a specific line you're debugging
203
+ list_local_screenshots({ line: 25 })
106
204
  ```
107
205
 
108
206
  2. **Review key points** in the test execution:
@@ -117,21 +215,31 @@ view_local_screenshot({ path: ".testdriver/screenshots/my-test.test/after-login.
117
215
 
118
216
  ### Comparison and Analysis
119
217
 
120
- Compare screenshots across multiple test runs to identify flaky behavior or UI changes:
218
+ Compare screenshots to identify issues:
121
219
 
122
- 1. **List screenshots from multiple test runs** (note: each test run clears the folder, so copy screenshots elsewhere for comparison if needed)
220
+ **Using phase filtering for before/after comparison:**
123
221
 
124
- 2. **View screenshots side-by-side** to spot differences:
222
+ ```
223
+ // See state before all clicks
224
+ list_local_screenshots({ action: "click", phase: "before" })
125
225
 
226
+ // See state after all clicks
227
+ list_local_screenshots({ action: "click", phase: "after" })
126
228
  ```
127
- view_local_screenshot({ path: ".testdriver/screenshots/test.test/before-click.png" })
128
- // Analyze first run
129
229
 
130
- view_local_screenshot({ path: ".testdriver/screenshots-backup/test.test/before-click.png" })
131
- // Compare with previous run
230
+ **Using line-based debugging:**
231
+
232
+ ```
233
+ // Something went wrong around line 50
234
+ list_local_screenshots({ lineRange: { start: 45, end: 55 } })
132
235
  ```
133
236
 
134
- 3. **Identify timing issues** - if element positions or states vary between runs, you may have timing/race condition issues
237
+ **Using regex patterns:**
238
+
239
+ ```
240
+ // Find screenshots related to login functionality
241
+ list_local_screenshots({ pattern: "login|signin|email|password" })
242
+ ```
135
243
 
136
244
  ## Best Practices
137
245
 
@@ -188,20 +296,37 @@ Understanding the directory structure helps with efficient screenshot viewing:
188
296
  .testdriver/
189
297
  screenshots/
190
298
  login.test/ # Test file name (without .mjs extension)
191
- screenshot-1737633600000.png # Auto-generated timestamp filename
192
- initial-state.png # Custom descriptive filename
193
- after-click.png
299
+ 001-find-before-L15-email-input.png # Auto: before find() at line 15
300
+ 002-find-after-L15-email-input.png # Auto: after find() at line 15
301
+ 003-click-before-L16-email-input.png # Auto: before click() at line 16
302
+ 004-click-after-L16-email-input.png # Auto: after click() at line 16
303
+ login-complete.png # Manual: screenshot("login-complete")
194
304
  checkout.test/
195
- screenshot-1737633700000.png
196
- product-page.png
197
- profile.test/
198
- screenshot-1737633800000.png
305
+ 001-find-before-L12-add-to-cart.png
306
+ 002-find-after-L12-add-to-cart.png
307
+ ...
199
308
  ```
200
309
 
310
+ ### Automatic Screenshot Naming Format
311
+
312
+ `<seq>-<action>-<phase>-L<line>-<description>.png`
313
+
314
+ | Component | Description | Example |
315
+ |-----------|-------------|---------|
316
+ | `seq` | Sequential number | `001`, `002` |
317
+ | `action` | Command name | `click`, `type`, `find` |
318
+ | `phase` | Before, after, or error | `before`, `after`, `error` |
319
+ | `L<line>` | Line number from test file | `L42` |
320
+ | `description` | Element/action description | `submit-button` |
321
+
322
+ ### Key Points
323
+
201
324
  - Each test file gets its own subdirectory
202
- - Filenames are either timestamps (default) or custom names you provide
325
+ - Automatic screenshots include line numbers for easy tracing
326
+ - Manual `screenshot()` calls use custom names you provide
203
327
  - Folders are cleared at the start of each test run
204
328
  - All screenshots are PNG format
329
+ - Disable automatic screenshots with `autoScreenshots: false` if needed
205
330
 
206
331
  ## Integration with Test Development
207
332
 
@@ -248,11 +373,16 @@ When tests fail or behave unexpectedly:
248
373
  </Accordion>
249
374
 
250
375
  <Accordion title="Too many screenshots">
251
- If you have hundreds of screenshots making it hard to find what you need:
376
+ If you have hundreds of screenshots making it hard to find what you need, use filtering:
252
377
 
253
- - Use the `directory` parameter to filter by test file
254
- - Consider adding more descriptive filenames in your tests
255
- - Clean up old screenshot folders: `rm -rf .testdriver/screenshots/*`
378
+ - Filter by test file: `list_local_screenshots({ directory: "my-test.test" })`
379
+ - Filter by line number: `list_local_screenshots({ line: 42 })` or `list_local_screenshots({ lineRange: { start: 40, end: 50 } })`
380
+ - Filter by action: `list_local_screenshots({ action: "click" })`
381
+ - Filter by phase: `list_local_screenshots({ phase: "before" })`
382
+ - Use regex: `list_local_screenshots({ pattern: "submit|login" })`
383
+ - Limit results: `list_local_screenshots({ limit: 10 })`
384
+ - Sort by line: `list_local_screenshots({ sortBy: "line" })`
385
+ - Clean up old folders: `rm -rf .testdriver/screenshots/*`
256
386
  </Accordion>
257
387
 
258
388
  <Accordion title="Screenshots from old test runs">
@@ -52,6 +52,30 @@ const element = await testdriver.find(description, options)
52
52
  <ParamField path="zoom" type="boolean" default={false}>
53
53
  Enable two-phase zoom mode for better precision in crowded UIs with many similar elements.
54
54
  </ParamField>
55
+
56
+ <ParamField path="ai" type="object">
57
+ AI sampling configuration for this find call (overrides global `ai` config from constructor).
58
+
59
+ <Expandable title="properties">
60
+ <ParamField path="temperature" type="number">
61
+ Controls randomness. `0` = deterministic. Default: `0` for find verification.
62
+ </ParamField>
63
+
64
+ <ParamField path="top" type="object">
65
+ Sampling parameters
66
+
67
+ <Expandable title="properties">
68
+ <ParamField path="p" type="number">
69
+ Top-P (nucleus sampling). Range: 0-1.
70
+ </ParamField>
71
+
72
+ <ParamField path="k" type="number">
73
+ Top-K sampling. `1` = most deterministic.
74
+ </ParamField>
75
+ </Expandable>
76
+ </ParamField>
77
+ </Expandable>
78
+ </ParamField>
55
79
  </Expandable>
56
80
  </ParamField>
57
81
 
@@ -220,6 +244,69 @@ This is useful for:
220
244
  ```
221
245
  </Check>
222
246
 
247
+ ## Confidence Threshold
248
+
249
+ Require a minimum AI confidence score for element matches. If the confidence is below the threshold, `find()` treats the result as not found:
250
+
251
+ ```javascript
252
+ // Require at least 90% confidence
253
+ const element = await testdriver.find('submit button', { confidence: 0.9 });
254
+
255
+ if (!element.found()) {
256
+ // AI found something but wasn't confident enough
257
+ throw new Error('Could not confidently locate submit button');
258
+ }
259
+
260
+ await element.click();
261
+ ```
262
+
263
+ This is useful for:
264
+ - Critical test steps where an incorrect click could cause cascading failures
265
+ - Distinguishing between similar elements (e.g., multiple buttons)
266
+ - Failing fast when the UI has changed unexpectedly
267
+
268
+ ```javascript
269
+ // Combine with timeout for robust polling with confidence gate
270
+ const element = await testdriver.find('success notification', {
271
+ confidence: 0.85,
272
+ timeout: 15000,
273
+ });
274
+ ```
275
+
276
+ <Tip>
277
+ The `confidence` value is a float between 0 and 1 (e.g., `0.9` = 90%). The AI returns its confidence with each find result, which you can also read from `element.confidence` after a successful find.
278
+ </Tip>
279
+ ## Element Type
280
+
281
+ Use the `type` option to hint what kind of element you're looking for. This wraps your description into a more specific prompt for the AI, improving match accuracy — especially when users provide short or ambiguous descriptions.
282
+
283
+ ```javascript
284
+ // Find text on the page
285
+ const label = await testdriver.find('Sign In', { type: 'text' });
286
+ // AI prompt becomes: The text "Sign In"
287
+
288
+ // Find an image
289
+ const logo = await testdriver.find('company logo', { type: 'image' });
290
+ // AI prompt becomes: The image "company logo"
291
+
292
+ // Find a UI element (button, input, checkbox, etc.)
293
+ const btn = await testdriver.find('Submit', { type: 'ui' });
294
+ // AI prompt becomes: The UI element "Submit"
295
+
296
+ // No wrapping — same as omitting the option
297
+ const el = await testdriver.find('the blue submit button', { type: 'any' });
298
+ ```
299
+
300
+ | Type | Prompt sent to AI |
301
+ |------|----|
302
+ | `"text"` | `The text "..."` |
303
+ | `"image"` | `The image "..."` |
304
+ | `"ui"` | `The UI element "..."` |
305
+ | `"any"` | Original description (no wrapping) |
306
+
307
+ <Tip>
308
+ This is particularly useful for short descriptions like `"Submit"` or `"Login"` where the AI may not know whether to look for a button, a link, or visible text. Specifying `type` removes the ambiguity.
309
+ </Tip>
223
310
  ## Polling for Dynamic Elements
224
311
 
225
312
  For elements that may not be immediately visible, use the `timeout` option to automatically poll: