@vitest/browser 2.1.0-beta.6 → 2.1.0
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/context.d.ts +11 -0
- package/dist/client/.vite/manifest.json +6 -6
- package/dist/client/__vitest__/assets/{index-BevOiAy-.css → index-D5rK8X7L.css} +1 -1
- package/dist/client/__vitest__/assets/index-DsWp6aFQ.js +52 -0
- package/dist/client/__vitest__/index.html +2 -2
- package/dist/client/__vitest_browser__/{orchestrator-CoMoQEYq.js → orchestrator-qtq9EW1J.js} +243 -91
- package/dist/client/__vitest_browser__/preload-helper-D-WYp1PK.js +317 -0
- package/dist/client/__vitest_browser__/{tester-C7y_vb57.js → tester-Bm6k0JOu.js} +585 -371
- package/dist/client/esm-client-injector.js +1 -0
- package/dist/client/orchestrator.html +2 -2
- package/dist/client/tester/tester.html +2 -2
- package/dist/context.js +39 -23
- package/dist/{index-DcU_z8HM.js → index-Cgg35wOd.js} +19 -0
- package/dist/index.d.ts +7 -13
- package/dist/index.js +272 -287
- package/dist/locators/index.d.ts +1 -0
- package/dist/locators/index.js +1 -1
- package/dist/locators/playwright.js +1 -1
- package/dist/locators/preview.js +15 -2
- package/dist/locators/webdriverio.js +1 -1
- package/dist/providers.js +1 -1
- package/dist/state.js +1 -1
- package/dist/{webdriver-BdVqnfdE.js → webdriver-Cv9wga63.js} +10 -1
- package/package.json +10 -7
- package/dist/client/__vitest__/assets/index-D7jfm8wn.js +0 -52
- package/dist/client/__vitest_browser__/preload-helper-YsBSwBkS.js +0 -310
package/dist/index.js
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
|
-
import { createDebugger, isFileServingAllowed, getFilePoolName, resolveApiServerConfig, resolveFsAllow, distDir,
|
|
2
|
-
import
|
|
1
|
+
import { createDebugger, isFileServingAllowed, getFilePoolName, resolveApiServerConfig, resolveFsAllow, distDir, createViteLogger, createViteServer } from 'vitest/node';
|
|
2
|
+
import c from 'tinyrainbow';
|
|
3
|
+
import fs, { existsSync, promises, readFileSync, lstatSync } from 'node:fs';
|
|
3
4
|
import { WebSocketServer } from 'ws';
|
|
4
|
-
import {
|
|
5
|
+
import { ServerMockResolver, dynamicImportPlugin } from '@vitest/mocker/node';
|
|
5
6
|
import { readFile as readFile$1, mkdir } from 'node:fs/promises';
|
|
6
7
|
import { fileURLToPath } from 'node:url';
|
|
7
8
|
import { createDefer, slash, toArray } from '@vitest/utils';
|
|
8
9
|
import { parseErrorStacktrace, parseStacktrace } from '@vitest/utils/source-map';
|
|
10
|
+
import { createRequire } from 'node:module';
|
|
9
11
|
import sirv from 'sirv';
|
|
10
12
|
import { defaultBrowserPort, coverageConfigDefaults } from 'vitest/config';
|
|
11
|
-
import { P as PlaywrightBrowserProvider, W as WebdriverBrowserProvider } from './webdriver-BdVqnfdE.js';
|
|
12
|
-
import { resolve as resolve$1, dirname as dirname$1, normalize as normalize$1 } from 'node:path';
|
|
13
13
|
import MagicString from 'magic-string';
|
|
14
|
-
import {
|
|
14
|
+
import { P as PlaywrightBrowserProvider, W as WebdriverBrowserProvider } from './webdriver-Cv9wga63.js';
|
|
15
|
+
import { resolve as resolve$1, dirname as dirname$1, basename as basename$1, normalize as normalize$1 } from 'node:path';
|
|
15
16
|
import crypto from 'node:crypto';
|
|
16
17
|
import * as nodeos from 'node:os';
|
|
17
18
|
|
|
19
|
+
var version = "2.1.0";
|
|
20
|
+
|
|
18
21
|
const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
|
|
19
22
|
function normalizeWindowsPath(input = "") {
|
|
20
23
|
if (!input) {
|
|
@@ -403,129 +406,8 @@ const stringify = (value, replacer, space) => {
|
|
|
403
406
|
}
|
|
404
407
|
};
|
|
405
408
|
|
|
406
|
-
async function resolveMock(project, rawId, importer, hasFactory) {
|
|
407
|
-
const { id, fsPath, external } = await resolveId(project, rawId, importer);
|
|
408
|
-
if (hasFactory) {
|
|
409
|
-
const needsInteropMap = viteDepsInteropMap(project.browser.vite.config);
|
|
410
|
-
const needsInterop = needsInteropMap?.get(fsPath) ?? false;
|
|
411
|
-
return { type: "factory", resolvedId: id, needsInterop };
|
|
412
|
-
}
|
|
413
|
-
const mockPath = resolveMockPath(project.config.root, fsPath, external);
|
|
414
|
-
return {
|
|
415
|
-
type: mockPath === null ? "automock" : "redirect",
|
|
416
|
-
mockPath,
|
|
417
|
-
resolvedId: id
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
async function resolveId(project, rawId, importer) {
|
|
421
|
-
const resolved = await project.browser.vite.pluginContainer.resolveId(
|
|
422
|
-
rawId,
|
|
423
|
-
importer,
|
|
424
|
-
{
|
|
425
|
-
ssr: false
|
|
426
|
-
}
|
|
427
|
-
);
|
|
428
|
-
return resolveModule(project, rawId, resolved);
|
|
429
|
-
}
|
|
430
|
-
async function resolveModule(project, rawId, resolved) {
|
|
431
|
-
const id = resolved?.id || rawId;
|
|
432
|
-
const external = !isAbsolute(id) || isModuleDirectory(project.config, id) ? rawId : null;
|
|
433
|
-
return {
|
|
434
|
-
id,
|
|
435
|
-
fsPath: cleanUrl(id),
|
|
436
|
-
external
|
|
437
|
-
};
|
|
438
|
-
}
|
|
439
|
-
function isModuleDirectory(config, path) {
|
|
440
|
-
const moduleDirectories = config.server.deps?.moduleDirectories || [
|
|
441
|
-
"/node_modules/"
|
|
442
|
-
];
|
|
443
|
-
return moduleDirectories.some((dir) => path.includes(dir));
|
|
444
|
-
}
|
|
445
|
-
function resolveMockPath(root, mockPath, external) {
|
|
446
|
-
const path = external || mockPath;
|
|
447
|
-
if (external || isNodeBuiltin(mockPath) || !existsSync(mockPath)) {
|
|
448
|
-
const mockDirname = dirname(path);
|
|
449
|
-
const mockFolder = join(
|
|
450
|
-
root,
|
|
451
|
-
"__mocks__",
|
|
452
|
-
mockDirname
|
|
453
|
-
);
|
|
454
|
-
if (!existsSync(mockFolder)) {
|
|
455
|
-
return null;
|
|
456
|
-
}
|
|
457
|
-
const files = readdirSync(mockFolder);
|
|
458
|
-
const baseOriginal = basename(path);
|
|
459
|
-
for (const file of files) {
|
|
460
|
-
const baseFile = basename(file, extname(file));
|
|
461
|
-
if (baseFile === baseOriginal) {
|
|
462
|
-
return resolve(mockFolder, file);
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
return null;
|
|
466
|
-
}
|
|
467
|
-
const dir = dirname(path);
|
|
468
|
-
const baseId = basename(path);
|
|
469
|
-
const fullPath = resolve(dir, "__mocks__", baseId);
|
|
470
|
-
return existsSync(fullPath) ? fullPath : null;
|
|
471
|
-
}
|
|
472
|
-
const prefixedBuiltins = /* @__PURE__ */ new Set(["node:test"]);
|
|
473
|
-
const builtins = /* @__PURE__ */ new Set([
|
|
474
|
-
...builtinModules,
|
|
475
|
-
"assert/strict",
|
|
476
|
-
"diagnostics_channel",
|
|
477
|
-
"dns/promises",
|
|
478
|
-
"fs/promises",
|
|
479
|
-
"path/posix",
|
|
480
|
-
"path/win32",
|
|
481
|
-
"readline/promises",
|
|
482
|
-
"stream/consumers",
|
|
483
|
-
"stream/promises",
|
|
484
|
-
"stream/web",
|
|
485
|
-
"timers/promises",
|
|
486
|
-
"util/types",
|
|
487
|
-
"wasi"
|
|
488
|
-
]);
|
|
489
|
-
const NODE_BUILTIN_NAMESPACE = "node:";
|
|
490
|
-
function isNodeBuiltin(id) {
|
|
491
|
-
if (prefixedBuiltins.has(id)) {
|
|
492
|
-
return true;
|
|
493
|
-
}
|
|
494
|
-
return builtins.has(
|
|
495
|
-
id.startsWith(NODE_BUILTIN_NAMESPACE) ? id.slice(NODE_BUILTIN_NAMESPACE.length) : id
|
|
496
|
-
);
|
|
497
|
-
}
|
|
498
|
-
const postfixRE = /[?#].*$/;
|
|
499
|
-
function cleanUrl(url) {
|
|
500
|
-
return url.replace(postfixRE, "");
|
|
501
|
-
}
|
|
502
|
-
const metadata = /* @__PURE__ */ new WeakMap();
|
|
503
|
-
function viteDepsInteropMap(config) {
|
|
504
|
-
if (metadata.has(config)) {
|
|
505
|
-
return metadata.get(config);
|
|
506
|
-
}
|
|
507
|
-
const cacheDirPath = getDepsCacheDir(config);
|
|
508
|
-
const metadataPath = resolve(cacheDirPath, "_metadata.json");
|
|
509
|
-
if (!existsSync(metadataPath)) {
|
|
510
|
-
return null;
|
|
511
|
-
}
|
|
512
|
-
const { optimized } = JSON.parse(readFileSync(metadataPath, "utf-8"));
|
|
513
|
-
const needsInteropMap = /* @__PURE__ */ new Map();
|
|
514
|
-
for (const name in optimized) {
|
|
515
|
-
const dep = optimized[name];
|
|
516
|
-
const file = resolve(cacheDirPath, dep.file);
|
|
517
|
-
needsInteropMap.set(file, dep.needsInterop);
|
|
518
|
-
}
|
|
519
|
-
metadata.set(config, needsInteropMap);
|
|
520
|
-
return needsInteropMap;
|
|
521
|
-
}
|
|
522
|
-
function getDepsCacheDir(config) {
|
|
523
|
-
return resolve(config.cacheDir, "deps");
|
|
524
|
-
}
|
|
525
|
-
|
|
526
409
|
const debug$1 = createDebugger("vitest:browser:api");
|
|
527
410
|
const BROWSER_API_PATH = "/__vitest_browser_api__";
|
|
528
|
-
const VALID_ID_PREFIX = "/@id/";
|
|
529
411
|
function setupBrowserRpc(server) {
|
|
530
412
|
const project = server.project;
|
|
531
413
|
const vite = server.vite;
|
|
@@ -563,6 +445,9 @@ function setupBrowserRpc(server) {
|
|
|
563
445
|
}
|
|
564
446
|
}
|
|
565
447
|
function setupClient(sessionId, ws) {
|
|
448
|
+
const mockResolver = new ServerMockResolver(server.vite, {
|
|
449
|
+
moduleDirectories: project.config.server?.deps?.moduleDirectories
|
|
450
|
+
});
|
|
566
451
|
const rpc = createBirpc(
|
|
567
452
|
{
|
|
568
453
|
async onUnhandledError(error, type) {
|
|
@@ -622,34 +507,7 @@ function setupBrowserRpc(server) {
|
|
|
622
507
|
ctx.cancelCurrentRun(reason);
|
|
623
508
|
},
|
|
624
509
|
async resolveId(id, importer) {
|
|
625
|
-
|
|
626
|
-
id,
|
|
627
|
-
importer,
|
|
628
|
-
{
|
|
629
|
-
ssr: false
|
|
630
|
-
}
|
|
631
|
-
);
|
|
632
|
-
if (!resolved) {
|
|
633
|
-
return null;
|
|
634
|
-
}
|
|
635
|
-
const isOptimized = resolved.id.startsWith(withTrailingSlash(vite.config.cacheDir));
|
|
636
|
-
let url;
|
|
637
|
-
const root = vite.config.root;
|
|
638
|
-
if (resolved.id.startsWith(withTrailingSlash(root))) {
|
|
639
|
-
url = resolved.id.slice(root.length);
|
|
640
|
-
} else if (resolved.id !== "/@react-refresh" && isAbsolute(resolved.id) && existsSync(cleanUrl(resolved.id))) {
|
|
641
|
-
url = join("/@fs/", resolved.id);
|
|
642
|
-
} else {
|
|
643
|
-
url = resolved.id;
|
|
644
|
-
}
|
|
645
|
-
if (url[0] !== "." && url[0] !== "/") {
|
|
646
|
-
url = id.startsWith(VALID_ID_PREFIX) ? id : VALID_ID_PREFIX + id.replace("\0", "__x00__");
|
|
647
|
-
}
|
|
648
|
-
return {
|
|
649
|
-
id: resolved.id,
|
|
650
|
-
url,
|
|
651
|
-
optimized: isOptimized
|
|
652
|
-
};
|
|
510
|
+
return mockResolver.resolveId(id, importer);
|
|
653
511
|
},
|
|
654
512
|
debug(...args) {
|
|
655
513
|
ctx.logger.console.debug(...args);
|
|
@@ -693,17 +551,11 @@ function setupBrowserRpc(server) {
|
|
|
693
551
|
debug$1?.("[%s] Finishing browser tests for context", contextId);
|
|
694
552
|
return server.state.getContext(contextId)?.resolve();
|
|
695
553
|
},
|
|
696
|
-
resolveMock(rawId, importer,
|
|
697
|
-
return resolveMock(
|
|
554
|
+
resolveMock(rawId, importer, options) {
|
|
555
|
+
return mockResolver.resolveMock(rawId, importer, options);
|
|
698
556
|
},
|
|
699
557
|
invalidate(ids) {
|
|
700
|
-
|
|
701
|
-
const moduleGraph = server.vite.moduleGraph;
|
|
702
|
-
const module = moduleGraph.getModuleById(id);
|
|
703
|
-
if (module) {
|
|
704
|
-
moduleGraph.invalidateModule(module, /* @__PURE__ */ new Set(), Date.now(), true);
|
|
705
|
-
}
|
|
706
|
-
});
|
|
558
|
+
return mockResolver.invalidate(ids);
|
|
707
559
|
},
|
|
708
560
|
// CDP
|
|
709
561
|
async sendCdpEvent(contextId, event, payload) {
|
|
@@ -752,12 +604,6 @@ function stringifyReplace(key, value) {
|
|
|
752
604
|
return value;
|
|
753
605
|
}
|
|
754
606
|
}
|
|
755
|
-
function withTrailingSlash(path) {
|
|
756
|
-
if (path[path.length - 1] !== "/") {
|
|
757
|
-
return `${path}/`;
|
|
758
|
-
}
|
|
759
|
-
return path;
|
|
760
|
-
}
|
|
761
607
|
|
|
762
608
|
class BrowserServerState {
|
|
763
609
|
orchestrators = /* @__PURE__ */ new Map();
|
|
@@ -1418,11 +1264,6 @@ var DOM_KEY_LOCATION;
|
|
|
1418
1264
|
];
|
|
1419
1265
|
|
|
1420
1266
|
const keyboard = async (context, text, state) => {
|
|
1421
|
-
function focusIframe() {
|
|
1422
|
-
if (!document.activeElement || document.activeElement.ownerDocument !== document || document.activeElement === document.body) {
|
|
1423
|
-
window.focus();
|
|
1424
|
-
}
|
|
1425
|
-
}
|
|
1426
1267
|
if (context.provider instanceof PlaywrightBrowserProvider) {
|
|
1427
1268
|
const frame = await context.frame();
|
|
1428
1269
|
await frame.evaluate(focusIframe);
|
|
@@ -1436,12 +1277,6 @@ const keyboard = async (context, text, state) => {
|
|
|
1436
1277
|
context.contextId,
|
|
1437
1278
|
text,
|
|
1438
1279
|
async () => {
|
|
1439
|
-
function selectAll() {
|
|
1440
|
-
const element = document.activeElement;
|
|
1441
|
-
if (element && element.select) {
|
|
1442
|
-
element.select();
|
|
1443
|
-
}
|
|
1444
|
-
}
|
|
1445
1280
|
if (context.provider instanceof PlaywrightBrowserProvider) {
|
|
1446
1281
|
const frame = await context.frame();
|
|
1447
1282
|
await frame.evaluate(selectAll);
|
|
@@ -1457,7 +1292,7 @@ const keyboard = async (context, text, state) => {
|
|
|
1457
1292
|
unreleased: Array.from(pressed)
|
|
1458
1293
|
};
|
|
1459
1294
|
};
|
|
1460
|
-
async function keyboardImplementation(pressed, provider, contextId, text,
|
|
1295
|
+
async function keyboardImplementation(pressed, provider, contextId, text, selectAll2, skipRelease) {
|
|
1461
1296
|
if (provider instanceof PlaywrightBrowserProvider) {
|
|
1462
1297
|
const page = provider.getPage(contextId);
|
|
1463
1298
|
const actions = parseKeyDef(defaultKeyMap, text);
|
|
@@ -1469,7 +1304,7 @@ async function keyboardImplementation(pressed, provider, contextId, text, select
|
|
|
1469
1304
|
}
|
|
1470
1305
|
if (!releasePrevious) {
|
|
1471
1306
|
if (key === "selectall") {
|
|
1472
|
-
await
|
|
1307
|
+
await selectAll2();
|
|
1473
1308
|
continue;
|
|
1474
1309
|
}
|
|
1475
1310
|
for (let i = 1; i <= repeat; i++) {
|
|
@@ -1507,7 +1342,7 @@ async function keyboardImplementation(pressed, provider, contextId, text, select
|
|
|
1507
1342
|
if (key === "selectall") {
|
|
1508
1343
|
await keyboard2.perform();
|
|
1509
1344
|
keyboard2 = browser.action("key");
|
|
1510
|
-
await
|
|
1345
|
+
await selectAll2();
|
|
1511
1346
|
continue;
|
|
1512
1347
|
}
|
|
1513
1348
|
for (let i = 1; i <= repeat; i++) {
|
|
@@ -1527,6 +1362,17 @@ async function keyboardImplementation(pressed, provider, contextId, text, select
|
|
|
1527
1362
|
pressed
|
|
1528
1363
|
};
|
|
1529
1364
|
}
|
|
1365
|
+
function focusIframe() {
|
|
1366
|
+
if (!document.activeElement || document.activeElement.ownerDocument !== document || document.activeElement === document.body) {
|
|
1367
|
+
window.focus();
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
function selectAll() {
|
|
1371
|
+
const element = document.activeElement;
|
|
1372
|
+
if (element && element.select) {
|
|
1373
|
+
element.select();
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1530
1376
|
|
|
1531
1377
|
const type = async (context, selector, text, options = {}) => {
|
|
1532
1378
|
const { skipClick = false, skipAutoClose = false } = options;
|
|
@@ -1689,6 +1535,131 @@ const hover = async (context, selector, options = {}) => {
|
|
|
1689
1535
|
}
|
|
1690
1536
|
};
|
|
1691
1537
|
|
|
1538
|
+
const upload = async (context, selector, files) => {
|
|
1539
|
+
const testPath = context.testPath;
|
|
1540
|
+
if (!testPath) {
|
|
1541
|
+
throw new Error(`Cannot upload files outside of a test`);
|
|
1542
|
+
}
|
|
1543
|
+
const testDir = dirname(testPath);
|
|
1544
|
+
if (context.provider instanceof PlaywrightBrowserProvider) {
|
|
1545
|
+
const { iframe } = context;
|
|
1546
|
+
const playwrightFiles = files.map((file) => {
|
|
1547
|
+
if (typeof file === "string") {
|
|
1548
|
+
return resolve(testDir, file);
|
|
1549
|
+
}
|
|
1550
|
+
return {
|
|
1551
|
+
name: file.name,
|
|
1552
|
+
mimeType: file.mimeType,
|
|
1553
|
+
buffer: Buffer.from(file.base64, "base64")
|
|
1554
|
+
};
|
|
1555
|
+
});
|
|
1556
|
+
await iframe.locator(selector).setInputFiles(playwrightFiles);
|
|
1557
|
+
} else if (context.provider instanceof WebdriverBrowserProvider) {
|
|
1558
|
+
for (const file of files) {
|
|
1559
|
+
if (typeof file !== "string") {
|
|
1560
|
+
throw new TypeError(`The "${context.provider.name}" provider doesn't support uploading files objects. Provide a file path instead.`);
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
const element = context.browser.$(selector);
|
|
1564
|
+
for (const file of files) {
|
|
1565
|
+
const filepath = resolve(testDir, file);
|
|
1566
|
+
const remoteFilePath = await context.browser.uploadFile(filepath);
|
|
1567
|
+
await element.addValue(remoteFilePath);
|
|
1568
|
+
}
|
|
1569
|
+
} else {
|
|
1570
|
+
throw new TypeError(`Provider "${context.provider.name}" does not support uploading files via userEvent.upload`);
|
|
1571
|
+
}
|
|
1572
|
+
};
|
|
1573
|
+
|
|
1574
|
+
const types = { "application/andrew-inset": ["ez"], "application/appinstaller": ["appinstaller"], "application/applixware": ["aw"], "application/appx": ["appx"], "application/appxbundle": ["appxbundle"], "application/atom+xml": ["atom"], "application/atomcat+xml": ["atomcat"], "application/atomdeleted+xml": ["atomdeleted"], "application/atomsvc+xml": ["atomsvc"], "application/atsc-dwd+xml": ["dwd"], "application/atsc-held+xml": ["held"], "application/atsc-rsat+xml": ["rsat"], "application/automationml-aml+xml": ["aml"], "application/automationml-amlx+zip": ["amlx"], "application/bdoc": ["bdoc"], "application/calendar+xml": ["xcs"], "application/ccxml+xml": ["ccxml"], "application/cdfx+xml": ["cdfx"], "application/cdmi-capability": ["cdmia"], "application/cdmi-container": ["cdmic"], "application/cdmi-domain": ["cdmid"], "application/cdmi-object": ["cdmio"], "application/cdmi-queue": ["cdmiq"], "application/cpl+xml": ["cpl"], "application/cu-seeme": ["cu"], "application/cwl": ["cwl"], "application/dash+xml": ["mpd"], "application/dash-patch+xml": ["mpp"], "application/davmount+xml": ["davmount"], "application/docbook+xml": ["dbk"], "application/dssc+der": ["dssc"], "application/dssc+xml": ["xdssc"], "application/ecmascript": ["ecma"], "application/emma+xml": ["emma"], "application/emotionml+xml": ["emotionml"], "application/epub+zip": ["epub"], "application/exi": ["exi"], "application/express": ["exp"], "application/fdf": ["fdf"], "application/fdt+xml": ["fdt"], "application/font-tdpfr": ["pfr"], "application/geo+json": ["geojson"], "application/gml+xml": ["gml"], "application/gpx+xml": ["gpx"], "application/gxf": ["gxf"], "application/gzip": ["gz"], "application/hjson": ["hjson"], "application/hyperstudio": ["stk"], "application/inkml+xml": ["ink", "inkml"], "application/ipfix": ["ipfix"], "application/its+xml": ["its"], "application/java-archive": ["jar", "war", "ear"], "application/java-serialized-object": ["ser"], "application/java-vm": ["class"], "application/javascript": ["*js"], "application/json": ["json", "map"], "application/json5": ["json5"], "application/jsonml+json": ["jsonml"], "application/ld+json": ["jsonld"], "application/lgr+xml": ["lgr"], "application/lost+xml": ["lostxml"], "application/mac-binhex40": ["hqx"], "application/mac-compactpro": ["cpt"], "application/mads+xml": ["mads"], "application/manifest+json": ["webmanifest"], "application/marc": ["mrc"], "application/marcxml+xml": ["mrcx"], "application/mathematica": ["ma", "nb", "mb"], "application/mathml+xml": ["mathml"], "application/mbox": ["mbox"], "application/media-policy-dataset+xml": ["mpf"], "application/mediaservercontrol+xml": ["mscml"], "application/metalink+xml": ["metalink"], "application/metalink4+xml": ["meta4"], "application/mets+xml": ["mets"], "application/mmt-aei+xml": ["maei"], "application/mmt-usd+xml": ["musd"], "application/mods+xml": ["mods"], "application/mp21": ["m21", "mp21"], "application/mp4": ["*mp4", "*mpg4", "mp4s", "m4p"], "application/msix": ["msix"], "application/msixbundle": ["msixbundle"], "application/msword": ["doc", "dot"], "application/mxf": ["mxf"], "application/n-quads": ["nq"], "application/n-triples": ["nt"], "application/node": ["cjs"], "application/octet-stream": ["bin", "dms", "lrf", "mar", "so", "dist", "distz", "pkg", "bpk", "dump", "elc", "deploy", "exe", "dll", "deb", "dmg", "iso", "img", "msi", "msp", "msm", "buffer"], "application/oda": ["oda"], "application/oebps-package+xml": ["opf"], "application/ogg": ["ogx"], "application/omdoc+xml": ["omdoc"], "application/onenote": ["onetoc", "onetoc2", "onetmp", "onepkg"], "application/oxps": ["oxps"], "application/p2p-overlay+xml": ["relo"], "application/patch-ops-error+xml": ["xer"], "application/pdf": ["pdf"], "application/pgp-encrypted": ["pgp"], "application/pgp-keys": ["asc"], "application/pgp-signature": ["sig", "*asc"], "application/pics-rules": ["prf"], "application/pkcs10": ["p10"], "application/pkcs7-mime": ["p7m", "p7c"], "application/pkcs7-signature": ["p7s"], "application/pkcs8": ["p8"], "application/pkix-attr-cert": ["ac"], "application/pkix-cert": ["cer"], "application/pkix-crl": ["crl"], "application/pkix-pkipath": ["pkipath"], "application/pkixcmp": ["pki"], "application/pls+xml": ["pls"], "application/postscript": ["ai", "eps", "ps"], "application/provenance+xml": ["provx"], "application/pskc+xml": ["pskcxml"], "application/raml+yaml": ["raml"], "application/rdf+xml": ["rdf", "owl"], "application/reginfo+xml": ["rif"], "application/relax-ng-compact-syntax": ["rnc"], "application/resource-lists+xml": ["rl"], "application/resource-lists-diff+xml": ["rld"], "application/rls-services+xml": ["rs"], "application/route-apd+xml": ["rapd"], "application/route-s-tsid+xml": ["sls"], "application/route-usd+xml": ["rusd"], "application/rpki-ghostbusters": ["gbr"], "application/rpki-manifest": ["mft"], "application/rpki-roa": ["roa"], "application/rsd+xml": ["rsd"], "application/rss+xml": ["rss"], "application/rtf": ["rtf"], "application/sbml+xml": ["sbml"], "application/scvp-cv-request": ["scq"], "application/scvp-cv-response": ["scs"], "application/scvp-vp-request": ["spq"], "application/scvp-vp-response": ["spp"], "application/sdp": ["sdp"], "application/senml+xml": ["senmlx"], "application/sensml+xml": ["sensmlx"], "application/set-payment-initiation": ["setpay"], "application/set-registration-initiation": ["setreg"], "application/shf+xml": ["shf"], "application/sieve": ["siv", "sieve"], "application/smil+xml": ["smi", "smil"], "application/sparql-query": ["rq"], "application/sparql-results+xml": ["srx"], "application/sql": ["sql"], "application/srgs": ["gram"], "application/srgs+xml": ["grxml"], "application/sru+xml": ["sru"], "application/ssdl+xml": ["ssdl"], "application/ssml+xml": ["ssml"], "application/swid+xml": ["swidtag"], "application/tei+xml": ["tei", "teicorpus"], "application/thraud+xml": ["tfi"], "application/timestamped-data": ["tsd"], "application/toml": ["toml"], "application/trig": ["trig"], "application/ttml+xml": ["ttml"], "application/ubjson": ["ubj"], "application/urc-ressheet+xml": ["rsheet"], "application/urc-targetdesc+xml": ["td"], "application/voicexml+xml": ["vxml"], "application/wasm": ["wasm"], "application/watcherinfo+xml": ["wif"], "application/widget": ["wgt"], "application/winhlp": ["hlp"], "application/wsdl+xml": ["wsdl"], "application/wspolicy+xml": ["wspolicy"], "application/xaml+xml": ["xaml"], "application/xcap-att+xml": ["xav"], "application/xcap-caps+xml": ["xca"], "application/xcap-diff+xml": ["xdf"], "application/xcap-el+xml": ["xel"], "application/xcap-ns+xml": ["xns"], "application/xenc+xml": ["xenc"], "application/xfdf": ["xfdf"], "application/xhtml+xml": ["xhtml", "xht"], "application/xliff+xml": ["xlf"], "application/xml": ["xml", "xsl", "xsd", "rng"], "application/xml-dtd": ["dtd"], "application/xop+xml": ["xop"], "application/xproc+xml": ["xpl"], "application/xslt+xml": ["*xsl", "xslt"], "application/xspf+xml": ["xspf"], "application/xv+xml": ["mxml", "xhvml", "xvml", "xvm"], "application/yang": ["yang"], "application/yin+xml": ["yin"], "application/zip": ["zip"], "audio/3gpp": ["*3gpp"], "audio/aac": ["adts", "aac"], "audio/adpcm": ["adp"], "audio/amr": ["amr"], "audio/basic": ["au", "snd"], "audio/midi": ["mid", "midi", "kar", "rmi"], "audio/mobile-xmf": ["mxmf"], "audio/mp3": ["*mp3"], "audio/mp4": ["m4a", "mp4a"], "audio/mpeg": ["mpga", "mp2", "mp2a", "mp3", "m2a", "m3a"], "audio/ogg": ["oga", "ogg", "spx", "opus"], "audio/s3m": ["s3m"], "audio/silk": ["sil"], "audio/wav": ["wav"], "audio/wave": ["*wav"], "audio/webm": ["weba"], "audio/xm": ["xm"], "font/collection": ["ttc"], "font/otf": ["otf"], "font/ttf": ["ttf"], "font/woff": ["woff"], "font/woff2": ["woff2"], "image/aces": ["exr"], "image/apng": ["apng"], "image/avci": ["avci"], "image/avcs": ["avcs"], "image/avif": ["avif"], "image/bmp": ["bmp", "dib"], "image/cgm": ["cgm"], "image/dicom-rle": ["drle"], "image/dpx": ["dpx"], "image/emf": ["emf"], "image/fits": ["fits"], "image/g3fax": ["g3"], "image/gif": ["gif"], "image/heic": ["heic"], "image/heic-sequence": ["heics"], "image/heif": ["heif"], "image/heif-sequence": ["heifs"], "image/hej2k": ["hej2"], "image/hsj2": ["hsj2"], "image/ief": ["ief"], "image/jls": ["jls"], "image/jp2": ["jp2", "jpg2"], "image/jpeg": ["jpeg", "jpg", "jpe"], "image/jph": ["jph"], "image/jphc": ["jhc"], "image/jpm": ["jpm", "jpgm"], "image/jpx": ["jpx", "jpf"], "image/jxr": ["jxr"], "image/jxra": ["jxra"], "image/jxrs": ["jxrs"], "image/jxs": ["jxs"], "image/jxsc": ["jxsc"], "image/jxsi": ["jxsi"], "image/jxss": ["jxss"], "image/ktx": ["ktx"], "image/ktx2": ["ktx2"], "image/png": ["png"], "image/sgi": ["sgi"], "image/svg+xml": ["svg", "svgz"], "image/t38": ["t38"], "image/tiff": ["tif", "tiff"], "image/tiff-fx": ["tfx"], "image/webp": ["webp"], "image/wmf": ["wmf"], "message/disposition-notification": ["disposition-notification"], "message/global": ["u8msg"], "message/global-delivery-status": ["u8dsn"], "message/global-disposition-notification": ["u8mdn"], "message/global-headers": ["u8hdr"], "message/rfc822": ["eml", "mime"], "model/3mf": ["3mf"], "model/gltf+json": ["gltf"], "model/gltf-binary": ["glb"], "model/iges": ["igs", "iges"], "model/jt": ["jt"], "model/mesh": ["msh", "mesh", "silo"], "model/mtl": ["mtl"], "model/obj": ["obj"], "model/prc": ["prc"], "model/step+xml": ["stpx"], "model/step+zip": ["stpz"], "model/step-xml+zip": ["stpxz"], "model/stl": ["stl"], "model/u3d": ["u3d"], "model/vrml": ["wrl", "vrml"], "model/x3d+binary": ["*x3db", "x3dbz"], "model/x3d+fastinfoset": ["x3db"], "model/x3d+vrml": ["*x3dv", "x3dvz"], "model/x3d+xml": ["x3d", "x3dz"], "model/x3d-vrml": ["x3dv"], "text/cache-manifest": ["appcache", "manifest"], "text/calendar": ["ics", "ifb"], "text/coffeescript": ["coffee", "litcoffee"], "text/css": ["css"], "text/csv": ["csv"], "text/html": ["html", "htm", "shtml"], "text/jade": ["jade"], "text/javascript": ["js", "mjs"], "text/jsx": ["jsx"], "text/less": ["less"], "text/markdown": ["md", "markdown"], "text/mathml": ["mml"], "text/mdx": ["mdx"], "text/n3": ["n3"], "text/plain": ["txt", "text", "conf", "def", "list", "log", "in", "ini"], "text/richtext": ["rtx"], "text/rtf": ["*rtf"], "text/sgml": ["sgml", "sgm"], "text/shex": ["shex"], "text/slim": ["slim", "slm"], "text/spdx": ["spdx"], "text/stylus": ["stylus", "styl"], "text/tab-separated-values": ["tsv"], "text/troff": ["t", "tr", "roff", "man", "me", "ms"], "text/turtle": ["ttl"], "text/uri-list": ["uri", "uris", "urls"], "text/vcard": ["vcard"], "text/vtt": ["vtt"], "text/wgsl": ["wgsl"], "text/xml": ["*xml"], "text/yaml": ["yaml", "yml"], "video/3gpp": ["3gp", "3gpp"], "video/3gpp2": ["3g2"], "video/h261": ["h261"], "video/h263": ["h263"], "video/h264": ["h264"], "video/iso.segment": ["m4s"], "video/jpeg": ["jpgv"], "video/jpm": ["*jpm", "*jpgm"], "video/mj2": ["mj2", "mjp2"], "video/mp2t": ["ts"], "video/mp4": ["mp4", "mp4v", "mpg4"], "video/mpeg": ["mpeg", "mpg", "mpe", "m1v", "m2v"], "video/ogg": ["ogv"], "video/quicktime": ["qt", "mov"], "video/webm": ["webm"] };
|
|
1575
|
+
Object.freeze(types);
|
|
1576
|
+
|
|
1577
|
+
var __classPrivateFieldGet = (null && null.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
1578
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
1579
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
1580
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
1581
|
+
};
|
|
1582
|
+
var _Mime_extensionToType, _Mime_typeToExtension, _Mime_typeToExtensions;
|
|
1583
|
+
class Mime {
|
|
1584
|
+
constructor(...args) {
|
|
1585
|
+
_Mime_extensionToType.set(this, new Map());
|
|
1586
|
+
_Mime_typeToExtension.set(this, new Map());
|
|
1587
|
+
_Mime_typeToExtensions.set(this, new Map());
|
|
1588
|
+
for (const arg of args) {
|
|
1589
|
+
this.define(arg);
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
define(typeMap, force = false) {
|
|
1593
|
+
for (let [type, extensions] of Object.entries(typeMap)) {
|
|
1594
|
+
type = type.toLowerCase();
|
|
1595
|
+
extensions = extensions.map((ext) => ext.toLowerCase());
|
|
1596
|
+
if (!__classPrivateFieldGet(this, _Mime_typeToExtensions, "f").has(type)) {
|
|
1597
|
+
__classPrivateFieldGet(this, _Mime_typeToExtensions, "f").set(type, new Set());
|
|
1598
|
+
}
|
|
1599
|
+
const allExtensions = __classPrivateFieldGet(this, _Mime_typeToExtensions, "f").get(type);
|
|
1600
|
+
let first = true;
|
|
1601
|
+
for (let extension of extensions) {
|
|
1602
|
+
const starred = extension.startsWith('*');
|
|
1603
|
+
extension = starred ? extension.slice(1) : extension;
|
|
1604
|
+
allExtensions?.add(extension);
|
|
1605
|
+
if (first) {
|
|
1606
|
+
__classPrivateFieldGet(this, _Mime_typeToExtension, "f").set(type, extension);
|
|
1607
|
+
}
|
|
1608
|
+
first = false;
|
|
1609
|
+
if (starred)
|
|
1610
|
+
continue;
|
|
1611
|
+
const currentType = __classPrivateFieldGet(this, _Mime_extensionToType, "f").get(extension);
|
|
1612
|
+
if (currentType && currentType != type && !force) {
|
|
1613
|
+
throw new Error(`"${type} -> ${extension}" conflicts with "${currentType} -> ${extension}". Pass \`force=true\` to override this definition.`);
|
|
1614
|
+
}
|
|
1615
|
+
__classPrivateFieldGet(this, _Mime_extensionToType, "f").set(extension, type);
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
return this;
|
|
1619
|
+
}
|
|
1620
|
+
getType(path) {
|
|
1621
|
+
if (typeof path !== 'string')
|
|
1622
|
+
return null;
|
|
1623
|
+
const last = path.replace(/^.*[/\\]/, '').toLowerCase();
|
|
1624
|
+
const ext = last.replace(/^.*\./, '').toLowerCase();
|
|
1625
|
+
const hasPath = last.length < path.length;
|
|
1626
|
+
const hasDot = ext.length < last.length - 1;
|
|
1627
|
+
if (!hasDot && hasPath)
|
|
1628
|
+
return null;
|
|
1629
|
+
return __classPrivateFieldGet(this, _Mime_extensionToType, "f").get(ext) ?? null;
|
|
1630
|
+
}
|
|
1631
|
+
getExtension(type) {
|
|
1632
|
+
if (typeof type !== 'string')
|
|
1633
|
+
return null;
|
|
1634
|
+
type = type?.split?.(';')[0];
|
|
1635
|
+
return ((type && __classPrivateFieldGet(this, _Mime_typeToExtension, "f").get(type.trim().toLowerCase())) ?? null);
|
|
1636
|
+
}
|
|
1637
|
+
getAllExtensions(type) {
|
|
1638
|
+
if (typeof type !== 'string')
|
|
1639
|
+
return null;
|
|
1640
|
+
return __classPrivateFieldGet(this, _Mime_typeToExtensions, "f").get(type.toLowerCase()) ?? null;
|
|
1641
|
+
}
|
|
1642
|
+
_freeze() {
|
|
1643
|
+
this.define = () => {
|
|
1644
|
+
throw new Error('define() not allowed for built-in Mime objects. See https://github.com/broofa/mime/blob/main/README.md#custom-mime-instances');
|
|
1645
|
+
};
|
|
1646
|
+
Object.freeze(this);
|
|
1647
|
+
for (const extensions of __classPrivateFieldGet(this, _Mime_typeToExtensions, "f").values()) {
|
|
1648
|
+
Object.freeze(extensions);
|
|
1649
|
+
}
|
|
1650
|
+
return this;
|
|
1651
|
+
}
|
|
1652
|
+
_getTestState() {
|
|
1653
|
+
return {
|
|
1654
|
+
types: __classPrivateFieldGet(this, _Mime_extensionToType, "f"),
|
|
1655
|
+
extensions: __classPrivateFieldGet(this, _Mime_typeToExtension, "f"),
|
|
1656
|
+
};
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
_Mime_extensionToType = new WeakMap(), _Mime_typeToExtension = new WeakMap(), _Mime_typeToExtensions = new WeakMap();
|
|
1660
|
+
|
|
1661
|
+
var mime = new Mime(types)._freeze();
|
|
1662
|
+
|
|
1692
1663
|
function assertFileAccess(path, project) {
|
|
1693
1664
|
if (!isFileServingAllowed(path, project.server) && !isFileServingAllowed(path, project.ctx.server)) {
|
|
1694
1665
|
throw new Error(
|
|
@@ -1718,12 +1689,22 @@ const removeFile = async ({ project, testPath = process.cwd() }, path) => {
|
|
|
1718
1689
|
assertFileAccess(filepath, project);
|
|
1719
1690
|
await promises.rm(filepath);
|
|
1720
1691
|
};
|
|
1692
|
+
const _fileInfo = async ({ project, testPath = process.cwd() }, path, encoding) => {
|
|
1693
|
+
const filepath = resolve$1(dirname$1(testPath), path);
|
|
1694
|
+
assertFileAccess(filepath, project);
|
|
1695
|
+
const content = await promises.readFile(filepath, encoding || "base64");
|
|
1696
|
+
return {
|
|
1697
|
+
content,
|
|
1698
|
+
basename: basename$1(filepath),
|
|
1699
|
+
mime: mime.getType(filepath)
|
|
1700
|
+
};
|
|
1701
|
+
};
|
|
1721
1702
|
|
|
1722
1703
|
const screenshot = async (context, name, options = {}) => {
|
|
1723
1704
|
if (!context.testPath) {
|
|
1724
1705
|
throw new Error(`Cannot take a screenshot without a test path`);
|
|
1725
1706
|
}
|
|
1726
|
-
const path = options.path ? resolve(context.testPath, options.path) : resolveScreenshotPath(
|
|
1707
|
+
const path = options.path ? resolve(dirname(context.testPath), options.path) : resolveScreenshotPath(
|
|
1727
1708
|
context.testPath,
|
|
1728
1709
|
name,
|
|
1729
1710
|
context.project.config
|
|
@@ -1786,6 +1767,8 @@ var builtinCommands = {
|
|
|
1786
1767
|
readFile,
|
|
1787
1768
|
removeFile,
|
|
1788
1769
|
writeFile,
|
|
1770
|
+
__vitest_fileInfo: _fileInfo,
|
|
1771
|
+
__vitest_upload: upload,
|
|
1789
1772
|
__vitest_click: click,
|
|
1790
1773
|
__vitest_dblClick: dblClick,
|
|
1791
1774
|
__vitest_tripleClick: tripleClick,
|
|
@@ -1844,7 +1827,7 @@ async function generateContextFile(server) {
|
|
|
1844
1827
|
);
|
|
1845
1828
|
const distContextPath = slash(`/@fs/${resolve(__dirname, "context.js")}`);
|
|
1846
1829
|
return `
|
|
1847
|
-
import { page,
|
|
1830
|
+
import { page, createUserEvent, cdp } from '${distContextPath}'
|
|
1848
1831
|
${userEventNonProviderImport}
|
|
1849
1832
|
const filepath = () => ${filepathCode}
|
|
1850
1833
|
const rpc = () => __vitest_worker__.rpc
|
|
@@ -1861,35 +1844,13 @@ export const server = {
|
|
|
1861
1844
|
config: __vitest_browser_runner__.config,
|
|
1862
1845
|
}
|
|
1863
1846
|
export const commands = server.commands
|
|
1864
|
-
export const userEvent =
|
|
1847
|
+
export const userEvent = createUserEvent(_userEventSetup)
|
|
1865
1848
|
export { page, cdp }
|
|
1866
1849
|
`;
|
|
1867
1850
|
}
|
|
1868
|
-
function getUserEvent(provider) {
|
|
1869
|
-
if (provider.name !== "preview") {
|
|
1870
|
-
return "__userEvent_CDP__";
|
|
1871
|
-
}
|
|
1872
|
-
return `{
|
|
1873
|
-
..._userEventSetup,
|
|
1874
|
-
setup() {
|
|
1875
|
-
const userEvent = __vitest_user_event__.setup()
|
|
1876
|
-
userEvent.setup = this.setup
|
|
1877
|
-
userEvent.fill = this.fill.bind(userEvent)
|
|
1878
|
-
userEvent.dragAndDrop = this.dragAndDrop
|
|
1879
|
-
return userEvent
|
|
1880
|
-
},
|
|
1881
|
-
async fill(element, text) {
|
|
1882
|
-
await this.clear(element)
|
|
1883
|
-
await this.type(element, text)
|
|
1884
|
-
},
|
|
1885
|
-
dragAndDrop: async () => {
|
|
1886
|
-
throw new Error('Provider "preview" does not support dragging elements')
|
|
1887
|
-
}
|
|
1888
|
-
}`;
|
|
1889
|
-
}
|
|
1890
1851
|
async function getUserEventImport(provider, resolve2) {
|
|
1891
1852
|
if (provider.name !== "preview") {
|
|
1892
|
-
return "";
|
|
1853
|
+
return "const _userEventSetup = undefined";
|
|
1893
1854
|
}
|
|
1894
1855
|
const resolved = await resolve2("@testing-library/user-event", __dirname);
|
|
1895
1856
|
if (!resolved) {
|
|
@@ -1902,53 +1863,6 @@ const _userEventSetup = __vitest_user_event__.setup()
|
|
|
1902
1863
|
`;
|
|
1903
1864
|
}
|
|
1904
1865
|
|
|
1905
|
-
function injectDynamicImport(code, id, parse) {
|
|
1906
|
-
const s = new MagicString(code);
|
|
1907
|
-
let ast;
|
|
1908
|
-
try {
|
|
1909
|
-
ast = parse(code);
|
|
1910
|
-
} catch (err) {
|
|
1911
|
-
console.error(`Cannot parse ${id}:
|
|
1912
|
-
${err.message}`);
|
|
1913
|
-
return;
|
|
1914
|
-
}
|
|
1915
|
-
esmWalker(ast, {
|
|
1916
|
-
// TODO: make env updatable
|
|
1917
|
-
onImportMeta() {
|
|
1918
|
-
},
|
|
1919
|
-
onDynamicImport(node) {
|
|
1920
|
-
const replaceString = "__vitest_browser_runner__.wrapModule(() => import(";
|
|
1921
|
-
const importSubstring = code.substring(node.start, node.end);
|
|
1922
|
-
const hasIgnore = importSubstring.includes("/* @vite-ignore */");
|
|
1923
|
-
s.overwrite(
|
|
1924
|
-
node.start,
|
|
1925
|
-
node.source.start,
|
|
1926
|
-
replaceString + (hasIgnore ? "/* @vite-ignore */ " : "")
|
|
1927
|
-
);
|
|
1928
|
-
s.overwrite(node.end - 1, node.end, "))");
|
|
1929
|
-
}
|
|
1930
|
-
});
|
|
1931
|
-
return {
|
|
1932
|
-
ast,
|
|
1933
|
-
code: s.toString(),
|
|
1934
|
-
map: s.generateMap({ hires: "boundary", source: id })
|
|
1935
|
-
};
|
|
1936
|
-
}
|
|
1937
|
-
|
|
1938
|
-
const regexDynamicImport = /import\s*\(/;
|
|
1939
|
-
var DynamicImport = () => {
|
|
1940
|
-
return {
|
|
1941
|
-
name: "vitest:browser:esm-injector",
|
|
1942
|
-
enforce: "post",
|
|
1943
|
-
transform(source, id) {
|
|
1944
|
-
if (!regexDynamicImport.test(source)) {
|
|
1945
|
-
return;
|
|
1946
|
-
}
|
|
1947
|
-
return injectDynamicImport(source, id, this.parse);
|
|
1948
|
-
}
|
|
1949
|
-
};
|
|
1950
|
-
};
|
|
1951
|
-
|
|
1952
1866
|
async function resolveOrchestrator(server, url, res) {
|
|
1953
1867
|
const project = server.project;
|
|
1954
1868
|
let contextId = url.searchParams.get("contextId");
|
|
@@ -2194,6 +2108,28 @@ var BrowserPlugin = (browserServer, base = "/") => {
|
|
|
2194
2108
|
resolve(distDir, "utils.js"),
|
|
2195
2109
|
...project.config.snapshotSerializers || []
|
|
2196
2110
|
];
|
|
2111
|
+
const exclude = [
|
|
2112
|
+
"vitest",
|
|
2113
|
+
"vitest/utils",
|
|
2114
|
+
"vitest/browser",
|
|
2115
|
+
"vitest/runners",
|
|
2116
|
+
"@vitest/browser",
|
|
2117
|
+
"@vitest/browser/client",
|
|
2118
|
+
"@vitest/utils",
|
|
2119
|
+
"@vitest/utils/source-map",
|
|
2120
|
+
"@vitest/runner",
|
|
2121
|
+
"@vitest/spy",
|
|
2122
|
+
"@vitest/utils/error",
|
|
2123
|
+
"@vitest/snapshot",
|
|
2124
|
+
"@vitest/expect",
|
|
2125
|
+
"std-env",
|
|
2126
|
+
"tinybench",
|
|
2127
|
+
"tinyspy",
|
|
2128
|
+
"tinyrainbow",
|
|
2129
|
+
"pathe",
|
|
2130
|
+
"msw",
|
|
2131
|
+
"msw/browser"
|
|
2132
|
+
];
|
|
2197
2133
|
if (project.config.diff) {
|
|
2198
2134
|
entries.push(project.config.diff);
|
|
2199
2135
|
}
|
|
@@ -2204,11 +2140,13 @@ var BrowserPlugin = (browserServer, base = "/") => {
|
|
|
2204
2140
|
const path = tryResolve("@vitest/coverage-v8", [project.ctx.config.root]);
|
|
2205
2141
|
if (path) {
|
|
2206
2142
|
entries.push(path);
|
|
2143
|
+
exclude.push("@vitest/coverage-v8/browser");
|
|
2207
2144
|
}
|
|
2208
2145
|
} else if (provider === "istanbul") {
|
|
2209
2146
|
const path = tryResolve("@vitest/coverage-istanbul", [project.ctx.config.root]);
|
|
2210
2147
|
if (path) {
|
|
2211
2148
|
entries.push(path);
|
|
2149
|
+
exclude.push("@vitest/coverage-istanbul");
|
|
2212
2150
|
}
|
|
2213
2151
|
} else if (provider === "custom" && coverage.customProviderModule) {
|
|
2214
2152
|
entries.push(coverage.customProviderModule);
|
|
@@ -2230,28 +2168,6 @@ var BrowserPlugin = (browserServer, base = "/") => {
|
|
|
2230
2168
|
if (vue) {
|
|
2231
2169
|
include.push(vue);
|
|
2232
2170
|
}
|
|
2233
|
-
const exclude = [
|
|
2234
|
-
"vitest",
|
|
2235
|
-
"vitest/utils",
|
|
2236
|
-
"vitest/browser",
|
|
2237
|
-
"vitest/runners",
|
|
2238
|
-
"@vitest/browser",
|
|
2239
|
-
"@vitest/browser/client",
|
|
2240
|
-
"@vitest/utils",
|
|
2241
|
-
"@vitest/utils/source-map",
|
|
2242
|
-
"@vitest/runner",
|
|
2243
|
-
"@vitest/spy",
|
|
2244
|
-
"@vitest/utils/error",
|
|
2245
|
-
"@vitest/snapshot",
|
|
2246
|
-
"@vitest/expect",
|
|
2247
|
-
"std-env",
|
|
2248
|
-
"tinybench",
|
|
2249
|
-
"tinyspy",
|
|
2250
|
-
"tinyrainbow",
|
|
2251
|
-
"pathe",
|
|
2252
|
-
"msw",
|
|
2253
|
-
"msw/browser"
|
|
2254
|
-
];
|
|
2255
2171
|
const svelte = tryResolve("vitest-browser-svelte", [project.ctx.config.root]);
|
|
2256
2172
|
if (svelte) {
|
|
2257
2173
|
exclude.push(svelte);
|
|
@@ -2307,7 +2223,9 @@ var BrowserPlugin = (browserServer, base = "/") => {
|
|
|
2307
2223
|
}
|
|
2308
2224
|
},
|
|
2309
2225
|
BrowserContext(browserServer),
|
|
2310
|
-
|
|
2226
|
+
dynamicImportPlugin({
|
|
2227
|
+
globalThisAccessor: '"__vitest_browser_runner__"'
|
|
2228
|
+
}),
|
|
2311
2229
|
{
|
|
2312
2230
|
name: "vitest:browser:config",
|
|
2313
2231
|
enforce: "post",
|
|
@@ -2343,6 +2261,23 @@ var BrowserPlugin = (browserServer, base = "/") => {
|
|
|
2343
2261
|
};
|
|
2344
2262
|
}
|
|
2345
2263
|
},
|
|
2264
|
+
{
|
|
2265
|
+
name: "vitest:browser:in-source-tests",
|
|
2266
|
+
transform(code, id) {
|
|
2267
|
+
if (!project.isTestFile(id) || !code.includes("import.meta.vitest")) {
|
|
2268
|
+
return;
|
|
2269
|
+
}
|
|
2270
|
+
const s = new MagicString(code, { filename: cleanUrl(id) });
|
|
2271
|
+
s.prepend(
|
|
2272
|
+
`import.meta.vitest = __vitest_index__;
|
|
2273
|
+
`
|
|
2274
|
+
);
|
|
2275
|
+
return {
|
|
2276
|
+
code: s.toString(),
|
|
2277
|
+
map: s.generateMap({ hires: true })
|
|
2278
|
+
};
|
|
2279
|
+
}
|
|
2280
|
+
},
|
|
2346
2281
|
// TODO: remove this when @testing-library/vue supports ESM
|
|
2347
2282
|
{
|
|
2348
2283
|
name: "vitest:browser:support-testing-library",
|
|
@@ -2420,14 +2355,18 @@ function resolveCoverageFolder(project) {
|
|
|
2420
2355
|
}
|
|
2421
2356
|
return [resolve(root, subdir), `/${basename(root)}/${subdir}/`];
|
|
2422
2357
|
}
|
|
2358
|
+
const postfixRE = /[?#].*$/;
|
|
2359
|
+
function cleanUrl(url) {
|
|
2360
|
+
return url.replace(postfixRE, "");
|
|
2361
|
+
}
|
|
2423
2362
|
|
|
2424
2363
|
const debug = createDebugger("vitest:browser:pool");
|
|
2364
|
+
async function waitForTests(method, contextId, project, files) {
|
|
2365
|
+
const context = project.browser.state.createAsyncContext(method, contextId, files);
|
|
2366
|
+
return await context;
|
|
2367
|
+
}
|
|
2425
2368
|
function createBrowserPool(ctx) {
|
|
2426
2369
|
const providers = /* @__PURE__ */ new Set();
|
|
2427
|
-
const waitForTests = async (method, contextId, project, files) => {
|
|
2428
|
-
const context = project.browser.state.createAsyncContext(method, contextId, files);
|
|
2429
|
-
return await context;
|
|
2430
|
-
};
|
|
2431
2370
|
const executeTests = async (method, project, files) => {
|
|
2432
2371
|
ctx.state.clearFiles(project, files);
|
|
2433
2372
|
const browser = project.browser;
|
|
@@ -2441,6 +2380,20 @@ function createBrowserPool(ctx) {
|
|
|
2441
2380
|
`Can't find browser origin URL for project "${project.getName()}" when running tests for files "${files.join('", "')}"`
|
|
2442
2381
|
);
|
|
2443
2382
|
}
|
|
2383
|
+
async function setBreakpoint(contextId, file) {
|
|
2384
|
+
if (!project.config.inspector.waitForDebugger) {
|
|
2385
|
+
return;
|
|
2386
|
+
}
|
|
2387
|
+
if (!provider.getCDPSession) {
|
|
2388
|
+
throw new Error("Unable to set breakpoint, CDP not supported");
|
|
2389
|
+
}
|
|
2390
|
+
const session = await provider.getCDPSession(contextId);
|
|
2391
|
+
await session.send("Debugger.enable", {});
|
|
2392
|
+
await session.send("Debugger.setBreakpointByUrl", {
|
|
2393
|
+
lineNumber: 0,
|
|
2394
|
+
urlRegex: escapePathToRegexp(file)
|
|
2395
|
+
});
|
|
2396
|
+
}
|
|
2444
2397
|
const filesPerThread = Math.ceil(files.length / threadsCount);
|
|
2445
2398
|
const chunks = [];
|
|
2446
2399
|
for (let i = 0; i < files.length; i += filesPerThread) {
|
|
@@ -2477,7 +2430,7 @@ function createBrowserPool(ctx) {
|
|
|
2477
2430
|
);
|
|
2478
2431
|
const url = new URL("/", origin);
|
|
2479
2432
|
url.searchParams.set("contextId", contextId);
|
|
2480
|
-
const page = provider.openPage(contextId, url.toString()).then(() => waitPromise);
|
|
2433
|
+
const page = provider.openPage(contextId, url.toString(), () => setBreakpoint(contextId, files2[0])).then(() => waitPromise);
|
|
2481
2434
|
promises.push(page);
|
|
2482
2435
|
}
|
|
2483
2436
|
});
|
|
@@ -2522,15 +2475,47 @@ function createBrowserPool(ctx) {
|
|
|
2522
2475
|
collectTests: (files) => runWorkspaceTests("collect", files)
|
|
2523
2476
|
};
|
|
2524
2477
|
}
|
|
2478
|
+
function escapePathToRegexp(path) {
|
|
2479
|
+
return path.replace(/[/\\.?*()^${}|[\]+]/g, "\\$&");
|
|
2480
|
+
}
|
|
2525
2481
|
|
|
2526
2482
|
async function createBrowserServer(project, configFile, prePlugins = [], postPlugins = []) {
|
|
2483
|
+
if (project.ctx.version !== version) {
|
|
2484
|
+
project.ctx.logger.warn(
|
|
2485
|
+
c.yellow(
|
|
2486
|
+
`Loaded ${c.inverse(c.yellow(` vitest@${project.ctx.version} `))} and ${c.inverse(c.yellow(` @vitest/browser@${version} `))}.
|
|
2487
|
+
Running mixed versions is not supported and may lead into bugs
|
|
2488
|
+
Update your dependencies and make sure the versions match.`
|
|
2489
|
+
)
|
|
2490
|
+
);
|
|
2491
|
+
}
|
|
2527
2492
|
const server = new BrowserServer(project, "/");
|
|
2528
2493
|
const configPath = typeof configFile === "string" ? configFile : false;
|
|
2529
|
-
const
|
|
2494
|
+
const logLevel = process.env.VITEST_BROWSER_DEBUG ?? "info";
|
|
2495
|
+
const logger = createViteLogger(logLevel);
|
|
2496
|
+
const vite = await createViteServer({
|
|
2530
2497
|
...project.options,
|
|
2531
2498
|
// spread project config inlined in root workspace config
|
|
2532
2499
|
base: "/",
|
|
2533
|
-
logLevel
|
|
2500
|
+
logLevel,
|
|
2501
|
+
customLogger: {
|
|
2502
|
+
...logger,
|
|
2503
|
+
info(msg, options) {
|
|
2504
|
+
logger.info(msg, options);
|
|
2505
|
+
if (msg.includes("optimized dependencies changed. reloading")) {
|
|
2506
|
+
logger.warn(
|
|
2507
|
+
[
|
|
2508
|
+
c.yellow(`
|
|
2509
|
+
${c.bold("[vitest]")} Vite unexpectedly reloaded a test. This may cause tests to fail, lead to flaky behaviour or duplicated test runs.
|
|
2510
|
+
`),
|
|
2511
|
+
c.yellow(`For a stable experience, please add mentioned dependencies to your config's ${c.bold("`optimizeDeps.include`")} field manually.
|
|
2512
|
+
|
|
2513
|
+
`)
|
|
2514
|
+
].join("")
|
|
2515
|
+
);
|
|
2516
|
+
}
|
|
2517
|
+
}
|
|
2518
|
+
},
|
|
2534
2519
|
mode: project.config.mode,
|
|
2535
2520
|
configFile: configPath,
|
|
2536
2521
|
// watch is handled by Vitest
|