@vitest/browser 3.1.2 → 3.2.0-beta.1
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/dist/client/.vite/manifest.json +1 -1
- package/dist/client/__vitest__/assets/{index-Cv3XDLXs.js → index-BZjudRZr.js} +12 -12
- package/dist/client/__vitest__/assets/{index-D6BhetW8.css → index-DJfrXR3P.css} +1 -1
- package/dist/client/__vitest__/index.html +2 -2
- package/dist/client/__vitest_browser__/{tester-D8qCxA_3.js → tester-D-yxPeOx.js} +5 -5
- package/dist/client/error-catcher.js +1 -14
- package/dist/client/tester/tester.html +1 -1
- package/dist/client.js +19 -8
- package/dist/expect-element.js +1 -1
- package/dist/{index-C34csx3Z.js → index-C3ICQ6zz.js} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +36 -16
- package/dist/locators/index.js +1 -1
- package/dist/locators/playwright.js +1 -1
- package/dist/locators/preview.js +1 -1
- package/dist/locators/webdriverio.js +1 -1
- package/dist/providers.js +3 -1
- package/dist/{public-utils-xf4CCUzp.js → public-utils-DUr23h1p.js} +2 -2
- package/dist/utils.js +1 -1
- package/dist/{webdriver-BzjiKqT8.js → webdriver-D7k26Na7.js} +75 -5
- package/package.json +12 -12
- package/providers/playwright.d.ts +6 -1
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { createManualModuleSource } from '@vitest/mocker/node';
|
|
2
|
+
import c from 'tinyrainbow';
|
|
3
|
+
import { createDebugger } from 'vitest/node';
|
|
2
4
|
|
|
5
|
+
const debug$1 = createDebugger("vitest:browser:playwright");
|
|
3
6
|
const playwrightBrowsers = [
|
|
4
7
|
"firefox",
|
|
5
8
|
"webkit",
|
|
@@ -16,25 +19,41 @@ class PlaywrightBrowserProvider {
|
|
|
16
19
|
pages = new Map();
|
|
17
20
|
browserPromise = null;
|
|
18
21
|
mocker;
|
|
22
|
+
closing = false;
|
|
19
23
|
getSupportedBrowsers() {
|
|
20
24
|
return playwrightBrowsers;
|
|
21
25
|
}
|
|
22
26
|
initialize(project, { browser, options }) {
|
|
27
|
+
this.closing = false;
|
|
23
28
|
this.project = project;
|
|
24
29
|
this.browserName = browser;
|
|
25
30
|
this.options = options;
|
|
26
31
|
this.mocker = this.createMocker();
|
|
27
32
|
}
|
|
28
33
|
async openBrowser() {
|
|
34
|
+
await this._throwIfClosing();
|
|
29
35
|
if (this.browserPromise) {
|
|
36
|
+
debug$1?.("[%s] the browser is resolving, reusing the promise", this.browserName);
|
|
30
37
|
return this.browserPromise;
|
|
31
38
|
}
|
|
32
39
|
if (this.browser) {
|
|
40
|
+
debug$1?.("[%s] the browser is resolved, reusing it", this.browserName);
|
|
33
41
|
return this.browser;
|
|
34
42
|
}
|
|
35
43
|
this.browserPromise = (async () => {
|
|
36
44
|
const options = this.project.config.browser;
|
|
37
45
|
const playwright = await import('playwright');
|
|
46
|
+
if (this.options?.connect) {
|
|
47
|
+
if (this.options.launch) {
|
|
48
|
+
this.project.vitest.logger.warn(c.yellow(`Found both ${c.bold(c.italic(c.yellow("connect")))} and ${c.bold(c.italic(c.yellow("launch")))} options in browser instance configuration.
|
|
49
|
+
Ignoring ${c.bold(c.italic(c.yellow("launch")))} options and using ${c.bold(c.italic(c.yellow("connect")))} mode.
|
|
50
|
+
You probably want to remove one of the two options and keep only the one you want to use.`));
|
|
51
|
+
}
|
|
52
|
+
const browser = await playwright[this.browserName].connect(this.options.connect.wsEndpoint, this.options.connect.options);
|
|
53
|
+
this.browser = browser;
|
|
54
|
+
this.browserPromise = null;
|
|
55
|
+
return this.browser;
|
|
56
|
+
}
|
|
38
57
|
const launchOptions = {
|
|
39
58
|
...this.options?.launch,
|
|
40
59
|
headless: options.headless
|
|
@@ -55,8 +74,8 @@ class PlaywrightBrowserProvider {
|
|
|
55
74
|
launchOptions.args.push("--start-maximized");
|
|
56
75
|
}
|
|
57
76
|
}
|
|
58
|
-
|
|
59
|
-
this.browser =
|
|
77
|
+
debug$1?.("[%s] initializing the browser with launch options: %O", this.browserName, launchOptions);
|
|
78
|
+
this.browser = await playwright[this.browserName].launch(launchOptions);
|
|
60
79
|
this.browserPromise = null;
|
|
61
80
|
return this.browser;
|
|
62
81
|
})();
|
|
@@ -166,10 +185,13 @@ class PlaywrightBrowserProvider {
|
|
|
166
185
|
};
|
|
167
186
|
}
|
|
168
187
|
async createContext(sessionId) {
|
|
188
|
+
await this._throwIfClosing();
|
|
169
189
|
if (this.contexts.has(sessionId)) {
|
|
190
|
+
debug$1?.("[%s][%s] the context already exists, reusing it", sessionId, this.browserName);
|
|
170
191
|
return this.contexts.get(sessionId);
|
|
171
192
|
}
|
|
172
193
|
const browser = await this.openBrowser();
|
|
194
|
+
await this._throwIfClosing(browser);
|
|
173
195
|
const { actionTimeout,...contextOptions } = this.options?.context ?? {};
|
|
174
196
|
const options = {
|
|
175
197
|
...contextOptions,
|
|
@@ -179,9 +201,11 @@ class PlaywrightBrowserProvider {
|
|
|
179
201
|
options.viewport = null;
|
|
180
202
|
}
|
|
181
203
|
const context = await browser.newContext(options);
|
|
204
|
+
await this._throwIfClosing(context);
|
|
182
205
|
if (actionTimeout) {
|
|
183
206
|
context.setDefaultTimeout(actionTimeout);
|
|
184
207
|
}
|
|
208
|
+
debug$1?.("[%s][%s] the context is ready", sessionId, this.browserName);
|
|
185
209
|
this.contexts.set(sessionId, context);
|
|
186
210
|
return context;
|
|
187
211
|
}
|
|
@@ -219,13 +243,17 @@ class PlaywrightBrowserProvider {
|
|
|
219
243
|
};
|
|
220
244
|
}
|
|
221
245
|
async openBrowserPage(sessionId) {
|
|
246
|
+
await this._throwIfClosing();
|
|
222
247
|
if (this.pages.has(sessionId)) {
|
|
248
|
+
debug$1?.("[%s][%s] the page already exists, closing the old one", sessionId, this.browserName);
|
|
223
249
|
const page = this.pages.get(sessionId);
|
|
224
250
|
await page.close();
|
|
225
251
|
this.pages.delete(sessionId);
|
|
226
252
|
}
|
|
227
253
|
const context = await this.createContext(sessionId);
|
|
228
254
|
const page = await context.newPage();
|
|
255
|
+
debug$1?.("[%s][%s] the page is ready", sessionId, this.browserName);
|
|
256
|
+
await this._throwIfClosing(page);
|
|
229
257
|
this.pages.set(sessionId, page);
|
|
230
258
|
if (process.env.VITEST_PW_DEBUG) {
|
|
231
259
|
page.on("requestfailed", (request) => {
|
|
@@ -235,9 +263,23 @@ class PlaywrightBrowserProvider {
|
|
|
235
263
|
return page;
|
|
236
264
|
}
|
|
237
265
|
async openPage(sessionId, url, beforeNavigate) {
|
|
266
|
+
debug$1?.("[%s][%s] creating the browser page for %s", sessionId, this.browserName, url);
|
|
238
267
|
const browserPage = await this.openBrowserPage(sessionId);
|
|
239
268
|
await beforeNavigate?.();
|
|
269
|
+
debug$1?.("[%s][%s] browser page is created, opening %s", sessionId, this.browserName, url);
|
|
240
270
|
await browserPage.goto(url, { timeout: 0 });
|
|
271
|
+
await this._throwIfClosing(browserPage);
|
|
272
|
+
}
|
|
273
|
+
async _throwIfClosing(disposable) {
|
|
274
|
+
if (this.closing) {
|
|
275
|
+
debug$1?.("[%s] provider was closed, cannot perform the action on %s", this.browserName, String(disposable));
|
|
276
|
+
await disposable?.close();
|
|
277
|
+
this.pages.clear();
|
|
278
|
+
this.contexts.clear();
|
|
279
|
+
this.browser = null;
|
|
280
|
+
this.browserPromise = null;
|
|
281
|
+
throw new Error(`[vitest] The provider was closed.`);
|
|
282
|
+
}
|
|
241
283
|
}
|
|
242
284
|
async getCDPSession(sessionid) {
|
|
243
285
|
const page = this.getPage(sessionid);
|
|
@@ -259,13 +301,20 @@ class PlaywrightBrowserProvider {
|
|
|
259
301
|
};
|
|
260
302
|
}
|
|
261
303
|
async close() {
|
|
304
|
+
debug$1?.("[%s] closing provider", this.browserName);
|
|
305
|
+
this.closing = true;
|
|
262
306
|
const browser = this.browser;
|
|
263
307
|
this.browser = null;
|
|
308
|
+
if (this.browserPromise) {
|
|
309
|
+
await this.browserPromise;
|
|
310
|
+
this.browserPromise = null;
|
|
311
|
+
}
|
|
264
312
|
await Promise.all([...this.pages.values()].map((p) => p.close()));
|
|
265
313
|
this.pages.clear();
|
|
266
314
|
await Promise.all([...this.contexts.values()].map((c) => c.close()));
|
|
267
315
|
this.contexts.clear();
|
|
268
316
|
await browser?.close();
|
|
317
|
+
debug$1?.("[%s] provider is closed", this.browserName);
|
|
269
318
|
}
|
|
270
319
|
}
|
|
271
320
|
function getHeaders(config) {
|
|
@@ -295,6 +344,7 @@ function isDirectCSSRequest(request) {
|
|
|
295
344
|
return CSS_LANGS_RE.test(request) && directRequestRE.test(request);
|
|
296
345
|
}
|
|
297
346
|
|
|
347
|
+
const debug = createDebugger("vitest:browser:wdio");
|
|
298
348
|
const webdriverBrowsers = [
|
|
299
349
|
"firefox",
|
|
300
350
|
"chrome",
|
|
@@ -308,10 +358,12 @@ class WebdriverBrowserProvider {
|
|
|
308
358
|
browserName;
|
|
309
359
|
project;
|
|
310
360
|
options;
|
|
361
|
+
closing = false;
|
|
311
362
|
getSupportedBrowsers() {
|
|
312
363
|
return webdriverBrowsers;
|
|
313
364
|
}
|
|
314
365
|
async initialize(ctx, { browser, options }) {
|
|
366
|
+
this.closing = false;
|
|
315
367
|
this.project = ctx;
|
|
316
368
|
this.browserName = browser;
|
|
317
369
|
this.options = options;
|
|
@@ -337,7 +389,9 @@ class WebdriverBrowserProvider {
|
|
|
337
389
|
return { browser: this.browser };
|
|
338
390
|
}
|
|
339
391
|
async openBrowser() {
|
|
392
|
+
await this._throwIfClosing("opening the browser");
|
|
340
393
|
if (this.browser) {
|
|
394
|
+
debug?.("[%s] the browser is already opened, reusing it", this.browserName);
|
|
341
395
|
return this.browser;
|
|
342
396
|
}
|
|
343
397
|
const options = this.project.config.browser;
|
|
@@ -347,11 +401,14 @@ class WebdriverBrowserProvider {
|
|
|
347
401
|
}
|
|
348
402
|
}
|
|
349
403
|
const { remote } = await import('webdriverio');
|
|
350
|
-
|
|
404
|
+
const remoteOptions = {
|
|
351
405
|
...this.options,
|
|
352
406
|
logLevel: "error",
|
|
353
407
|
capabilities: this.buildCapabilities()
|
|
354
|
-
}
|
|
408
|
+
};
|
|
409
|
+
debug?.("[%s] opening the browser with options: %O", this.browserName, remoteOptions);
|
|
410
|
+
this.browser = await remote(remoteOptions);
|
|
411
|
+
await this._throwIfClosing();
|
|
355
412
|
return this.browser;
|
|
356
413
|
}
|
|
357
414
|
buildCapabilities() {
|
|
@@ -386,11 +443,24 @@ class WebdriverBrowserProvider {
|
|
|
386
443
|
}
|
|
387
444
|
return capabilities;
|
|
388
445
|
}
|
|
389
|
-
async openPage(
|
|
446
|
+
async openPage(sessionId, url) {
|
|
447
|
+
await this._throwIfClosing("creating the browser");
|
|
448
|
+
debug?.("[%s][%s] creating the browser page for %s", sessionId, this.browserName, url);
|
|
390
449
|
const browserInstance = await this.openBrowser();
|
|
450
|
+
debug?.("[%s][%s] browser page is created, opening %s", sessionId, this.browserName, url);
|
|
391
451
|
await browserInstance.url(url);
|
|
452
|
+
await this._throwIfClosing("opening the url");
|
|
453
|
+
}
|
|
454
|
+
async _throwIfClosing(action) {
|
|
455
|
+
if (this.closing) {
|
|
456
|
+
debug?.(`[%s] provider was closed, cannot perform the action${action ? ` ${action}` : ""}`, this.browserName);
|
|
457
|
+
await (this.browser?.sessionId ? this.browser?.deleteSession?.() : null);
|
|
458
|
+
throw new Error(`[vitest] The provider was closed.`);
|
|
459
|
+
}
|
|
392
460
|
}
|
|
393
461
|
async close() {
|
|
462
|
+
debug?.("[%s] closing provider", this.browserName);
|
|
463
|
+
this.closing = true;
|
|
394
464
|
await Promise.all([this.browser?.sessionId ? this.browser?.deleteSession?.() : null]);
|
|
395
465
|
process.exit();
|
|
396
466
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitest/browser",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.1
|
|
4
|
+
"version": "3.2.0-beta.1",
|
|
5
5
|
"description": "Browser running for Vitest",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"funding": "https://opencollective.com/vitest",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"peerDependencies": {
|
|
67
67
|
"playwright": "*",
|
|
68
68
|
"webdriverio": "^7.0.0 || ^8.0.0 || ^9.0.0",
|
|
69
|
-
"vitest": "3.1
|
|
69
|
+
"vitest": "3.2.0-beta.1"
|
|
70
70
|
},
|
|
71
71
|
"peerDependenciesMeta": {
|
|
72
72
|
"playwright": {
|
|
@@ -86,27 +86,27 @@
|
|
|
86
86
|
"sirv": "^3.0.1",
|
|
87
87
|
"tinyrainbow": "^2.0.0",
|
|
88
88
|
"ws": "^8.18.1",
|
|
89
|
-
"@vitest/
|
|
90
|
-
"@vitest/
|
|
89
|
+
"@vitest/mocker": "3.2.0-beta.1",
|
|
90
|
+
"@vitest/utils": "3.2.0-beta.1"
|
|
91
91
|
},
|
|
92
92
|
"devDependencies": {
|
|
93
93
|
"@types/ws": "^8.18.1",
|
|
94
94
|
"@wdio/protocols": "^9.12.5",
|
|
95
|
-
"@wdio/types": "^9.12.
|
|
95
|
+
"@wdio/types": "^9.12.6",
|
|
96
96
|
"birpc": "2.3.0",
|
|
97
97
|
"flatted": "^3.3.3",
|
|
98
98
|
"ivya": "^1.6.0",
|
|
99
99
|
"mime": "^4.0.7",
|
|
100
100
|
"pathe": "^2.0.3",
|
|
101
101
|
"periscopic": "^4.0.2",
|
|
102
|
-
"playwright": "^1.
|
|
103
|
-
"playwright-core": "^1.
|
|
102
|
+
"playwright": "^1.52.0",
|
|
103
|
+
"playwright-core": "^1.52.0",
|
|
104
104
|
"safaridriver": "^1.0.0",
|
|
105
|
-
"webdriverio": "^9.12.
|
|
106
|
-
"@vitest/runner": "3.1
|
|
107
|
-
"@vitest/ui": "3.1
|
|
108
|
-
"
|
|
109
|
-
"vitest": "3.1
|
|
105
|
+
"webdriverio": "^9.12.7",
|
|
106
|
+
"@vitest/runner": "3.2.0-beta.1",
|
|
107
|
+
"@vitest/ui": "3.2.0-beta.1",
|
|
108
|
+
"vitest": "3.2.0-beta.1",
|
|
109
|
+
"@vitest/ws-client": "3.2.0-beta.1"
|
|
110
110
|
},
|
|
111
111
|
"scripts": {
|
|
112
112
|
"build": "rimraf dist && pnpm build:node && pnpm build:client",
|
|
@@ -5,7 +5,8 @@ import type {
|
|
|
5
5
|
FrameLocator,
|
|
6
6
|
LaunchOptions,
|
|
7
7
|
Page,
|
|
8
|
-
CDPSession
|
|
8
|
+
CDPSession,
|
|
9
|
+
ConnectOptions
|
|
9
10
|
} from 'playwright'
|
|
10
11
|
import { Protocol } from 'playwright-core/types/protocol'
|
|
11
12
|
import '../matchers.js'
|
|
@@ -14,6 +15,10 @@ import type {} from "vitest/node"
|
|
|
14
15
|
declare module 'vitest/node' {
|
|
15
16
|
export interface BrowserProviderOptions {
|
|
16
17
|
launch?: LaunchOptions
|
|
18
|
+
connect?: {
|
|
19
|
+
wsEndpoint: string
|
|
20
|
+
options?: ConnectOptions
|
|
21
|
+
}
|
|
17
22
|
context?: Omit<
|
|
18
23
|
BrowserContextOptions,
|
|
19
24
|
'ignoreHTTPSErrors' | 'serviceWorkers'
|