testdriverai 7.3.12 → 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 +4 -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 +126 -18
  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,293 @@
1
+ ---
2
+ name: testdriver:focus-application
3
+ description: Bring an application window to the foreground
4
+ ---
5
+ <!-- Generated from focus-application.mdx. DO NOT EDIT. -->
6
+
7
+ ## Overview
8
+
9
+ Bring a specific application window to the foreground and make it the active window for interactions.
10
+
11
+ ## Syntax
12
+
13
+ ```javascript
14
+ await testdriver.focusApplication(name)
15
+ ```
16
+
17
+ ## Parameters
18
+
19
+ <ParamField path="name" type="string" required>
20
+ Application name (e.g., `'Google Chrome'`, `'Microsoft Edge'`, `'Notepad'`)
21
+ </ParamField>
22
+
23
+ ## Returns
24
+
25
+ `Promise<string>` - Result message
26
+
27
+ ## Examples
28
+
29
+ ### Common Applications
30
+
31
+ ```javascript
32
+ // Focus Chrome browser
33
+ await testdriver.focusApplication('Google Chrome');
34
+
35
+ // Focus Edge browser
36
+ await testdriver.focusApplication('Microsoft Edge');
37
+
38
+ // Focus Notepad
39
+ await testdriver.focusApplication('Notepad');
40
+
41
+ // Focus File Explorer
42
+ await testdriver.focusApplication('File Explorer');
43
+
44
+ // Focus Visual Studio Code
45
+ await testdriver.focusApplication('Visual Studio Code');
46
+ ```
47
+
48
+ ### After Opening Applications
49
+
50
+ ```javascript
51
+ // Open Chrome and focus it
52
+ await testdriver.exec('pwsh', `
53
+ Start-Process "C:/Program Files/Google/Chrome/Application/chrome.exe" -ArgumentList "https://example.com"
54
+ `, 5000);
55
+
56
+ await new Promise(r => setTimeout(r, 2000)); // Wait for launch
57
+
58
+ // Focus the Chrome window
59
+ await testdriver.focusApplication('Google Chrome');
60
+ ```
61
+
62
+ ## Best Practices
63
+
64
+ <Check>
65
+ **Focus before UI interactions**
66
+
67
+ Always focus the target application before interacting with its UI:
68
+
69
+ ```javascript
70
+ await testdriver.focusApplication('Google Chrome');
71
+
72
+ const button = await testdriver.find('submit button');
73
+ await button.click();
74
+ ```
75
+ </Check>
76
+
77
+ <Check>
78
+ **Wait after launching apps**
79
+
80
+ Give applications time to open before focusing:
81
+
82
+ ```javascript
83
+ await testdriver.exec('pwsh', 'Start-Process notepad', 5000);
84
+ await new Promise(r => setTimeout(r, 1000)); // Wait for launch
85
+ await testdriver.focusApplication('Notepad');
86
+ ```
87
+ </Check>
88
+
89
+ <Check>
90
+ **Use exact application names**
91
+
92
+ ```javascript
93
+ // ✅ Correct
94
+ await testdriver.focusApplication('Google Chrome');
95
+
96
+ // ❌ May not work
97
+ await testdriver.focusApplication('Chrome');
98
+ await testdriver.focusApplication('chrome.exe');
99
+ ```
100
+ </Check>
101
+
102
+ <Warning>
103
+ **Application must be running**
104
+
105
+ The application must already be running. `focusApplication()` won't launch applications, only bring existing windows to the foreground.
106
+ </Warning>
107
+
108
+ ## Use Cases
109
+
110
+ <AccordionGroup>
111
+ <Accordion title="Multi-Application Testing">
112
+ ```javascript
113
+ // Test workflow across multiple apps
114
+ await testdriver.focusApplication('Google Chrome');
115
+ const data = await testdriver.extract('the order number');
116
+
117
+ await testdriver.focusApplication('Notepad');
118
+ await testdriver.type(data);
119
+ await testdriver.pressKeys(['ctrl', 's']);
120
+
121
+ await testdriver.focusApplication('Google Chrome');
122
+ const nextButton = await testdriver.find('next button');
123
+ await nextButton.click();
124
+ ```
125
+ </Accordion>
126
+
127
+ <Accordion title="Browser Switching">
128
+ ```javascript
129
+ // Compare behavior in different browsers
130
+ await testdriver.focusApplication('Google Chrome');
131
+ await testdriver.assert('page loaded correctly in Chrome');
132
+
133
+ await testdriver.focusApplication('Microsoft Edge');
134
+ await testdriver.assert('page loaded correctly in Edge');
135
+ ```
136
+ </Accordion>
137
+
138
+ <Accordion title="Desktop Application Testing">
139
+ ```javascript
140
+ // Launch and focus desktop app
141
+ await testdriver.exec('pwsh', 'Start-Process notepad', 5000);
142
+ await new Promise(r => setTimeout(r, 1000));
143
+
144
+ await testdriver.focusApplication('Notepad');
145
+ await testdriver.type('Test content');
146
+ ```
147
+ </Accordion>
148
+
149
+ <Accordion title="Window Management">
150
+ ```javascript
151
+ // Show desktop first
152
+ await testdriver.pressKeys(['winleft', 'd']);
153
+
154
+ // Click desktop icon
155
+ const icon = await testdriver.find('Chrome icon on desktop');
156
+ await icon.click();
157
+
158
+ await new Promise(r => setTimeout(r, 2000));
159
+
160
+ // Focus the opened window
161
+ await testdriver.focusApplication('Google Chrome');
162
+ ```
163
+ </Accordion>
164
+ </AccordionGroup>
165
+
166
+ ## Common Application Names
167
+
168
+ ### Browsers
169
+ - `'Google Chrome'`
170
+ - `'Microsoft Edge'`
171
+ - `'Mozilla Firefox'`
172
+ - `'Safari'` (macOS)
173
+
174
+ ### Office Applications
175
+ - `'Microsoft Word'`
176
+ - `'Microsoft Excel'`
177
+ - `'Microsoft PowerPoint'`
178
+ - `'Microsoft Outlook'`
179
+
180
+ ### Development Tools
181
+ - `'Visual Studio Code'`
182
+ - `'Visual Studio'`
183
+ - `'IntelliJ IDEA'`
184
+ - `'Sublime Text'`
185
+
186
+ ### System Applications
187
+ - `'Notepad'`
188
+ - `'File Explorer'`
189
+ - `'Command Prompt'`
190
+ - `'Windows PowerShell'`
191
+ - `'Task Manager'`
192
+
193
+ ### Communication
194
+ - `'Microsoft Teams'`
195
+ - `'Slack'`
196
+ - `'Discord'`
197
+ - `'Zoom'`
198
+
199
+ ## Complete Example
200
+
201
+ ```javascript
202
+ import { beforeAll, afterAll, describe, it } from 'vitest';
203
+ import TestDriver from 'testdriverai';
204
+
205
+ describe('Multi-Application Workflow', () => {
206
+ let testdriver;
207
+
208
+ beforeAll(async () => {
209
+ client = new TestDriver(process.env.TD_API_KEY);
210
+ await testdriver.auth();
211
+ await testdriver.connect();
212
+ });
213
+
214
+ afterAll(async () => {
215
+ await testdriver.disconnect();
216
+ });
217
+
218
+ it('should work across multiple applications', async () => {
219
+ // Start in browser
220
+ await testdriver.focusApplication('Google Chrome');
221
+
222
+ // Get data from web page
223
+ const orderNumber = await testdriver.extract('the order number');
224
+ console.log('Order:', orderNumber);
225
+
226
+ // Open Notepad
227
+ await testdriver.exec('pwsh', 'Start-Process notepad', 5000);
228
+ await new Promise(r => setTimeout(r, 1500));
229
+
230
+ // Focus Notepad and save data
231
+ await testdriver.focusApplication('Notepad');
232
+ await testdriver.type(`Order Number: ${orderNumber}`);
233
+ await testdriver.type('\n');
234
+ await testdriver.type(`Date: ${new Date().toISOString()}`);
235
+
236
+ // Save file
237
+ await testdriver.pressKeys(['ctrl', 's']);
238
+ await new Promise(r => setTimeout(r, 500));
239
+
240
+ await testdriver.type('C:\\order-info.txt');
241
+ await testdriver.pressKeys(['enter']);
242
+
243
+ // Return to browser
244
+ await testdriver.focusApplication('Google Chrome');
245
+
246
+ const confirmButton = await testdriver.find('confirm order button');
247
+ await confirmButton.click();
248
+
249
+ await testdriver.assert('order confirmed');
250
+ });
251
+
252
+ it('should switch between browser tabs', async () => {
253
+ await testdriver.focusApplication('Google Chrome');
254
+
255
+ // Open new tab
256
+ await testdriver.pressKeys(['ctrl', 't']);
257
+ await new Promise(r => setTimeout(r, 500));
258
+
259
+ // Navigate to URL
260
+ await testdriver.pressKeys(['ctrl', 'l']);
261
+ await testdriver.type('https://example.com');
262
+ await testdriver.pressKeys(['enter']);
263
+
264
+ await new Promise(r => setTimeout(r, 2000));
265
+
266
+ // Ensure Chrome is still focused
267
+ await testdriver.focusApplication('Google Chrome');
268
+
269
+ await testdriver.assert('example.com page is loaded');
270
+ });
271
+
272
+ it('should handle dialog boxes', async () => {
273
+ await testdriver.focusApplication('Google Chrome');
274
+
275
+ const deleteButton = await testdriver.find('delete account button');
276
+ await deleteButton.click();
277
+
278
+ await new Promise(r => setTimeout(r, 500));
279
+
280
+ // Dialog appears - make sure it's focused
281
+ await testdriver.focusApplication('Google Chrome');
282
+
283
+ const confirmBtn = await testdriver.find('confirm deletion button');
284
+ await confirmBtn.click();
285
+ });
286
+ });
287
+ ```
288
+
289
+ ## Related Methods
290
+
291
+ - [`exec()`](/v7/exec) - Launch applications with PowerShell
292
+ - [`pressKeys()`](/v7/press-keys) - Use Alt+Tab to switch windows
293
+ - [`find()`](/v7/find) - Locate elements in the focused window
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: testdriver:generating-tests
3
+ description: Use AI coding agents and exploration mode to generate TestDriver tests
4
+ ---
5
+ <!-- Generated from generating-tests.mdx. DO NOT EDIT. -->
6
+
7
+ ## Instructions for Coding Agents
8
+
9
+ We recommend starting with [our quickstart](./quickstart) then supplying your coding agent with our agent instructions file.
10
+
11
+ <Card title="TestDriver Agent Instructions" icon="link" arrow="true" horizontal href="https://github.com/testdriverai/testdriverai/blob/main/ai/agents/testdriver.md?plain=1">
12
+ Copy the current version of our agent instructions to provide your coding agent with up-to-date instructions on how to generate TestDriver tests.
13
+ </Card>
14
+
15
+ Then, you can prompt your coding agent to generate tests. Here is an example prompt:
16
+
17
+ ```md
18
+ Make me a TestDriver test that does the following steps:
19
+
20
+ Navigate to practicetestautomation.com
21
+ Type username student into Username field
22
+ Type password Password123 into Password field
23
+ Push Submit button
24
+ Verify new page contains expected text 'logged in'
25
+ ```
26
+
27
+ ## AI Exploration Mode
28
+
29
+ Within a test, the `ai()` method lets TestDriver autonomously figure out how to accomplish a task. It's useful for dynamic or unpredictable UIs where explicit actions may be difficult to define.
30
+
31
+ ```javascript
32
+ // Handle dynamic or unpredictable UI
33
+ await testdriver.ai('dismiss any popups or modals that appear');
34
+ ```
35
+
36
+ <Info>Explicit commands are preferred for production tests, as they are cheaper, faster, and more reliable.</Info>
@@ -0,0 +1,278 @@
1
+ ---
2
+ name: testdriver:hover
3
+ description: Hover over elements or coordinates
4
+ ---
5
+ <!-- Generated from hover.mdx. DO NOT EDIT. -->
6
+
7
+ ## Overview
8
+
9
+ Move the mouse cursor over elements or specific coordinates without clicking, useful for revealing tooltips, dropdowns, and hover effects.
10
+
11
+ ## Element Hover
12
+
13
+ Hover over a located element.
14
+
15
+ ### Syntax
16
+
17
+ ```javascript
18
+ await element.hover()
19
+ ```
20
+
21
+ ### Returns
22
+
23
+ `Promise<void>`
24
+
25
+ ### Examples
26
+
27
+ ```javascript
28
+ // Find and hover
29
+ const tooltip = await testdriver.find('info icon');
30
+ await tooltip.hover();
31
+
32
+ // Wait to see tooltip
33
+ await new Promise(r => setTimeout(r, 1000));
34
+
35
+ // Hover over menu to reveal submenu
36
+ const menu = await testdriver.find('Products menu');
37
+ await menu.hover();
38
+
39
+ const submenu = await testdriver.find('Laptops submenu item');
40
+ await submenu.click();
41
+ ```
42
+
43
+ ## Coordinate Hover
44
+
45
+ Hover at specific screen coordinates.
46
+
47
+ ### Syntax
48
+
49
+ ```javascript
50
+ await testdriver.hover(x, y)
51
+ ```
52
+
53
+ ### Parameters
54
+
55
+ <ParamField path="x" type="number" required>
56
+ X coordinate
57
+ </ParamField>
58
+
59
+ <ParamField path="y" type="number" required>
60
+ Y coordinate
61
+ </ParamField>
62
+
63
+ ### Returns
64
+
65
+ `Promise<void>`
66
+
67
+ ### Examples
68
+
69
+ ```javascript
70
+ // Hover at coordinates
71
+ await testdriver.hover(500, 300);
72
+
73
+ // Hover and wait
74
+ await testdriver.hover(500, 300);
75
+ await new Promise(r => setTimeout(r, 1000));
76
+ ```
77
+
78
+ ## Best Practices
79
+
80
+ <Check>
81
+ **Prefer element hover over coordinates**
82
+
83
+ ```javascript
84
+ // ✅ Preferred
85
+ const icon = await testdriver.find('info icon');
86
+ await icon.hover();
87
+
88
+ // ❌ Avoid
89
+ await testdriver.hover(500, 300);
90
+ ```
91
+ </Check>
92
+
93
+ <Check>
94
+ **Wait after hovering for dynamic content**
95
+
96
+ ```javascript
97
+ const menuItem = await testdriver.find('Settings menu');
98
+ await menuItem.hover();
99
+
100
+ // Wait for submenu to appear
101
+ await new Promise(r => setTimeout(r, 500));
102
+
103
+ const subItem = await testdriver.find('Profile submenu');
104
+ await subItem.click();
105
+ ```
106
+ </Check>
107
+
108
+ <Check>
109
+ **Verify element was found before hovering**
110
+
111
+ ```javascript
112
+ const element = await testdriver.find('tooltip trigger');
113
+ if (!element.found()) {
114
+ throw new Error('Element not found');
115
+ }
116
+ await element.hover();
117
+ ```
118
+ </Check>
119
+
120
+ ## Use Cases
121
+
122
+ <AccordionGroup>
123
+ <Accordion title="Tooltips">
124
+ ```javascript
125
+ // Hover to show tooltip
126
+ const icon = await testdriver.find('help icon');
127
+ await icon.hover();
128
+
129
+ await new Promise(r => setTimeout(r, 1000));
130
+
131
+ // Read tooltip content
132
+ const tooltipText = await testdriver.extract('the tooltip text');
133
+ console.log('Tooltip:', tooltipText);
134
+ ```
135
+ </Accordion>
136
+
137
+ <Accordion title="Dropdown Menus">
138
+ ```javascript
139
+ // Hover to reveal dropdown
140
+ const menuItem = await testdriver.find('Products menu item');
141
+ await menuItem.hover();
142
+
143
+ // Wait for dropdown animation
144
+ await new Promise(r => setTimeout(r, 500));
145
+
146
+ // Click submenu option
147
+ const category = await testdriver.find('Electronics category');
148
+ await category.click();
149
+ ```
150
+ </Accordion>
151
+
152
+ <Accordion title="Image Previews">
153
+ ```javascript
154
+ // Hover over thumbnail to see preview
155
+ const thumbnail = await testdriver.find('product thumbnail');
156
+ await thumbnail.hover();
157
+
158
+ await new Promise(r => setTimeout(r, 800));
159
+
160
+ // Verify preview appears
161
+ await testdriver.assert('product preview is displayed');
162
+ ```
163
+ </Accordion>
164
+
165
+ <Accordion title="Hover Effects">
166
+ ```javascript
167
+ // Test hover state styling
168
+ const button = await testdriver.find('call to action button');
169
+ await button.hover();
170
+
171
+ await new Promise(r => setTimeout(r, 500));
172
+
173
+ // Verify hover effect
174
+ await testdriver.assert('button background changed to blue');
175
+ ```
176
+ </Accordion>
177
+
178
+ <Accordion title="Drag and Drop">
179
+ ```javascript
180
+ // Use hover in drag and drop
181
+ const item = await testdriver.find('draggable item');
182
+ await item.mouseDown();
183
+
184
+ // Hover over drop zone
185
+ const dropZone = await testdriver.find('drop area');
186
+ await dropZone.hover();
187
+
188
+ await new Promise(r => setTimeout(r, 300));
189
+ await dropZone.mouseUp();
190
+ ```
191
+ </Accordion>
192
+ </AccordionGroup>
193
+
194
+ ## Complete Example
195
+
196
+ ```javascript
197
+ import { beforeAll, afterAll, describe, it } from 'vitest';
198
+ import TestDriver from 'testdriverai';
199
+
200
+ describe('Hover Interactions', () => {
201
+ let testdriver;
202
+
203
+ beforeAll(async () => {
204
+ client = new TestDriver(process.env.TD_API_KEY);
205
+ await testdriver.auth();
206
+ await testdriver.connect();
207
+ });
208
+
209
+ afterAll(async () => {
210
+ await testdriver.disconnect();
211
+ });
212
+
213
+ it('should show tooltip on hover', async () => {
214
+ await testdriver.focusApplication('Google Chrome');
215
+
216
+ // Find and hover over icon
217
+ const infoIcon = await testdriver.find('information icon');
218
+ await infoIcon.hover();
219
+
220
+ // Wait for tooltip to appear
221
+ await new Promise(r => setTimeout(r, 1000));
222
+
223
+ // Verify tooltip is visible
224
+ await testdriver.assert('tooltip is displayed');
225
+
226
+ // Extract tooltip text
227
+ const tooltipText = await testdriver.extract('the tooltip message');
228
+ console.log('Tooltip says:', tooltipText);
229
+ });
230
+
231
+ it('should navigate dropdown menu', async () => {
232
+ // Hover over main menu
233
+ const menu = await testdriver.find('Navigation menu');
234
+ await menu.hover();
235
+
236
+ // Wait for dropdown
237
+ await new Promise(r => setTimeout(r, 500));
238
+
239
+ // Hover over submenu item
240
+ const submenu = await testdriver.find('Account submenu');
241
+ await submenu.hover();
242
+
243
+ await new Promise(r => setTimeout(r, 300));
244
+
245
+ // Click nested menu item
246
+ const settings = await testdriver.find('Settings option');
247
+ await settings.click();
248
+
249
+ await testdriver.assert('settings page is displayed');
250
+ });
251
+
252
+ it('should preview images on hover', async () => {
253
+ // Hover over product image
254
+ const productImg = await testdriver.find('product 1 thumbnail');
255
+ await productImg.hover();
256
+
257
+ // Wait for preview
258
+ await new Promise(r => setTimeout(r, 800));
259
+
260
+ // Verify preview appeared
261
+ await testdriver.assert('large product preview is shown');
262
+
263
+ // Move away
264
+ const otherElement = await testdriver.find('page heading');
265
+ await otherElement.hover();
266
+
267
+ // Verify preview disappeared
268
+ await new Promise(r => setTimeout(r, 500));
269
+ await testdriver.assert('product preview is hidden');
270
+ });
271
+ });
272
+ ```
273
+
274
+ ## Related Methods
275
+
276
+ - [`find()`](/v7/find) - Locate elements to hover
277
+ - [`click()`](/v7/click) - Click after hovering
278
+ - [`mouseDown()`](/v7/click) - Start drag operations
@@ -0,0 +1,71 @@
1
+ ---
2
+ name: testdriver:locating-elements
3
+ description: Find UI elements using natural language descriptions
4
+ ---
5
+ <!-- Generated from locating-elements.mdx. DO NOT EDIT. -->
6
+
7
+ ## Locating Single Elements
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:
10
+
11
+ ```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"');
15
+ ```
16
+
17
+ <Info>TestDriver will cache found elements for improved performance on subsequent calls. Learn more about [element caching here](/v7/caching).</Info>
18
+
19
+ ## Debugging Found Elements
20
+
21
+ After finding an element, you can inspect its properties for debugging:
22
+
23
+ ```javascript
24
+ const button = await testdriver.find('submit button');
25
+ console.log(button);
26
+ ```
27
+
28
+ This outputs all element properties:
29
+
30
+ ```javascript
31
+ {
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://...'
47
+ }
48
+ }
49
+ ```
50
+
51
+ ## Working with Multiple Elements
52
+
53
+ Find and interact with multiple elements:
54
+
55
+ ```javascript
56
+ // Find all matching elements
57
+ const products = await testdriver.findAll('product card');
58
+ console.log(`Found ${products.length} products`);
59
+
60
+ // Interact with each
61
+ for (const product of products) {
62
+ const title = await product.find('title text');
63
+ console.log('Product:', title.text);
64
+
65
+ await product.find('add to cart button').click();
66
+ }
67
+
68
+ // Or find specific element
69
+ const firstProduct = products[0];
70
+ await firstProduct.click();
71
+ ```
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: testdriver:making-assertions
3
+ description: Verify application state with AI-powered assertions
4
+ ---
5
+ <!-- Generated from making-assertions.mdx. DO NOT EDIT. -->
6
+
7
+ ## Making Assertions
8
+
9
+ Use AI-powered assertions to verify application state:
10
+
11
+ ```javascript
12
+ // Verify visibility
13
+ await testdriver.assert('login page is displayed');
14
+ await testdriver.assert('submit button is visible');
15
+ await testdriver.assert('loading spinner is not visible');
16
+
17
+ // Verify content
18
+ await testdriver.assert('page title is "Welcome"');
19
+ await testdriver.assert('success message says "Account created"');
20
+ await testdriver.assert('error message contains "Invalid email"');
21
+
22
+ // Verify state
23
+ await testdriver.assert('checkbox is checked');
24
+ await testdriver.assert('dropdown shows "United States"');
25
+ await testdriver.assert('button is disabled');
26
+
27
+ // Verify visual appearance
28
+ await testdriver.assert('submit button is blue');
29
+ await testdriver.assert('form has red border');
30
+ ```
31
+
32
+ <Info>Assertions are not cached and always re-evaluated to ensure accuracy.</Info>