testdriverai 7.1.1 → 7.1.3
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/agent/lib/commands.js +7 -2
- package/docs/docs.json +23 -30
- package/docs/v7/getting-started/quickstart.mdx +11 -9
- package/docs/v7/getting-started/running-and-debugging.mdx +3 -2
- package/docs/v7/getting-started/writing-tests.mdx +4 -5
- package/docs/v7/presets/chrome.mdx +38 -41
- package/docs/v7/presets/electron.mdx +107 -100
- package/docs/v7/presets/webapp.mdx +40 -43
- package/interfaces/cli/commands/init.js +4 -4
- package/interfaces/vitest-plugin.mjs +36 -9
- package/lib/vitest/hooks.mjs +5 -1
- package/package.json +1 -1
- package/sdk.js +59 -6
- package/test/testdriver/exec-output.test.mjs +1 -1
- package/test/testdriver/exec-pwsh.test.mjs +1 -1
- package/test/testdriver/focus-window.test.mjs +1 -1
- package/test/testdriver/hover-image.test.mjs +1 -1
- package/test/testdriver/match-image.test.mjs +1 -1
- package/test/testdriver/scroll-keyboard.test.mjs +1 -1
- package/test/testdriver/scroll-until-image.test.mjs +1 -1
- package/test/testdriver/scroll-until-text.test.mjs +18 -1
- package/test/testdriver/scroll.test.mjs +1 -1
- package/test/testdriver/setup/lifecycleHelpers.mjs +105 -5
- package/test/testdriver/setup/testHelpers.mjs +6 -2
- package/vitest.config.mjs +2 -2
- package/test/testdriver/exec-js.test.mjs +0 -43
|
@@ -16,7 +16,7 @@ The `electron()` preset automatically sets up an Electron application with TestD
|
|
|
16
16
|
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
17
17
|
|
|
18
18
|
test('my test', async (context) => {
|
|
19
|
-
const testdriver = TestDriver(context);
|
|
19
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
20
20
|
await testdriver.provision.electron({
|
|
21
21
|
appPath: './dist/my-app'
|
|
22
22
|
});
|
|
@@ -31,16 +31,16 @@ The `electron()` preset automatically sets up an Electron application with TestD
|
|
|
31
31
|
|
|
32
32
|
```javascript
|
|
33
33
|
import { test } from 'vitest';
|
|
34
|
-
import {
|
|
34
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
35
35
|
|
|
36
36
|
test('electron app test', async (context) => {
|
|
37
|
-
const
|
|
38
|
-
appPath: './dist/my-app'
|
|
39
|
-
});
|
|
37
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
40
38
|
|
|
41
|
-
await
|
|
42
|
-
|
|
43
|
-
await
|
|
39
|
+
await testdriver.provision.electron({ appPath: './dist/my-app' });
|
|
40
|
+
|
|
41
|
+
await testdriver.find('main window').click();
|
|
42
|
+
await testdriver.find('File menu').click();
|
|
43
|
+
await testdriver.find('New Document').click();
|
|
44
44
|
});
|
|
45
45
|
```
|
|
46
46
|
|
|
@@ -98,15 +98,15 @@ electron(context, options): Promise<ElectronResult>
|
|
|
98
98
|
|
|
99
99
|
```javascript
|
|
100
100
|
import { test } from 'vitest';
|
|
101
|
-
import {
|
|
101
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
102
102
|
|
|
103
103
|
test('opens main window', async (context) => {
|
|
104
|
-
const
|
|
105
|
-
appPath: './dist/my-electron-app'
|
|
106
|
-
});
|
|
104
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
107
105
|
|
|
108
|
-
await
|
|
109
|
-
|
|
106
|
+
await testdriver.provision.electron({ appPath: './dist/my-electron-app' });
|
|
107
|
+
|
|
108
|
+
await testdriver.assert('Main window is visible');
|
|
109
|
+
await testdriver.find('Welcome message').click();
|
|
110
110
|
});
|
|
111
111
|
```
|
|
112
112
|
|
|
@@ -114,10 +114,12 @@ test('opens main window', async (context) => {
|
|
|
114
114
|
|
|
115
115
|
```javascript
|
|
116
116
|
import { test } from 'vitest';
|
|
117
|
-
import {
|
|
117
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
118
118
|
|
|
119
119
|
test('app with debug mode', async (context) => {
|
|
120
|
-
const
|
|
120
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
121
|
+
|
|
122
|
+
await testdriver.provision.electron({
|
|
121
123
|
appPath: './dist/app',
|
|
122
124
|
args: [
|
|
123
125
|
'--enable-logging',
|
|
@@ -126,8 +128,8 @@ test('app with debug mode', async (context) => {
|
|
|
126
128
|
]
|
|
127
129
|
});
|
|
128
130
|
|
|
129
|
-
await
|
|
130
|
-
await
|
|
131
|
+
await testdriver.find('Debug panel').click();
|
|
132
|
+
await testdriver.assert('Debug information is visible');
|
|
131
133
|
});
|
|
132
134
|
```
|
|
133
135
|
|
|
@@ -135,27 +137,27 @@ test('app with debug mode', async (context) => {
|
|
|
135
137
|
|
|
136
138
|
```javascript
|
|
137
139
|
import { test } from 'vitest';
|
|
138
|
-
import {
|
|
140
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
139
141
|
|
|
140
142
|
test('file menu operations', async (context) => {
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
});
|
|
143
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
144
|
+
|
|
145
|
+
await testdriver.provision.electron({ appPath: './dist/editor-app' });
|
|
144
146
|
|
|
145
147
|
// Open File menu
|
|
146
|
-
await
|
|
147
|
-
await
|
|
148
|
+
await testdriver.find('File').click();
|
|
149
|
+
await testdriver.find('New File').click();
|
|
148
150
|
|
|
149
151
|
// Verify new file created
|
|
150
|
-
await
|
|
152
|
+
await testdriver.assert('Untitled document is open');
|
|
151
153
|
|
|
152
154
|
// Save file
|
|
153
|
-
await
|
|
154
|
-
await
|
|
155
|
-
await
|
|
156
|
-
await
|
|
155
|
+
await testdriver.find('File').click();
|
|
156
|
+
await testdriver.find('Save As').click();
|
|
157
|
+
await testdriver.type('test-document.txt');
|
|
158
|
+
await testdriver.pressKeys(['enter']);
|
|
157
159
|
|
|
158
|
-
await
|
|
160
|
+
await testdriver.assert('File saved successfully');
|
|
159
161
|
});
|
|
160
162
|
```
|
|
161
163
|
|
|
@@ -163,24 +165,26 @@ test('file menu operations', async (context) => {
|
|
|
163
165
|
|
|
164
166
|
```javascript
|
|
165
167
|
import { test } from 'vitest';
|
|
166
|
-
import {
|
|
168
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
167
169
|
|
|
168
170
|
test('windows electron app', async (context) => {
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
171
|
+
const testdriver = TestDriver(context, { headless: true, os: 'windows' });
|
|
172
|
+
|
|
173
|
+
await testdriver.provision.electron({
|
|
174
|
+
appPath: 'C:\\Program Files\\MyApp\\MyApp.exe'
|
|
172
175
|
});
|
|
173
176
|
|
|
174
|
-
await
|
|
177
|
+
await testdriver.find('Start button').click();
|
|
175
178
|
});
|
|
176
179
|
|
|
177
180
|
test('mac electron app', async (context) => {
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
+
const testdriver = TestDriver(context, { headless: true, os: 'mac' });
|
|
182
|
+
|
|
183
|
+
await testdriver.provision.electron({
|
|
184
|
+
appPath: '/Applications/MyApp.app/Contents/MacOS/MyApp'
|
|
181
185
|
});
|
|
182
186
|
|
|
183
|
-
await
|
|
187
|
+
await testdriver.find('Start button').click();
|
|
184
188
|
});
|
|
185
189
|
```
|
|
186
190
|
|
|
@@ -188,27 +192,27 @@ test('mac electron app', async (context) => {
|
|
|
188
192
|
|
|
189
193
|
```javascript
|
|
190
194
|
import { test } from 'vitest';
|
|
191
|
-
import {
|
|
195
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
192
196
|
|
|
193
197
|
test('configure app settings', async (context) => {
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
});
|
|
198
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
199
|
+
|
|
200
|
+
await testdriver.provision.electron({ appPath: './dist/my-app' });
|
|
197
201
|
|
|
198
202
|
// Open preferences
|
|
199
|
-
await
|
|
203
|
+
await testdriver.find('Settings').click();
|
|
200
204
|
|
|
201
205
|
// Change theme
|
|
202
|
-
await
|
|
203
|
-
await
|
|
206
|
+
await testdriver.find('Appearance').click();
|
|
207
|
+
await testdriver.find('Dark mode toggle').click();
|
|
204
208
|
|
|
205
209
|
// Verify change
|
|
206
|
-
await
|
|
210
|
+
await testdriver.assert('Dark mode is enabled');
|
|
207
211
|
|
|
208
212
|
// Save settings
|
|
209
|
-
await
|
|
213
|
+
await testdriver.find('Save button').click();
|
|
210
214
|
|
|
211
|
-
await
|
|
215
|
+
await testdriver.assert('Settings saved');
|
|
212
216
|
});
|
|
213
217
|
```
|
|
214
218
|
|
|
@@ -216,25 +220,25 @@ test('configure app settings', async (context) => {
|
|
|
216
220
|
|
|
217
221
|
```javascript
|
|
218
222
|
import { test } from 'vitest';
|
|
219
|
-
import {
|
|
223
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
220
224
|
|
|
221
225
|
test('multiple windows', async (context) => {
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
});
|
|
226
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
227
|
+
|
|
228
|
+
await testdriver.provision.electron({ appPath: './dist/multi-window-app' });
|
|
225
229
|
|
|
226
230
|
// Open new window
|
|
227
|
-
await
|
|
228
|
-
await
|
|
231
|
+
await testdriver.find('File').click();
|
|
232
|
+
await testdriver.find('New Window').click();
|
|
229
233
|
|
|
230
234
|
// Switch between windows
|
|
231
|
-
await
|
|
232
|
-
await
|
|
235
|
+
await testdriver.find('second window').click();
|
|
236
|
+
await testdriver.assert('Second window is focused');
|
|
233
237
|
|
|
234
238
|
// Close window
|
|
235
|
-
await
|
|
239
|
+
await testdriver.find('Close button').click();
|
|
236
240
|
|
|
237
|
-
await
|
|
241
|
+
await testdriver.assert('Window closed');
|
|
238
242
|
});
|
|
239
243
|
```
|
|
240
244
|
|
|
@@ -242,29 +246,29 @@ test('multiple windows', async (context) => {
|
|
|
242
246
|
|
|
243
247
|
```javascript
|
|
244
248
|
import { test } from 'vitest';
|
|
245
|
-
import {
|
|
249
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
246
250
|
|
|
247
251
|
test('form submission', async (context) => {
|
|
248
|
-
const
|
|
249
|
-
|
|
250
|
-
});
|
|
252
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
253
|
+
|
|
254
|
+
await testdriver.provision.electron({ appPath: './dist/form-app' });
|
|
251
255
|
|
|
252
256
|
// Fill form
|
|
253
|
-
await
|
|
254
|
-
await
|
|
255
|
-
await
|
|
257
|
+
await testdriver.find('Name input').type('John Doe');
|
|
258
|
+
await testdriver.find('Email input').type('john@example.com');
|
|
259
|
+
await testdriver.find('Phone input').type('555-1234');
|
|
256
260
|
|
|
257
261
|
// Select dropdown
|
|
258
|
-
await
|
|
259
|
-
await
|
|
262
|
+
await testdriver.find('Country dropdown').click();
|
|
263
|
+
await testdriver.find('United States').click();
|
|
260
264
|
|
|
261
265
|
// Check checkbox
|
|
262
|
-
await
|
|
266
|
+
await testdriver.find('Terms and conditions').click();
|
|
263
267
|
|
|
264
268
|
// Submit
|
|
265
|
-
await
|
|
269
|
+
await testdriver.find('Submit button').click();
|
|
266
270
|
|
|
267
|
-
await
|
|
271
|
+
await testdriver.assert('Form submitted successfully');
|
|
268
272
|
|
|
269
273
|
// Dashcam captures entire interaction
|
|
270
274
|
});
|
|
@@ -291,15 +295,15 @@ At test end:
|
|
|
291
295
|
|
|
292
296
|
```javascript
|
|
293
297
|
test('ipc events', async (context) => {
|
|
294
|
-
const
|
|
295
|
-
|
|
296
|
-
});
|
|
298
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
299
|
+
|
|
300
|
+
await testdriver.provision.electron({ appPath: './dist/ipc-app' });
|
|
297
301
|
|
|
298
302
|
// Trigger IPC event from renderer
|
|
299
|
-
await
|
|
303
|
+
await testdriver.find('Send Message button').click();
|
|
300
304
|
|
|
301
305
|
// Verify main process response
|
|
302
|
-
await
|
|
306
|
+
await testdriver.assert('Response received from main process');
|
|
303
307
|
});
|
|
304
308
|
```
|
|
305
309
|
|
|
@@ -307,12 +311,12 @@ test('ipc events', async (context) => {
|
|
|
307
311
|
|
|
308
312
|
```javascript
|
|
309
313
|
test('system notifications', async (context) => {
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
});
|
|
314
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
315
|
+
|
|
316
|
+
await testdriver.provision.electron({ appPath: './dist/notification-app' });
|
|
313
317
|
|
|
314
|
-
await
|
|
315
|
-
await
|
|
318
|
+
await testdriver.find('Show Notification').click();
|
|
319
|
+
await testdriver.assert('System notification appears');
|
|
316
320
|
});
|
|
317
321
|
```
|
|
318
322
|
|
|
@@ -320,17 +324,17 @@ test('system notifications', async (context) => {
|
|
|
320
324
|
|
|
321
325
|
```javascript
|
|
322
326
|
test('system tray', async (context) => {
|
|
323
|
-
const
|
|
324
|
-
|
|
325
|
-
});
|
|
327
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
328
|
+
|
|
329
|
+
await testdriver.provision.electron({ appPath: './dist/tray-app' });
|
|
326
330
|
|
|
327
331
|
// Click tray icon
|
|
328
|
-
await
|
|
332
|
+
await testdriver.find('app tray icon').click();
|
|
329
333
|
|
|
330
334
|
// Interact with tray menu
|
|
331
|
-
await
|
|
335
|
+
await testdriver.find('Show Window').click();
|
|
332
336
|
|
|
333
|
-
await
|
|
337
|
+
await testdriver.assert('Main window appears');
|
|
334
338
|
});
|
|
335
339
|
```
|
|
336
340
|
|
|
@@ -338,17 +342,19 @@ test('system tray', async (context) => {
|
|
|
338
342
|
|
|
339
343
|
```javascript
|
|
340
344
|
test('app update', async (context) => {
|
|
341
|
-
const
|
|
345
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
346
|
+
|
|
347
|
+
await testdriver.provision.electron({
|
|
342
348
|
appPath: './dist/updatable-app',
|
|
343
349
|
args: ['--check-updates']
|
|
344
350
|
});
|
|
345
351
|
|
|
346
|
-
await
|
|
347
|
-
await
|
|
352
|
+
await testdriver.find('Check for Updates').click();
|
|
353
|
+
await testdriver.assert('Checking for updates message');
|
|
348
354
|
|
|
349
355
|
// Assuming update is available
|
|
350
|
-
await
|
|
351
|
-
await
|
|
356
|
+
await testdriver.find('Download Update').click();
|
|
357
|
+
await testdriver.assert('Update downloaded');
|
|
352
358
|
});
|
|
353
359
|
```
|
|
354
360
|
|
|
@@ -398,9 +404,8 @@ test('using provision', async (context) => {
|
|
|
398
404
|
```javascript
|
|
399
405
|
test('handles missing app path', async (context) => {
|
|
400
406
|
try {
|
|
401
|
-
const
|
|
402
|
-
|
|
403
|
-
});
|
|
407
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
408
|
+
await testdriver.provision.electron({ appPath: '/nonexistent/path' });
|
|
404
409
|
} catch (error) {
|
|
405
410
|
// Cleanup still happens automatically
|
|
406
411
|
expect(error.message).toContain('appPath');
|
|
@@ -408,13 +413,13 @@ test('handles missing app path', async (context) => {
|
|
|
408
413
|
});
|
|
409
414
|
|
|
410
415
|
test('handles app crashes', async (context) => {
|
|
411
|
-
const
|
|
412
|
-
|
|
413
|
-
});
|
|
416
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
417
|
+
|
|
418
|
+
await testdriver.provision.electron({ appPath: './dist/my-app' });
|
|
414
419
|
|
|
415
420
|
try {
|
|
416
421
|
// Trigger something that might crash
|
|
417
|
-
await
|
|
422
|
+
await testdriver.find('Crash button').click();
|
|
418
423
|
} catch (error) {
|
|
419
424
|
// Dashcam still saves replay of crash
|
|
420
425
|
console.error('App crashed:', error);
|
|
@@ -431,7 +436,9 @@ test('handles app crashes', async (context) => {
|
|
|
431
436
|
|
|
432
437
|
```javascript
|
|
433
438
|
test('with debugging enabled', async (context) => {
|
|
434
|
-
const
|
|
439
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
440
|
+
|
|
441
|
+
await testdriver.provision.electron({
|
|
435
442
|
appPath: './dist/my-app',
|
|
436
443
|
args: [
|
|
437
444
|
'--enable-logging',
|
|
@@ -13,13 +13,12 @@ The `webApp()` preset provides a generic interface for testing web applications.
|
|
|
13
13
|
|
|
14
14
|
```javascript
|
|
15
15
|
import { test } from 'vitest';
|
|
16
|
-
import {
|
|
16
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
17
17
|
|
|
18
18
|
test('web app test', async (context) => {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
});
|
|
19
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
20
|
+
|
|
21
|
+
await testdriver.provision.chrome({ url: 'https://myapp.com' });
|
|
23
22
|
|
|
24
23
|
await testdriver.find('Login button').click();
|
|
25
24
|
});
|
|
@@ -83,12 +82,12 @@ webApp(context, options): Promise<WebAppResult>
|
|
|
83
82
|
|
|
84
83
|
```javascript
|
|
85
84
|
import { test } from 'vitest';
|
|
86
|
-
import {
|
|
85
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
87
86
|
|
|
88
87
|
test('user login flow', async (context) => {
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
});
|
|
88
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
89
|
+
|
|
90
|
+
await testdriver.provision.chrome({ url: 'https://myapp.com/login' });
|
|
92
91
|
|
|
93
92
|
await testdriver.find('email input').type('user@example.com');
|
|
94
93
|
await testdriver.find('password input').type('password123');
|
|
@@ -102,12 +101,12 @@ test('user login flow', async (context) => {
|
|
|
102
101
|
|
|
103
102
|
```javascript
|
|
104
103
|
import { test } from 'vitest';
|
|
105
|
-
import {
|
|
104
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
106
105
|
|
|
107
106
|
test('product purchase', async (context) => {
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
});
|
|
107
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
108
|
+
|
|
109
|
+
await testdriver.provision.chrome({ url: 'https://shop.example.com' });
|
|
111
110
|
|
|
112
111
|
// Search for product
|
|
113
112
|
await testdriver.find('search input').type('laptop');
|
|
@@ -131,12 +130,12 @@ test('product purchase', async (context) => {
|
|
|
131
130
|
|
|
132
131
|
```javascript
|
|
133
132
|
import { test } from 'vitest';
|
|
134
|
-
import {
|
|
133
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
135
134
|
|
|
136
135
|
test('single page app routing', async (context) => {
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
});
|
|
136
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
137
|
+
|
|
138
|
+
await testdriver.provision.chrome({ url: 'https://spa.example.com' });
|
|
140
139
|
|
|
141
140
|
// Navigate through SPA routes
|
|
142
141
|
await testdriver.find('About link').click();
|
|
@@ -154,12 +153,12 @@ test('single page app routing', async (context) => {
|
|
|
154
153
|
|
|
155
154
|
```javascript
|
|
156
155
|
import { test } from 'vitest';
|
|
157
|
-
import {
|
|
156
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
158
157
|
|
|
159
158
|
test('form validation errors', async (context) => {
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
});
|
|
159
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
160
|
+
|
|
161
|
+
await testdriver.provision.chrome({ url: 'https://myapp.com/register' });
|
|
163
162
|
|
|
164
163
|
// Submit empty form
|
|
165
164
|
await testdriver.find('Submit button').click();
|
|
@@ -183,12 +182,12 @@ test('form validation errors', async (context) => {
|
|
|
183
182
|
|
|
184
183
|
```javascript
|
|
185
184
|
import { test } from 'vitest';
|
|
186
|
-
import {
|
|
185
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
187
186
|
|
|
188
187
|
test('data fetching and display', async (context) => {
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
-
});
|
|
188
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
189
|
+
|
|
190
|
+
await testdriver.provision.chrome({ url: 'https://api-demo.example.com' });
|
|
192
191
|
|
|
193
192
|
// Trigger data fetch
|
|
194
193
|
await testdriver.find('Load Data button').click();
|
|
@@ -208,13 +207,12 @@ test('data fetching and display', async (context) => {
|
|
|
208
207
|
|
|
209
208
|
```javascript
|
|
210
209
|
import { test } from 'vitest';
|
|
211
|
-
import {
|
|
210
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
212
211
|
|
|
213
212
|
test('mobile menu', async (context) => {
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
});
|
|
213
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
214
|
+
|
|
215
|
+
await testdriver.provision.chrome({ url: 'https://responsive.example.com' });
|
|
218
216
|
|
|
219
217
|
// Resize to mobile
|
|
220
218
|
await testdriver.exec('sh', 'xdotool getactivewindow windowsize 375 667', 5000);
|
|
@@ -231,13 +229,12 @@ test('mobile menu', async (context) => {
|
|
|
231
229
|
|
|
232
230
|
## Browser Support
|
|
233
231
|
|
|
234
|
-
Currently
|
|
232
|
+
Currently supports Chrome:
|
|
235
233
|
|
|
236
234
|
```javascript
|
|
237
235
|
// ✅ Supported
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
});
|
|
236
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
237
|
+
await testdriver.provision.chrome({ url: 'https://myapp.com' });
|
|
241
238
|
|
|
242
239
|
// ❌ Not yet supported
|
|
243
240
|
const { testdriver } = await webApp(context, {
|
|
@@ -310,9 +307,9 @@ The behavior is identical, but `webApp()` provides a more generic interface for
|
|
|
310
307
|
|
|
311
308
|
```javascript
|
|
312
309
|
test('login and navigate', async (context) => {
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
});
|
|
310
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
311
|
+
|
|
312
|
+
await testdriver.provision.chrome({ url: 'https://myapp.com' });
|
|
316
313
|
|
|
317
314
|
// Login
|
|
318
315
|
await testdriver.find('email').type('user@example.com');
|
|
@@ -332,9 +329,9 @@ test('login and navigate', async (context) => {
|
|
|
332
329
|
|
|
333
330
|
```javascript
|
|
334
331
|
test('upload file', async (context) => {
|
|
335
|
-
const
|
|
336
|
-
|
|
337
|
-
});
|
|
332
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
333
|
+
|
|
334
|
+
await testdriver.provision.chrome({ url: 'https://upload.example.com' });
|
|
338
335
|
|
|
339
336
|
// Click upload button
|
|
340
337
|
await testdriver.find('Upload file button').click();
|
|
@@ -352,9 +349,9 @@ test('upload file', async (context) => {
|
|
|
352
349
|
|
|
353
350
|
```javascript
|
|
354
351
|
test('search with filters', async (context) => {
|
|
355
|
-
const
|
|
356
|
-
|
|
357
|
-
});
|
|
352
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
353
|
+
|
|
354
|
+
await testdriver.provision.chrome({ url: 'https://catalog.example.com' });
|
|
358
355
|
|
|
359
356
|
// Enter search query
|
|
360
357
|
await testdriver.find('search input').type('laptop');
|
|
@@ -202,8 +202,8 @@ dotenv.config();
|
|
|
202
202
|
export default defineConfig({
|
|
203
203
|
plugins: [TestDriver()],
|
|
204
204
|
test: {
|
|
205
|
-
testTimeout:
|
|
206
|
-
hookTimeout:
|
|
205
|
+
testTimeout: 300000,
|
|
206
|
+
hookTimeout: 300000,
|
|
207
207
|
},
|
|
208
208
|
});
|
|
209
209
|
`;
|
|
@@ -315,7 +315,7 @@ jobs:
|
|
|
315
315
|
console.log(chalk.cyan("\n Installing dependencies...\n"));
|
|
316
316
|
|
|
317
317
|
try {
|
|
318
|
-
execSync("npm install -D vitest testdriverai && npm install dotenv", {
|
|
318
|
+
execSync("npm install -D vitest testdriverai@beta && npm install dotenv", {
|
|
319
319
|
cwd: process.cwd(),
|
|
320
320
|
stdio: "inherit"
|
|
321
321
|
});
|
|
@@ -326,7 +326,7 @@ jobs:
|
|
|
326
326
|
"\n⚠️ Failed to install dependencies automatically. Please run:",
|
|
327
327
|
),
|
|
328
328
|
);
|
|
329
|
-
console.log(chalk.gray(" npm install -D vitest testdriverai"));
|
|
329
|
+
console.log(chalk.gray(" npm install -D vitest testdriverai@beta"));
|
|
330
330
|
console.log(chalk.gray(" npm install dotenv\n"));
|
|
331
331
|
}
|
|
332
332
|
}
|