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