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,164 @@
1
+ ---
2
+ name: testdriver:mouse-up
3
+ description: Release the mouse button
4
+ ---
5
+ <!-- Generated from mouse-up.mdx. DO NOT EDIT. -->
6
+
7
+ ## Overview
8
+
9
+ The `mouseUp()` method releases the mouse button, completing a drag operation or custom mouse gesture that was started with [`mouseDown()`](/v7/mouse-down). You can call it without parameters to release at the current mouse position.
10
+
11
+ ## Syntax
12
+
13
+ ```javascript
14
+ // Release mouse button at current position
15
+ await ai.mouseUp();
16
+ ```
17
+
18
+ ## Parameters
19
+
20
+ None. The mouse button is released at the current cursor position.
21
+
22
+ ## Returns
23
+
24
+ Returns a `Promise<void>` that resolves when the mouse button is released.
25
+
26
+ ## Examples
27
+
28
+ ### Complete Drag and Drop
29
+
30
+ ```javascript
31
+ // Start dragging
32
+ await ai.mouseDown('file to drag');
33
+
34
+ // Move to drop location
35
+ await ai.hover('target folder');
36
+
37
+ // Complete the drop
38
+ await ai.mouseUp();
39
+ ```
40
+
41
+ ### Selecting Multiple Files
42
+
43
+ ```javascript
44
+ import { test } from 'vitest';
45
+ import { vscode } from '@testdriver/sdk';
46
+
47
+ test('selects range of files', async () => {
48
+ const { ai } = await vscode();
49
+
50
+ // Click first file
51
+ await ai.click('first-file.js in explorer');
52
+
53
+ // Hold shift and click last file
54
+ await ai.pressKeys('Shift');
55
+ await ai.mouseDown('last-file.js in explorer');
56
+ await ai.mouseUp();
57
+
58
+ // Verify multiple files selected
59
+ const selectedCount = await ai.find('status bar showing file count');
60
+ expect(selectedCount.text).toContain('5 files');
61
+ });
62
+ ```
63
+
64
+ ### Drawing Application
65
+
66
+ ```javascript
67
+ test('draws a shape', async () => {
68
+ const { ai } = await chrome('https://drawing-app.example.com');
69
+
70
+ // Select pencil tool
71
+ await ai.click('pencil tool');
72
+
73
+ // Draw a line
74
+ await ai.mouseDown('canvas near top-left');
75
+ await ai.hover('canvas center');
76
+ await ai.hover('canvas bottom-right');
77
+ await ai.mouseUp();
78
+
79
+ // Verify drawing exists
80
+ const strokes = await ai.exec('canvas.getContext("2d").getImageData(0,0,100,100)');
81
+ expect(strokes).toBeTruthy();
82
+ });
83
+ ```
84
+
85
+ ### Resizing Window Panels
86
+
87
+ ```javascript
88
+ test('resizes editor panel', async () => {
89
+ const { ai } = await vscode();
90
+
91
+ // Grab the divider
92
+ await ai.mouseDown('panel resize divider');
93
+
94
+ // Drag to new position
95
+ await ai.hover('position 400 pixels from left');
96
+
97
+ // Release to complete resize
98
+ await ai.mouseUp();
99
+
100
+ // Verify new panel size
101
+ const panel = await ai.find('editor panel');
102
+ expect(panel.width).toBeGreaterThan(350);
103
+ });
104
+ ```
105
+
106
+ ### Drag to Reorder List Items
107
+
108
+ ```javascript
109
+ import { test } from 'vitest';
110
+ import { chrome } from '@testdriver/sdk';
111
+
112
+ test('reorders tasks in list', async () => {
113
+ const { ai } = await chrome('https://todo-app.example.com');
114
+
115
+ // Start dragging first task
116
+ await ai.mouseDown('drag handle on first task');
117
+
118
+ // Move down to third position
119
+ await ai.hover('third task position');
120
+
121
+ // Drop the task
122
+ await ai.mouseUp();
123
+
124
+ // Verify new order
125
+ const thirdTask = await ai.find('third task in list');
126
+ expect(thirdTask.text).toContain('Original first task');
127
+ });
128
+ ```
129
+
130
+ ### Text Selection with Mouse
131
+
132
+ ```javascript
133
+ test('selects text with mouse drag', async () => {
134
+ const { ai } = await chrome('https://document.example.com');
135
+
136
+ // Start selection at beginning of word
137
+ await ai.mouseDown('start of "TestDriver" word');
138
+
139
+ // Drag to end of word
140
+ await ai.hover('end of "TestDriver" word');
141
+
142
+ // Complete selection
143
+ await ai.mouseUp();
144
+
145
+ // Verify selection
146
+ const selection = await ai.exec('window.getSelection().toString()');
147
+ expect(selection).toBe('TestDriver');
148
+ });
149
+ ```
150
+
151
+ ## Important Notes
152
+
153
+ - `mouseUp()` must be preceded by [`mouseDown()`](/v7/mouse-down) to have an effect
154
+ - Releases the button at the current cursor position
155
+ - Completes any drag or selection operation that was in progress
156
+ - For simple clicks, use [`click()`](/v7/click) instead of mouseDown/mouseUp pair
157
+
158
+ ## Related Methods
159
+
160
+ - [`mouseDown()`](/v7/mouse-down) - Press mouse button without releasing
161
+ - [`hover()`](/v7/hover) - Move mouse to element
162
+ - [`click()`](/v7/click) - Complete click (mouseDown + mouseUp)
163
+ - [`doubleClick()`](/v7/double-click) - Double-click on element
164
+ - [`rightClick()`](/v7/right-click) - Right-click for context menu
@@ -0,0 +1,51 @@
1
+ ---
2
+ name: testdriver:performing-actions
3
+ description: Click, type, hover, scroll and more with TestDriver
4
+ ---
5
+ <!-- Generated from performing-actions.mdx. DO NOT EDIT. -->
6
+
7
+ ## Performing Actions
8
+
9
+ TestDriver provides a variety of actions you can perform, like [clicking](/v7/click), [typing](/v7/type), [hovering](/v7/hover), and [scrolling](/v7/scroll). For a full list, see the [API Reference](/v7/click).
10
+
11
+ ```javascript
12
+ // Clicking
13
+ await testdriver.find('submit button').click();
14
+ await testdriver.find('file item').doubleClick();
15
+ await testdriver.find('text area').rightClick();
16
+
17
+ // Typing
18
+ await testdriver.find('email input').type('user@example.com');
19
+ await testdriver.find('password input').type('secret', { secret: true });
20
+
21
+ // Keyboard shortcuts
22
+ await testdriver.pressKeys(['enter']);
23
+ await testdriver.pressKeys(['ctrl', 'c']);
24
+
25
+ // Hovering
26
+ await testdriver.find('dropdown menu').hover();
27
+
28
+ // Scrolling
29
+ await testdriver.scroll('down', 500);
30
+ await testdriver.scrollUntilText('Footer content');
31
+
32
+ // Extracting information from screen
33
+ const price = await testdriver.extract('the total price');
34
+ const orderNumber = await testdriver.extract('the order confirmation number');
35
+ ```
36
+
37
+ ## Chaining Actions
38
+
39
+ TestDriver supports method chaining for cleaner code:
40
+
41
+ ```javascript
42
+ // Chain find() with actions
43
+ const button = await testdriver.find('submit button').click();
44
+ ```
45
+
46
+ Or save element reference for later use:
47
+
48
+ ```javascript
49
+ const button = await testdriver.find('submit button');
50
+ await button.click();
51
+ ```
@@ -0,0 +1,348 @@
1
+ ---
2
+ name: testdriver:press-keys
3
+ description: Press keyboard keys and shortcuts
4
+ ---
5
+ <!-- Generated from press-keys.mdx. DO NOT EDIT. -->
6
+
7
+ ## Overview
8
+
9
+ Press one or more keyboard keys simultaneously, useful for keyboard shortcuts, navigation, and special keys.
10
+
11
+ ## Syntax
12
+
13
+ ```javascript
14
+ await testdriver.pressKeys(keys)
15
+ ```
16
+
17
+ ## Parameters
18
+
19
+ <ParamField path="keys" type="Array&lt;string&gt;" required>
20
+ Array of keys to press simultaneously
21
+ </ParamField>
22
+
23
+ ## Returns
24
+
25
+ `Promise<void>`
26
+
27
+ ## Common Keys
28
+
29
+ ### Special Keys
30
+ - `'enter'`, `'tab'`, `'escape'`, `'backspace'`, `'delete'`
31
+ - `'space'`, `'up'`, `'down'`, `'left'`, `'right'`
32
+ - `'home'`, `'end'`, `'pageup'`, `'pagedown'`
33
+
34
+ ### Modifier Keys
35
+ - `'ctrl'`, `'alt'`, `'shift'`
36
+ - `'command'` (macOS), `'win'` (Windows)
37
+ - `'ctrlleft'`, `'ctrlright'`, `'shiftleft'`, `'shiftright'`
38
+
39
+ ### Function Keys
40
+ - `'f1'` through `'f24'`
41
+
42
+ ## Examples
43
+
44
+ ### Navigation
45
+
46
+ ```javascript
47
+ // Tab to next field
48
+ await testdriver.pressKeys(['tab']);
49
+
50
+ // Shift+Tab to previous field
51
+ await testdriver.pressKeys(['shift', 'tab']);
52
+
53
+ // Arrow keys
54
+ await testdriver.pressKeys(['down']);
55
+ await testdriver.pressKeys(['up']);
56
+ await testdriver.pressKeys(['left']);
57
+ await testdriver.pressKeys(['right']);
58
+
59
+ // Home/End
60
+ await testdriver.pressKeys(['home']); // Start of line
61
+ await testdriver.pressKeys(['end']); // End of line
62
+
63
+ // Page navigation
64
+ await testdriver.pressKeys(['pagedown']);
65
+ await testdriver.pressKeys(['pageup']);
66
+ ```
67
+
68
+ ### Keyboard Shortcuts
69
+
70
+ ```javascript
71
+ // Copy (Ctrl+C / Cmd+C)
72
+ await testdriver.pressKeys(['ctrl', 'c']);
73
+
74
+ // Paste (Ctrl+V / Cmd+V)
75
+ await testdriver.pressKeys(['ctrl', 'v']);
76
+
77
+ // Save (Ctrl+S)
78
+ await testdriver.pressKeys(['ctrl', 's']);
79
+
80
+ // Select All (Ctrl+A)
81
+ await testdriver.pressKeys(['ctrl', 'a']);
82
+
83
+ // Undo (Ctrl+Z)
84
+ await testdriver.pressKeys(['ctrl', 'z']);
85
+
86
+ // Redo (Ctrl+Y)
87
+ await testdriver.pressKeys(['ctrl', 'y']);
88
+
89
+ // Find (Ctrl+F)
90
+ await testdriver.pressKeys(['ctrl', 'f']);
91
+
92
+ // New tab (Ctrl+T)
93
+ await testdriver.pressKeys(['ctrl', 't']);
94
+
95
+ // Close tab (Ctrl+W)
96
+ await testdriver.pressKeys(['ctrl', 'w']);
97
+
98
+ // Refresh (F5 or Ctrl+R)
99
+ await testdriver.pressKeys(['f5']);
100
+ await testdriver.pressKeys(['ctrl', 'r']);
101
+ ```
102
+
103
+ ### System Shortcuts
104
+
105
+ ```javascript
106
+ // Alt+Tab (Windows - switch apps)
107
+ await testdriver.pressKeys(['alt', 'tab']);
108
+
109
+ // Alt+F4 (Windows - close window)
110
+ await testdriver.pressKeys(['alt', 'f4']);
111
+
112
+ // Win+D (Windows - show desktop)
113
+ await testdriver.pressKeys(['winleft', 'd']);
114
+
115
+ // Win+L (Windows - lock screen)
116
+ await testdriver.pressKeys(['winleft', 'l']);
117
+
118
+ // Cmd+Tab (macOS - switch apps)
119
+ await testdriver.pressKeys(['command', 'tab']);
120
+
121
+ // Cmd+Q (macOS - quit app)
122
+ await testdriver.pressKeys(['command', 'q']);
123
+ ```
124
+
125
+ ### Form Submission
126
+
127
+ ```javascript
128
+ // Submit form
129
+ await testdriver.pressKeys(['enter']);
130
+
131
+ // Cancel/Close
132
+ await testdriver.pressKeys(['escape']);
133
+
134
+ // Check checkbox
135
+ await testdriver.pressKeys(['space']);
136
+ ```
137
+
138
+ ### Text Editing
139
+
140
+ ```javascript
141
+ // Delete selected text
142
+ await testdriver.pressKeys(['delete']);
143
+
144
+ // Backspace
145
+ await testdriver.pressKeys(['backspace']);
146
+
147
+ // Select all and delete
148
+ await testdriver.pressKeys(['ctrl', 'a']);
149
+ await testdriver.pressKeys(['delete']);
150
+
151
+ // Cut text
152
+ await testdriver.pressKeys(['ctrl', 'x']);
153
+ ```
154
+
155
+ ## Best Practices
156
+
157
+ <Check>
158
+ **Wait after shortcuts**
159
+
160
+ Some keyboard shortcuts trigger animations or navigation:
161
+
162
+ ```javascript
163
+ await testdriver.pressKeys(['ctrl', 't']); // New tab
164
+ await new Promise(r => setTimeout(r, 500)); // Wait for tab
165
+ await testdriver.pressKeys(['ctrl', 'l']); // Focus URL bar
166
+ ```
167
+ </Check>
168
+
169
+ <Check>
170
+ **Use Tab for form navigation**
171
+
172
+ Tab is more reliable than clicking multiple fields:
173
+
174
+ ```javascript
175
+ const firstField = await testdriver.find('email input');
176
+ await firstField.click();
177
+ await testdriver.type('user@example.com');
178
+
179
+ await testdriver.pressKeys(['tab']);
180
+ await testdriver.type('password123');
181
+
182
+ await testdriver.pressKeys(['tab']);
183
+ await testdriver.pressKeys(['enter']); // Submit
184
+ ```
185
+ </Check>
186
+
187
+ <Warning>
188
+ **Platform-specific keys**
189
+
190
+ Use the appropriate modifier key for the platform:
191
+ - Windows/Linux: `'ctrl'`
192
+ - macOS: `'command'`
193
+
194
+ ```javascript
195
+ // For cross-platform, you might need to detect OS
196
+ const modKey = process.platform === 'darwin' ? 'command' : 'ctrl';
197
+ await testdriver.pressKeys([modKey, 'c']); // Copy
198
+ ```
199
+ </Warning>
200
+
201
+ ## Use Cases
202
+
203
+ <AccordionGroup>
204
+ <Accordion title="Form Navigation">
205
+ ```javascript
206
+ // Fill form using Tab
207
+ const firstField = await testdriver.find('name field');
208
+ await firstField.click();
209
+ await testdriver.type('John Doe');
210
+
211
+ await testdriver.pressKeys(['tab']);
212
+ await testdriver.type('john@example.com');
213
+
214
+ await testdriver.pressKeys(['tab']);
215
+ await testdriver.type('555-0123');
216
+
217
+ await testdriver.pressKeys(['tab']);
218
+ await testdriver.pressKeys(['enter']); // Submit
219
+ ```
220
+ </Accordion>
221
+
222
+ <Accordion title="Text Manipulation">
223
+ ```javascript
224
+ const textArea = await testdriver.find('comment textarea');
225
+ await textArea.click();
226
+
227
+ // Select all existing text
228
+ await testdriver.pressKeys(['ctrl', 'a']);
229
+
230
+ // Copy it
231
+ await testdriver.pressKeys(['ctrl', 'c']);
232
+
233
+ // Type new text
234
+ await testdriver.type('New comment');
235
+
236
+ // Undo if needed
237
+ await testdriver.pressKeys(['ctrl', 'z']);
238
+ ```
239
+ </Accordion>
240
+
241
+ <Accordion title="Browser Navigation">
242
+ ```javascript
243
+ // Open new tab
244
+ await testdriver.pressKeys(['ctrl', 't']);
245
+ await new Promise(r => setTimeout(r, 500));
246
+
247
+ // Focus address bar
248
+ await testdriver.pressKeys(['ctrl', 'l']);
249
+ await testdriver.type('https://example.com');
250
+ await testdriver.pressKeys(['enter']);
251
+
252
+ // Refresh page
253
+ await testdriver.pressKeys(['f5']);
254
+
255
+ // Close tab
256
+ await testdriver.pressKeys(['ctrl', 'w']);
257
+ ```
258
+ </Accordion>
259
+
260
+ <Accordion title="Application Shortcuts">
261
+ ```javascript
262
+ // Save document
263
+ await testdriver.pressKeys(['ctrl', 's']);
264
+
265
+ // Print
266
+ await testdriver.pressKeys(['ctrl', 'p']);
267
+
268
+ // Find in page
269
+ await testdriver.pressKeys(['ctrl', 'f']);
270
+ await testdriver.type('search term');
271
+ await testdriver.pressKeys(['escape']); // Close find
272
+ ```
273
+ </Accordion>
274
+ </AccordionGroup>
275
+
276
+ ## Complete Example
277
+
278
+ ```javascript
279
+ import { beforeAll, afterAll, describe, it } from 'vitest';
280
+ import TestDriver from 'testdriverai';
281
+
282
+ describe('Keyboard Navigation', () => {
283
+ let testdriver;
284
+
285
+ beforeAll(async () => {
286
+ client = new TestDriver(process.env.TD_API_KEY);
287
+ await testdriver.auth();
288
+ await testdriver.connect();
289
+ });
290
+
291
+ afterAll(async () => {
292
+ await testdriver.disconnect();
293
+ });
294
+
295
+ it('should navigate form with keyboard', async () => {
296
+ await testdriver.focusApplication('Google Chrome');
297
+
298
+ // Find first field
299
+ const emailField = await testdriver.find('email input');
300
+ await emailField.click();
301
+ await testdriver.type('user@example.com');
302
+
303
+ // Tab through fields
304
+ await testdriver.pressKeys(['tab']);
305
+ await testdriver.type('John');
306
+
307
+ await testdriver.pressKeys(['tab']);
308
+ await testdriver.type('Doe');
309
+
310
+ await testdriver.pressKeys(['tab']);
311
+ await testdriver.type('password123');
312
+
313
+ // Submit with Enter
314
+ await testdriver.pressKeys(['tab']);
315
+ await testdriver.pressKeys(['enter']);
316
+
317
+ await testdriver.assert('form submitted successfully');
318
+ });
319
+
320
+ it('should use keyboard shortcuts', async () => {
321
+ // Open new browser tab
322
+ await testdriver.pressKeys(['ctrl', 't']);
323
+ await new Promise(r => setTimeout(r, 500));
324
+
325
+ // Focus address bar
326
+ await testdriver.pressKeys(['ctrl', 'l']);
327
+ await testdriver.type('https://example.com');
328
+ await testdriver.pressKeys(['enter']);
329
+
330
+ await new Promise(r => setTimeout(r, 2000));
331
+
332
+ // Select all page content
333
+ await testdriver.pressKeys(['ctrl', 'a']);
334
+
335
+ // Copy
336
+ await testdriver.pressKeys(['ctrl', 'c']);
337
+
338
+ // Refresh page
339
+ await testdriver.pressKeys(['f5']);
340
+ });
341
+ });
342
+ ```
343
+
344
+ ## Related Methods
345
+
346
+ - [`type()`](/v7/type) - Type text
347
+ - [`click()`](/v7/click) - Click elements
348
+ - [`scroll()`](/v7/scroll) - Scroll pages