vitest 4.0.9 → 4.0.10

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.
Files changed (42) hide show
  1. package/dist/browser.js +1 -1
  2. package/dist/chunks/_commonjsHelpers.D26ty3Ew.js +6 -0
  3. package/dist/chunks/{base.CiIV2DDC.js → base.BFVArrYW.js} +5 -5
  4. package/dist/chunks/{cac.B_NTJoIH.js → cac.D9CYcNPM.js} +7 -7
  5. package/dist/chunks/{cli-api.D48wY175.js → cli-api.RnIE1JbW.js} +56 -54
  6. package/dist/chunks/{creator.BzqvXeRE.js → creator.DU9qFjsW.js} +2 -2
  7. package/dist/chunks/{globals.DBrtKPdh.js → globals.NLOzC_A5.js} +3 -3
  8. package/dist/chunks/{index.op2Re5rn.js → index.B8lJfb0J.js} +1 -1
  9. package/dist/chunks/{index.kotH7DY7.js → index.BYek7GgP.js} +5 -3
  10. package/dist/chunks/{index.z7NPOg2E.js → index.D4KonVSU.js} +1 -1
  11. package/dist/chunks/{index.CGezRSGU.js → index.DZ-mI_Nm.js} +1 -1
  12. package/dist/chunks/{index.CPA8jGhR.js → index.Dua7TZg_.js} +2 -2
  13. package/dist/chunks/{index.BfmpdV5p.js → index.QWbK7rHY.js} +3 -3
  14. package/dist/chunks/init-forks.BZSlxfwV.js +32 -0
  15. package/dist/chunks/{init-threads.C7T0-YMD.js → init-threads.CwE2n-Bv.js} +1 -1
  16. package/dist/chunks/{init.BQhNfT0h.js → init.Cz2kTB9a.js} +1 -1
  17. package/dist/chunks/{plugin.d.DevON6kQ.d.ts → plugin.d.C6KrdvNG.d.ts} +1 -1
  18. package/dist/chunks/{reporters.d.BQ0wpUaj.d.ts → reporters.d.keG-yFSu.d.ts} +2 -1
  19. package/dist/chunks/{setup-common.Dw1XgX0v.js → setup-common.BOzbXE3x.js} +2 -2
  20. package/dist/chunks/{test.w5HLbjmU.js → test.BPErLMrw.js} +1 -1
  21. package/dist/chunks/{vi.CyIUVSoU.js → vi.BiaV1qII.js} +2 -2
  22. package/dist/chunks/{vm.DXN8eCh2.js → vm.wSHjz-et.js} +1 -1
  23. package/dist/cli.js +2 -2
  24. package/dist/config.d.ts +3 -3
  25. package/dist/coverage.d.ts +1 -1
  26. package/dist/environments.js +1 -1
  27. package/dist/index.d.ts +2 -2
  28. package/dist/index.js +3 -3
  29. package/dist/node.d.ts +3 -3
  30. package/dist/node.js +9 -9
  31. package/dist/reporters.d.ts +1 -1
  32. package/dist/reporters.js +2 -2
  33. package/dist/runners.js +3 -3
  34. package/dist/worker.js +9 -9
  35. package/dist/workers/forks.js +10 -11
  36. package/dist/workers/runVmTests.js +6 -6
  37. package/dist/workers/threads.js +10 -10
  38. package/dist/workers/vmForks.js +4 -5
  39. package/dist/workers/vmThreads.js +4 -4
  40. package/package.json +14 -14
  41. package/dist/chunks/_commonjsHelpers.BFTU3MAI.js +0 -7
  42. package/dist/chunks/init-forks.aqTzCSR2.js +0 -65
package/dist/browser.js CHANGED
@@ -1,4 +1,4 @@
1
- export { l as loadDiffConfig, b as loadSnapshotSerializers, c as setupCommonEnv, s as startCoverageInsideWorker, a as stopCoverageInsideWorker, t as takeCoverageInsideWorker } from './chunks/setup-common.Dw1XgX0v.js';
1
+ export { l as loadDiffConfig, b as loadSnapshotSerializers, c as setupCommonEnv, s as startCoverageInsideWorker, a as stopCoverageInsideWorker, t as takeCoverageInsideWorker } from './chunks/setup-common.BOzbXE3x.js';
2
2
  export { collectTests, startTests } from '@vitest/runner';
3
3
  import * as spyModule from '@vitest/spy';
4
4
  export { spyModule as SpyModule };
@@ -0,0 +1,6 @@
1
+ var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
2
+ function getDefaultExportFromCjs(x) {
3
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
4
+ }
5
+
6
+ export { commonjsGlobal as c, getDefaultExportFromCjs as g };
@@ -1,20 +1,20 @@
1
1
  import { runInThisContext } from 'node:vm';
2
2
  import * as spyModule from '@vitest/spy';
3
- import { r as resolveTestRunner, a as resolveSnapshotEnvironment, s as setupChaiConfig } from './index.CPA8jGhR.js';
4
- import { l as loadEnvironment } from './init.BQhNfT0h.js';
3
+ import { r as resolveTestRunner, a as resolveSnapshotEnvironment, s as setupChaiConfig } from './index.Dua7TZg_.js';
4
+ import { l as loadEnvironment } from './init.Cz2kTB9a.js';
5
5
  import { V as VitestEvaluatedModules } from './evaluatedModules.Dg1zASAC.js';
6
6
  import { s as startVitestModuleRunner, c as createNodeImportMeta } from './startModuleRunner.DLjmA_wU.js';
7
7
  import { performance as performance$1 } from 'node:perf_hooks';
8
8
  import { startTests, collectTests } from '@vitest/runner';
9
- import { c as setupCommonEnv, s as startCoverageInsideWorker, a as stopCoverageInsideWorker } from './setup-common.Dw1XgX0v.js';
10
- import { g as globalExpect, v as vi } from './vi.CyIUVSoU.js';
9
+ import { c as setupCommonEnv, s as startCoverageInsideWorker, a as stopCoverageInsideWorker } from './setup-common.BOzbXE3x.js';
10
+ import { g as globalExpect, v as vi } from './vi.BiaV1qII.js';
11
11
  import { c as closeInspector } from './inspector.CvyFGlXm.js';
12
12
  import { createRequire } from 'node:module';
13
13
  import timers from 'node:timers';
14
14
  import timersPromises from 'node:timers/promises';
15
15
  import util from 'node:util';
16
16
  import { KNOWN_ASSET_TYPES } from '@vitest/utils/constants';
17
- import { i as index } from './index.CGezRSGU.js';
17
+ import { i as index } from './index.DZ-mI_Nm.js';
18
18
  import { g as getWorkerState, r as resetModules, p as provideWorkerState } from './utils.DvEY5TfP.js';
19
19
 
20
20
  // this should only be used in Node
@@ -3,7 +3,7 @@ import { EventEmitter } from 'events';
3
3
  import { normalize } from 'pathe';
4
4
  import c from 'tinyrainbow';
5
5
  import { a as defaultPort, d as defaultBrowserPort } from './constants.D_Q9UYh-.js';
6
- import { R as ReportersMap } from './index.kotH7DY7.js';
6
+ import { R as ReportersMap } from './index.BYek7GgP.js';
7
7
 
8
8
  function toArr(any) {
9
9
  return any == null ? [] : Array.isArray(any) ? any : [any];
@@ -619,7 +619,7 @@ class CAC extends EventEmitter {
619
619
 
620
620
  const cac = (name = "") => new CAC(name);
621
621
 
622
- var version = "4.0.9";
622
+ var version = "4.0.10";
623
623
 
624
624
  const apiConfig = (port) => ({
625
625
  port: {
@@ -1357,11 +1357,11 @@ function normalizeCliOptions(cliFilters, argv) {
1357
1357
  }
1358
1358
  async function start(mode, cliFilters, options) {
1359
1359
  try {
1360
- const { startVitest } = await import('./cli-api.D48wY175.js').then(function (n) { return n.p; });
1360
+ const { startVitest } = await import('./cli-api.RnIE1JbW.js').then(function (n) { return n.p; });
1361
1361
  const ctx = await startVitest(mode, cliFilters.map(normalize), normalizeCliOptions(cliFilters, options));
1362
1362
  if (!ctx.shouldKeepServer()) await ctx.exit();
1363
1363
  } catch (e) {
1364
- const { errorBanner } = await import('./index.kotH7DY7.js').then(function (n) { return n.u; });
1364
+ const { errorBanner } = await import('./index.BYek7GgP.js').then(function (n) { return n.u; });
1365
1365
  console.error(`\n${errorBanner("Startup Error")}`);
1366
1366
  console.error(e);
1367
1367
  console.error("\n\n");
@@ -1374,12 +1374,12 @@ async function init(project) {
1374
1374
  console.error(/* @__PURE__ */ new Error("Only the \"browser\" project is supported. Use \"vitest init browser\" to create a new project."));
1375
1375
  process.exit(1);
1376
1376
  }
1377
- const { create } = await import('./creator.BzqvXeRE.js');
1377
+ const { create } = await import('./creator.DU9qFjsW.js');
1378
1378
  await create();
1379
1379
  }
1380
1380
  async function collect(mode, cliFilters, options) {
1381
1381
  try {
1382
- const { prepareVitest, processCollected, outputFileList } = await import('./cli-api.D48wY175.js').then(function (n) { return n.p; });
1382
+ const { prepareVitest, processCollected, outputFileList } = await import('./cli-api.RnIE1JbW.js').then(function (n) { return n.p; });
1383
1383
  const ctx = await prepareVitest(mode, {
1384
1384
  ...normalizeCliOptions(cliFilters, options),
1385
1385
  watch: false,
@@ -1398,7 +1398,7 @@ async function collect(mode, cliFilters, options) {
1398
1398
  } else outputFileList(await ctx.getRelevantTestSpecifications(cliFilters.map(normalize)), options);
1399
1399
  await ctx.close();
1400
1400
  } catch (e) {
1401
- const { errorBanner } = await import('./index.kotH7DY7.js').then(function (n) { return n.u; });
1401
+ const { errorBanner } = await import('./index.BYek7GgP.js').then(function (n) { return n.u; });
1402
1402
  console.error(`\n${errorBanner("Collect Error")}`);
1403
1403
  console.error(e);
1404
1404
  console.error("\n\n");
@@ -3,7 +3,7 @@ import { relative, resolve, dirname, join, extname, normalize, basename, isAbsol
3
3
  import { C as CoverageProviderMap } from './coverage.D_JHT54q.js';
4
4
  import path, { resolve as resolve$1 } from 'node:path';
5
5
  import { noop, createDefer, slash, isExternalUrl, unwrapId, nanoid, withTrailingSlash, cleanUrl, wrapId, toArray, deepMerge, deepClone, isPrimitive, notNullish } from '@vitest/utils/helpers';
6
- import { a as any, p as prompt } from './index.z7NPOg2E.js';
6
+ import { a as any, p as prompt } from './index.D4KonVSU.js';
7
7
  import { h as hash, R as RandomSequencer, i as isPackageExists, c as isBrowserEnabled, r as resolveConfig, g as getCoverageProvider, a as resolveApiServerConfig, d as resolveModule } from './coverage.BUlIqJrL.js';
8
8
  import * as vite from 'vite';
9
9
  import { parseAst, fetchModule, version, searchForWorkspaceRoot, mergeConfig, createServer } from 'vite';
@@ -12,9 +12,10 @@ import * as nodeos from 'node:os';
12
12
  import nodeos__default, { tmpdir } from 'node:os';
13
13
  import { generateHash as generateHash$1, calculateSuiteHash, someTasksAreOnly, interpretTaskModes, hasFailed, generateFileHash, limitConcurrency, createFileTask as createFileTask$1, getTasks, isTestCase } from '@vitest/runner/utils';
14
14
  import { SnapshotManager } from '@vitest/snapshot/manager';
15
- import { v as version$1 } from './cac.B_NTJoIH.js';
15
+ import { v as version$1 } from './cac.D9CYcNPM.js';
16
+ import { performance as performance$1 } from 'node:perf_hooks';
16
17
  import { c as createBirpc } from './index.0kCJoeWi.js';
17
- import { p as parse, d as stringify, e as TraceMap, o as originalPositionFor, h as ancestor, i as printError, f as formatProjectName, w as withLabel, j as errorBanner, k as divider, l as Typechecker, m as generateCodeFrame, n as createDefinesScript, R as ReportersMap, B as BlobReporter, r as readBlobs, q as convertTasksToEvents, H as HangingProcessReporter } from './index.kotH7DY7.js';
18
+ import { p as parse, d as stringify, e as TraceMap, o as originalPositionFor, h as ancestor, i as printError, f as formatProjectName, w as withLabel, j as errorBanner, k as divider, l as Typechecker, m as generateCodeFrame, n as createDefinesScript, R as ReportersMap, B as BlobReporter, r as readBlobs, q as convertTasksToEvents, H as HangingProcessReporter } from './index.BYek7GgP.js';
18
19
  import require$$0$3 from 'events';
19
20
  import require$$1$1 from 'https';
20
21
  import require$$2 from 'http';
@@ -25,7 +26,7 @@ import require$$0$2 from 'stream';
25
26
  import require$$7 from 'url';
26
27
  import require$$0 from 'zlib';
27
28
  import require$$0$1 from 'buffer';
28
- import { g as getDefaultExportFromCjs } from './_commonjsHelpers.BFTU3MAI.js';
29
+ import { g as getDefaultExportFromCjs } from './_commonjsHelpers.D26ty3Ew.js';
29
30
  import crypto, { createHash } from 'node:crypto';
30
31
  import { rootDir, distDir } from '../path.js';
31
32
  import createDebug from 'debug';
@@ -41,7 +42,6 @@ import { i as isTTY, a as isWindows } from './env.D4Lgay0q.js';
41
42
  import { isatty } from 'node:tty';
42
43
  import EventEmitter$1, { EventEmitter } from 'node:events';
43
44
  import { fork } from 'node:child_process';
44
- import v8 from 'node:v8';
45
45
  import { Worker } from 'node:worker_threads';
46
46
  import pm from 'picomatch';
47
47
  import { glob, isDynamicPattern } from 'tinyglobby';
@@ -51,7 +51,7 @@ import { c as configDefaults } from './defaults.BOqNVLsY.js';
51
51
  import { KNOWN_ASSET_RE } from '@vitest/utils/constants';
52
52
  import { findNearestPackageData } from '@vitest/utils/resolver';
53
53
  import * as esModuleLexer from 'es-module-lexer';
54
- import { a as BenchmarkReportsMap } from './index.op2Re5rn.js';
54
+ import { a as BenchmarkReportsMap } from './index.B8lJfb0J.js';
55
55
  import assert$1 from 'node:assert';
56
56
  import { serializeValue } from '@vitest/utils/serialize';
57
57
  import { parseErrorStacktrace } from '@vitest/utils/source-map';
@@ -5198,6 +5198,8 @@ function setup(ctx, _server) {
5198
5198
  ctx.reporters.push(new WebSocketReporter(ctx, wss, clients));
5199
5199
  }
5200
5200
  class WebSocketReporter {
5201
+ start = 0;
5202
+ end = 0;
5201
5203
  constructor(ctx, wss, clients) {
5202
5204
  this.ctx = ctx;
5203
5205
  this.wss = wss;
@@ -5211,6 +5213,7 @@ class WebSocketReporter {
5211
5213
  }
5212
5214
  onTestRunStart(specifications) {
5213
5215
  if (this.clients.size === 0) return;
5216
+ this.start = performance$1.now();
5214
5217
  const serializedSpecs = specifications.map((spec) => spec.toJSON());
5215
5218
  this.clients.forEach((client) => {
5216
5219
  client.onSpecsCollected?.(serializedSpecs)?.catch?.(noop);
@@ -5228,12 +5231,21 @@ class WebSocketReporter {
5228
5231
  client.onTaskUpdate?.(packs, events)?.catch?.(noop);
5229
5232
  });
5230
5233
  }
5234
+ sum(items, cb) {
5235
+ return items.reduce((total, next) => {
5236
+ return total + Math.max(cb(next) || 0, 0);
5237
+ }, 0);
5238
+ }
5231
5239
  onTestRunEnd(testModules, unhandledErrors) {
5232
5240
  if (!this.clients.size) return;
5233
5241
  const files = testModules.map((testModule) => testModule.task);
5234
5242
  const errors = [...unhandledErrors];
5243
+ this.end = performance$1.now();
5244
+ const blobs = this.ctx.state.blobs;
5245
+ // Execution time is either sum of all runs of `--merge-reports` or the current run's time
5246
+ const executionTime = blobs?.executionTimes ? this.sum(blobs.executionTimes, (time) => time) : this.end - this.start;
5235
5247
  this.clients.forEach((client) => {
5236
- client.onFinished?.(files, errors)?.catch?.(noop);
5248
+ client.onFinished?.(files, errors, void 0, executionTime)?.catch?.(noop);
5237
5249
  });
5238
5250
  }
5239
5251
  onFinishedReportCoverage() {
@@ -6214,7 +6226,7 @@ class VitestPackageInstaller {
6214
6226
  if (/* @__PURE__ */ isPackageExists(dependency, { paths: [root, __dirname$1] })) return true;
6215
6227
  process.stderr.write(c.red(`${c.inverse(c.red(" MISSING DEPENDENCY "))} Cannot find dependency '${dependency}'\n\n`));
6216
6228
  if (!isTTY) return false;
6217
- const { install } = await (await import('./index.z7NPOg2E.js').then(function (n) { return n.i; })).default({
6229
+ const { install } = await (await import('./index.D4KonVSU.js').then(function (n) { return n.i; })).default({
6218
6230
  type: "confirm",
6219
6231
  name: "install",
6220
6232
  message: c.reset(`Do you want to install ${c.green(dependency)}?`)
@@ -6514,7 +6526,7 @@ class BrowserPool {
6514
6526
  return;
6515
6527
  }
6516
6528
  debug?.("[%s] error during %s test run: %s", sessionId, file, error);
6517
- this.reject(error);
6529
+ this.reject(new Error(`Failed to run the test ${file.filepath}.`, { cause: error }));
6518
6530
  });
6519
6531
  }).catch((err) => this.reject(err));
6520
6532
  }
@@ -6648,11 +6660,16 @@ class PoolRunner {
6648
6660
  environment;
6649
6661
  _state = RunnerState.IDLE;
6650
6662
  _operationLock = null;
6663
+ _terminatePromise = createDefer();
6651
6664
  _eventEmitter = new EventEmitter();
6665
+ _offCancel;
6652
6666
  _rpc;
6653
6667
  get isTerminated() {
6654
6668
  return this._state === RunnerState.STOPPED;
6655
6669
  }
6670
+ waitForTerminated() {
6671
+ return this._terminatePromise;
6672
+ }
6656
6673
  get isStarted() {
6657
6674
  return this._state === RunnerState.STARTED;
6658
6675
  }
@@ -6665,11 +6682,13 @@ class PoolRunner {
6665
6682
  cacheFs: worker.cacheFs
6666
6683
  }), {
6667
6684
  eventNames: ["onCancel"],
6668
- post: (request) => this.postMessage(request),
6685
+ post: (request) => {
6686
+ if (this._state !== RunnerState.STOPPING && this._state !== RunnerState.STOPPED) this.postMessage(request);
6687
+ },
6669
6688
  on: (callback) => this._eventEmitter.on("rpc", callback),
6670
6689
  timeout: -1
6671
6690
  });
6672
- this.project.vitest.onCancel((reason) => this._rpc.onCancel(reason));
6691
+ this._offCancel = this.project.vitest.onCancel((reason) => this._rpc.onCancel(reason));
6673
6692
  }
6674
6693
  postMessage(message) {
6675
6694
  // Only send messages when runner is active (not fully stopped)
@@ -6744,6 +6763,7 @@ class PoolRunner {
6744
6763
  });
6745
6764
  }), STOP_TIMEOUT);
6746
6765
  this._eventEmitter.removeAllListeners();
6766
+ this._offCancel();
6747
6767
  this._rpc.$close(/* @__PURE__ */ new Error("[vitest-pool-runner]: Pending methods while closing rpc"));
6748
6768
  // Stop the worker process (this sets _fork/_thread to undefined)
6749
6769
  // Worker's event listeners (error, message) are implicitly removed when worker terminates
@@ -6756,6 +6776,7 @@ class PoolRunner {
6756
6776
  } finally {
6757
6777
  this._operationLock.resolve();
6758
6778
  this._operationLock = null;
6779
+ this._terminatePromise.resolve();
6759
6780
  }
6760
6781
  }
6761
6782
  on(event, callback) {
@@ -6835,14 +6856,14 @@ class ForksPoolWorker {
6835
6856
  this.fork.off(event, callback);
6836
6857
  }
6837
6858
  send(message) {
6838
- if ("context" in message && "config" in message.context) message.context.config = wrapSerializableConfig(message.context.config);
6839
- this.fork.send(v8.serialize(message));
6859
+ this.fork.send(message);
6840
6860
  }
6841
6861
  async start() {
6842
6862
  this._fork ||= fork(this.entrypoint, [], {
6843
6863
  env: this.env,
6844
6864
  execArgv: this.execArgv,
6845
- stdio: "pipe"
6865
+ stdio: "pipe",
6866
+ serialization: "advanced"
6846
6867
  });
6847
6868
  if (this._fork.stdout) {
6848
6869
  this.stdout.setMaxListeners(1 + this.stdout.getMaxListeners());
@@ -6880,41 +6901,13 @@ class ForksPoolWorker {
6880
6901
  this._fork = void 0;
6881
6902
  }
6882
6903
  deserialize(data) {
6883
- try {
6884
- return v8.deserialize(Buffer.from(data));
6885
- } catch (error) {
6886
- let stringified = "";
6887
- try {
6888
- stringified = `\nReceived value: ${JSON.stringify(data)}`;
6889
- } catch {}
6890
- throw new Error(`[vitest-pool]: Unexpected call to process.send(). Make sure your test cases are not interfering with process's channel.${stringified}`, { cause: error });
6891
- }
6904
+ return data;
6892
6905
  }
6893
6906
  get fork() {
6894
6907
  if (!this._fork) throw new Error(`The child process was torn down or never initialized. This is a bug in Vitest.`);
6895
6908
  return this._fork;
6896
6909
  }
6897
6910
  }
6898
- /**
6899
- * Prepares `SerializedConfig` for serialization, e.g. `node:v8.serialize`
6900
- * - Unwrapping done in {@link file://./../../../runtime/workers/init-forks.ts}
6901
- */
6902
- function wrapSerializableConfig(config) {
6903
- let testNamePattern = config.testNamePattern;
6904
- let defines = config.defines;
6905
- // v8 serialize does not support regex
6906
- if (testNamePattern && typeof testNamePattern !== "string") testNamePattern = `$$vitest:${testNamePattern.toString()}`;
6907
- // v8 serialize drops properties with undefined value
6908
- if (defines) defines = {
6909
- keys: Object.keys(defines),
6910
- original: defines
6911
- };
6912
- return {
6913
- ...config,
6914
- testNamePattern,
6915
- defines
6916
- };
6917
- }
6918
6911
 
6919
6912
  /** @experimental */
6920
6913
  class ThreadsPoolWorker {
@@ -7215,8 +7208,9 @@ class Pool {
7215
7208
  cancelTask
7216
7209
  };
7217
7210
  this.activeTasks.push(activeTask);
7211
+ // active tasks receive cancel signal and shut down gracefully
7218
7212
  async function cancelTask() {
7219
- await runner.stop();
7213
+ await runner.waitForTerminated();
7220
7214
  resolver.reject(/* @__PURE__ */ new Error("Cancelled"));
7221
7215
  }
7222
7216
  const onFinished = (message) => {
@@ -9394,7 +9388,7 @@ function deduped(cb) {
9394
9388
  }
9395
9389
  async function initializeProject(workspacePath, ctx, options) {
9396
9390
  const project = new TestProject(ctx, options);
9397
- const { configFile,...restOptions } = options;
9391
+ const { configFile, ...restOptions } = options;
9398
9392
  await createViteServer({
9399
9393
  ...restOptions,
9400
9394
  configFile,
@@ -9567,8 +9561,8 @@ async function resolveBrowserProjects(vitest, names, resolvedProjects) {
9567
9561
  });
9568
9562
  return resolvedProjects.filter((project) => !removeProjects.has(project));
9569
9563
  }
9570
- function cloneConfig(project, { browser,...config }) {
9571
- const { locators, viewport, testerHtmlPath, headless, screenshotDirectory, screenshotFailures, browser: _browser, name, provider,...overrideConfig } = config;
9564
+ function cloneConfig(project, { browser, ...config }) {
9565
+ const { locators, viewport, testerHtmlPath, headless, screenshotDirectory, screenshotFailures, browser: _browser, name, provider, ...overrideConfig } = config;
9572
9566
  const currentConfig = project.config.browser;
9573
9567
  const clonedConfig = deepClone(project.config);
9574
9568
  return mergeConfig({
@@ -11166,6 +11160,7 @@ class Vitest {
11166
11160
  /** @internal */ filenamePattern;
11167
11161
  /** @internal */ runningPromise;
11168
11162
  /** @internal */ closingPromise;
11163
+ /** @internal */ cancelPromise;
11169
11164
  /** @internal */ isCancelling = false;
11170
11165
  /** @internal */ coreWorkspaceProject;
11171
11166
  /** @internal */ _browserSessions = new BrowserSessions();
@@ -11197,7 +11192,7 @@ class Vitest {
11197
11192
  _onRestartListeners = [];
11198
11193
  _onClose = [];
11199
11194
  _onSetServer = [];
11200
- _onCancelListeners = [];
11195
+ _onCancelListeners = /* @__PURE__ */ new Set();
11201
11196
  _onUserTestsRerun = [];
11202
11197
  _onFilterWatchedSpecification = [];
11203
11198
  /**
@@ -11590,8 +11585,9 @@ class Vitest {
11590
11585
  async runFiles(specs, allTestsRun) {
11591
11586
  await this._testRun.start(specs);
11592
11587
  // previous run
11588
+ await this.cancelPromise;
11593
11589
  await this.runningPromise;
11594
- this._onCancelListeners = [];
11590
+ this._onCancelListeners.clear();
11595
11591
  this.isCancelling = false;
11596
11592
  // schedule the new run
11597
11593
  this.runningPromise = (async () => {
@@ -11656,8 +11652,9 @@ class Vitest {
11656
11652
  const filepaths = specifications.map((spec) => spec.moduleId);
11657
11653
  this.state.collectPaths(filepaths);
11658
11654
  // previous run
11655
+ await this.cancelPromise;
11659
11656
  await this.runningPromise;
11660
- this._onCancelListeners = [];
11657
+ this._onCancelListeners.clear();
11661
11658
  this.isCancelling = false;
11662
11659
  // schedule the new run
11663
11660
  this.runningPromise = (async () => {
@@ -11692,7 +11689,8 @@ class Vitest {
11692
11689
  */
11693
11690
  async cancelCurrentRun(reason) {
11694
11691
  this.isCancelling = true;
11695
- await Promise.all(this._onCancelListeners.splice(0).map((listener) => listener(reason)));
11692
+ this.cancelPromise = Promise.all([...this._onCancelListeners].map((listener) => listener(reason)));
11693
+ await this.cancelPromise.finally(() => this.cancelPromise = void 0);
11696
11694
  await this.runningPromise;
11697
11695
  }
11698
11696
  /** @internal */
@@ -11817,6 +11815,7 @@ class Vitest {
11817
11815
  async scheduleRerun(triggerId) {
11818
11816
  const currentCount = this.restartsCount;
11819
11817
  clearTimeout(this._rerunTimer);
11818
+ await this.cancelPromise;
11820
11819
  await this.runningPromise;
11821
11820
  clearTimeout(this._rerunTimer);
11822
11821
  // server restarted
@@ -11950,7 +11949,10 @@ class Vitest {
11950
11949
  * Register a handler that will be called when the test run is cancelled with `vitest.cancelCurrentRun`.
11951
11950
  */
11952
11951
  onCancel(fn) {
11953
- this._onCancelListeners.push(fn);
11952
+ this._onCancelListeners.add(fn);
11953
+ return () => {
11954
+ this._onCancelListeners.delete(fn);
11955
+ };
11954
11956
  }
11955
11957
  /**
11956
11958
  * Register a handler that will be called when the server is closed.
@@ -12091,7 +12093,7 @@ async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(
12091
12093
  options.api = resolveApiServerConfig(options, defaultPort);
12092
12094
  // we replace every "import.meta.env" with "process.env"
12093
12095
  // to allow reassigning, so we need to put all envs on process.env
12094
- const { PROD, DEV,...envs } = viteConfig.env;
12096
+ const { PROD, DEV, ...envs } = viteConfig.env;
12095
12097
  // process.env can have only string values and will cast string on it if we pass other type,
12096
12098
  // so we are making them truthy
12097
12099
  process.env.PROD ??= PROD ? "1" : "";
@@ -12143,7 +12145,7 @@ async function createVitest(mode, options, viteOverrides = {}, vitestOptions = {
12143
12145
  const root = slash(resolve$1(options.root || process.cwd()));
12144
12146
  const configPath = options.config === false ? false : options.config ? resolveModule(options.config, { paths: [root] }) ?? resolve$1(root, options.config) : any(configFiles, { cwd: root });
12145
12147
  options.config = configPath;
12146
- const { browser: _removeBrowser,...restOptions } = options;
12148
+ const { browser: _removeBrowser, ...restOptions } = options;
12147
12149
  const server = await createViteServer(mergeConfig({
12148
12150
  configFile: configPath,
12149
12151
  configLoader: options.configLoader,
@@ -2,14 +2,14 @@ import { existsSync, writeFileSync, readFileSync } from 'node:fs';
2
2
  import { mkdir, writeFile } from 'node:fs/promises';
3
3
  import { resolve, dirname, relative } from 'node:path';
4
4
  import { detectPackageManager, installPackage } from './index.D3XRDfWc.js';
5
- import { p as prompt, a as any } from './index.z7NPOg2E.js';
5
+ import { p as prompt, a as any } from './index.D4KonVSU.js';
6
6
  import { x } from 'tinyexec';
7
7
  import c from 'tinyrainbow';
8
8
  import { c as configFiles } from './constants.D_Q9UYh-.js';
9
9
  import 'node:process';
10
10
  import 'node:module';
11
11
  import 'node:url';
12
- import './_commonjsHelpers.BFTU3MAI.js';
12
+ import './_commonjsHelpers.D26ty3Ew.js';
13
13
  import 'readline';
14
14
  import 'events';
15
15
 
@@ -1,6 +1,6 @@
1
1
  import { g as globalApis } from './constants.D_Q9UYh-.js';
2
- import { i as index } from './index.CGezRSGU.js';
3
- import './vi.CyIUVSoU.js';
2
+ import { i as index } from './index.DZ-mI_Nm.js';
3
+ import './vi.BiaV1qII.js';
4
4
  import '@vitest/expect';
5
5
  import '@vitest/runner';
6
6
  import '@vitest/runner/utils';
@@ -12,7 +12,7 @@ import '@vitest/utils/helpers';
12
12
  import '@vitest/spy';
13
13
  import '@vitest/utils/offset';
14
14
  import '@vitest/utils/source-map';
15
- import './_commonjsHelpers.BFTU3MAI.js';
15
+ import './_commonjsHelpers.D26ty3Ew.js';
16
16
  import './date.Bq6ZW5rf.js';
17
17
  import './benchmark.B3N2zMcH.js';
18
18
  import './evaluatedModules.Dg1zASAC.js';
@@ -2,7 +2,7 @@ import fs from 'node:fs';
2
2
  import { getTasks, getFullName, getTests } from '@vitest/runner/utils';
3
3
  import * as pathe from 'pathe';
4
4
  import c from 'tinyrainbow';
5
- import { g as getStateSymbol, t as truncateString, F as F_RIGHT, D as DefaultReporter, f as formatProjectName, s as separator } from './index.kotH7DY7.js';
5
+ import { g as getStateSymbol, t as truncateString, F as F_RIGHT, D as DefaultReporter, f as formatProjectName, s as separator } from './index.BYek7GgP.js';
6
6
  import { stripVTControlCharacters } from 'node:util';
7
7
  import { notNullish } from '@vitest/utils/helpers';
8
8
 
@@ -527,7 +527,6 @@ class BaseReporter {
527
527
  onInit(ctx) {
528
528
  this.ctx = ctx;
529
529
  this.ctx.logger.printBanner();
530
- this.start = performance$1.now();
531
530
  }
532
531
  log(...messages) {
533
532
  this.ctx.logger.log(...messages);
@@ -538,6 +537,10 @@ class BaseReporter {
538
537
  relative(path) {
539
538
  return relative(this.ctx.config.root, path);
540
539
  }
540
+ onTestRunStart(_specifications) {
541
+ this.start = performance$1.now();
542
+ this._timeStart = formatTimeString(/* @__PURE__ */ new Date());
543
+ }
541
544
  onTestRunEnd(testModules, unhandledErrors, _reason) {
542
545
  const files = testModules.map((testModule) => testModule.task);
543
546
  const errors = [...unhandledErrors];
@@ -712,8 +715,6 @@ class BaseReporter {
712
715
  if (this.ctx.configOverride.testNamePattern) this.log(BADGE_PADDING + c.dim(" Test name pattern: ") + c.blue(String(this.ctx.configOverride.testNamePattern)));
713
716
  this.log("");
714
717
  for (const testModule of this.failedUnwatchedFiles) this.printTestModule(testModule);
715
- this._timeStart = formatTimeString(/* @__PURE__ */ new Date());
716
- this.start = performance$1.now();
717
718
  }
718
719
  onUserConsoleLog(log, taskState) {
719
720
  if (!this.shouldLog(log, taskState)) return;
@@ -1287,6 +1288,7 @@ class DefaultReporter extends BaseReporter {
1287
1288
  if (this.renderSucceed === void 0) this.renderSucceed = !!this.renderSucceed;
1288
1289
  if (this.renderSucceed !== true) this.renderSucceed = specifications.length <= 1;
1289
1290
  }
1291
+ super.onTestRunStart(specifications);
1290
1292
  this.summary?.onTestRunStart(specifications);
1291
1293
  }
1292
1294
  onTestRunEnd(testModules, unhandledErrors, reason) {
@@ -2,7 +2,7 @@ import { resolve, isAbsolute, dirname, join } from 'node:path';
2
2
  import { existsSync } from 'node:fs';
3
3
  import 'node:module';
4
4
  import 'node:url';
5
- import { g as getDefaultExportFromCjs } from './_commonjsHelpers.BFTU3MAI.js';
5
+ import { g as getDefaultExportFromCjs } from './_commonjsHelpers.D26ty3Ew.js';
6
6
  import require$$0 from 'readline';
7
7
  import require$$0$1 from 'events';
8
8
 
@@ -1,4 +1,4 @@
1
- import { b as assert, c as createExpect, g as globalExpect, i as inject, s as should, v as vi, d as vitest } from './vi.CyIUVSoU.js';
1
+ import { b as assert, c as createExpect, g as globalExpect, i as inject, s as should, v as vi, d as vitest } from './vi.BiaV1qII.js';
2
2
  import { b as bench } from './benchmark.B3N2zMcH.js';
3
3
  import { V as VitestEvaluatedModules } from './evaluatedModules.Dg1zASAC.js';
4
4
  import { expectTypeOf } from 'expect-type';
@@ -1,8 +1,8 @@
1
1
  import { chai } from '@vitest/expect';
2
- import { l as loadDiffConfig, b as loadSnapshotSerializers, t as takeCoverageInsideWorker } from './setup-common.Dw1XgX0v.js';
2
+ import { l as loadDiffConfig, b as loadSnapshotSerializers, t as takeCoverageInsideWorker } from './setup-common.BOzbXE3x.js';
3
3
  import { r as rpc } from './rpc.BytlcPfC.js';
4
4
  import { g as getWorkerState } from './utils.DvEY5TfP.js';
5
- import { V as VitestTestRunner, N as NodeBenchmarkRunner } from './test.w5HLbjmU.js';
5
+ import { V as VitestTestRunner, N as NodeBenchmarkRunner } from './test.BPErLMrw.js';
6
6
 
7
7
  function setupChaiConfig(config) {
8
8
  Object.assign(chai.config, config);
@@ -431,7 +431,7 @@ var jsdom = {
431
431
  NodeBlob_ = globalThis.Blob;
432
432
  NodeRequest_ = globalThis.Request;
433
433
  const { CookieJar, JSDOM, ResourceLoader, VirtualConsole } = await import('jsdom');
434
- const { html = "<!DOCTYPE html>", userAgent, url = "http://localhost:3000", contentType = "text/html", pretendToBeVisual = true, includeNodeLocations = false, runScripts = "dangerously", resources, console = false, cookieJar = false,...restOptions } = jsdom;
434
+ const { html = "<!DOCTYPE html>", userAgent, url = "http://localhost:3000", contentType = "text/html", pretendToBeVisual = true, includeNodeLocations = false, runScripts = "dangerously", resources, console = false, cookieJar = false, ...restOptions } = jsdom;
435
435
  let virtualConsole;
436
436
  if (console && globalThis.console) {
437
437
  virtualConsole = new VirtualConsole();
@@ -499,7 +499,7 @@ var jsdom = {
499
499
  NodeBlob_ = globalThis.Blob;
500
500
  NodeRequest_ = globalThis.Request;
501
501
  const { CookieJar, JSDOM, ResourceLoader, VirtualConsole } = await import('jsdom');
502
- const { html = "<!DOCTYPE html>", userAgent, url = "http://localhost:3000", contentType = "text/html", pretendToBeVisual = true, includeNodeLocations = false, runScripts = "dangerously", resources, console = false, cookieJar = false,...restOptions } = jsdom;
502
+ const { html = "<!DOCTYPE html>", userAgent, url = "http://localhost:3000", contentType = "text/html", pretendToBeVisual = true, includeNodeLocations = false, runScripts = "dangerously", resources, console = false, cookieJar = false, ...restOptions } = jsdom;
503
503
  let virtualConsole;
504
504
  if (console && globalThis.console) {
505
505
  virtualConsole = new VirtualConsole();
@@ -593,7 +593,7 @@ function patchAddEventListener(window) {
593
593
  const originalAddEventListener = window.EventTarget.prototype.addEventListener;
594
594
  window.EventTarget.prototype.addEventListener = function addEventListener(type, callback, options) {
595
595
  if (typeof options === "object" && options.signal != null) {
596
- const { signal,...otherOptions } = options;
596
+ const { signal, ...otherOptions } = options;
597
597
  // - this happens because AbortSignal is provided by Node.js,
598
598
  // but jsdom APIs require jsdom's AbortSignal, while Node APIs
599
599
  // (like fetch and Request) require a Node.js AbortSignal
@@ -0,0 +1,32 @@
1
+ import { i as init } from './init.Cz2kTB9a.js';
2
+
3
+ if (!process.send) throw new Error("Expected worker to be run in node:child_process");
4
+ // Store globals in case tests overwrite them
5
+ const processExit = process.exit.bind(process);
6
+ const processSend = process.send.bind(process);
7
+ const processOn = process.on.bind(process);
8
+ const processOff = process.off.bind(process);
9
+ const processRemoveAllListeners = process.removeAllListeners.bind(process);
10
+ // Work-around for nodejs/node#55094
11
+ if (process.execArgv.some((execArg) => execArg.startsWith("--prof") || execArg.startsWith("--cpu-prof") || execArg.startsWith("--heap-prof") || execArg.startsWith("--diagnostic-dir"))) processOn("SIGTERM", () => processExit());
12
+ function workerInit(options) {
13
+ const { runTests } = options;
14
+ init({
15
+ post: (v) => processSend(v),
16
+ on: (cb) => processOn("message", cb),
17
+ off: (cb) => processOff("message", cb),
18
+ teardown: () => processRemoveAllListeners("message"),
19
+ runTests: (state) => executeTests("run", state),
20
+ collectTests: (state) => executeTests("collect", state),
21
+ setup: options.setup
22
+ });
23
+ async function executeTests(method, state) {
24
+ try {
25
+ await runTests(method, state);
26
+ } finally {
27
+ process.exit = processExit;
28
+ }
29
+ }
30
+ }
31
+
32
+ export { workerInit as w };
@@ -1,5 +1,5 @@
1
1
  import { isMainThread, parentPort } from 'node:worker_threads';
2
- import { i as init } from './init.BQhNfT0h.js';
2
+ import { i as init } from './init.Cz2kTB9a.js';
3
3
 
4
4
  if (isMainThread || !parentPort) throw new Error("Expected worker to be run in node:worker_threads");
5
5
  function workerInit(options) {
@@ -4,7 +4,7 @@ import { pathToFileURL } from 'node:url';
4
4
  import { resolve } from 'pathe';
5
5
  import { ModuleRunner } from 'vite/module-runner';
6
6
  import { b as VitestTransport } from './startModuleRunner.DLjmA_wU.js';
7
- import { e as environments } from './index.BfmpdV5p.js';
7
+ import { e as environments } from './index.QWbK7rHY.js';
8
8
  import { serializeError } from '@vitest/utils/error';
9
9
  import { o as onCancel, a as rpcDone, c as createRuntimeRpc } from './rpc.BytlcPfC.js';
10
10
  import { createStackString, parseStacktrace } from '@vitest/utils/source-map';
@@ -1,4 +1,4 @@
1
- import { V as Vitest, T as TestProject, a as TestProjectConfiguration } from './reporters.d.BQ0wpUaj.js';
1
+ import { V as Vitest, T as TestProject, a as TestProjectConfiguration } from './reporters.d.keG-yFSu.js';
2
2
 
3
3
  interface VitestPluginContext {
4
4
  vitest: Vitest;
@@ -1325,7 +1325,7 @@ declare class Vitest {
1325
1325
  /**
1326
1326
  * Register a handler that will be called when the test run is cancelled with `vitest.cancelCurrentRun`.
1327
1327
  */
1328
- onCancel(fn: (reason: CancelReason) => Awaitable<void>): void;
1328
+ onCancel(fn: (reason: CancelReason) => Awaitable<void>): () => void;
1329
1329
  /**
1330
1330
  * Register a handler that will be called when the server is closed.
1331
1331
  */
@@ -1965,6 +1965,7 @@ declare abstract class BaseReporter implements Reporter {
1965
1965
  log(...messages: any): void;
1966
1966
  error(...messages: any): void;
1967
1967
  relative(path: string): string;
1968
+ onTestRunStart(_specifications: ReadonlyArray<TestSpecification>): void;
1968
1969
  onTestRunEnd(testModules: ReadonlyArray<TestModule>, unhandledErrors: ReadonlyArray<SerializedError>, _reason: TestRunEndReason): void;
1969
1970
  onTestCaseResult(testCase: TestCase): void;
1970
1971
  onTestSuiteResult(testSuite: TestSuite): void;