vitest 3.0.0-beta.2 → 3.0.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -315
- package/config.d.ts +2 -0
- package/dist/browser.d.ts +3 -3
- package/dist/browser.js +1 -1
- package/dist/chunks/{RandomSequencer.gisBJ77r.js → RandomSequencer.DB__To1b.js} +38 -8
- package/dist/chunks/{base.CUgXReRN.js → base.BJ8KO-VX.js} +2 -2
- package/dist/chunks/{cac.Xzv7eNWw.js → cac.BAYqQ2aM.js} +21 -10
- package/dist/chunks/{cli-api.CETCDGgZ.js → cli-api.Dhl34Trr.js} +263 -58
- package/dist/chunks/{config.BTPBhmK5.d.ts → config.BRtC-JeT.d.ts} +6 -0
- package/dist/chunks/{console.BYGVloWk.js → console.CN7AiMGV.js} +16 -7
- package/dist/chunks/{creator.DcAcUhMD.js → creator.Ot9GlSGw.js} +16 -14
- package/dist/chunks/{execute.2pr0rHgK.js → execute.BMOaRArH.js} +27 -16
- package/dist/chunks/{globals.BFncSRNA.js → globals.C5RQxaV3.js} +2 -2
- package/dist/chunks/{index.DoV7W5gc.js → index.B2M9nD1V.js} +6 -1
- package/dist/chunks/{index.CkWmZCXU.js → index.BQbxGbG9.js} +1 -1
- package/dist/chunks/index.CAueP3cK.js +3205 -0
- package/dist/chunks/{reporters.DTtxC3KQ.d.ts → reporters.Dcdq51WE.d.ts} +211 -257
- package/dist/chunks/{resolveConfig.BA-_OKEx.js → resolveConfig.kZFMjKCQ.js} +28 -6
- package/dist/chunks/{runBaseTests.D0dWpzZV.js → runBaseTests.URiUrnWK.js} +8 -6
- package/dist/chunks/{setup-common.Cp_bu5q3.js → setup-common.D0zLenuv.js} +1 -1
- package/dist/chunks/{utils.CMUTX-p8.js → utils.yHKcm4dz.js} +10 -21
- package/dist/chunks/{vi.S4Fq8wSo.js → vi.Da_PT3Vw.js} +554 -272
- package/dist/chunks/{vite.CXaetSK3.d.ts → vite.DzluO1Kj.d.ts} +1 -1
- package/dist/chunks/{vm.DGhTouO3.js → vm.DrFVeTXo.js} +4 -4
- package/dist/chunks/{worker.ClntunZp.d.ts → worker.BIVMnzXw.d.ts} +1 -1
- package/dist/chunks/{worker.o1PBoDdo.d.ts → worker.Hz_LAzfd.d.ts} +2 -1
- package/dist/cli.js +1 -1
- package/dist/config.cjs +1 -0
- package/dist/config.d.ts +4 -4
- package/dist/config.js +1 -0
- package/dist/coverage.d.ts +2 -2
- package/dist/coverage.js +33 -8
- package/dist/execute.d.ts +3 -3
- package/dist/execute.js +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.js +2 -2
- package/dist/node.d.ts +6 -6
- package/dist/node.js +10 -11
- package/dist/reporters.d.ts +2 -2
- package/dist/reporters.js +3 -7
- package/dist/runners.d.ts +1 -1
- package/dist/runners.js +5 -12
- package/dist/workers/forks.js +2 -2
- package/dist/workers/runVmTests.js +7 -5
- package/dist/workers/threads.js +2 -2
- package/dist/workers/vmForks.js +3 -3
- package/dist/workers/vmThreads.js +3 -3
- package/dist/workers.d.ts +3 -3
- package/dist/workers.js +4 -4
- package/package.json +17 -19
- package/dist/chunks/index.9ZEBV_TJ.js +0 -5442
|
@@ -2,7 +2,7 @@ import { existsSync, promises, readFileSync, mkdirSync, writeFileSync } from 'no
|
|
|
2
2
|
import { normalize, relative, dirname, resolve, join, basename, isAbsolute } from 'pathe';
|
|
3
3
|
import { g as getCoverageProvider, C as CoverageProviderMap } from './coverage.BWeNbfBa.js';
|
|
4
4
|
import a, { resolve as resolve$1 } from 'node:path';
|
|
5
|
-
import { noop, isPrimitive, toArray, deepMerge, nanoid, slash,
|
|
5
|
+
import { noop, isPrimitive, createDefer, toArray, deepMerge, nanoid, slash, deepClone, notNullish } from '@vitest/utils';
|
|
6
6
|
import { f as findUp, p as prompt } from './index.BJDntFik.js';
|
|
7
7
|
import { searchForWorkspaceRoot, version, createServer, mergeConfig } from 'vite';
|
|
8
8
|
import { A as API_PATH, c as configFiles, a as defaultBrowserPort, w as workspacesFiles, d as defaultPort } from './constants.fzPh7AOq.js';
|
|
@@ -10,9 +10,9 @@ import { createFileTask, limitConcurrency, getTasks, hasFailed, getTests } from
|
|
|
10
10
|
import { SnapshotManager } from '@vitest/snapshot/manager';
|
|
11
11
|
import { ViteNodeRunner } from 'vite-node/client';
|
|
12
12
|
import { ViteNodeServer } from 'vite-node/server';
|
|
13
|
-
import { v as version$1 } from './cac.
|
|
13
|
+
import { v as version$1 } from './cac.BAYqQ2aM.js';
|
|
14
14
|
import { c as createBirpc } from './index.68735LiX.js';
|
|
15
|
-
import { s as stringify, p as parse, i as generateCodeFrame, R as ReportersMap, h as BenchmarkReportsMap, f as TestModule, g as TestSuite, e as TestCase, L as Logger, j as BlobReporter, r as readBlobs } from './index.
|
|
15
|
+
import { s as stringify, p as parse, i as generateCodeFrame, R as ReportersMap, h as BenchmarkReportsMap, f as TestModule, g as TestSuite, e as TestCase, L as Logger, j as BlobReporter, r as readBlobs } from './index.CAueP3cK.js';
|
|
16
16
|
import require$$0$2 from 'stream';
|
|
17
17
|
import require$$0 from 'zlib';
|
|
18
18
|
import require$$0$1 from 'buffer';
|
|
@@ -26,12 +26,11 @@ import require$$7 from 'url';
|
|
|
26
26
|
import { g as getDefaultExportFromCjs, c as commonjsGlobal } from './_commonjsHelpers.BFTU3MAI.js';
|
|
27
27
|
import { parseErrorStacktrace } from '@vitest/utils/source-map';
|
|
28
28
|
import { distDir, rootDir } from '../path.js';
|
|
29
|
-
import { i as isPackageExists, e as requireMicromatch, V as VitestCache, f as configDefaults, g as getFilePoolName, h as isBrowserEnabled, m as mm, a as resolveConfig, j as groupBy, w as wildcardPatternToRegExp, k as createPool, b as resolveApiServerConfig, c as coverageConfigDefaults, s as stdout } from './resolveConfig.
|
|
29
|
+
import { i as isPackageExists, e as requireMicromatch, V as VitestCache, f as configDefaults, g as getFilePoolName, h as isBrowserEnabled, m as mm, a as resolveConfig, j as groupBy, w as wildcardPatternToRegExp, k as createPool, b as resolveApiServerConfig, c as coverageConfigDefaults, s as stdout } from './resolveConfig.kZFMjKCQ.js';
|
|
30
30
|
import { createRequire } from 'node:module';
|
|
31
31
|
import url from 'node:url';
|
|
32
32
|
import c from 'tinyrainbow';
|
|
33
|
-
import { h as hash,
|
|
34
|
-
import { isCI } from 'std-env';
|
|
33
|
+
import { i as isTTY, h as hash, b as isWindows } from './RandomSequencer.DB__To1b.js';
|
|
35
34
|
import { rm } from 'node:fs/promises';
|
|
36
35
|
import nodeos__default, { tmpdir } from 'node:os';
|
|
37
36
|
import require$$0$4 from 'os';
|
|
@@ -40,6 +39,7 @@ import require$$0$6 from 'fs';
|
|
|
40
39
|
import { normalizeRequestId, cleanUrl } from 'vite-node/utils';
|
|
41
40
|
import { hoistMocksPlugin, automockPlugin } from '@vitest/mocker/node';
|
|
42
41
|
import MagicString from 'magic-string';
|
|
42
|
+
import { w as withLabel } from './utils.yHKcm4dz.js';
|
|
43
43
|
import readline from 'node:readline';
|
|
44
44
|
import { stripVTControlCharacters } from 'node:util';
|
|
45
45
|
|
|
@@ -4947,11 +4947,12 @@ function setup(ctx, _server) {
|
|
|
4947
4947
|
async getModuleGraph(project, id, browser) {
|
|
4948
4948
|
return getModuleGraph(ctx, project, id, browser);
|
|
4949
4949
|
},
|
|
4950
|
-
updateSnapshot(file) {
|
|
4950
|
+
async updateSnapshot(file) {
|
|
4951
4951
|
if (!file) {
|
|
4952
|
-
|
|
4952
|
+
await ctx.updateSnapshot();
|
|
4953
|
+
} else {
|
|
4954
|
+
await ctx.updateSnapshot([file.filepath]);
|
|
4953
4955
|
}
|
|
4954
|
-
return ctx.updateSnapshot([file.filepath]);
|
|
4955
4956
|
},
|
|
4956
4957
|
getUnhandledErrors() {
|
|
4957
4958
|
return ctx.state.getUnhandledErrors();
|
|
@@ -5060,6 +5061,33 @@ var setup$1 = /*#__PURE__*/Object.freeze({
|
|
|
5060
5061
|
setup: setup
|
|
5061
5062
|
});
|
|
5062
5063
|
|
|
5064
|
+
class BrowserSessions {
|
|
5065
|
+
sessions = /* @__PURE__ */ new Map();
|
|
5066
|
+
getSession(sessionId) {
|
|
5067
|
+
return this.sessions.get(sessionId);
|
|
5068
|
+
}
|
|
5069
|
+
createAsyncSession(method, sessionId, files, project) {
|
|
5070
|
+
const defer = createDefer();
|
|
5071
|
+
const timeout = setTimeout(() => {
|
|
5072
|
+
defer.reject(new Error(`Failed to connect to the browser session "${sessionId}" within the timeout.`));
|
|
5073
|
+
}, project.vitest.config.browser.connectTimeout ?? 6e4).unref();
|
|
5074
|
+
this.sessions.set(sessionId, {
|
|
5075
|
+
files,
|
|
5076
|
+
method,
|
|
5077
|
+
project,
|
|
5078
|
+
connected: () => {
|
|
5079
|
+
clearTimeout(timeout);
|
|
5080
|
+
},
|
|
5081
|
+
resolve: () => {
|
|
5082
|
+
defer.resolve();
|
|
5083
|
+
this.sessions.delete(sessionId);
|
|
5084
|
+
},
|
|
5085
|
+
reject: defer.reject
|
|
5086
|
+
});
|
|
5087
|
+
return defer;
|
|
5088
|
+
}
|
|
5089
|
+
}
|
|
5090
|
+
|
|
5063
5091
|
class FilesNotFoundError extends Error {
|
|
5064
5092
|
code = "VITEST_FILES_NOT_FOUND";
|
|
5065
5093
|
constructor(mode) {
|
|
@@ -5081,7 +5109,7 @@ class LocationFilterFileNotFoundError extends Error {
|
|
|
5081
5109
|
class IncludeTaskLocationDisabledError extends Error {
|
|
5082
5110
|
code = "VITEST_INCLUDE_TASK_LOCATION_DISABLED";
|
|
5083
5111
|
constructor() {
|
|
5084
|
-
super("
|
|
5112
|
+
super("Received line number filters while `includeTaskLocation` option is disabled");
|
|
5085
5113
|
}
|
|
5086
5114
|
}
|
|
5087
5115
|
class RangeLocationFilterProvidedError extends Error {
|
|
@@ -5111,7 +5139,6 @@ class VitestPackageInstaller {
|
|
|
5111
5139
|
if (/* @__PURE__ */ isPackageExists(dependency, { paths: [root, __dirname] })) {
|
|
5112
5140
|
return true;
|
|
5113
5141
|
}
|
|
5114
|
-
const promptInstall = !isCI && process.stdout.isTTY;
|
|
5115
5142
|
process.stderr.write(
|
|
5116
5143
|
c.red(
|
|
5117
5144
|
`${c.inverse(
|
|
@@ -5121,11 +5148,11 @@ class VitestPackageInstaller {
|
|
|
5121
5148
|
`
|
|
5122
5149
|
)
|
|
5123
5150
|
);
|
|
5124
|
-
if (!
|
|
5151
|
+
if (!isTTY) {
|
|
5125
5152
|
return false;
|
|
5126
5153
|
}
|
|
5127
5154
|
const prompts = await import('./index.BJDntFik.js').then(function (n) { return n.i; });
|
|
5128
|
-
const { install } = await prompts.
|
|
5155
|
+
const { install } = await prompts.default({
|
|
5129
5156
|
type: "confirm",
|
|
5130
5157
|
name: "install",
|
|
5131
5158
|
message: c.reset(`Do you want to install ${c.green(dependency)}?`)
|
|
@@ -8289,7 +8316,7 @@ function requireOut () {
|
|
|
8289
8316
|
}
|
|
8290
8317
|
win32.convertPathToPattern = convertPathToPattern;
|
|
8291
8318
|
})(FastGlob.win32 || (FastGlob.win32 = {}));
|
|
8292
|
-
})(FastGlob
|
|
8319
|
+
})(FastGlob);
|
|
8293
8320
|
function getWorks(source, _Provider, options) {
|
|
8294
8321
|
const patterns = [].concat(source);
|
|
8295
8322
|
const settings = new settings_1.default(options);
|
|
@@ -9652,13 +9679,14 @@ class TestProject {
|
|
|
9652
9679
|
vitenode;
|
|
9653
9680
|
/** @internal */
|
|
9654
9681
|
typechecker;
|
|
9682
|
+
/** @internal */
|
|
9683
|
+
_config;
|
|
9655
9684
|
runner;
|
|
9656
9685
|
closingPromise;
|
|
9657
9686
|
testFilesList = null;
|
|
9658
9687
|
typecheckFilesList = null;
|
|
9659
9688
|
_globalSetups;
|
|
9660
9689
|
_provided = {};
|
|
9661
|
-
_config;
|
|
9662
9690
|
_vite;
|
|
9663
9691
|
// "provide" is a property, not a method to keep the context when destructed in the global setup,
|
|
9664
9692
|
// making it a method would be a breaking change, and can be done in Vitest 3 at minimum
|
|
@@ -9716,6 +9744,11 @@ class TestProject {
|
|
|
9716
9744
|
if (!this._vite) {
|
|
9717
9745
|
throw new Error("The server was not set. It means that `project.vite` was called before the Vite server was established.");
|
|
9718
9746
|
}
|
|
9747
|
+
Object.defineProperty(this, "vite", {
|
|
9748
|
+
configurable: true,
|
|
9749
|
+
writable: true,
|
|
9750
|
+
value: this._vite
|
|
9751
|
+
});
|
|
9719
9752
|
return this._vite;
|
|
9720
9753
|
}
|
|
9721
9754
|
/**
|
|
@@ -9737,7 +9770,7 @@ class TestProject {
|
|
|
9737
9770
|
* Serialized project configuration. This is the config that tests receive.
|
|
9738
9771
|
*/
|
|
9739
9772
|
get serializedConfig() {
|
|
9740
|
-
return this.
|
|
9773
|
+
return this._serializeOverriddenConfig();
|
|
9741
9774
|
}
|
|
9742
9775
|
/** @deprecated use `vite` instead */
|
|
9743
9776
|
get server() {
|
|
@@ -9881,19 +9914,19 @@ class TestProject {
|
|
|
9881
9914
|
* Returns if the file is a test file. Requires `.globTestFiles()` to be called first.
|
|
9882
9915
|
* @internal
|
|
9883
9916
|
*/
|
|
9884
|
-
|
|
9917
|
+
_isCachedTestFile(testPath) {
|
|
9885
9918
|
return !!this.testFilesList && this.testFilesList.includes(testPath);
|
|
9886
9919
|
}
|
|
9887
9920
|
/**
|
|
9888
9921
|
* Returns if the file is a typecheck test file. Requires `.globTestFiles()` to be called first.
|
|
9889
9922
|
* @internal
|
|
9890
9923
|
*/
|
|
9891
|
-
|
|
9924
|
+
_isCachedTypecheckFile(testPath) {
|
|
9892
9925
|
return !!this.typecheckFilesList && this.typecheckFilesList.includes(testPath);
|
|
9893
9926
|
}
|
|
9894
9927
|
/** @deprecated use `serializedConfig` instead */
|
|
9895
9928
|
getSerializableConfig() {
|
|
9896
|
-
return this.
|
|
9929
|
+
return this._serializeOverriddenConfig();
|
|
9897
9930
|
}
|
|
9898
9931
|
/** @internal */
|
|
9899
9932
|
async globFiles(include, exclude, cwd) {
|
|
@@ -9909,7 +9942,7 @@ class TestProject {
|
|
|
9909
9942
|
* Test if a file matches the test globs. This does the actual glob matching if the test is not cached, unlike `isCachedTestFile`.
|
|
9910
9943
|
*/
|
|
9911
9944
|
matchesTestGlob(moduleId, source) {
|
|
9912
|
-
if (this.
|
|
9945
|
+
if (this._isCachedTestFile(moduleId)) {
|
|
9913
9946
|
return true;
|
|
9914
9947
|
}
|
|
9915
9948
|
const relativeId = relative(this.config.dir || this.config.root, moduleId);
|
|
@@ -9955,11 +9988,19 @@ class TestProject {
|
|
|
9955
9988
|
return testFiles;
|
|
9956
9989
|
}
|
|
9957
9990
|
/** @internal */
|
|
9958
|
-
|
|
9959
|
-
|
|
9991
|
+
_parentBrowser;
|
|
9992
|
+
/** @internal */
|
|
9993
|
+
_parent;
|
|
9994
|
+
/** @internal */
|
|
9995
|
+
_initParentBrowser = deduped(async () => {
|
|
9996
|
+
if (!this.isBrowserEnabled() || this._parentBrowser) {
|
|
9960
9997
|
return;
|
|
9961
9998
|
}
|
|
9962
|
-
await this.vitest.packageInstaller.ensureInstalled(
|
|
9999
|
+
await this.vitest.packageInstaller.ensureInstalled(
|
|
10000
|
+
"@vitest/browser",
|
|
10001
|
+
this.config.root,
|
|
10002
|
+
this.vitest.version
|
|
10003
|
+
);
|
|
9963
10004
|
const { createBrowserServer, distRoot } = await import('@vitest/browser');
|
|
9964
10005
|
const browser = await createBrowserServer(
|
|
9965
10006
|
this,
|
|
@@ -9974,13 +10015,20 @@ class TestProject {
|
|
|
9974
10015
|
}
|
|
9975
10016
|
})
|
|
9976
10017
|
],
|
|
9977
|
-
[CoverageTransform(this.
|
|
10018
|
+
[CoverageTransform(this.vitest)]
|
|
9978
10019
|
);
|
|
9979
|
-
this.
|
|
10020
|
+
this._parentBrowser = browser;
|
|
9980
10021
|
if (this.config.browser.ui) {
|
|
9981
10022
|
setup(this.vitest, browser.vite);
|
|
9982
10023
|
}
|
|
9983
|
-
}
|
|
10024
|
+
});
|
|
10025
|
+
/** @internal */
|
|
10026
|
+
_initBrowserServer = deduped(async () => {
|
|
10027
|
+
await this._parent?._initParentBrowser();
|
|
10028
|
+
if (!this.browser && this._parent?._parentBrowser) {
|
|
10029
|
+
this.browser = this._parent._parentBrowser.spawn(this);
|
|
10030
|
+
}
|
|
10031
|
+
});
|
|
9984
10032
|
/**
|
|
9985
10033
|
* Closes the project and all associated resources. This can only be called once; the closing promise is cached until the server restarts.
|
|
9986
10034
|
* If the resources are needed again, create a new project.
|
|
@@ -10049,7 +10097,7 @@ class TestProject {
|
|
|
10049
10097
|
}
|
|
10050
10098
|
});
|
|
10051
10099
|
}
|
|
10052
|
-
|
|
10100
|
+
_serializeOverriddenConfig() {
|
|
10053
10101
|
const config = serializeConfig(
|
|
10054
10102
|
this.config,
|
|
10055
10103
|
this.vitest.config,
|
|
@@ -10074,14 +10122,24 @@ class TestProject {
|
|
|
10074
10122
|
return this._initBrowserProvider();
|
|
10075
10123
|
}
|
|
10076
10124
|
/** @internal */
|
|
10077
|
-
async
|
|
10125
|
+
_initBrowserProvider = deduped(async () => {
|
|
10078
10126
|
if (!this.isBrowserEnabled() || this.browser?.provider) {
|
|
10079
10127
|
return;
|
|
10080
10128
|
}
|
|
10081
10129
|
if (!this.browser) {
|
|
10082
10130
|
await this._initBrowserServer();
|
|
10083
10131
|
}
|
|
10084
|
-
await this.browser?.initBrowserProvider();
|
|
10132
|
+
await this.browser?.initBrowserProvider(this);
|
|
10133
|
+
});
|
|
10134
|
+
/** @internal */
|
|
10135
|
+
_provideObject(context) {
|
|
10136
|
+
for (const _providedKey in context) {
|
|
10137
|
+
const providedKey = _providedKey;
|
|
10138
|
+
this.provide(
|
|
10139
|
+
providedKey,
|
|
10140
|
+
context[providedKey]
|
|
10141
|
+
);
|
|
10142
|
+
}
|
|
10085
10143
|
}
|
|
10086
10144
|
/** @internal */
|
|
10087
10145
|
static _createBasicProject(vitest) {
|
|
@@ -10093,15 +10151,34 @@ class TestProject {
|
|
|
10093
10151
|
project.runner = vitest.runner;
|
|
10094
10152
|
project._vite = vitest.server;
|
|
10095
10153
|
project._config = vitest.config;
|
|
10096
|
-
|
|
10097
|
-
const providedKey = _providedKey;
|
|
10098
|
-
project.provide(
|
|
10099
|
-
providedKey,
|
|
10100
|
-
vitest.config.provide[providedKey]
|
|
10101
|
-
);
|
|
10102
|
-
}
|
|
10154
|
+
project._provideObject(vitest.config.provide);
|
|
10103
10155
|
return project;
|
|
10104
10156
|
}
|
|
10157
|
+
/** @internal */
|
|
10158
|
+
static _cloneBrowserProject(parent, config) {
|
|
10159
|
+
const clone = new TestProject(
|
|
10160
|
+
parent.path,
|
|
10161
|
+
parent.vitest
|
|
10162
|
+
);
|
|
10163
|
+
clone.vitenode = parent.vitenode;
|
|
10164
|
+
clone.runner = parent.runner;
|
|
10165
|
+
clone._vite = parent._vite;
|
|
10166
|
+
clone._config = config;
|
|
10167
|
+
clone._parent = parent;
|
|
10168
|
+
clone._provideObject(config.provide);
|
|
10169
|
+
return clone;
|
|
10170
|
+
}
|
|
10171
|
+
}
|
|
10172
|
+
function deduped(cb) {
|
|
10173
|
+
let _promise;
|
|
10174
|
+
return (...args) => {
|
|
10175
|
+
if (!_promise) {
|
|
10176
|
+
_promise = cb(...args).finally(() => {
|
|
10177
|
+
_promise = void 0;
|
|
10178
|
+
});
|
|
10179
|
+
}
|
|
10180
|
+
return _promise;
|
|
10181
|
+
};
|
|
10105
10182
|
}
|
|
10106
10183
|
async function initializeProject(workspacePath, ctx, options) {
|
|
10107
10184
|
const project = new TestProject(workspacePath, ctx, options);
|
|
@@ -10233,10 +10310,10 @@ class VitestSpecifications {
|
|
|
10233
10310
|
}
|
|
10234
10311
|
const specs = [];
|
|
10235
10312
|
for (const project of this.vitest.projects) {
|
|
10236
|
-
if (project.
|
|
10313
|
+
if (project._isCachedTestFile(moduleId)) {
|
|
10237
10314
|
specs.push(project.createSpecification(moduleId));
|
|
10238
10315
|
}
|
|
10239
|
-
if (project.
|
|
10316
|
+
if (project._isCachedTypecheckFile(moduleId)) {
|
|
10240
10317
|
specs.push(project.createSpecification(moduleId, [], "typescript"));
|
|
10241
10318
|
}
|
|
10242
10319
|
}
|
|
@@ -10653,7 +10730,7 @@ class VitestWatcher {
|
|
|
10653
10730
|
return moduleGraph.getModulesByFile(filepath)?.size;
|
|
10654
10731
|
});
|
|
10655
10732
|
if (!projects.length) {
|
|
10656
|
-
if (this.vitest.state.filesMap.has(filepath) || this.vitest.projects.some((project) => project.
|
|
10733
|
+
if (this.vitest.state.filesMap.has(filepath) || this.vitest.projects.some((project) => project._isCachedTestFile(filepath))) {
|
|
10657
10734
|
this.changedTests.add(filepath);
|
|
10658
10735
|
return true;
|
|
10659
10736
|
}
|
|
@@ -10666,7 +10743,7 @@ class VitestWatcher {
|
|
|
10666
10743
|
continue;
|
|
10667
10744
|
}
|
|
10668
10745
|
this.invalidates.add(filepath);
|
|
10669
|
-
if (this.vitest.state.filesMap.has(filepath) || project.
|
|
10746
|
+
if (this.vitest.state.filesMap.has(filepath) || project._isCachedTestFile(filepath)) {
|
|
10670
10747
|
this.changedTests.add(filepath);
|
|
10671
10748
|
files.push(filepath);
|
|
10672
10749
|
continue;
|
|
@@ -10787,7 +10864,7 @@ async function resolveWorkspace(vitest, cliOptions, workspaceConfigPath, workspa
|
|
|
10787
10864
|
);
|
|
10788
10865
|
}
|
|
10789
10866
|
if (!projectPromises.length) {
|
|
10790
|
-
return [vitest._ensureRootProject()];
|
|
10867
|
+
return resolveBrowserWorkspace(vitest, /* @__PURE__ */ new Set(), [vitest._ensureRootProject()]);
|
|
10791
10868
|
}
|
|
10792
10869
|
const resolvedProjects = await Promise.all(projectPromises);
|
|
10793
10870
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -10811,8 +10888,136 @@ async function resolveWorkspace(vitest, cliOptions, workspaceConfigPath, workspa
|
|
|
10811
10888
|
}
|
|
10812
10889
|
names.add(name);
|
|
10813
10890
|
}
|
|
10891
|
+
return resolveBrowserWorkspace(vitest, names, resolvedProjects);
|
|
10892
|
+
}
|
|
10893
|
+
async function resolveBrowserWorkspace(vitest, names, resolvedProjects) {
|
|
10894
|
+
const filters = toArray(vitest.config.project).map((s) => wildcardPatternToRegExp(s));
|
|
10895
|
+
const removeProjects = /* @__PURE__ */ new Set();
|
|
10896
|
+
resolvedProjects.forEach((project) => {
|
|
10897
|
+
if (!project.config.browser.enabled) {
|
|
10898
|
+
return;
|
|
10899
|
+
}
|
|
10900
|
+
const configs = project.config.browser.instances || [];
|
|
10901
|
+
if (configs.length === 0) {
|
|
10902
|
+
configs.push({ browser: project.config.browser.name });
|
|
10903
|
+
console.warn(
|
|
10904
|
+
withLabel(
|
|
10905
|
+
"yellow",
|
|
10906
|
+
"Vitest",
|
|
10907
|
+
[
|
|
10908
|
+
`No browser "instances" were defined`,
|
|
10909
|
+
project.name ? ` for the "${project.name}" project. ` : ". ",
|
|
10910
|
+
`Running tests in "${project.config.browser.name}" browser. `,
|
|
10911
|
+
'The "browser.name" field is deprecated since Vitest 3. ',
|
|
10912
|
+
"Read more: https://vitest.dev/guide/browser/config#browser-instances"
|
|
10913
|
+
].filter(Boolean).join("")
|
|
10914
|
+
)
|
|
10915
|
+
);
|
|
10916
|
+
}
|
|
10917
|
+
const originalName = project.config.name;
|
|
10918
|
+
const filteredConfigs = !filters.length ? configs : configs.filter((config) => {
|
|
10919
|
+
const browser = config.browser;
|
|
10920
|
+
const newName = config.name || (originalName ? `${originalName} (${browser})` : browser);
|
|
10921
|
+
return filters.some((pattern) => pattern.test(newName));
|
|
10922
|
+
});
|
|
10923
|
+
if (!filteredConfigs.length) {
|
|
10924
|
+
return;
|
|
10925
|
+
}
|
|
10926
|
+
if (project.config.browser.providerOptions) {
|
|
10927
|
+
vitest.logger.warn(
|
|
10928
|
+
withLabel("yellow", "Vitest", `"providerOptions"${originalName ? ` in "${originalName}" project` : ""} is ignored because it's overriden by the configs. To hide this warning, remove the "providerOptions" property from the browser configuration.`)
|
|
10929
|
+
);
|
|
10930
|
+
}
|
|
10931
|
+
filteredConfigs.forEach((config, index) => {
|
|
10932
|
+
const browser = config.browser;
|
|
10933
|
+
if (!browser) {
|
|
10934
|
+
const nth = index + 1;
|
|
10935
|
+
const ending = nth === 2 ? "nd" : nth === 3 ? "rd" : "th";
|
|
10936
|
+
throw new Error(`The browser configuration must have a "browser" property. The ${nth}${ending} item in "browser.instances" doesn't have it. Make sure your${originalName ? ` "${originalName}"` : ""} configuration is correct.`);
|
|
10937
|
+
}
|
|
10938
|
+
const name = config.name;
|
|
10939
|
+
const newName = name || (originalName ? `${originalName} (${browser})` : browser);
|
|
10940
|
+
if (names.has(newName)) {
|
|
10941
|
+
throw new Error(
|
|
10942
|
+
[
|
|
10943
|
+
`Cannot define a nested project for a ${browser} browser. The project name "${newName}" was already defined. `,
|
|
10944
|
+
'If you have multiple instances for the same browser, make sure to define a custom "name". ',
|
|
10945
|
+
"All projects in a workspace should have unique names. Make sure your configuration is correct."
|
|
10946
|
+
].join("")
|
|
10947
|
+
);
|
|
10948
|
+
}
|
|
10949
|
+
names.add(newName);
|
|
10950
|
+
const clonedConfig = cloneConfig(project, config);
|
|
10951
|
+
clonedConfig.name = newName;
|
|
10952
|
+
const clone = TestProject._cloneBrowserProject(project, clonedConfig);
|
|
10953
|
+
resolvedProjects.push(clone);
|
|
10954
|
+
});
|
|
10955
|
+
removeProjects.add(project);
|
|
10956
|
+
});
|
|
10957
|
+
resolvedProjects = resolvedProjects.filter((project) => !removeProjects.has(project));
|
|
10958
|
+
const headedBrowserProjects = resolvedProjects.filter((project) => {
|
|
10959
|
+
return project.config.browser.enabled && !project.config.browser.headless;
|
|
10960
|
+
});
|
|
10961
|
+
if (headedBrowserProjects.length > 1) {
|
|
10962
|
+
const message = [
|
|
10963
|
+
`Found multiple projects that run browser tests in headed mode: "${headedBrowserProjects.map((p) => p.name).join('", "')}".`,
|
|
10964
|
+
` Vitest cannot run multiple headed browsers at the same time.`
|
|
10965
|
+
].join("");
|
|
10966
|
+
if (!isTTY) {
|
|
10967
|
+
throw new Error(`${message} Please, filter projects with --browser=name or --project=name flag or run tests with "headless: true" option.`);
|
|
10968
|
+
}
|
|
10969
|
+
const prompts = await import('./index.BJDntFik.js').then(function (n) { return n.i; });
|
|
10970
|
+
const { projectName } = await prompts.default({
|
|
10971
|
+
type: "select",
|
|
10972
|
+
name: "projectName",
|
|
10973
|
+
choices: headedBrowserProjects.map((project) => ({
|
|
10974
|
+
title: project.name,
|
|
10975
|
+
value: project.name
|
|
10976
|
+
})),
|
|
10977
|
+
message: `${message} Select a single project to run or cancel and run tests with "headless: true" option. Note that you can also start tests with --browser=name or --project=name flag.`
|
|
10978
|
+
});
|
|
10979
|
+
if (!projectName) {
|
|
10980
|
+
throw new Error("The test run was aborted.");
|
|
10981
|
+
}
|
|
10982
|
+
return resolvedProjects.filter((project) => project.name === projectName);
|
|
10983
|
+
}
|
|
10814
10984
|
return resolvedProjects;
|
|
10815
10985
|
}
|
|
10986
|
+
function cloneConfig(project, { browser, ...config }) {
|
|
10987
|
+
const {
|
|
10988
|
+
locators,
|
|
10989
|
+
viewport,
|
|
10990
|
+
testerHtmlPath,
|
|
10991
|
+
headless,
|
|
10992
|
+
screenshotDirectory,
|
|
10993
|
+
screenshotFailures,
|
|
10994
|
+
// @ts-expect-error remove just in case
|
|
10995
|
+
browser: _browser,
|
|
10996
|
+
name,
|
|
10997
|
+
...overrideConfig
|
|
10998
|
+
} = config;
|
|
10999
|
+
const currentConfig = project.config.browser;
|
|
11000
|
+
return mergeConfig({
|
|
11001
|
+
...deepClone(project.config),
|
|
11002
|
+
browser: {
|
|
11003
|
+
...project.config.browser,
|
|
11004
|
+
locators: locators ? {
|
|
11005
|
+
testIdAttribute: locators.testIdAttribute ?? currentConfig.locators.testIdAttribute
|
|
11006
|
+
} : project.config.browser.locators,
|
|
11007
|
+
viewport: viewport ?? currentConfig.viewport,
|
|
11008
|
+
testerHtmlPath: testerHtmlPath ?? currentConfig.testerHtmlPath,
|
|
11009
|
+
screenshotDirectory: screenshotDirectory ?? currentConfig.screenshotDirectory,
|
|
11010
|
+
screenshotFailures: screenshotFailures ?? currentConfig.screenshotFailures,
|
|
11011
|
+
// TODO: test that CLI arg is preferred over the local config
|
|
11012
|
+
headless: project.vitest._options?.browser?.headless ?? headless ?? currentConfig.headless,
|
|
11013
|
+
name: browser,
|
|
11014
|
+
providerOptions: config,
|
|
11015
|
+
instances: void 0
|
|
11016
|
+
// projects cannot spawn more configs
|
|
11017
|
+
}
|
|
11018
|
+
// TODO: should resolve, not merge/override
|
|
11019
|
+
}, overrideConfig);
|
|
11020
|
+
}
|
|
10816
11021
|
async function resolveTestProjectConfigs(vitest, workspaceConfigPath, workspaceDefinition) {
|
|
10817
11022
|
const projectsOptions = [];
|
|
10818
11023
|
const workspaceConfigFiles = [];
|
|
@@ -10824,8 +11029,8 @@ async function resolveTestProjectConfigs(vitest, workspaceConfigPath, workspaceD
|
|
|
10824
11029
|
if (!isDynamicPattern(stringOption)) {
|
|
10825
11030
|
const file = resolve(vitest.config.root, stringOption);
|
|
10826
11031
|
if (!existsSync(file)) {
|
|
10827
|
-
const
|
|
10828
|
-
const note = workspaceConfigPath ? `Workspace config file "${
|
|
11032
|
+
const relativeWorkSpaceConfigPath = workspaceConfigPath ? relative(vitest.config.root, workspaceConfigPath) : void 0;
|
|
11033
|
+
const note = workspaceConfigPath ? `Workspace config file "${relativeWorkSpaceConfigPath}"` : "Inline workspace";
|
|
10829
11034
|
throw new Error(`${note} references a non-existing file or a directory: ${file}`);
|
|
10830
11035
|
}
|
|
10831
11036
|
const stats = await promises.stat(file);
|
|
@@ -10964,6 +11169,8 @@ class Vitest {
|
|
|
10964
11169
|
/** @internal */
|
|
10965
11170
|
_browserLastPort = defaultBrowserPort;
|
|
10966
11171
|
/** @internal */
|
|
11172
|
+
_browserSessions = new BrowserSessions();
|
|
11173
|
+
/** @internal */
|
|
10967
11174
|
_options = {};
|
|
10968
11175
|
/** @internal */
|
|
10969
11176
|
reporters = void 0;
|
|
@@ -11204,7 +11411,7 @@ class Vitest {
|
|
|
11204
11411
|
const workspaceConfigPath = await this.resolveWorkspaceConfigPath();
|
|
11205
11412
|
this._workspaceConfigPath = workspaceConfigPath;
|
|
11206
11413
|
if (!workspaceConfigPath) {
|
|
11207
|
-
return [this._ensureRootProject()];
|
|
11414
|
+
return resolveBrowserWorkspace(this, /* @__PURE__ */ new Set(), [this._ensureRootProject()]);
|
|
11208
11415
|
}
|
|
11209
11416
|
const workspaceModule = await this.import(workspaceConfigPath);
|
|
11210
11417
|
if (!workspaceModule.default || !Array.isArray(workspaceModule.default)) {
|
|
@@ -11380,7 +11587,7 @@ class Vitest {
|
|
|
11380
11587
|
return this.getModuleSpecifications(file);
|
|
11381
11588
|
}
|
|
11382
11589
|
/**
|
|
11383
|
-
* Get test specifications
|
|
11590
|
+
* Get test specifications associated with the given module. If module is not a test file, an empty array is returned.
|
|
11384
11591
|
*
|
|
11385
11592
|
* **Note:** this method relies on a cache generated by `globTestSpecifications`. If the file was not processed yet, use `project.matchesGlobPattern` instead.
|
|
11386
11593
|
* @param moduleId The module ID to get test specifications for.
|
|
@@ -11389,7 +11596,7 @@ class Vitest {
|
|
|
11389
11596
|
return this.specifications.getModuleSpecifications(moduleId);
|
|
11390
11597
|
}
|
|
11391
11598
|
/**
|
|
11392
|
-
* Vitest automatically caches test specifications for each file. This method clears the cache for the given file or the whole cache
|
|
11599
|
+
* Vitest automatically caches test specifications for each file. This method clears the cache for the given file or the whole cache altogether.
|
|
11393
11600
|
*/
|
|
11394
11601
|
clearSpecificationsCache(moduleId) {
|
|
11395
11602
|
this.specifications.clearCache(moduleId);
|
|
@@ -11516,6 +11723,7 @@ class Vitest {
|
|
|
11516
11723
|
async cancelCurrentRun(reason) {
|
|
11517
11724
|
this.isCancelling = true;
|
|
11518
11725
|
await Promise.all(this._onCancelListeners.splice(0).map((listener) => listener(reason)));
|
|
11726
|
+
await this.runningPromise;
|
|
11519
11727
|
}
|
|
11520
11728
|
/** @internal */
|
|
11521
11729
|
async _initBrowserServers() {
|
|
@@ -11545,8 +11753,9 @@ class Vitest {
|
|
|
11545
11753
|
this.report("onWatcherRerun", files, trigger),
|
|
11546
11754
|
...this._onUserTestsRerun.map((fn) => fn(specifications))
|
|
11547
11755
|
]);
|
|
11548
|
-
await this.runFiles(specifications, allTestsRun);
|
|
11756
|
+
const testResult = await this.runFiles(specifications, allTestsRun);
|
|
11549
11757
|
await this.report("onWatcherStart", this.state.getFiles(files));
|
|
11758
|
+
return testResult;
|
|
11550
11759
|
}
|
|
11551
11760
|
/** @internal */
|
|
11552
11761
|
async rerunTask(id) {
|
|
@@ -11599,7 +11808,10 @@ class Vitest {
|
|
|
11599
11808
|
async rerunFailed() {
|
|
11600
11809
|
await this.rerunFiles(this.state.getFailedFilepaths(), "rerun failed", false);
|
|
11601
11810
|
}
|
|
11602
|
-
/**
|
|
11811
|
+
/**
|
|
11812
|
+
* Update snapshots in specified files. If no files are provided, it will update files with failed tests and obsolete snapshots.
|
|
11813
|
+
* @param files The list of files on the file system
|
|
11814
|
+
*/
|
|
11603
11815
|
async updateSnapshot(files) {
|
|
11604
11816
|
files = files || [
|
|
11605
11817
|
...this.state.getFailedFilepaths(),
|
|
@@ -11607,7 +11819,7 @@ class Vitest {
|
|
|
11607
11819
|
];
|
|
11608
11820
|
this.enableSnapshotUpdate();
|
|
11609
11821
|
try {
|
|
11610
|
-
await this.rerunFiles(files, "update snapshot", false);
|
|
11822
|
+
return await this.rerunFiles(files, "update snapshot", false);
|
|
11611
11823
|
} finally {
|
|
11612
11824
|
this.resetSnapshotUpdate();
|
|
11613
11825
|
}
|
|
@@ -11625,12 +11837,14 @@ class Vitest {
|
|
|
11625
11837
|
// environment is resolved inside a worker thread
|
|
11626
11838
|
snapshotEnvironment: null
|
|
11627
11839
|
};
|
|
11840
|
+
this.snapshot.options.updateSnapshot = "all";
|
|
11628
11841
|
}
|
|
11629
11842
|
/**
|
|
11630
11843
|
* Disable the mode that allows updating snapshots when running tests.
|
|
11631
11844
|
*/
|
|
11632
11845
|
resetSnapshotUpdate() {
|
|
11633
11846
|
delete this.configOverride.snapshotOptions;
|
|
11847
|
+
this.snapshot.options.updateSnapshot = this.config.snapshotOptions.updateSnapshot;
|
|
11634
11848
|
}
|
|
11635
11849
|
/**
|
|
11636
11850
|
* Set the global test name pattern to a regexp.
|
|
@@ -11764,7 +11978,6 @@ class Vitest {
|
|
|
11764
11978
|
this.logger.error("error during close", r.reason);
|
|
11765
11979
|
}
|
|
11766
11980
|
});
|
|
11767
|
-
this.logger.logUpdate.done();
|
|
11768
11981
|
});
|
|
11769
11982
|
})();
|
|
11770
11983
|
}
|
|
@@ -12293,13 +12506,11 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout2) {
|
|
|
12293
12506
|
async function _keypressHandler(str, key) {
|
|
12294
12507
|
if (str === "" || str === "\x1B" || key && key.ctrl && key.name === "c") {
|
|
12295
12508
|
if (!ctx.isCancelling) {
|
|
12296
|
-
ctx.logger.logUpdate.clear();
|
|
12297
12509
|
ctx.logger.log(
|
|
12298
12510
|
c.red("Cancelling test run. Press CTRL+c again to exit forcefully.\n")
|
|
12299
12511
|
);
|
|
12300
12512
|
process.exitCode = 130;
|
|
12301
12513
|
await ctx.cancelCurrentRun("keyboard-input");
|
|
12302
|
-
await ctx.runningPromise;
|
|
12303
12514
|
}
|
|
12304
12515
|
return ctx.exit(true);
|
|
12305
12516
|
}
|
|
@@ -12514,12 +12725,6 @@ async function prepareVitest(mode, options = {}, viteOverrides, vitestOptions) {
|
|
|
12514
12725
|
options.watch = false;
|
|
12515
12726
|
}
|
|
12516
12727
|
const root = resolve(options.root || process.cwd());
|
|
12517
|
-
if (typeof options.browser === "object" && !("enabled" in options.browser)) {
|
|
12518
|
-
options.browser.enabled = true;
|
|
12519
|
-
}
|
|
12520
|
-
if (typeof options.typecheck?.only === "boolean") {
|
|
12521
|
-
options.typecheck.enabled ??= true;
|
|
12522
|
-
}
|
|
12523
12728
|
const ctx = await createVitest(mode, options, viteOverrides, vitestOptions);
|
|
12524
12729
|
const environmentPackage = getEnvPackageName(ctx.config.environment);
|
|
12525
12730
|
if (environmentPackage && !await ctx.packageInstaller.ensureInstalled(environmentPackage, root)) {
|
|
@@ -60,6 +60,12 @@ interface FakeTimerInstallOpts {
|
|
|
60
60
|
* @default true
|
|
61
61
|
*/
|
|
62
62
|
shouldClearNativeTimers?: boolean | undefined;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Don't throw error when asked to fake timers that are not present.
|
|
66
|
+
* @default false
|
|
67
|
+
*/
|
|
68
|
+
ignoreMissingTimers?: boolean | undefined;
|
|
63
69
|
}
|
|
64
70
|
|
|
65
71
|
/**
|