@testdriverai/agent 7.11.229-canary → 7.11.232-test

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 (100) hide show
  1. package/docs/_data/examples-manifest.json +16 -16
  2. package/docs/_scripts/generate-examples.js +38 -45
  3. package/docs/agent.mdx +174 -93
  4. package/docs/assert.mdx +73 -269
  5. package/docs/aws-setup.mdx +196 -314
  6. package/docs/bring-your-own-machine.mdx +139 -206
  7. package/docs/cache.mdx +144 -151
  8. package/docs/caching.mdx +99 -89
  9. package/docs/captcha.mdx +126 -111
  10. package/docs/ci-cd.mdx +154 -543
  11. package/docs/click.mdx +74 -229
  12. package/docs/client.mdx +177 -231
  13. package/docs/copilot/auto-healing.mdx +86 -370
  14. package/docs/copilot/running-tests.mdx +121 -930
  15. package/docs/customizing-devices.mdx +74 -251
  16. package/docs/dashcam.mdx +72 -405
  17. package/docs/debugging-with-screenshots.mdx +105 -371
  18. package/docs/docs.json +79 -22
  19. package/docs/double-click.mdx +48 -68
  20. package/docs/errors.mdx +102 -176
  21. package/docs/events.mdx +170 -327
  22. package/docs/examples/{hover-text-with-description.mdx → add-to-cart.mdx} +30 -35
  23. package/docs/examples/assert.mdx +28 -41
  24. package/docs/examples/click-button.mdx +71 -0
  25. package/docs/examples/{hover-image.mdx → click-icon.mdx} +32 -28
  26. package/docs/examples/element-not-found.mdx +27 -26
  27. package/docs/examples/findall-coffee-icons.mdx +28 -32
  28. package/docs/examples/installer.mdx +61 -25
  29. package/docs/examples/launch-vscode-linux.mdx +28 -51
  30. package/docs/examples/navigate-and-scroll.mdx +82 -0
  31. package/docs/examples/parse.mdx +24 -28
  32. package/docs/examples/press-keys.mdx +28 -25
  33. package/docs/examples/scroll.mdx +25 -27
  34. package/docs/examples/type.mdx +26 -21
  35. package/docs/exec.mdx +92 -256
  36. package/docs/extract.mdx +69 -170
  37. package/docs/find.mdx +140 -736
  38. package/docs/focus-application.mdx +69 -246
  39. package/docs/generating-tests.mdx +103 -137
  40. package/docs/guide/best-practices-polling.mdx +65 -141
  41. package/docs/hosted.mdx +80 -144
  42. package/docs/hover.mdx +62 -235
  43. package/docs/locating-elements.mdx +74 -369
  44. package/docs/making-assertions.mdx +116 -74
  45. package/docs/mcp-setup.mdx +80 -63
  46. package/docs/mouse-down.mdx +48 -125
  47. package/docs/mouse-up.mdx +47 -129
  48. package/docs/options.mdx +75 -48
  49. package/docs/parse.mdx +95 -184
  50. package/docs/performing-actions.mdx +104 -94
  51. package/docs/press-keys.mdx +59 -299
  52. package/docs/provision.mdx +137 -182
  53. package/docs/quickstart-claude.mdx +85 -0
  54. package/docs/quickstart-github.mdx +62 -32
  55. package/docs/quickstart-manual.mdx +60 -33
  56. package/docs/quickstart-vscode.mdx +97 -0
  57. package/docs/quickstart.mdx +26 -9
  58. package/docs/redraw.mdx +101 -165
  59. package/docs/reusable-code.mdx +97 -200
  60. package/docs/right-click.mdx +47 -89
  61. package/docs/screenshot.mdx +47 -201
  62. package/docs/screenshots.mdx +87 -137
  63. package/docs/scroll.mdx +71 -154
  64. package/docs/secrets.mdx +96 -91
  65. package/docs/self-hosted.mdx +83 -142
  66. package/docs/snippets/enterprise.mdx +15 -0
  67. package/docs/styles.css +68 -0
  68. package/docs/test-results-json.mdx +167 -204
  69. package/docs/type.mdx +56 -304
  70. package/docs/variables.mdx +121 -81
  71. package/docs/wait.mdx +33 -31
  72. package/docs/what-is-testdriver.mdx +80 -32
  73. package/examples/{hover-text-with-description.test.mjs → add-to-cart.test.mjs} +4 -5
  74. package/examples/assert.test.mjs +3 -20
  75. package/examples/{hover-text.test.mjs → click-button.test.mjs} +3 -4
  76. package/examples/{hover-image.test.mjs → click-icon.test.mjs} +5 -6
  77. package/examples/element-not-found.test.mjs +3 -5
  78. package/examples/findall-coffee-icons.test.mjs +3 -3
  79. package/examples/installer.test.mjs +1 -1
  80. package/examples/launch-vscode-linux.test.mjs +6 -33
  81. package/examples/{scroll-keyboard.test.mjs → navigate-and-scroll.test.mjs} +4 -5
  82. package/examples/parse.test.mjs +1 -2
  83. package/examples/press-keys.test.mjs +4 -4
  84. package/examples/scroll.test.mjs +3 -6
  85. package/examples/type.test.mjs +5 -2
  86. package/lib/provision.js +6 -2
  87. package/package.json +1 -1
  88. package/sdk.d.ts +4 -2
  89. package/sdk.js +1 -1
  90. package/docs/claude-mcp-plugin.mdx +0 -244
  91. package/docs/elements.mdx +0 -606
  92. package/docs/examples/ai.mdx +0 -78
  93. package/docs/examples/captcha-api.mdx +0 -92
  94. package/docs/examples/chrome-extension.mdx +0 -156
  95. package/docs/examples/drag-and-drop.mdx +0 -100
  96. package/docs/examples/formatted-logging.mdx +0 -74
  97. package/docs/examples/hover-text.mdx +0 -70
  98. package/docs/examples/match-image.mdx +0 -97
  99. package/docs/examples/scroll-keyboard.mdx +0 -80
  100. package/docs/examples/scroll-until-text.mdx +0 -109
package/docs/exec.mdx CHANGED
@@ -1,318 +1,154 @@
1
1
  ---
2
2
  title: "exec()"
3
3
  sidebarTitle: "exec"
4
- description: "Execute shell or PowerShell commands in the sandbox"
4
+ description: "Run a shell or PowerShell command in the sandbox and get its output."
5
5
  icon: "terminal"
6
6
  ---
7
7
 
8
- ## Overview
9
-
10
- Run shell commands (Linux) or PowerShell commands (Windows) in the sandbox.
11
-
12
- ## Syntax
8
+ Run a command in the sandbox, for example to create test files, install software, or launch an app. `exec()` returns the command's output.
13
9
 
14
10
  ```javascript
15
- await testdriver.exec(language, code, timeout, silent)
11
+ const files = await testdriver.exec({ language: 'sh', code: 'ls ~/Downloads' });
16
12
  ```
17
13
 
18
- ## Parameters
14
+ - On Linux sandboxes, use `'sh'`. The command runs in Bash.
15
+ - On Windows sandboxes, use `'pwsh'`. The command runs in PowerShell.
19
16
 
20
- <ParamField path="language" type="string" required>
21
- The language to run: `'sh'` (Shell/Linux) or `'pwsh'` (PowerShell/Windows)
22
- </ParamField>
17
+ ## Signature
23
18
 
24
- <ParamField path="code" type="string" required>
25
- The code or the command to run
26
- </ParamField>
19
+ ```typescript
20
+ testdriver.exec(options: ExecOptions): Promise<string>
21
+ ```
27
22
 
28
- <ParamField path="timeout" type="number" required>
29
- The timeout in milliseconds
30
- </ParamField>
23
+ ## Parameters
31
24
 
32
- <ParamField path="silent" type="boolean" default="false">
33
- If `true`, TestDriver does not show the output
25
+ <ParamField path="options" type="ExecOptions" required>
26
+ <Expandable title="properties">
27
+ <ParamField path="code" type="string" required>
28
+ The command or script to run. It can span several lines.
29
+ </ParamField>
30
+ <ParamField path="language" type="'sh' | 'pwsh'" default="pwsh">
31
+ The shell to run it in. The default is `'pwsh'`, so set `'sh'` on Linux, which is the default sandbox. On a Windows sandbox, `'sh'` switches to `'pwsh'` with a warning.
32
+ </ParamField>
33
+ <ParamField path="timeout" type="number" default="300000">
34
+ How long the command may run, in milliseconds. The default is 5 minutes.
35
+ </ParamField>
36
+ <ParamField path="silent" type="boolean" default="false">
37
+ Keep the command and its output out of the test log.
38
+ </ParamField>
39
+ </Expandable>
34
40
  </ParamField>
35
41
 
36
- ## Returns
37
-
38
- `Promise<string>` - The command output
42
+ Commands run in one shell session that stays open for the whole test. A `cd` or an environment variable you set carries over to the next `exec()` call.
39
43
 
40
- ## Shell Execution (Linux)
44
+ ## Returns
41
45
 
42
- Run shell commands in the Linux sandbox.
46
+ `Promise<string>`. The command's standard output, with leading and trailing whitespace trimmed. Output over 5 MB is cut off.
43
47
 
44
- ### Basic Commands
48
+ ## Errors
45
49
 
46
- ```javascript
47
- // List files
48
- const files = await testdriver.exec('sh', 'ls -la', 5000);
50
+ `exec()` throws when:
49
51
 
50
- // Check current directory
51
- const pwd = await testdriver.exec('sh', 'pwd', 5000);
52
-
53
- // Run a script
54
- await testdriver.exec('sh', './setup.sh', 60000);
55
- ```
52
+ - The command exits with a non-zero code. The message is `Command failed with exit code <code>: <stderr>`.
53
+ - The command runs longer than `timeout`.
56
54
 
57
- ### File Operations
55
+ To allow a failure, catch the error:
58
56
 
59
57
  ```javascript
60
- // Create a file
61
- await testdriver.exec('sh', 'echo "Hello World" > test.txt', 5000);
62
-
63
- // Read a file
64
- const content = await testdriver.exec('sh', 'cat test.txt', 5000);
65
-
66
- // Copy files
67
- await testdriver.exec('sh', 'cp source.txt dest.txt', 5000);
68
-
69
- // Delete files
70
- await testdriver.exec('sh', 'rm test.txt', 5000);
58
+ try {
59
+ await testdriver.exec({ language: 'sh', code: 'pkill -f my-app' });
60
+ } catch (error) {
61
+ // pkill exits with 1 when no process matched
62
+ }
71
63
  ```
72
64
 
73
- ## PowerShell Execution (Windows)
74
-
75
- Execute PowerShell commands in the Windows sandbox.
65
+ ## Examples
76
66
 
77
- ### Software Installation
67
+ ### Create a file the test needs
78
68
 
79
69
  ```javascript
80
- // Install npm package globally
81
- await testdriver.exec('pwsh', 'npm install -g http-server', 30000);
82
-
83
- // Install via Chocolatey
84
- await testdriver.exec('pwsh', 'choco install firefox -y', 60000);
85
-
86
- // Download and run installer
87
- await testdriver.exec('pwsh', `
88
- Invoke-WebRequest -Uri "https://example.com/setup.exe" -OutFile "C:\\setup.exe"
89
- Start-Process -FilePath "C:\\setup.exe" -ArgumentList "/S" -Wait
90
- `, 120000);
70
+ await testdriver.exec({
71
+ language: 'sh',
72
+ code: 'echo "name,email" > ~/Desktop/contacts.csv',
73
+ });
91
74
  ```
92
75
 
93
- ### File Operations
76
+ ### Read a value and check it
94
77
 
95
78
  ```javascript
96
- // Create a file
97
- await testdriver.exec('pwsh', `
98
- Set-Content -Path "C:\\test.txt" -Value "Hello World"
99
- `, 5000);
100
-
101
- // Read a file
102
- const content = await testdriver.exec('pwsh',
103
- 'Get-Content -Path "C:\\test.txt"',
104
- 5000
105
- );
106
-
107
- // Copy files
108
- await testdriver.exec('pwsh',
109
- 'Copy-Item -Path "C:\\source.txt" -Destination "C:\\dest.txt"',
110
- 5000
111
- );
112
-
113
- // Delete files
114
- await testdriver.exec('pwsh',
115
- 'Remove-Item -Path "C:\\test.txt"',
116
- 5000
117
- );
118
-
119
- // List directory
120
- const files = await testdriver.exec('pwsh',
121
- 'Get-ChildItem -Path "C:\\Users\\testdriver\\Documents"',
122
- 5000
123
- );
79
+ const version = await testdriver.exec({ language: 'sh', code: 'node --version' });
80
+ expect(version).toMatch(/^v\d+/);
124
81
  ```
125
82
 
126
- ### Process Management
83
+ ### Install software on Windows
127
84
 
128
85
  ```javascript
129
- // List running processes
130
- const processes = await testdriver.exec('pwsh', 'Get-Process', 5000);
131
-
132
- // Start application
133
- await testdriver.exec('pwsh', `
134
- Start-Process "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" -ArgumentList "--start-maximized", "https://example.com"
135
- `, 5000);
136
-
137
- // Kill a process
138
- await testdriver.exec('pwsh', 'Stop-Process -Name "chrome" -Force', 5000);
139
-
140
- // Wait for process
141
- await testdriver.exec('pwsh', 'Start-Process notepad -Wait', 30000);
86
+ await testdriver.exec({
87
+ language: 'pwsh',
88
+ code: 'choco install firefox -y',
89
+ timeout: 600000,
90
+ silent: true,
91
+ });
142
92
  ```
143
93
 
144
- ### Environment Variables
94
+ ### Launch an app on Windows
145
95
 
146
96
  ```javascript
147
- // Set environment variable (session)
148
- await testdriver.exec('pwsh', '$env:MY_VAR = "value"', 5000);
149
-
150
- // Get environment variable
151
- const value = await testdriver.exec('pwsh', '$env:MY_VAR', 5000);
152
-
153
- // Set persistent environment variable
154
- await testdriver.exec('pwsh', `
155
- [Environment]::SetEnvironmentVariable("MY_VAR", "value", "User")
156
- `, 5000);
97
+ await testdriver.exec({ language: 'pwsh', code: 'Start-Process notepad' });
98
+ await testdriver.focusApplication('Notepad');
157
99
  ```
158
100
 
159
- ### Network Operations
101
+ To open Chrome, VS Code, Electron apps, or installers, use [`provision`](/provision) instead. It launches the app and waits for it.
160
102
 
161
- ```javascript
162
- // Test connectivity
163
- const pingResult = await testdriver.exec('pwsh',
164
- 'Test-NetConnection google.com',
165
- 10000
166
- );
167
-
168
- // Download file
169
- await testdriver.exec('pwsh', `
170
- Invoke-WebRequest -Uri "https://example.com/file.zip" -OutFile "C:\\Downloads\\file.zip"
171
- `, 30000);
172
-
173
- // Check if port is open
174
- const portOpen = await testdriver.exec('pwsh',
175
- 'Test-NetConnection -ComputerName localhost -Port 3000',
176
- 5000
177
- );
178
- ```
103
+ ## Positional form
179
104
 
180
- ## Silent Execution
105
+ Older tests pass the options as arguments:
181
106
 
182
- Suppress output for background operations:
107
+ ```typescript
108
+ testdriver.exec(language: 'sh' | 'pwsh', code: string, timeout?: number, silent?: boolean): Promise<string>
109
+ ```
183
110
 
184
111
  ```javascript
185
- // Silent installation
186
- await testdriver.exec('pwsh', 'npm install -g some-package', 30000, true);
112
+ await testdriver.exec('sh', 'ls ~/Downloads', 5000);
113
+ ```
187
114
 
188
- // Start background process
189
- await testdriver.exec('pwsh', 'Start-Process notepad', 5000, true);
115
+ It behaves the same. Use the options object in new tests.
190
116
 
191
- // Run setup script silently
192
- await testdriver.exec('pwsh', '.\\setup.ps1', 60000, true);
193
- ```
117
+ <Note>
118
+ `language: 'js'` is also accepted. It runs the code in Node on your own machine, not in the sandbox, and returns the value you assign to a `result` variable. Write the JavaScript directly in your test instead.
119
+ </Note>
194
120
 
195
- ## Best Practices
196
-
197
- <Check>
198
- **Use appropriate timeouts**
199
-
200
- ```javascript
201
- // Quick operations: 5000ms
202
- await testdriver.exec('sh', 'ls -la', 5000);
203
-
204
- // Installations: 30000-60000ms
205
- await testdriver.exec('pwsh', 'npm install -g package', 30000);
206
-
207
- // Downloads or complex operations: 60000-120000ms
208
- await testdriver.exec('pwsh', 'Install-Module Something', 120000);
209
- ```
210
- </Check>
211
-
212
- <Check>
213
- **Handle errors gracefully**
214
-
215
- ```javascript
216
- try {
217
- await testdriver.exec('pwsh', 'Some-Command', 5000);
218
- } catch (error) {
219
- console.error('Command failed:', error.message);
220
- // Fallback or retry logic
221
- }
222
- ```
223
- </Check>
224
-
225
- <Check>
226
- **Use silent mode for background tasks**
227
-
228
- ```javascript
229
- // Silent install
230
- await testdriver.exec('pwsh', 'npm install -g tool', 30000, true);
231
-
232
- // Background service
233
- await testdriver.exec('pwsh', 'Start-Service MyService', 5000, true);
234
- ```
235
- </Check>
236
-
237
- <Warning>
238
- **Escape strings properly in PowerShell**
239
-
240
- Use proper escaping for special characters:
241
-
242
- ```javascript
243
- // Use backticks for newlines
244
- await testdriver.exec('pwsh', `
245
- Write-Host "Line 1\`nLine 2"
246
- `, 5000);
247
-
248
- // Use single quotes to avoid variable expansion
249
- await testdriver.exec('pwsh',
250
- "Write-Host 'Text with $special chars'",
251
- 5000
252
- );
253
- ```
254
- </Warning>
255
-
256
- ## Complete Example
121
+ ## Complete example
257
122
 
258
- ```javascript
259
- import { beforeAll, afterAll, describe, it } from 'vitest';
260
- import TestDriver from 'testdriverai';
123
+ ```javascript tests/download.test.mjs
124
+ import { describe, expect, it } from 'vitest';
125
+ import { TestDriver } from 'testdriverai/vitest/hooks';
261
126
 
262
- describe('Code Execution', () => {
263
- let testdriver;
127
+ describe('Downloads', () => {
128
+ it('opens a file created in the sandbox', async (context) => {
129
+ const testdriver = TestDriver(context);
130
+ await testdriver.provision.chrome({ url: 'https://testdriver-sandbox.vercel.app/login' });
264
131
 
265
- beforeAll(async () => {
266
- client = new TestDriver(process.env.TD_API_KEY);
267
- await testdriver.auth();
268
- await testdriver.connect();
269
- });
132
+ await testdriver.exec({
133
+ language: 'sh',
134
+ code: 'echo "<h1>Hello from exec</h1>" > /tmp/hello.html',
135
+ });
270
136
 
271
- afterAll(async () => {
272
- await testdriver.disconnect();
273
- });
137
+ const contents = await testdriver.exec({ language: 'sh', code: 'cat /tmp/hello.html' });
138
+ expect(contents).toContain('Hello from exec');
274
139
 
275
- it('should execute shell commands on Linux', async () => {
276
- // List directory
277
- const files = await testdriver.exec('sh', 'ls -la', 5000);
278
- console.log('Files:', files);
279
-
280
- // Create a file
281
- await testdriver.exec('sh', 'echo "Hello World" > test.txt', 5000);
282
-
283
- // Read the file
284
- const content = await testdriver.exec('sh', 'cat test.txt', 5000);
285
- expect(content).toContain('Hello World');
286
- });
140
+ await testdriver.pressKeys(['ctrl', 'l']);
141
+ await testdriver.type('file:///tmp/hello.html');
142
+ await testdriver.pressKeys(['enter']);
287
143
 
288
- it('should install and use tools on Windows', async () => {
289
- // Install tool
290
- await testdriver.exec('pwsh', 'npm install -g http-server', 30000, true);
291
-
292
- // Create HTML file
293
- await testdriver.exec('pwsh', `
294
- Set-Content -Path "C:\\index.html" -Value "<h1>Test Page</h1>"
295
- `, 5000);
296
-
297
- // Start server in background
298
- await testdriver.exec('pwsh', `
299
- Start-Process pwsh -ArgumentList "-Command", "http-server C:\\ -p 8080"
300
- `, 5000, true);
301
-
302
- await new Promise(r => setTimeout(r, 3000));
303
-
304
- // Launch browser
305
- await testdriver.exec('pwsh', `
306
- Start-Process chrome -ArgumentList "http://localhost:8080"
307
- `, 5000);
308
-
309
- await testdriver.focusApplication('Google Chrome');
144
+ const result = await testdriver.assert('the page shows "Hello from exec"');
145
+ expect(result).toBe(true);
310
146
  });
311
147
  });
312
148
  ```
313
149
 
314
- ## Related Methods
150
+ ## Related
315
151
 
316
- - [`focusApplication()`](/focus-application) - Focus apps before exec
317
- - [`find()`](/find) - Locate elements visually
318
- - [`type()`](/type) - Type text into inputs
152
+ - [Launch apps](/provision): open Chrome, VS Code, and installers
153
+ - [focusApplication()](/focus-application): bring a launched app to the front
154
+ - [Customize devices](/customizing-devices): set up the sandbox before your test