@vitest/browser 5.0.0-beta.7 → 5.0.0-rc.2
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 +4 -1
- package/dist/client/.vite/manifest.json +10 -10
- package/dist/client/__vitest_browser__/{defineProperty-WHpdAQXR.js → defineProperty-BOtRrjRA.js} +13 -1
- package/dist/client/__vitest_browser__/{orchestrator-Bdv4lWwV.js → orchestrator-DJgIeTMM.js} +1 -1
- package/dist/client/__vitest_browser__/{rrweb-snapshot-DkFyu2W8.js → rrweb-snapshot-g5vjbXoV.js} +6 -4
- package/dist/client/__vitest_browser__/{tester-CREI5Ivt.js → tester-DDRabqAJ.js} +41 -18
- package/dist/client/orchestrator.html +2 -2
- package/dist/client/tester/locators.d.ts +2 -2
- package/dist/client/tester/tester.html +2 -2
- package/dist/client/tester/trace.d.ts +3 -3
- package/dist/client.js +14 -14
- package/dist/context.js +2 -0
- package/dist/expect-element.js +30 -30
- package/dist/index.d.ts +1 -1
- package/dist/index.js +479 -52
- package/dist/locators-BTqFw5Up.js +5 -0
- package/dist/locators.d.ts +2 -2
- package/dist/locators.js +1 -1
- package/dist/state.js +3 -1
- package/dist/types.d.ts +2 -10
- package/jest-dom.d.ts +5 -5
- package/matchers.d.ts +5 -13
- package/package.json +17 -16
- package/dist/locators-Cxk-0tRh.js +0 -5
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { distClientRoot } from '@vitest/ui';
|
|
|
6
6
|
import { slash as slash$1, deepMerge, cleanUrl as cleanUrl$1, toArray } from '@vitest/utils/helpers';
|
|
7
7
|
import sirv from 'sirv';
|
|
8
8
|
import c from 'tinyrainbow';
|
|
9
|
-
import { isFileLoadingAllowed, createDebugger, isValidApiRequest, isCSSRequest, distDir, rolldownVersion, isFileServingAllowed } from 'vitest/node';
|
|
9
|
+
import { isFileLoadingAllowed, createDebugger, isValidApiRequest, BrowserConnectionError, isCSSRequest, distDir, rolldownVersion, isFileServingAllowed } from 'vitest/node';
|
|
10
10
|
import { fileURLToPath } from 'node:url';
|
|
11
11
|
import crypto from 'node:crypto';
|
|
12
12
|
import MagicString from 'magic-string';
|
|
@@ -209,7 +209,7 @@ const basename = function(p, extension) {
|
|
|
209
209
|
return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment;
|
|
210
210
|
};
|
|
211
211
|
|
|
212
|
-
var version = "5.0.0-
|
|
212
|
+
var version = "5.0.0-rc.2";
|
|
213
213
|
|
|
214
214
|
const pkgRoot = resolve(fileURLToPath(import.meta.url), "../..");
|
|
215
215
|
const distRoot = resolve(pkgRoot, "dist");
|
|
@@ -509,11 +509,10 @@ var DOM_KEY_LOCATION = /*#__PURE__*/ function(DOM_KEY_LOCATION) {
|
|
|
509
509
|
}
|
|
510
510
|
];
|
|
511
511
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
}(bracketDict || {});
|
|
512
|
+
const bracketDict = {
|
|
513
|
+
'{': '}',
|
|
514
|
+
'[': ']'
|
|
515
|
+
};
|
|
517
516
|
/**
|
|
518
517
|
* Read the next key definition from user input
|
|
519
518
|
*
|
|
@@ -548,16 +547,16 @@ function readPrintableChar(text, pos, context) {
|
|
|
548
547
|
};
|
|
549
548
|
}
|
|
550
549
|
function readTag(text, pos, startBracket, context) {
|
|
550
|
+
var _ref;
|
|
551
551
|
var _text_slice_match, _text_slice_match1;
|
|
552
552
|
const releasePreviousModifier = text[pos] === '/' ? '/' : '';
|
|
553
553
|
pos += releasePreviousModifier.length;
|
|
554
554
|
const escapedDescriptor = startBracket === '{' && text[pos] === '\\';
|
|
555
555
|
pos += Number(escapedDescriptor);
|
|
556
|
-
const descriptor = escapedDescriptor ? text[pos] : (_text_slice_match = text.slice(pos).match(startBracket === '{' ? /^\w+|^[^}>/]/ : /^\w+/)) === null || _text_slice_match ===
|
|
556
|
+
const descriptor = escapedDescriptor ? text[pos] : (_text_slice_match = text.slice(pos).match(startBracket === '{' ? /^\w+|^[^}>/]/ : /^\w+/)) === null || _text_slice_match === void 0 ? void 0 : _text_slice_match[0];
|
|
557
557
|
assertDescriptor(descriptor, text, pos);
|
|
558
558
|
pos += descriptor.length;
|
|
559
|
-
|
|
560
|
-
const repeatModifier = (_text_slice_match_ = (_text_slice_match1 = text.slice(pos).match(/^>\d+/)) === null || _text_slice_match1 === undefined ? undefined : _text_slice_match1[0]) !== null && _text_slice_match_ !== undefined ? _text_slice_match_ : '';
|
|
559
|
+
const repeatModifier = (_ref = (_text_slice_match1 = text.slice(pos).match(/^>\d+/)) === null || _text_slice_match1 === void 0 ? void 0 : _text_slice_match1[0]) !== null && _ref !== void 0 ? _ref : '';
|
|
561
560
|
pos += repeatModifier.length;
|
|
562
561
|
const releaseSelfModifier = text[pos] === '/' || !repeatModifier && text[pos] === '>' ? text[pos] : '';
|
|
563
562
|
pos += releaseSelfModifier.length;
|
|
@@ -593,7 +592,7 @@ function hasReleaseSelf(releaseSelfModifier, repeatModifier) {
|
|
|
593
592
|
}
|
|
594
593
|
}
|
|
595
594
|
function getErrorMessage(expected, found, text, context) {
|
|
596
|
-
return `Expected ${expected} but found "${found !== null && found !==
|
|
595
|
+
return `Expected ${expected} but found "${found !== null && found !== void 0 ? found : ''}" in "${text}"
|
|
597
596
|
See ${`https://testing-library.com/docs/user-event/keyboard`}
|
|
598
597
|
for more information about how userEvent parses your input.`;
|
|
599
598
|
}
|
|
@@ -610,18 +609,18 @@ function getErrorMessage(expected, found, text, context) {
|
|
|
610
609
|
*/ function parseKeyDef$1(keyboardMap, text) {
|
|
611
610
|
const defs = [];
|
|
612
611
|
do {
|
|
613
|
-
const { type, descriptor, consumedLength, releasePrevious, releaseSelf = true, repeat } = readNextDescriptor(text);
|
|
614
612
|
var _keyboardMap_find;
|
|
613
|
+
const { type, descriptor, consumedLength, releasePrevious, releaseSelf = true, repeat } = readNextDescriptor(text);
|
|
615
614
|
const keyDef = (_keyboardMap_find = keyboardMap.find((def)=>{
|
|
616
615
|
if (type === '[') {
|
|
617
616
|
var _def_code;
|
|
618
|
-
return ((_def_code = def.code) === null || _def_code ===
|
|
617
|
+
return ((_def_code = def.code) === null || _def_code === void 0 ? void 0 : _def_code.toLowerCase()) === descriptor.toLowerCase();
|
|
619
618
|
} else if (type === '{') {
|
|
620
619
|
var _def_key;
|
|
621
|
-
return ((_def_key = def.key) === null || _def_key ===
|
|
620
|
+
return ((_def_key = def.key) === null || _def_key === void 0 ? void 0 : _def_key.toLowerCase()) === descriptor.toLowerCase();
|
|
622
621
|
}
|
|
623
622
|
return def.key === descriptor;
|
|
624
|
-
})) !== null && _keyboardMap_find !==
|
|
623
|
+
})) !== null && _keyboardMap_find !== void 0 ? _keyboardMap_find : {
|
|
625
624
|
key: 'Unknown',
|
|
626
625
|
code: 'Unknown',
|
|
627
626
|
[type === '[' ? 'code' : 'key']: descriptor
|
|
@@ -968,6 +967,7 @@ var BrowserPlugin = (contribution) => {
|
|
|
968
967
|
BrowserContext(contribution),
|
|
969
968
|
dynamicImportPlugin({
|
|
970
969
|
globalThisAccessor: "\"__vitest_browser_runner__\"",
|
|
970
|
+
// injected only into the `client` environment via the browser contribution
|
|
971
971
|
filter(id) {
|
|
972
972
|
if (id.includes(distRoot)) {
|
|
973
973
|
return false;
|
|
@@ -1025,6 +1025,8 @@ function cleanUrl(url) {
|
|
|
1025
1025
|
}
|
|
1026
1026
|
|
|
1027
1027
|
class BrowserServerCDPHandler {
|
|
1028
|
+
session;
|
|
1029
|
+
tester;
|
|
1028
1030
|
listenerIds = {};
|
|
1029
1031
|
listeners = {};
|
|
1030
1032
|
constructor(session, tester) {
|
|
@@ -1668,6 +1670,7 @@ function getComparator(comparator, context) {
|
|
|
1668
1670
|
|
|
1669
1671
|
const defaultOptions = {
|
|
1670
1672
|
comparatorName: "pixelmatch",
|
|
1673
|
+
// these are handled by each comparator on its own
|
|
1671
1674
|
comparatorOptions: {},
|
|
1672
1675
|
screenshotOptions: {
|
|
1673
1676
|
animations: "disabled",
|
|
@@ -1722,6 +1725,7 @@ function resolveOptions({ context, name, options, testName }) {
|
|
|
1722
1725
|
resolvedOptions,
|
|
1723
1726
|
paths: {
|
|
1724
1727
|
reference: resolvedOptions.resolveScreenshotPath(resolvePathData),
|
|
1728
|
+
// lazily initialize this, as it might not be needed at all
|
|
1725
1729
|
get diffs() {
|
|
1726
1730
|
const diffs = {
|
|
1727
1731
|
reference: resolvedOptions.resolveDiffPath({
|
|
@@ -1967,6 +1971,7 @@ async function determineOutcome({ comparator, comparatorOptions, paths, referenc
|
|
|
1967
1971
|
diff: comparisonResult.diff && {
|
|
1968
1972
|
image: {
|
|
1969
1973
|
data: comparisonResult.diff,
|
|
1974
|
+
// `comparator` only returns pixel data; diff dimensions always match reference
|
|
1970
1975
|
metadata: reference.metadata
|
|
1971
1976
|
},
|
|
1972
1977
|
path: paths.diffs.diff
|
|
@@ -2202,6 +2207,7 @@ var builtinCommands = {
|
|
|
2202
2207
|
readFile,
|
|
2203
2208
|
removeFile,
|
|
2204
2209
|
writeFile,
|
|
2210
|
+
// private commands
|
|
2205
2211
|
__vitest_markTrace: _markTrace,
|
|
2206
2212
|
__vitest_groupTraceStart: _groupTraceStart,
|
|
2207
2213
|
__vitest_groupTraceEnd: _groupTraceEnd,
|
|
@@ -2217,6 +2223,9 @@ class BrowserServerState {
|
|
|
2217
2223
|
}
|
|
2218
2224
|
|
|
2219
2225
|
class ProjectBrowser {
|
|
2226
|
+
parent;
|
|
2227
|
+
project;
|
|
2228
|
+
base;
|
|
2220
2229
|
testerHtml;
|
|
2221
2230
|
testerFilepath;
|
|
2222
2231
|
// the tester template is read once per server, so the transformed HTML
|
|
@@ -2304,6 +2313,7 @@ function wrapConfig(config) {
|
|
|
2304
2313
|
}
|
|
2305
2314
|
|
|
2306
2315
|
class ParentBrowserProject {
|
|
2316
|
+
base;
|
|
2307
2317
|
orchestratorScripts;
|
|
2308
2318
|
faviconUrl;
|
|
2309
2319
|
prefixOrchestratorUrl;
|
|
@@ -2486,11 +2496,348 @@ class ParentBrowserProject {
|
|
|
2486
2496
|
}
|
|
2487
2497
|
}
|
|
2488
2498
|
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2499
|
+
function _mergeNamespaces$1(n, m) {
|
|
2500
|
+
m.forEach(function(e) {
|
|
2501
|
+
e && typeof e !== "string" && !Array.isArray(e) && Object.keys(e).forEach(function(k) {
|
|
2502
|
+
if (k !== "default" && !(k in n)) {
|
|
2503
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
2504
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
2505
|
+
enumerable: true,
|
|
2506
|
+
get: function() {
|
|
2507
|
+
return e[k];
|
|
2508
|
+
}
|
|
2509
|
+
});
|
|
2510
|
+
}
|
|
2511
|
+
});
|
|
2512
|
+
});
|
|
2513
|
+
return Object.freeze(n);
|
|
2514
|
+
}
|
|
2515
|
+
function getDefaultExportFromCjs(x) {
|
|
2516
|
+
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
2517
|
+
}
|
|
2518
|
+
var reactIs$1 = { exports: {} };
|
|
2519
|
+
var reactIs_production = {};
|
|
2520
|
+
/**
|
|
2521
|
+
* @license React
|
|
2522
|
+
* react-is.production.js
|
|
2523
|
+
*
|
|
2524
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2525
|
+
*
|
|
2526
|
+
* This source code is licensed under the MIT license found in the
|
|
2527
|
+
* LICENSE file in the root directory of this source tree.
|
|
2528
|
+
*/
|
|
2529
|
+
var hasRequiredReactIs_production;
|
|
2530
|
+
function requireReactIs_production() {
|
|
2531
|
+
if (hasRequiredReactIs_production) return reactIs_production;
|
|
2532
|
+
hasRequiredReactIs_production = 1;
|
|
2533
|
+
var REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_VIEW_TRANSITION_TYPE = Symbol.for("react.view_transition"), REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference");
|
|
2534
|
+
function typeOf(object) {
|
|
2535
|
+
if ("object" === typeof object && null !== object) {
|
|
2536
|
+
var $$typeof = object.$$typeof;
|
|
2537
|
+
switch ($$typeof) {
|
|
2538
|
+
case REACT_ELEMENT_TYPE: switch (object = object.type, object) {
|
|
2539
|
+
case REACT_FRAGMENT_TYPE:
|
|
2540
|
+
case REACT_PROFILER_TYPE:
|
|
2541
|
+
case REACT_STRICT_MODE_TYPE:
|
|
2542
|
+
case REACT_SUSPENSE_TYPE:
|
|
2543
|
+
case REACT_SUSPENSE_LIST_TYPE:
|
|
2544
|
+
case REACT_VIEW_TRANSITION_TYPE: return object;
|
|
2545
|
+
default: switch (object = object && object.$$typeof, object) {
|
|
2546
|
+
case REACT_CONTEXT_TYPE:
|
|
2547
|
+
case REACT_FORWARD_REF_TYPE:
|
|
2548
|
+
case REACT_LAZY_TYPE:
|
|
2549
|
+
case REACT_MEMO_TYPE: return object;
|
|
2550
|
+
case REACT_CONSUMER_TYPE: return object;
|
|
2551
|
+
default: return $$typeof;
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
case REACT_PORTAL_TYPE: return $$typeof;
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
reactIs_production.ContextConsumer = REACT_CONSUMER_TYPE;
|
|
2559
|
+
reactIs_production.ContextProvider = REACT_CONTEXT_TYPE;
|
|
2560
|
+
reactIs_production.Element = REACT_ELEMENT_TYPE;
|
|
2561
|
+
reactIs_production.ForwardRef = REACT_FORWARD_REF_TYPE;
|
|
2562
|
+
reactIs_production.Fragment = REACT_FRAGMENT_TYPE;
|
|
2563
|
+
reactIs_production.Lazy = REACT_LAZY_TYPE;
|
|
2564
|
+
reactIs_production.Memo = REACT_MEMO_TYPE;
|
|
2565
|
+
reactIs_production.Portal = REACT_PORTAL_TYPE;
|
|
2566
|
+
reactIs_production.Profiler = REACT_PROFILER_TYPE;
|
|
2567
|
+
reactIs_production.StrictMode = REACT_STRICT_MODE_TYPE;
|
|
2568
|
+
reactIs_production.Suspense = REACT_SUSPENSE_TYPE;
|
|
2569
|
+
reactIs_production.SuspenseList = REACT_SUSPENSE_LIST_TYPE;
|
|
2570
|
+
reactIs_production.isContextConsumer = function(object) {
|
|
2571
|
+
return typeOf(object) === REACT_CONSUMER_TYPE;
|
|
2572
|
+
};
|
|
2573
|
+
reactIs_production.isContextProvider = function(object) {
|
|
2574
|
+
return typeOf(object) === REACT_CONTEXT_TYPE;
|
|
2575
|
+
};
|
|
2576
|
+
reactIs_production.isElement = function(object) {
|
|
2577
|
+
return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE;
|
|
2578
|
+
};
|
|
2579
|
+
reactIs_production.isForwardRef = function(object) {
|
|
2580
|
+
return typeOf(object) === REACT_FORWARD_REF_TYPE;
|
|
2581
|
+
};
|
|
2582
|
+
reactIs_production.isFragment = function(object) {
|
|
2583
|
+
return typeOf(object) === REACT_FRAGMENT_TYPE;
|
|
2584
|
+
};
|
|
2585
|
+
reactIs_production.isLazy = function(object) {
|
|
2586
|
+
return typeOf(object) === REACT_LAZY_TYPE;
|
|
2587
|
+
};
|
|
2588
|
+
reactIs_production.isMemo = function(object) {
|
|
2589
|
+
return typeOf(object) === REACT_MEMO_TYPE;
|
|
2590
|
+
};
|
|
2591
|
+
reactIs_production.isPortal = function(object) {
|
|
2592
|
+
return typeOf(object) === REACT_PORTAL_TYPE;
|
|
2593
|
+
};
|
|
2594
|
+
reactIs_production.isProfiler = function(object) {
|
|
2595
|
+
return typeOf(object) === REACT_PROFILER_TYPE;
|
|
2596
|
+
};
|
|
2597
|
+
reactIs_production.isStrictMode = function(object) {
|
|
2598
|
+
return typeOf(object) === REACT_STRICT_MODE_TYPE;
|
|
2599
|
+
};
|
|
2600
|
+
reactIs_production.isSuspense = function(object) {
|
|
2601
|
+
return typeOf(object) === REACT_SUSPENSE_TYPE;
|
|
2602
|
+
};
|
|
2603
|
+
reactIs_production.isSuspenseList = function(object) {
|
|
2604
|
+
return typeOf(object) === REACT_SUSPENSE_LIST_TYPE;
|
|
2605
|
+
};
|
|
2606
|
+
reactIs_production.isValidElementType = function(type) {
|
|
2607
|
+
return "string" === typeof type || "function" === typeof type || type === REACT_FRAGMENT_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || "object" === typeof type && null !== type && (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_CONSUMER_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_CLIENT_REFERENCE || void 0 !== type.getModuleId) ? true : false;
|
|
2608
|
+
};
|
|
2609
|
+
reactIs_production.typeOf = typeOf;
|
|
2610
|
+
return reactIs_production;
|
|
2611
|
+
}
|
|
2612
|
+
var hasRequiredReactIs$1;
|
|
2613
|
+
function requireReactIs$1() {
|
|
2614
|
+
if (hasRequiredReactIs$1) return reactIs$1.exports;
|
|
2615
|
+
hasRequiredReactIs$1 = 1;
|
|
2616
|
+
{
|
|
2617
|
+
reactIs$1.exports = requireReactIs_production();
|
|
2618
|
+
}
|
|
2619
|
+
return reactIs$1.exports;
|
|
2620
|
+
}
|
|
2621
|
+
var reactIsExports$1 = requireReactIs$1();
|
|
2622
|
+
var index$1 = /*@__PURE__*/ getDefaultExportFromCjs(reactIsExports$1);
|
|
2623
|
+
var ReactIs19 = /*#__PURE__*/ _mergeNamespaces$1({
|
|
2624
|
+
__proto__: null,
|
|
2625
|
+
default: index$1
|
|
2626
|
+
}, [reactIsExports$1]);
|
|
2627
|
+
var reactIs = { exports: {} };
|
|
2628
|
+
var reactIs_production_min = {};
|
|
2629
|
+
/**
|
|
2630
|
+
* @license React
|
|
2631
|
+
* react-is.production.min.js
|
|
2632
|
+
*
|
|
2633
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
2634
|
+
*
|
|
2635
|
+
* This source code is licensed under the MIT license found in the
|
|
2636
|
+
* LICENSE file in the root directory of this source tree.
|
|
2637
|
+
*/
|
|
2638
|
+
var hasRequiredReactIs_production_min;
|
|
2639
|
+
function requireReactIs_production_min() {
|
|
2640
|
+
if (hasRequiredReactIs_production_min) return reactIs_production_min;
|
|
2641
|
+
hasRequiredReactIs_production_min = 1;
|
|
2642
|
+
var b = Symbol.for("react.element"), c = Symbol.for("react.portal"), d = Symbol.for("react.fragment"), e = Symbol.for("react.strict_mode"), f = Symbol.for("react.profiler"), g = Symbol.for("react.provider"), h = Symbol.for("react.context"), k = Symbol.for("react.server_context"), l = Symbol.for("react.forward_ref"), m = Symbol.for("react.suspense"), n = Symbol.for("react.suspense_list"), p = Symbol.for("react.memo"), q = Symbol.for("react.lazy"), t = Symbol.for("react.offscreen"), u;
|
|
2643
|
+
u = Symbol.for("react.module.reference");
|
|
2644
|
+
function v(a) {
|
|
2645
|
+
if ("object" === typeof a && null !== a) {
|
|
2646
|
+
var r = a.$$typeof;
|
|
2647
|
+
switch (r) {
|
|
2648
|
+
case b: switch (a = a.type, a) {
|
|
2649
|
+
case d:
|
|
2650
|
+
case f:
|
|
2651
|
+
case e:
|
|
2652
|
+
case m:
|
|
2653
|
+
case n: return a;
|
|
2654
|
+
default: switch (a = a && a.$$typeof, a) {
|
|
2655
|
+
case k:
|
|
2656
|
+
case h:
|
|
2657
|
+
case l:
|
|
2658
|
+
case q:
|
|
2659
|
+
case p:
|
|
2660
|
+
case g: return a;
|
|
2661
|
+
default: return r;
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
case c: return r;
|
|
2665
|
+
}
|
|
2666
|
+
}
|
|
2667
|
+
}
|
|
2668
|
+
reactIs_production_min.ContextConsumer = h;
|
|
2669
|
+
reactIs_production_min.ContextProvider = g;
|
|
2670
|
+
reactIs_production_min.Element = b;
|
|
2671
|
+
reactIs_production_min.ForwardRef = l;
|
|
2672
|
+
reactIs_production_min.Fragment = d;
|
|
2673
|
+
reactIs_production_min.Lazy = q;
|
|
2674
|
+
reactIs_production_min.Memo = p;
|
|
2675
|
+
reactIs_production_min.Portal = c;
|
|
2676
|
+
reactIs_production_min.Profiler = f;
|
|
2677
|
+
reactIs_production_min.StrictMode = e;
|
|
2678
|
+
reactIs_production_min.Suspense = m;
|
|
2679
|
+
reactIs_production_min.SuspenseList = n;
|
|
2680
|
+
reactIs_production_min.isAsyncMode = function() {
|
|
2681
|
+
return false;
|
|
2682
|
+
};
|
|
2683
|
+
reactIs_production_min.isConcurrentMode = function() {
|
|
2684
|
+
return false;
|
|
2685
|
+
};
|
|
2686
|
+
reactIs_production_min.isContextConsumer = function(a) {
|
|
2687
|
+
return v(a) === h;
|
|
2688
|
+
};
|
|
2689
|
+
reactIs_production_min.isContextProvider = function(a) {
|
|
2690
|
+
return v(a) === g;
|
|
2691
|
+
};
|
|
2692
|
+
reactIs_production_min.isElement = function(a) {
|
|
2693
|
+
return "object" === typeof a && null !== a && a.$$typeof === b;
|
|
2694
|
+
};
|
|
2695
|
+
reactIs_production_min.isForwardRef = function(a) {
|
|
2696
|
+
return v(a) === l;
|
|
2697
|
+
};
|
|
2698
|
+
reactIs_production_min.isFragment = function(a) {
|
|
2699
|
+
return v(a) === d;
|
|
2700
|
+
};
|
|
2701
|
+
reactIs_production_min.isLazy = function(a) {
|
|
2702
|
+
return v(a) === q;
|
|
2703
|
+
};
|
|
2704
|
+
reactIs_production_min.isMemo = function(a) {
|
|
2705
|
+
return v(a) === p;
|
|
2706
|
+
};
|
|
2707
|
+
reactIs_production_min.isPortal = function(a) {
|
|
2708
|
+
return v(a) === c;
|
|
2709
|
+
};
|
|
2710
|
+
reactIs_production_min.isProfiler = function(a) {
|
|
2711
|
+
return v(a) === f;
|
|
2712
|
+
};
|
|
2713
|
+
reactIs_production_min.isStrictMode = function(a) {
|
|
2714
|
+
return v(a) === e;
|
|
2715
|
+
};
|
|
2716
|
+
reactIs_production_min.isSuspense = function(a) {
|
|
2717
|
+
return v(a) === m;
|
|
2718
|
+
};
|
|
2719
|
+
reactIs_production_min.isSuspenseList = function(a) {
|
|
2720
|
+
return v(a) === n;
|
|
2721
|
+
};
|
|
2722
|
+
reactIs_production_min.isValidElementType = function(a) {
|
|
2723
|
+
return "string" === typeof a || "function" === typeof a || a === d || a === f || a === e || a === m || a === n || a === t || "object" === typeof a && null !== a && (a.$$typeof === q || a.$$typeof === p || a.$$typeof === g || a.$$typeof === h || a.$$typeof === l || a.$$typeof === u || void 0 !== a.getModuleId) ? true : false;
|
|
2724
|
+
};
|
|
2725
|
+
reactIs_production_min.typeOf = v;
|
|
2726
|
+
return reactIs_production_min;
|
|
2727
|
+
}
|
|
2728
|
+
var hasRequiredReactIs;
|
|
2729
|
+
function requireReactIs() {
|
|
2730
|
+
if (hasRequiredReactIs) return reactIs.exports;
|
|
2731
|
+
hasRequiredReactIs = 1;
|
|
2732
|
+
{
|
|
2733
|
+
reactIs.exports = requireReactIs_production_min();
|
|
2734
|
+
}
|
|
2735
|
+
return reactIs.exports;
|
|
2736
|
+
}
|
|
2737
|
+
var reactIsExports = requireReactIs();
|
|
2738
|
+
var index = /*@__PURE__*/ getDefaultExportFromCjs(reactIsExports);
|
|
2739
|
+
var ReactIs18 = /*#__PURE__*/ _mergeNamespaces$1({
|
|
2740
|
+
__proto__: null,
|
|
2741
|
+
default: index
|
|
2742
|
+
}, [reactIsExports]);
|
|
2743
|
+
const reactIsMethods = [
|
|
2744
|
+
"isAsyncMode",
|
|
2745
|
+
"isConcurrentMode",
|
|
2746
|
+
"isContextConsumer",
|
|
2747
|
+
"isContextProvider",
|
|
2748
|
+
"isElement",
|
|
2749
|
+
"isForwardRef",
|
|
2750
|
+
"isFragment",
|
|
2751
|
+
"isLazy",
|
|
2752
|
+
"isMemo",
|
|
2753
|
+
"isPortal",
|
|
2754
|
+
"isProfiler",
|
|
2755
|
+
"isStrictMode",
|
|
2756
|
+
"isSuspense",
|
|
2757
|
+
"isSuspenseList",
|
|
2758
|
+
"isValidElementType"
|
|
2759
|
+
];
|
|
2760
|
+
Object.fromEntries(reactIsMethods.map((m) => [m, (v) => ReactIs18[m](v) || ReactIs19[m](v)]));
|
|
2761
|
+
|
|
2762
|
+
var naturalCompare = {exports: {}};
|
|
2763
|
+
|
|
2764
|
+
var hasRequiredNaturalCompare;
|
|
2765
|
+
|
|
2766
|
+
function requireNaturalCompare () {
|
|
2767
|
+
if (hasRequiredNaturalCompare) return naturalCompare.exports;
|
|
2768
|
+
hasRequiredNaturalCompare = 1;
|
|
2769
|
+
/*
|
|
2770
|
+
* @version 1.4.0
|
|
2771
|
+
* @date 2015-10-26
|
|
2772
|
+
* @stability 3 - Stable
|
|
2773
|
+
* @author Lauri Rooden (https://github.com/litejs/natural-compare-lite)
|
|
2774
|
+
* @license MIT License
|
|
2775
|
+
*/
|
|
2776
|
+
|
|
2777
|
+
|
|
2778
|
+
var naturalCompare$1 = function(a, b) {
|
|
2779
|
+
var i, codeA
|
|
2780
|
+
, codeB = 1
|
|
2781
|
+
, posA = 0
|
|
2782
|
+
, posB = 0
|
|
2783
|
+
, alphabet = String.alphabet;
|
|
2784
|
+
|
|
2785
|
+
function getCode(str, pos, code) {
|
|
2786
|
+
if (code) {
|
|
2787
|
+
for (i = pos; code = getCode(str, i), code < 76 && code > 65;) ++i;
|
|
2788
|
+
return +str.slice(pos - 1, i)
|
|
2789
|
+
}
|
|
2790
|
+
code = alphabet && alphabet.indexOf(str.charAt(pos));
|
|
2791
|
+
return code > -1 ? code + 76 : ((code = str.charCodeAt(pos) || 0), code < 45 || code > 127) ? code
|
|
2792
|
+
: code < 46 ? 65 // -
|
|
2793
|
+
: code < 48 ? code - 1
|
|
2794
|
+
: code < 58 ? code + 18 // 0-9
|
|
2795
|
+
: code < 65 ? code - 11
|
|
2796
|
+
: code < 91 ? code + 11 // A-Z
|
|
2797
|
+
: code < 97 ? code - 37
|
|
2798
|
+
: code < 123 ? code + 5 // a-z
|
|
2799
|
+
: code - 63
|
|
2800
|
+
}
|
|
2801
|
+
|
|
2802
|
+
|
|
2803
|
+
if ((a+="") != (b+="")) for (;codeB;) {
|
|
2804
|
+
codeA = getCode(a, posA++);
|
|
2805
|
+
codeB = getCode(b, posB++);
|
|
2806
|
+
|
|
2807
|
+
if (codeA < 76 && codeB < 76 && codeA > 66 && codeB > 66) {
|
|
2808
|
+
codeA = getCode(a, posA, posA);
|
|
2809
|
+
codeB = getCode(b, posB, posA = i);
|
|
2810
|
+
posB = i;
|
|
2811
|
+
}
|
|
2812
|
+
|
|
2813
|
+
if (codeA != codeB) return (codeA < codeB) ? -1 : 1
|
|
2814
|
+
}
|
|
2815
|
+
return 0
|
|
2816
|
+
};
|
|
2817
|
+
|
|
2818
|
+
try {
|
|
2819
|
+
naturalCompare.exports = naturalCompare$1;
|
|
2820
|
+
} catch (e) {
|
|
2821
|
+
String.naturalCompare = naturalCompare$1;
|
|
2822
|
+
}
|
|
2823
|
+
return naturalCompare.exports;
|
|
2824
|
+
}
|
|
2825
|
+
|
|
2826
|
+
requireNaturalCompare();
|
|
2827
|
+
|
|
2828
|
+
// Evaluate a snapshot file's content into its snapshot key/value pairs.
|
|
2829
|
+
function evaluateSnapshotFile(filepath, content) {
|
|
2830
|
+
const data = Object.create(null);
|
|
2831
|
+
try {
|
|
2832
|
+
// eslint-disable-next-line no-new-func
|
|
2833
|
+
const populate = new Function("exports", content);
|
|
2834
|
+
populate(data);
|
|
2835
|
+
} catch (cause) {
|
|
2836
|
+
throw new Error(`Invalid snapshot file, please manually fix or delete it: ${filepath}`, { cause });
|
|
2837
|
+
}
|
|
2838
|
+
return data;
|
|
2839
|
+
}
|
|
2492
2840
|
|
|
2493
|
-
//#endregion
|
|
2494
2841
|
//#region src/utils.ts
|
|
2495
2842
|
function createPromiseWithResolvers() {
|
|
2496
2843
|
let resolve;
|
|
@@ -2513,7 +2860,6 @@ function nanoid(size = 21) {
|
|
|
2513
2860
|
return id;
|
|
2514
2861
|
}
|
|
2515
2862
|
|
|
2516
|
-
//#endregion
|
|
2517
2863
|
//#region src/main.ts
|
|
2518
2864
|
const DEFAULT_TIMEOUT = 6e4;
|
|
2519
2865
|
const defaultSerialize = (i) => i;
|
|
@@ -2530,7 +2876,7 @@ function createBirpc($functions, options) {
|
|
|
2530
2876
|
const req = {
|
|
2531
2877
|
m: method,
|
|
2532
2878
|
a: args,
|
|
2533
|
-
t:
|
|
2879
|
+
t: "q"
|
|
2534
2880
|
};
|
|
2535
2881
|
if (optional) req.o = true;
|
|
2536
2882
|
const send = async (_req) => post(serialize(_req));
|
|
@@ -2584,7 +2930,7 @@ function createBirpc($functions, options) {
|
|
|
2584
2930
|
$call: (method, ...args) => _call(method, args, false),
|
|
2585
2931
|
$callOptional: (method, ...args) => _call(method, args, false, true),
|
|
2586
2932
|
$callEvent: (method, ...args) => _call(method, args, true),
|
|
2587
|
-
$callRaw: (options
|
|
2933
|
+
$callRaw: (options) => _call(options.method, options.args, options.event, options.optional),
|
|
2588
2934
|
$rejectPendingCalls,
|
|
2589
2935
|
get $closed() {
|
|
2590
2936
|
return $closed;
|
|
@@ -2596,7 +2942,7 @@ function createBirpc($functions, options) {
|
|
|
2596
2942
|
$functions
|
|
2597
2943
|
};
|
|
2598
2944
|
if (proxify) rpc = new Proxy({}, { get(_, method) {
|
|
2599
|
-
if (Object.
|
|
2945
|
+
if (Object.hasOwn(builtinMethods, method)) return builtinMethods[method];
|
|
2600
2946
|
if (method === "then" && !eventNames.includes("then") && !("then" in $functions)) return void 0;
|
|
2601
2947
|
const sendEvent = (...args) => _call(method, args, true);
|
|
2602
2948
|
if (eventNames.includes(method)) {
|
|
@@ -2640,7 +2986,7 @@ function createBirpc($functions, options) {
|
|
|
2640
2986
|
if (options.onGeneralError?.call(rpc, e) !== true) throw e;
|
|
2641
2987
|
return;
|
|
2642
2988
|
}
|
|
2643
|
-
if (msg.t ===
|
|
2989
|
+
if (msg.t === "q") {
|
|
2644
2990
|
const { m: method, a: args, o: optional } = msg;
|
|
2645
2991
|
let result, error;
|
|
2646
2992
|
let fn = await (resolver ? resolver.call(rpc, method, $functions[method]) : $functions[method]);
|
|
@@ -2657,7 +3003,7 @@ function createBirpc($functions, options) {
|
|
|
2657
3003
|
}
|
|
2658
3004
|
if (!error) try {
|
|
2659
3005
|
await post(serialize({
|
|
2660
|
-
t:
|
|
3006
|
+
t: "s",
|
|
2661
3007
|
i: msg.i,
|
|
2662
3008
|
r: result
|
|
2663
3009
|
}), ...extra);
|
|
@@ -2668,7 +3014,7 @@ function createBirpc($functions, options) {
|
|
|
2668
3014
|
}
|
|
2669
3015
|
try {
|
|
2670
3016
|
await post(serialize({
|
|
2671
|
-
t:
|
|
3017
|
+
t: "s",
|
|
2672
3018
|
i: msg.i,
|
|
2673
3019
|
e: error
|
|
2674
3020
|
}), ...extra);
|
|
@@ -2693,6 +3039,24 @@ function createBirpc($functions, options) {
|
|
|
2693
3039
|
|
|
2694
3040
|
const debug = createDebugger("vitest:browser:api");
|
|
2695
3041
|
const BROWSER_API_PATH = "/__vitest_browser_api__";
|
|
3042
|
+
const DEFAULT_HEARTBEAT_INTERVAL = 15e3;
|
|
3043
|
+
const HEARTBEAT_MAX_MISSED = 2;
|
|
3044
|
+
let warnedInvalidHeartbeatInterval = false;
|
|
3045
|
+
function resolveHeartbeatInterval(vitest) {
|
|
3046
|
+
const rawInterval = process.env.VITEST_BROWSER_HEARTBEAT_INTERVAL;
|
|
3047
|
+
if (!rawInterval) {
|
|
3048
|
+
return DEFAULT_HEARTBEAT_INTERVAL;
|
|
3049
|
+
}
|
|
3050
|
+
const interval = Number(rawInterval);
|
|
3051
|
+
if (Number.isNaN(interval)) {
|
|
3052
|
+
if (!warnedInvalidHeartbeatInterval) {
|
|
3053
|
+
warnedInvalidHeartbeatInterval = true;
|
|
3054
|
+
vitest.logger.warn(`VITEST_BROWSER_HEARTBEAT_INTERVAL is expected to be a number, received "${rawInterval}". Using the default interval of ${DEFAULT_HEARTBEAT_INTERVAL}ms instead.`);
|
|
3055
|
+
}
|
|
3056
|
+
return DEFAULT_HEARTBEAT_INTERVAL;
|
|
3057
|
+
}
|
|
3058
|
+
return interval;
|
|
3059
|
+
}
|
|
2696
3060
|
function setupBrowserRpc(globalServer, defaultMockerRegistry) {
|
|
2697
3061
|
const vite = globalServer.vite;
|
|
2698
3062
|
const vitest = globalServer.vitest;
|
|
@@ -2741,8 +3105,31 @@ function setupBrowserRpc(globalServer, defaultMockerRegistry) {
|
|
|
2741
3105
|
const clients = type === "tester" ? state.testers : state.orchestrators;
|
|
2742
3106
|
clients.set(rpcId, rpc);
|
|
2743
3107
|
debug?.("[%s] Browser API connected to %s", rpcId, type);
|
|
3108
|
+
// if the browser stops answering pings, terminate the socket so the
|
|
3109
|
+
// "close" handler below rejects pending calls (like `createTesters`)
|
|
3110
|
+
// instead of the run hanging forever; timeouts that live in the browser
|
|
3111
|
+
// (`testTimeout`, iframe ack) cannot fire once its process is frozen
|
|
3112
|
+
const heartbeatInterval = resolveHeartbeatInterval(vitest);
|
|
3113
|
+
let missedPongs = 0;
|
|
3114
|
+
ws.on("pong", () => {
|
|
3115
|
+
missedPongs = 0;
|
|
3116
|
+
});
|
|
3117
|
+
const heartbeat = heartbeatInterval > 0 ? setInterval(() => {
|
|
3118
|
+
if (ws.readyState !== ws.OPEN) {
|
|
3119
|
+
return;
|
|
3120
|
+
}
|
|
3121
|
+
if (missedPongs >= HEARTBEAT_MAX_MISSED) {
|
|
3122
|
+
debug?.("[%s] %s did not respond to %s heartbeat pings, terminating the connection", rpcId, type, missedPongs);
|
|
3123
|
+
rpc.$close(new Error(`[vitest] The browser ${type} did not respond to a heartbeat ping for ${missedPongs * heartbeatInterval}ms. The browser process might be frozen or killed. Closing the connection.`));
|
|
3124
|
+
ws.terminate();
|
|
3125
|
+
return;
|
|
3126
|
+
}
|
|
3127
|
+
missedPongs++;
|
|
3128
|
+
ws.ping();
|
|
3129
|
+
}, heartbeatInterval).unref() : undefined;
|
|
2744
3130
|
ws.on("close", () => {
|
|
2745
3131
|
debug?.("[%s] Browser API disconnected from %s", rpcId, type);
|
|
3132
|
+
clearInterval(heartbeat);
|
|
2746
3133
|
offCancel();
|
|
2747
3134
|
clients.delete(rpcId);
|
|
2748
3135
|
globalServer.removeCDPHandler(rpcId);
|
|
@@ -2750,7 +3137,7 @@ function setupBrowserRpc(globalServer, defaultMockerRegistry) {
|
|
|
2750
3137
|
sessions.destroySession(sessionId);
|
|
2751
3138
|
}
|
|
2752
3139
|
// this will reject any hanging methods if there are any
|
|
2753
|
-
rpc.$close(new
|
|
3140
|
+
rpc.$close(new BrowserConnectionError(`[vitest] Browser connection was closed while running tests. Was the page closed unexpectedly?`));
|
|
2754
3141
|
});
|
|
2755
3142
|
});
|
|
2756
3143
|
});
|
|
@@ -2767,8 +3154,11 @@ function setupBrowserRpc(globalServer, defaultMockerRegistry) {
|
|
|
2767
3154
|
function canWrite(project) {
|
|
2768
3155
|
return project.config.api.allowWrite && project.vitest.config.api.allowWrite;
|
|
2769
3156
|
}
|
|
3157
|
+
function canExec(project) {
|
|
3158
|
+
return project.config.api.allowExec && project.vitest.config.api.allowExec;
|
|
3159
|
+
}
|
|
2770
3160
|
function isCdpAllowed(project) {
|
|
2771
|
-
return project
|
|
3161
|
+
return canExec(project) && canWrite(project);
|
|
2772
3162
|
}
|
|
2773
3163
|
function assertCdpAllowed(project) {
|
|
2774
3164
|
if (!isCdpAllowed(project)) {
|
|
@@ -2877,6 +3267,17 @@ function setupBrowserRpc(globalServer, defaultMockerRegistry) {
|
|
|
2877
3267
|
}
|
|
2878
3268
|
return promises.readFile(snapshotPath, "utf-8");
|
|
2879
3269
|
},
|
|
3270
|
+
async readSnapshotFileData(snapshotPath) {
|
|
3271
|
+
checkFileAccess(snapshotPath);
|
|
3272
|
+
if (!existsSync(snapshotPath)) {
|
|
3273
|
+
return null;
|
|
3274
|
+
}
|
|
3275
|
+
if (!canExec(project)) {
|
|
3276
|
+
throw new Error(`Cannot read snapshot file because browser API exec operations are disabled. See https://vitest.dev/config/api.`);
|
|
3277
|
+
}
|
|
3278
|
+
const content = await promises.readFile(snapshotPath, "utf-8");
|
|
3279
|
+
return evaluateSnapshotFile(snapshotPath, content);
|
|
3280
|
+
},
|
|
2880
3281
|
async saveSnapshotFile(id, content) {
|
|
2881
3282
|
checkFileAccess(id);
|
|
2882
3283
|
if (!canWrite(project)) {
|
|
@@ -2983,6 +3384,7 @@ function setupBrowserRpc(globalServer, defaultMockerRegistry) {
|
|
|
2983
3384
|
if (module.type === "redirect") {
|
|
2984
3385
|
const redirectUrl = new URL(module.redirect);
|
|
2985
3386
|
module.redirect = join(vite.config.root, redirectUrl.pathname);
|
|
3387
|
+
checkFileAccess(module.redirect);
|
|
2986
3388
|
}
|
|
2987
3389
|
defaultMockerRegistry.register(module);
|
|
2988
3390
|
}
|
|
@@ -3014,6 +3416,7 @@ function setupBrowserRpc(globalServer, defaultMockerRegistry) {
|
|
|
3014
3416
|
}
|
|
3015
3417
|
return mocker.delete(sessionId, id);
|
|
3016
3418
|
},
|
|
3419
|
+
// CDP
|
|
3017
3420
|
async sendCdpEvent(sessionId, event, payload) {
|
|
3018
3421
|
assertCdpAllowed(project);
|
|
3019
3422
|
const cdp = await globalServer.ensureCDPHandler(sessionId, rpcId);
|
|
@@ -3071,6 +3474,17 @@ function defineBrowserCommand(fn) {
|
|
|
3071
3474
|
return fn;
|
|
3072
3475
|
}
|
|
3073
3476
|
const versionRegexp = /(?:\?|&)v=\w{8}/;
|
|
3477
|
+
// pin a Cache-Control value and stop Vite's later middleware from overriding it
|
|
3478
|
+
function pinCacheControl(res, value) {
|
|
3479
|
+
res.setHeader("Cache-Control", value);
|
|
3480
|
+
const setHeader = res.setHeader.bind(res);
|
|
3481
|
+
res.setHeader = function(name, ...args) {
|
|
3482
|
+
if (name === "Cache-Control") {
|
|
3483
|
+
return res;
|
|
3484
|
+
}
|
|
3485
|
+
return setHeader(name, ...args);
|
|
3486
|
+
};
|
|
3487
|
+
}
|
|
3074
3488
|
/**
|
|
3075
3489
|
* The browser provider's `serverFactory`. Returns a `BrowserServerContribution`
|
|
3076
3490
|
* that Vitest core uses to build the SINGLE Vite server shared by `project.vite`
|
|
@@ -3218,21 +3632,24 @@ body {
|
|
|
3218
3632
|
}
|
|
3219
3633
|
}));
|
|
3220
3634
|
}
|
|
3635
|
+
// vitest's own dist files only change with the vitest version and
|
|
3636
|
+
// browser contexts don't outlive the process, so there is no reason
|
|
3637
|
+
// to revalidate them in every tester iframe. Skipped for persistent
|
|
3638
|
+
// contexts and preview providers — their disk cache would survive a vitest upgrade
|
|
3639
|
+
const persistentContext = (parentServer.config.browser.provider?.options)?.persistentContext;
|
|
3640
|
+
const immutablePrefixes = persistentContext || parentServer.config.browser.provider?.name === "preview" ? [] : [
|
|
3641
|
+
"/__vitest_browser__/",
|
|
3642
|
+
`/@fs${distDir}`,
|
|
3643
|
+
`/@fs${distRoot}`
|
|
3644
|
+
];
|
|
3221
3645
|
server.middlewares.use((req, res, next) => {
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
const setHeader = res.setHeader.bind(res);
|
|
3230
|
-
res.setHeader = function(name, value) {
|
|
3231
|
-
if (name === "Cache-Control") {
|
|
3232
|
-
return res;
|
|
3233
|
-
}
|
|
3234
|
-
return setHeader(name, value);
|
|
3235
|
-
};
|
|
3646
|
+
const url = req.url;
|
|
3647
|
+
if (url) {
|
|
3648
|
+
if (immutablePrefixes.some((prefix) => url.startsWith(prefix))) {
|
|
3649
|
+
pinCacheControl(res, "public,max-age=31536000,immutable");
|
|
3650
|
+
} else if (versionRegexp.test(url) && !url.includes("chunk-")) {
|
|
3651
|
+
pinCacheControl(res, "no-cache");
|
|
3652
|
+
}
|
|
3236
3653
|
}
|
|
3237
3654
|
next();
|
|
3238
3655
|
});
|
|
@@ -3268,6 +3685,9 @@ body {
|
|
|
3268
3685
|
server.middlewares.use("/__vitest__", sirv(distClientRoot));
|
|
3269
3686
|
}
|
|
3270
3687
|
},
|
|
3688
|
+
// Resolution-time config: only what is derivable from the (partial) user
|
|
3689
|
+
// config. The mocks / coverage / meta-env plugins come from the shared
|
|
3690
|
+
// workspace plugin set, not from here.
|
|
3271
3691
|
async config(viteConfig) {
|
|
3272
3692
|
const testConfig = viteConfig.test || {};
|
|
3273
3693
|
const config = {
|
|
@@ -3279,6 +3699,9 @@ body {
|
|
|
3279
3699
|
fs: { allow: [distRoot] },
|
|
3280
3700
|
middlewareMode: false,
|
|
3281
3701
|
watch: null,
|
|
3702
|
+
// Vitest forwards browser console logs and unhandled errors through its
|
|
3703
|
+
// own RPC, so Vite's client forwarding (defaults on under agents) would
|
|
3704
|
+
// double-report them and leak into stderr.
|
|
3282
3705
|
forwardConsole: false
|
|
3283
3706
|
}
|
|
3284
3707
|
};
|
|
@@ -3314,7 +3737,10 @@ body {
|
|
|
3314
3737
|
};
|
|
3315
3738
|
contribution.plugins = [
|
|
3316
3739
|
...BrowserPlugin(contribution),
|
|
3317
|
-
interceptorPlugin({
|
|
3740
|
+
interceptorPlugin({
|
|
3741
|
+
registry: mockerRegistry,
|
|
3742
|
+
registerWebSocketEvents: false
|
|
3743
|
+
}),
|
|
3318
3744
|
{
|
|
3319
3745
|
name: "vitest:browser:framework-sourcemaps",
|
|
3320
3746
|
enforce: "post",
|
|
@@ -3389,13 +3815,13 @@ function resolveBrowserOptimizeDeps(projectConfigs, testFiles, harness) {
|
|
|
3389
3815
|
// - vitest/browser, @vitest/browser/context, @vitest/browser/utils are
|
|
3390
3816
|
// VIRTUAL modules generated per-server (see pluginContext.ts) — optimizer
|
|
3391
3817
|
// cannot resolve/run their `load`, it would freeze stale/empty content.
|
|
3392
|
-
// - vite/module-runner is small enough to not need pre-bundling.
|
|
3393
3818
|
// - msw is a large, side-effectful service-worker library.
|
|
3394
3819
|
const exclude = [
|
|
3395
3820
|
"vitest/browser",
|
|
3396
|
-
"vite/module-runner",
|
|
3397
3821
|
"@vitest/browser/utils",
|
|
3398
3822
|
"@vitest/browser/context",
|
|
3823
|
+
"@vitest/browser/locators",
|
|
3824
|
+
"@vitest/browser/client",
|
|
3399
3825
|
"msw",
|
|
3400
3826
|
"msw/browser"
|
|
3401
3827
|
];
|
|
@@ -3422,19 +3848,20 @@ function resolveBrowserOptimizeDeps(projectConfigs, testFiles, harness) {
|
|
|
3422
3848
|
}
|
|
3423
3849
|
// Pre-bundle the vitest runtime so the browser fetches a few optimized
|
|
3424
3850
|
// chunks instead of ~20 separately-served dist chunks (faster startup).
|
|
3425
|
-
// `vitest
|
|
3426
|
-
//
|
|
3427
|
-
//
|
|
3428
|
-
//
|
|
3429
|
-
//
|
|
3430
|
-
//
|
|
3851
|
+
// `vitest` and `vitest/internal/browser` are optimized together in a single
|
|
3852
|
+
// pass, so esbuild dedupes their shared stateful chunks (the test collector,
|
|
3853
|
+
// the runner) to a single instance, preserving module identity between the
|
|
3854
|
+
// test files' `import 'vitest'` and the tester. Their transitive deps
|
|
3855
|
+
// (@vitest/utils, @vitest/spy, pathe, tinyrainbow, …) are inlined into
|
|
3856
|
+
// these bundles.
|
|
3431
3857
|
const include = [
|
|
3432
3858
|
"vitest > expect-type",
|
|
3433
3859
|
"vitest > magic-string",
|
|
3434
3860
|
"vitest > chai",
|
|
3861
|
+
"vitest > vite/module-runner",
|
|
3435
3862
|
"vitest",
|
|
3436
3863
|
"vitest/internal/browser",
|
|
3437
|
-
"
|
|
3864
|
+
"vitest/internal/traces"
|
|
3438
3865
|
];
|
|
3439
3866
|
const provider = testConfig.browser?.provider;
|
|
3440
3867
|
if (provider?.name === "preview") {
|