testdriverai 7.1.2 → 7.1.4
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/.github/workflows/test-init.yml +145 -0
- package/agent/lib/commander.js +2 -2
- package/agent/lib/commands.js +10 -5
- package/docs/docs.json +29 -84
- package/docs/v7/_drafts/migration.mdx +3 -3
- package/docs/v7/api/act.mdx +1 -1
- package/docs/v7/api/assert.mdx +1 -1
- package/docs/v7/api/assertions.mdx +14 -14
- 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/overview/readme.mdx +1 -1
- 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 +79 -21
- package/interfaces/vitest-plugin.mjs +36 -9
- package/lib/vitest/hooks.mjs +5 -1
- package/manual/test-init-command.js +223 -0
- package/package.json +2 -2
- package/schema.json +5 -5
- package/sdk-log-formatter.js +1 -1
- package/sdk.d.ts +8 -8
- package/sdk.js +64 -14
- 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/hover-text-with-description.test.mjs +0 -3
- 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 +7 -2
- package/test/testdriver/exec-js.test.mjs +0 -43
|
@@ -16,7 +16,7 @@ The `chrome()` preset automatically sets up a Chrome browser with TestDriver and
|
|
|
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.chrome({ url: 'https://example.com' });
|
|
21
21
|
// ...
|
|
22
22
|
});
|
|
@@ -29,12 +29,12 @@ The `chrome()` preset automatically sets up a Chrome browser with TestDriver and
|
|
|
29
29
|
|
|
30
30
|
```javascript
|
|
31
31
|
import { test } from 'vitest';
|
|
32
|
-
import {
|
|
32
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
33
33
|
|
|
34
34
|
test('login test', async (context) => {
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
});
|
|
35
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
36
|
+
|
|
37
|
+
await testdriver.provision.chrome({ url: 'https://myapp.com/login' });
|
|
38
38
|
|
|
39
39
|
await testdriver.find('email input').type('user@example.com');
|
|
40
40
|
await testdriver.find('password input').type('password123');
|
|
@@ -98,12 +98,12 @@ chrome(context, options): Promise<ChromeResult>
|
|
|
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('search functionality', async (context) => {
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
});
|
|
104
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
105
|
+
|
|
106
|
+
await testdriver.provision.chrome({ url: 'https://example.com' });
|
|
107
107
|
|
|
108
108
|
await testdriver.find('search input').type('TestDriver');
|
|
109
109
|
await testdriver.find('search button').click();
|
|
@@ -115,13 +115,12 @@ test('search functionality', async (context) => {
|
|
|
115
115
|
|
|
116
116
|
```javascript
|
|
117
117
|
import { test, expect } from 'vitest';
|
|
118
|
-
import {
|
|
118
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
119
119
|
|
|
120
120
|
test('checkout flow', async (context) => {
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
});
|
|
121
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
122
|
+
|
|
123
|
+
await testdriver.provision.chrome({ url: 'https://shop.example.com' });
|
|
125
124
|
|
|
126
125
|
// Add items to cart
|
|
127
126
|
await testdriver.find('Add to Cart button').click();
|
|
@@ -149,22 +148,20 @@ test('checkout flow', async (context) => {
|
|
|
149
148
|
|
|
150
149
|
```javascript
|
|
151
150
|
import { test } from 'vitest';
|
|
152
|
-
import {
|
|
151
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
153
152
|
|
|
154
153
|
test('windows chrome test', async (context) => {
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
});
|
|
154
|
+
const testdriver = TestDriver(context, { headless: true, os: 'windows' });
|
|
155
|
+
|
|
156
|
+
await testdriver.provision.chrome({ url: 'https://myapp.com' });
|
|
159
157
|
|
|
160
158
|
await testdriver.find('Start').click();
|
|
161
159
|
});
|
|
162
160
|
|
|
163
161
|
test('mac chrome test', async (context) => {
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
});
|
|
162
|
+
const testdriver = TestDriver(context, { headless: true, os: 'mac' });
|
|
163
|
+
|
|
164
|
+
await testdriver.provision.chrome({ url: 'https://myapp.com' });
|
|
168
165
|
|
|
169
166
|
await testdriver.find('Start').click();
|
|
170
167
|
});
|
|
@@ -174,13 +171,12 @@ test('mac chrome test', async (context) => {
|
|
|
174
171
|
|
|
175
172
|
```javascript
|
|
176
173
|
import { test } from 'vitest';
|
|
177
|
-
import {
|
|
174
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
178
175
|
|
|
179
176
|
test('quick test without recording', async (context) => {
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
});
|
|
177
|
+
const testdriver = TestDriver(context, { headless: true, dashcam: false });
|
|
178
|
+
|
|
179
|
+
await testdriver.provision.chrome({ url: 'https://example.com' });
|
|
184
180
|
|
|
185
181
|
await testdriver.find('button').click();
|
|
186
182
|
});
|
|
@@ -190,13 +186,14 @@ test('quick test without recording', async (context) => {
|
|
|
190
186
|
|
|
191
187
|
```javascript
|
|
192
188
|
import { test } from 'vitest';
|
|
193
|
-
import {
|
|
189
|
+
import { TestDriver } from 'testdriverai/vitest/hooks';
|
|
194
190
|
|
|
195
191
|
test('chrome extension', async (context) => {
|
|
196
|
-
const
|
|
192
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
193
|
+
|
|
194
|
+
await testdriver.provision.chrome({
|
|
197
195
|
url: 'chrome://extensions',
|
|
198
|
-
guest: false
|
|
199
|
-
maximized: true
|
|
196
|
+
guest: false // Need profile for extensions
|
|
200
197
|
});
|
|
201
198
|
|
|
202
199
|
await testdriver.find('Developer mode toggle').click();
|
|
@@ -226,9 +223,9 @@ At test end:
|
|
|
226
223
|
|
|
227
224
|
```javascript
|
|
228
225
|
test('user registration', async (context) => {
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
});
|
|
226
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
227
|
+
|
|
228
|
+
await testdriver.provision.chrome({ url: 'https://myapp.com/register' });
|
|
232
229
|
|
|
233
230
|
await testdriver.find('email field').type('user@example.com');
|
|
234
231
|
await testdriver.find('password field').type('SecurePass123!');
|
|
@@ -244,9 +241,9 @@ test('user registration', async (context) => {
|
|
|
244
241
|
|
|
245
242
|
```javascript
|
|
246
243
|
test('multi-page navigation', async (context) => {
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
});
|
|
244
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
245
|
+
|
|
246
|
+
await testdriver.provision.chrome({ url: 'https://myapp.com' });
|
|
250
247
|
|
|
251
248
|
// Navigate through pages
|
|
252
249
|
await testdriver.find('About link').click();
|
|
@@ -265,9 +262,9 @@ test('multi-page navigation', async (context) => {
|
|
|
265
262
|
```javascript
|
|
266
263
|
test('handles errors gracefully', async (context) => {
|
|
267
264
|
try {
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
});
|
|
265
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
266
|
+
|
|
267
|
+
await testdriver.provision.chrome({ url: 'https://myapp.com' });
|
|
271
268
|
|
|
272
269
|
await testdriver.find('non-existent element').click();
|
|
273
270
|
} catch (error) {
|
|
@@ -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',
|