vitest 3.0.0-beta.2 → 3.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.d.ts +2 -2
- package/dist/chunks/{RandomSequencer.gisBJ77r.js → RandomSequencer.C6x84bNN.js} +4 -3
- package/dist/chunks/{base.CUgXReRN.js → base.CQ2VEtuH.js} +1 -1
- package/dist/chunks/{cac.Xzv7eNWw.js → cac.e7qW4xLT.js} +19 -8
- package/dist/chunks/{cli-api.CETCDGgZ.js → cli-api.CWDlED-m.js} +244 -39
- package/dist/chunks/{creator.DcAcUhMD.js → creator.Ot9GlSGw.js} +16 -14
- package/dist/chunks/{index.DoV7W5gc.js → index.BBoOXW-l.js} +5 -0
- package/dist/chunks/{index.9ZEBV_TJ.js → index.CzkCSFCy.js} +37 -24
- package/dist/chunks/{reporters.DTtxC3KQ.d.ts → reporters.DCiyjXOg.d.ts} +131 -102
- package/dist/chunks/{resolveConfig.BA-_OKEx.js → resolveConfig.C1d7TK-U.js} +25 -3
- package/dist/chunks/{runBaseTests.D0dWpzZV.js → runBaseTests.qNWRkgHj.js} +1 -1
- package/dist/chunks/{utils.CMUTX-p8.js → utils.Coei4Wlj.js} +1 -1
- package/dist/chunks/{vite.CXaetSK3.d.ts → vite.CRSMFy31.d.ts} +1 -1
- package/dist/chunks/{worker.ClntunZp.d.ts → worker.R-PA7DpW.d.ts} +1 -1
- package/dist/chunks/{worker.o1PBoDdo.d.ts → worker.XbtCXEXv.d.ts} +1 -0
- package/dist/cli.js +1 -1
- package/dist/config.cjs +1 -0
- package/dist/config.d.ts +3 -3
- package/dist/config.js +1 -0
- package/dist/coverage.d.ts +1 -1
- package/dist/coverage.js +33 -8
- package/dist/execute.d.ts +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/node.d.ts +5 -5
- package/dist/node.js +10 -10
- package/dist/reporters.d.ts +1 -1
- package/dist/reporters.js +3 -3
- package/dist/runners.js +2 -2
- package/dist/workers/forks.js +1 -1
- package/dist/workers/runVmTests.js +1 -1
- package/dist/workers/threads.js +1 -1
- package/dist/workers.d.ts +2 -2
- package/dist/workers.js +1 -1
- package/package.json +13 -13
package/dist/browser.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as CoverageProvider, c as CoverageProviderModule } from './chunks/reporters.
|
|
1
|
+
import { b as CoverageProvider, c as CoverageProviderModule } from './chunks/reporters.DCiyjXOg.js';
|
|
2
2
|
import { a as SerializedCoverageConfig, S as SerializedConfig } from './chunks/config.BTPBhmK5.js';
|
|
3
3
|
import * as spy$1 from '@vitest/spy';
|
|
4
4
|
import * as _vitest_utils_diff from '@vitest/utils/diff';
|
|
@@ -20,7 +20,7 @@ import '@vitest/snapshot/manager';
|
|
|
20
20
|
import 'node:fs';
|
|
21
21
|
import '@vitest/snapshot/environment';
|
|
22
22
|
import 'vite-node/client';
|
|
23
|
-
import './chunks/worker.
|
|
23
|
+
import './chunks/worker.XbtCXEXv.js';
|
|
24
24
|
import 'node:vm';
|
|
25
25
|
import '@vitest/mocker';
|
|
26
26
|
import './chunks/mocker.cRtM890J.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import 'std-env';
|
|
1
|
+
import { isCI } from 'std-env';
|
|
2
2
|
import { writeFile, rm } from 'node:fs/promises';
|
|
3
3
|
import { performance } from 'node:perf_hooks';
|
|
4
4
|
import { generateHash, calculateSuiteHash, someTasksAreOnly, interpretTaskModes, getTasks } from '@vitest/runner/utils';
|
|
@@ -21,6 +21,7 @@ const hash = crypto.hash ?? ((algorithm, data, outputEncoding) => crypto.createH
|
|
|
21
21
|
const isNode = typeof process < "u" && typeof process.stdout < "u" && !process.versions?.deno && !globalThis.window;
|
|
22
22
|
const isDeno = typeof process < "u" && typeof process.stdout < "u" && process.versions?.deno !== void 0;
|
|
23
23
|
const isWindows = (isNode || isDeno) && process.platform === "win32";
|
|
24
|
+
const isTTY = (isNode || isDeno) && process.stdout?.isTTY && !isCI;
|
|
24
25
|
|
|
25
26
|
const REGEXP_WRAP_PREFIX = "$$vitest:";
|
|
26
27
|
function getOutputFile(config, reporter) {
|
|
@@ -709,7 +710,7 @@ class Typechecker {
|
|
|
709
710
|
if ("tasks" in task) {
|
|
710
711
|
markTasks(task.tasks);
|
|
711
712
|
}
|
|
712
|
-
if (!task.result?.state && task.mode === "run") {
|
|
713
|
+
if (!task.result?.state && (task.mode === "run" || task.mode === "queued")) {
|
|
713
714
|
task.result = {
|
|
714
715
|
state: "pass"
|
|
715
716
|
};
|
|
@@ -977,4 +978,4 @@ class RandomSequencer extends BaseSequencer {
|
|
|
977
978
|
}
|
|
978
979
|
}
|
|
979
980
|
|
|
980
|
-
export { BaseSequencer as B, RandomSequencer as R, Typechecker as T, TypeCheckError as a,
|
|
981
|
+
export { BaseSequencer as B, RandomSequencer as R, Typechecker as T, TypeCheckError as a, isTTY as b, getOutputFile as g, hash as h, isWindows as i, wrapSerializableConfig as w };
|
|
@@ -26,7 +26,7 @@ async function runBaseTests(method, state) {
|
|
|
26
26
|
));
|
|
27
27
|
const [executor, { run }] = await Promise.all([
|
|
28
28
|
startViteNode({ state, requestStubs: getDefaultRequestStubs() }),
|
|
29
|
-
import('./runBaseTests.
|
|
29
|
+
import('./runBaseTests.qNWRkgHj.js')
|
|
30
30
|
]);
|
|
31
31
|
const fileSpecs = ctx.files.map(
|
|
32
32
|
(f) => typeof f === "string" ? { filepath: f, testLocations: void 0 } : f
|
|
@@ -618,7 +618,7 @@ class CAC extends EventEmitter {
|
|
|
618
618
|
|
|
619
619
|
const cac = (name = "") => new CAC(name);
|
|
620
620
|
|
|
621
|
-
var version = "3.0.0-beta.
|
|
621
|
+
var version = "3.0.0-beta.3";
|
|
622
622
|
|
|
623
623
|
const apiConfig = (port) => ({
|
|
624
624
|
port: {
|
|
@@ -919,7 +919,7 @@ const cliOptionsConfig = {
|
|
|
919
919
|
description: "Run tests in the browser. Equivalent to `--browser.enabled` (default: `false`)"
|
|
920
920
|
},
|
|
921
921
|
name: {
|
|
922
|
-
description: "Run all tests in a specific browser. Some browsers are only available for specific providers (see `--browser.provider`). Visit [`browser.name`](https://vitest.dev/config/#browser-name) for more information",
|
|
922
|
+
description: "Run all tests in a specific browser. Some browsers are only available for specific providers (see `--browser.provider`). Visit [`browser.name`](https://vitest.dev/guide/browser/config/#browser-name) for more information",
|
|
923
923
|
argument: "<name>"
|
|
924
924
|
},
|
|
925
925
|
headless: {
|
|
@@ -951,6 +951,10 @@ const cliOptionsConfig = {
|
|
|
951
951
|
fileParallelism: {
|
|
952
952
|
description: "Should browser test files run in parallel. Use `--browser.fileParallelism=false` to disable (default: `true`)"
|
|
953
953
|
},
|
|
954
|
+
connectTimeout: {
|
|
955
|
+
description: "If connection to the browser takes longer, the test suite will fail (default: `60_000`)",
|
|
956
|
+
argument: "<timeout>"
|
|
957
|
+
},
|
|
954
958
|
orchestratorScripts: null,
|
|
955
959
|
testerScripts: null,
|
|
956
960
|
commands: null,
|
|
@@ -958,7 +962,8 @@ const cliOptionsConfig = {
|
|
|
958
962
|
screenshotDirectory: null,
|
|
959
963
|
screenshotFailures: null,
|
|
960
964
|
locators: null,
|
|
961
|
-
testerHtmlPath: null
|
|
965
|
+
testerHtmlPath: null,
|
|
966
|
+
instances: null
|
|
962
967
|
}
|
|
963
968
|
},
|
|
964
969
|
pool: {
|
|
@@ -1548,6 +1553,12 @@ function normalizeCliOptions(cliFilters, argv) {
|
|
|
1548
1553
|
if (cliFilters.some((filter) => filter.includes(":"))) {
|
|
1549
1554
|
argv.includeTaskLocation ??= true;
|
|
1550
1555
|
}
|
|
1556
|
+
if (typeof argv.browser === "object" && !("enabled" in argv.browser)) {
|
|
1557
|
+
argv.browser.enabled = true;
|
|
1558
|
+
}
|
|
1559
|
+
if (typeof argv.typecheck?.only === "boolean") {
|
|
1560
|
+
argv.typecheck.enabled ??= true;
|
|
1561
|
+
}
|
|
1551
1562
|
return argv;
|
|
1552
1563
|
}
|
|
1553
1564
|
async function start(mode, cliFilters, options) {
|
|
@@ -1556,13 +1567,13 @@ async function start(mode, cliFilters, options) {
|
|
|
1556
1567
|
} catch {
|
|
1557
1568
|
}
|
|
1558
1569
|
try {
|
|
1559
|
-
const { startVitest } = await import('./cli-api.
|
|
1570
|
+
const { startVitest } = await import('./cli-api.CWDlED-m.js').then(function (n) { return n.f; });
|
|
1560
1571
|
const ctx = await startVitest(mode, cliFilters.map(normalize), normalizeCliOptions(cliFilters, options));
|
|
1561
1572
|
if (!ctx.shouldKeepServer()) {
|
|
1562
1573
|
await ctx.exit();
|
|
1563
1574
|
}
|
|
1564
1575
|
} catch (e) {
|
|
1565
|
-
const { divider } = await import('./utils.
|
|
1576
|
+
const { divider } = await import('./utils.Coei4Wlj.js').then(function (n) { return n.u; });
|
|
1566
1577
|
console.error(`
|
|
1567
1578
|
${c.red(divider(c.bold(c.inverse(" Startup Error "))))}`);
|
|
1568
1579
|
console.error(e);
|
|
@@ -1578,7 +1589,7 @@ async function init(project) {
|
|
|
1578
1589
|
console.error(new Error('Only the "browser" project is supported. Use "vitest init browser" to create a new project.'));
|
|
1579
1590
|
process.exit(1);
|
|
1580
1591
|
}
|
|
1581
|
-
const { create } = await import('./creator.
|
|
1592
|
+
const { create } = await import('./creator.Ot9GlSGw.js');
|
|
1582
1593
|
await create();
|
|
1583
1594
|
}
|
|
1584
1595
|
async function collect(mode, cliFilters, options) {
|
|
@@ -1587,7 +1598,7 @@ async function collect(mode, cliFilters, options) {
|
|
|
1587
1598
|
} catch {
|
|
1588
1599
|
}
|
|
1589
1600
|
try {
|
|
1590
|
-
const { prepareVitest, processCollected, outputFileList } = await import('./cli-api.
|
|
1601
|
+
const { prepareVitest, processCollected, outputFileList } = await import('./cli-api.CWDlED-m.js').then(function (n) { return n.f; });
|
|
1591
1602
|
const ctx = await prepareVitest(mode, {
|
|
1592
1603
|
...normalizeCliOptions(cliFilters, options),
|
|
1593
1604
|
watch: false,
|
|
@@ -1609,7 +1620,7 @@ async function collect(mode, cliFilters, options) {
|
|
|
1609
1620
|
}
|
|
1610
1621
|
await ctx.close();
|
|
1611
1622
|
} catch (e) {
|
|
1612
|
-
const { divider } = await import('./utils.
|
|
1623
|
+
const { divider } = await import('./utils.Coei4Wlj.js').then(function (n) { return n.u; });
|
|
1613
1624
|
console.error(`
|
|
1614
1625
|
${c.red(divider(c.bold(c.inverse(" Collect Error "))))}`);
|
|
1615
1626
|
console.error(e);
|
|
@@ -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.e7qW4xLT.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.CzkCSFCy.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.C1d7TK-U.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, i as isWindows } from './RandomSequencer.
|
|
34
|
-
import { isCI } from 'std-env';
|
|
33
|
+
import { b as isTTY, h as hash, i as isWindows } from './RandomSequencer.C6x84bNN.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.Coei4Wlj.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) {
|
|
@@ -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)}?`)
|
|
@@ -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
|
/**
|
|
@@ -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.
|
|
@@ -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);
|
|
@@ -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 = [];
|
|
@@ -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)) {
|
|
@@ -11545,8 +11752,9 @@ class Vitest {
|
|
|
11545
11752
|
this.report("onWatcherRerun", files, trigger),
|
|
11546
11753
|
...this._onUserTestsRerun.map((fn) => fn(specifications))
|
|
11547
11754
|
]);
|
|
11548
|
-
await this.runFiles(specifications, allTestsRun);
|
|
11755
|
+
const testResult = await this.runFiles(specifications, allTestsRun);
|
|
11549
11756
|
await this.report("onWatcherStart", this.state.getFiles(files));
|
|
11757
|
+
return testResult;
|
|
11550
11758
|
}
|
|
11551
11759
|
/** @internal */
|
|
11552
11760
|
async rerunTask(id) {
|
|
@@ -11599,7 +11807,10 @@ class Vitest {
|
|
|
11599
11807
|
async rerunFailed() {
|
|
11600
11808
|
await this.rerunFiles(this.state.getFailedFilepaths(), "rerun failed", false);
|
|
11601
11809
|
}
|
|
11602
|
-
/**
|
|
11810
|
+
/**
|
|
11811
|
+
* Update snapshots in specified files. If no files are provided, it will update files with failed tests and obsolete snapshots.
|
|
11812
|
+
* @param files The list of files on the file system
|
|
11813
|
+
*/
|
|
11603
11814
|
async updateSnapshot(files) {
|
|
11604
11815
|
files = files || [
|
|
11605
11816
|
...this.state.getFailedFilepaths(),
|
|
@@ -11607,7 +11818,7 @@ class Vitest {
|
|
|
11607
11818
|
];
|
|
11608
11819
|
this.enableSnapshotUpdate();
|
|
11609
11820
|
try {
|
|
11610
|
-
await this.rerunFiles(files, "update snapshot", false);
|
|
11821
|
+
return await this.rerunFiles(files, "update snapshot", false);
|
|
11611
11822
|
} finally {
|
|
11612
11823
|
this.resetSnapshotUpdate();
|
|
11613
11824
|
}
|
|
@@ -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)) {
|