vitest 4.0.16 → 4.0.17

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 (40) hide show
  1. package/dist/browser.d.ts +2 -1
  2. package/dist/browser.js +1 -0
  3. package/dist/chunks/{base.Bin-9uYm.js → base.XJJQZiKB.js} +2 -2
  4. package/dist/chunks/{browser.d.Bz3lxTX-.d.ts → browser.d.ChKACdzH.d.ts} +3 -1
  5. package/dist/chunks/{cac.BGonGPac.js → cac.jRCLJDDc.js} +6 -6
  6. package/dist/chunks/{cli-api.BKg19Fvw.js → cli-api.Cx2DW4Bc.js} +127 -60
  7. package/dist/chunks/{config.d.CzIjkicf.d.ts → config.d.Cy95HiCx.d.ts} +5 -0
  8. package/dist/chunks/{coverage.BuJUwVtg.js → coverage.AVPTjMgw.js} +4 -0
  9. package/dist/chunks/{index.Drsj_6e7.js → index.C5r1PdPD.js} +1 -1
  10. package/dist/chunks/{index.BspFP3mn.js → index.CyBMJtT7.js} +1 -1
  11. package/dist/chunks/{index.456_DGfR.js → index.M8mOzt4Y.js} +26 -2
  12. package/dist/chunks/{init-forks.v9UONQS6.js → init-forks.BC6ZwHQN.js} +1 -1
  13. package/dist/chunks/{init-threads.DqYg3Trk.js → init-threads.CxSxLC0N.js} +1 -1
  14. package/dist/chunks/{init.KmQZdqFg.js → init.C9kljSTm.js} +4 -6
  15. package/dist/chunks/{plugin.d.v1sC_bv1.d.ts → plugin.d.CtqpEehP.d.ts} +1 -1
  16. package/dist/chunks/{reporters.d.Rsi0PyxX.d.ts → reporters.d.CWXNI2jG.d.ts} +6 -5
  17. package/dist/chunks/{startModuleRunner.DpqpB8k3.js → startModuleRunner.DEj0jb3e.js} +1 -1
  18. package/dist/chunks/{traces.U4xDYhzZ.js → traces.CCmnQaNT.js} +46 -1
  19. package/dist/chunks/{vm.qFl6P1nF.js → vm.CMjifoPa.js} +2 -2
  20. package/dist/chunks/{worker.d.5JNaocaN.d.ts → worker.d.Dyxm8DEL.d.ts} +2 -1
  21. package/dist/cli.js +2 -2
  22. package/dist/config.d.ts +6 -6
  23. package/dist/coverage.d.ts +5 -5
  24. package/dist/coverage.js +1 -1
  25. package/dist/environments.js +1 -1
  26. package/dist/index.d.ts +7 -7
  27. package/dist/module-evaluator.js +1 -1
  28. package/dist/module-runner.js +2 -2
  29. package/dist/node.d.ts +10 -8
  30. package/dist/node.js +8 -8
  31. package/dist/reporters.d.ts +4 -4
  32. package/dist/reporters.js +2 -2
  33. package/dist/runners.d.ts +1 -1
  34. package/dist/worker.d.ts +2 -2
  35. package/dist/worker.js +5 -5
  36. package/dist/workers/forks.js +6 -6
  37. package/dist/workers/threads.js +6 -6
  38. package/dist/workers/vmForks.js +6 -6
  39. package/dist/workers/vmThreads.js +6 -6
  40. package/package.json +12 -12
package/dist/browser.d.ts CHANGED
@@ -1,6 +1,7 @@
1
- import { a as SerializedCoverageConfig, S as SerializedConfig } from './chunks/config.d.CzIjkicf.js';
1
+ import { a as SerializedCoverageConfig, S as SerializedConfig } from './chunks/config.d.Cy95HiCx.js';
2
2
  import { R as RuntimeCoverageModuleLoader } from './chunks/coverage.d.BZtK59WP.js';
3
3
  import { SerializedDiffOptions } from '@vitest/utils/diff';
4
+ export { O as OTELCarrier, T as Traces } from './chunks/traces.d.402V_yFI.js';
4
5
  export { collectTests, startTests } from '@vitest/runner';
5
6
  import * as _vitest_spy from '@vitest/spy';
6
7
  export { _vitest_spy as SpyModule };
package/dist/browser.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { l as loadDiffConfig, b as loadSnapshotSerializers, c as setupCommonEnv, s as startCoverageInsideWorker, a as stopCoverageInsideWorker, t as takeCoverageInsideWorker } from './chunks/setup-common.Cm-kSBVi.js';
2
+ export { T as Traces } from './chunks/traces.CCmnQaNT.js';
2
3
  export { collectTests, startTests } from '@vitest/runner';
3
4
  import * as spyModule from '@vitest/spy';
4
5
  export { spyModule as SpyModule };
@@ -1,9 +1,9 @@
1
1
  import { runInThisContext } from 'node:vm';
2
2
  import * as spyModule from '@vitest/spy';
3
3
  import { r as resolveTestRunner, a as resolveSnapshotEnvironment, s as setupChaiConfig } from './index.6Qv1eEA6.js';
4
- import { l as loadEnvironment } from './init.KmQZdqFg.js';
4
+ import { l as loadEnvironment } from './init.C9kljSTm.js';
5
5
  import { V as VitestEvaluatedModules } from './evaluatedModules.Dg1zASAC.js';
6
- import { s as startVitestModuleRunner, c as createNodeImportMeta } from './startModuleRunner.DpqpB8k3.js';
6
+ import { s as startVitestModuleRunner, c as createNodeImportMeta } from './startModuleRunner.DEj0jb3e.js';
7
7
  import { performance as performance$1 } from 'node:perf_hooks';
8
8
  import { startTests, collectTests } from '@vitest/runner';
9
9
  import { c as setupCommonEnv, s as startCoverageInsideWorker, a as stopCoverageInsideWorker } from './setup-common.Cm-kSBVi.js';
@@ -1,5 +1,6 @@
1
1
  import { FileSpecification } from '@vitest/runner';
2
- import { T as TestExecutionMethod } from './worker.d.5JNaocaN.js';
2
+ import { O as OTELCarrier } from './traces.d.402V_yFI.js';
3
+ import { T as TestExecutionMethod } from './worker.d.Dyxm8DEL.js';
3
4
 
4
5
  type SerializedTestSpecification = [project: {
5
6
  name: string | undefined;
@@ -52,6 +53,7 @@ interface BrowserTesterOptions {
52
53
  method: TestExecutionMethod;
53
54
  files: FileSpecification[];
54
55
  providedContext: string;
56
+ otelCarrier?: OTELCarrier;
55
57
  }
56
58
 
57
59
  export type { BrowserTesterOptions as B, ModuleDefinitionDurationsDiagnostic as M, SerializedTestSpecification as S, UntrackedModuleDefinitionDiagnostic as U, ModuleDefinitionDiagnostic as a, ModuleDefinitionLocation as b, SourceModuleDiagnostic as c, SourceModuleLocations as d };
@@ -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.456_DGfR.js';
6
+ import { R as ReportersMap } from './index.M8mOzt4Y.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.16";
622
+ var version = "4.0.17";
623
623
 
624
624
  const apiConfig = (port) => ({
625
625
  port: {
@@ -1356,11 +1356,11 @@ function normalizeCliOptions(cliFilters, argv) {
1356
1356
  }
1357
1357
  async function start(mode, cliFilters, options) {
1358
1358
  try {
1359
- const { startVitest } = await import('./cli-api.BKg19Fvw.js').then(function (n) { return n.q; });
1359
+ const { startVitest } = await import('./cli-api.Cx2DW4Bc.js').then(function (n) { return n.q; });
1360
1360
  const ctx = await startVitest(mode, cliFilters.map(normalize), normalizeCliOptions(cliFilters, options));
1361
1361
  if (!ctx.shouldKeepServer()) await ctx.exit();
1362
1362
  } catch (e) {
1363
- const { errorBanner } = await import('./index.456_DGfR.js').then(function (n) { return n.A; });
1363
+ const { errorBanner } = await import('./index.M8mOzt4Y.js').then(function (n) { return n.A; });
1364
1364
  console.error(`\n${errorBanner("Startup Error")}`);
1365
1365
  console.error(e);
1366
1366
  console.error("\n\n");
@@ -1378,7 +1378,7 @@ async function init(project) {
1378
1378
  }
1379
1379
  async function collect(mode, cliFilters, options) {
1380
1380
  try {
1381
- const { prepareVitest, processCollected, outputFileList } = await import('./cli-api.BKg19Fvw.js').then(function (n) { return n.q; });
1381
+ const { prepareVitest, processCollected, outputFileList } = await import('./cli-api.Cx2DW4Bc.js').then(function (n) { return n.q; });
1382
1382
  const ctx = await prepareVitest(mode, {
1383
1383
  ...normalizeCliOptions(cliFilters, options),
1384
1384
  watch: false,
@@ -1397,7 +1397,7 @@ async function collect(mode, cliFilters, options) {
1397
1397
  } else outputFileList(await ctx.getRelevantTestSpecifications(cliFilters.map(normalize)), options);
1398
1398
  await ctx.close();
1399
1399
  } catch (e) {
1400
- const { errorBanner } = await import('./index.456_DGfR.js').then(function (n) { return n.A; });
1400
+ const { errorBanner } = await import('./index.M8mOzt4Y.js').then(function (n) { return n.A; });
1401
1401
  console.error(`\n${errorBanner("Collect Error")}`);
1402
1402
  console.error(e);
1403
1403
  console.error("\n\n");
@@ -4,7 +4,7 @@ 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, withTrailingSlash, cleanUrl, wrapId, isExternalUrl, unwrapId, toArray, deepMerge, nanoid, deepClone, isPrimitive, notNullish } from '@vitest/utils/helpers';
6
6
  import { a as any, p as prompt } from './index.D4KonVSU.js';
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.BuJUwVtg.js';
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.AVPTjMgw.js';
8
8
  import * as vite from 'vite';
9
9
  import { isFileServingAllowed as isFileServingAllowed$1, parseAst, searchForWorkspaceRoot, fetchModule, version, mergeConfig, createServer, isFileLoadingAllowed, normalizePath } from 'vite';
10
10
  import { A as API_PATH, c as configFiles, d as defaultBrowserPort, a as defaultPort } from './constants.D_Q9UYh-.js';
@@ -12,10 +12,10 @@ import * as nodeos from 'node:os';
12
12
  import nodeos__default, { tmpdir } from 'node:os';
13
13
  import { generateHash as generateHash$1, createTaskName, 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.BGonGPac.js';
15
+ import { v as version$1 } from './cac.jRCLJDDc.js';
16
16
  import { performance as performance$1 } from 'node:perf_hooks';
17
17
  import { c as createBirpc } from './index.Chj8NDwU.js';
18
- import { p as parse, d as stringify, e as createIndexLocationsMap, h as TraceMap, o as originalPositionFor, i as ancestor, j as printError, f as formatProjectName, w as withLabel, k as errorBanner, l as divider, m as Typechecker, n as generateCodeFrame, q as escapeRegExp, r as createDefinesScript, R as ReportersMap, u as groupBy, B as BlobReporter, v as readBlobs, x as convertTasksToEvents, H as HangingProcessReporter, y as wildcardPatternToRegExp, z as stdout } from './index.456_DGfR.js';
18
+ import { p as parse, d as stringify, e as createIndexLocationsMap, h as TraceMap, o as originalPositionFor, i as ancestor, j as printError, f as formatProjectName, w as withLabel, k as errorBanner, l as divider, m as Typechecker, n as generateCodeFrame, q as escapeRegExp, r as createDefinesScript, R as ReportersMap, u as groupBy, B as BlobReporter, v as readBlobs, x as convertTasksToEvents, H as HangingProcessReporter, y as wildcardPatternToRegExp, z as stdout } from './index.M8mOzt4Y.js';
19
19
  import require$$0$3 from 'events';
20
20
  import require$$1$1 from 'https';
21
21
  import require$$2 from 'http';
@@ -29,7 +29,7 @@ import require$$0$1 from 'buffer';
29
29
  import { g as getDefaultExportFromCjs } from './_commonjsHelpers.D26ty3Ew.js';
30
30
  import crypto, { createHash } from 'node:crypto';
31
31
  import { rootDir, distDir } from '../path.js';
32
- import { T as Traces } from './traces.U4xDYhzZ.js';
32
+ import { T as Traces } from './traces.CCmnQaNT.js';
33
33
  import { createDebug } from 'obug';
34
34
  import { rm, readFile, writeFile, rename, stat, unlink, mkdir, copyFile } from 'node:fs/promises';
35
35
  import c from 'tinyrainbow';
@@ -53,7 +53,7 @@ import { c as configDefaults } from './defaults.BOqNVLsY.js';
53
53
  import { KNOWN_ASSET_RE } from '@vitest/utils/constants';
54
54
  import { findNearestPackageData } from '@vitest/utils/resolver';
55
55
  import * as esModuleLexer from 'es-module-lexer';
56
- import { a as BenchmarkReportsMap } from './index.Drsj_6e7.js';
56
+ import { a as BenchmarkReportsMap } from './index.C5r1PdPD.js';
57
57
  import assert$1 from 'node:assert';
58
58
  import { serializeValue } from '@vitest/utils/serialize';
59
59
  import { parseErrorStacktrace } from '@vitest/utils/source-map';
@@ -5771,7 +5771,7 @@ class FileSystemModuleCache {
5771
5771
  */
5772
5772
  rootCache;
5773
5773
  metadataFilePath;
5774
- version = "1.0.0-beta.3";
5774
+ version = "1.0.0-beta.4";
5775
5775
  fsCacheRoots = /* @__PURE__ */ new WeakMap();
5776
5776
  fsEnvironmentHashMap = /* @__PURE__ */ new WeakMap();
5777
5777
  fsCacheKeyGenerators = /* @__PURE__ */ new Set();
@@ -5828,18 +5828,16 @@ class FileSystemModuleCache {
5828
5828
  url: meta.url,
5829
5829
  file: meta.file,
5830
5830
  code,
5831
- importers: meta.importers,
5832
5831
  importedUrls: meta.importedUrls,
5833
5832
  mappings: meta.mappings
5834
5833
  };
5835
5834
  }
5836
- async saveCachedModule(cachedFilePath, fetchResult, importers = [], importedUrls = [], mappings = false) {
5835
+ async saveCachedModule(cachedFilePath, fetchResult, importedUrls = [], mappings = false) {
5837
5836
  if ("code" in fetchResult) {
5838
5837
  const result = {
5839
5838
  file: fetchResult.file,
5840
5839
  id: fetchResult.id,
5841
5840
  url: fetchResult.url,
5842
- importers,
5843
5841
  importedUrls,
5844
5842
  mappings
5845
5843
  };
@@ -6178,17 +6176,16 @@ class ModuleFetcher {
6178
6176
  this.recordResult(trace, result);
6179
6177
  return result;
6180
6178
  });
6181
- const cachedModule = await this.getCachedModule(cachePath, environment, moduleGraphModule);
6179
+ const cachedModule = await this.getCachedModule(cachePath, environment, moduleGraphModule, importer);
6182
6180
  if (cachedModule) {
6183
6181
  this.recordResult(trace, cachedModule);
6184
6182
  return cachedModule;
6185
6183
  }
6186
6184
  const result = await this.fetchAndProcess(environment, url, importer, moduleGraphModule, options);
6187
- const importers = this.getSerializedDependencies(moduleGraphModule);
6188
6185
  const importedUrls = this.getSerializedImports(moduleGraphModule);
6189
6186
  const map = moduleGraphModule.transformResult?.map;
6190
6187
  const mappings = map && !("version" in map) && map.mappings === "";
6191
- return this.cacheResult(result, cachePath, importers, importedUrls, !!mappings);
6188
+ return this.cacheResult(result, cachePath, importedUrls, !!mappings);
6192
6189
  }
6193
6190
  // we need this for UI to be able to show a module graph
6194
6191
  getSerializedImports(node) {
@@ -6198,14 +6195,6 @@ class ModuleFetcher {
6198
6195
  });
6199
6196
  return imports;
6200
6197
  }
6201
- // we need this for the watcher to be able to find the related test file
6202
- getSerializedDependencies(node) {
6203
- const dependencies = [];
6204
- node.importers.forEach((importer) => {
6205
- if (importer.id) dependencies.push(importer.id);
6206
- });
6207
- return dependencies;
6208
- }
6209
6198
  recordResult(trace, result) {
6210
6199
  if ("externalize" in result) trace.setAttributes({
6211
6200
  "vitest.fetched_module.external": result.externalize,
@@ -6242,7 +6231,7 @@ class ModuleFetcher {
6242
6231
  if (loadResult != null) return loadResult.code;
6243
6232
  return "";
6244
6233
  }
6245
- async getCachedModule(cachePath, environment, moduleGraphModule) {
6234
+ async getCachedModule(cachePath, environment, moduleGraphModule, importer) {
6246
6235
  if (moduleGraphModule.transformResult?.__vitestTmp) return {
6247
6236
  cached: true,
6248
6237
  file: moduleGraphModule.file,
@@ -6265,13 +6254,16 @@ class ModuleFetcher {
6265
6254
  __vitestTmp: cachePath
6266
6255
  };
6267
6256
  // we populate the module graph to make the watch mode work because it relies on importers
6268
- cachedModule.importers.forEach((importer) => {
6257
+ if (importer) {
6269
6258
  const environmentNode = environment.moduleGraph.getModuleById(importer);
6270
6259
  if (environmentNode) moduleGraphModule.importers.add(environmentNode);
6271
- });
6260
+ }
6272
6261
  await Promise.all(cachedModule.importedUrls.map(async (url) => {
6273
6262
  const moduleNode = await environment.moduleGraph.ensureEntryFromUrl(url).catch(() => null);
6274
- if (moduleNode) moduleGraphModule.importedModules.add(moduleNode);
6263
+ if (moduleNode) {
6264
+ moduleNode.importers.add(moduleGraphModule);
6265
+ moduleGraphModule.importedModules.add(moduleNode);
6266
+ }
6275
6267
  }));
6276
6268
  return {
6277
6269
  cached: true,
@@ -6288,13 +6280,13 @@ class ModuleFetcher {
6288
6280
  inlineSourceMap: false
6289
6281
  }).catch(handleRollupError));
6290
6282
  }
6291
- async cacheResult(result, cachePath, importers = [], importedUrls = [], mappings = false) {
6283
+ async cacheResult(result, cachePath, importedUrls = [], mappings = false) {
6292
6284
  const returnResult = "code" in result ? getCachedResult(result, cachePath) : result;
6293
6285
  if (saveCachePromises.has(cachePath)) {
6294
6286
  await saveCachePromises.get(cachePath);
6295
6287
  return returnResult;
6296
6288
  }
6297
- const savePromise = this.fsCache.saveCachedModule(cachePath, result, importers, importedUrls, mappings).then(() => result).finally(() => {
6289
+ const savePromise = this.fsCache.saveCachedModule(cachePath, result, importedUrls, mappings).then(() => result).finally(() => {
6298
6290
  saveCachePromises.delete(cachePath);
6299
6291
  });
6300
6292
  saveCachePromises.set(cachePath, savePromise);
@@ -7129,12 +7121,21 @@ class BrowserPool {
7129
7121
  _promise;
7130
7122
  _providedContext;
7131
7123
  readySessions = /* @__PURE__ */ new Set();
7124
+ _traces;
7125
+ _otel;
7132
7126
  constructor(project, options) {
7133
7127
  this.project = project;
7134
7128
  this.options = options;
7129
+ this._traces = project.vitest._traces;
7130
+ this._otel = this._traces.startContextSpan("vitest.browser");
7131
+ this._otel.span.setAttributes({
7132
+ "vitest.project": project.name,
7133
+ "vitest.browser.provider": this.project.browser.provider.name
7134
+ });
7135
7135
  }
7136
7136
  cancel() {
7137
7137
  this._queue = [];
7138
+ this._otel.span.end();
7138
7139
  }
7139
7140
  reject(error) {
7140
7141
  this._promise?.reject(error);
@@ -7172,7 +7173,11 @@ class BrowserPool {
7172
7173
  this.project.vitest._browserSessions.sessionIds.add(sessionId);
7173
7174
  const project = this.project.name;
7174
7175
  debug?.("[%s] creating session for %s", sessionId, project);
7175
- const page = this.openPage(sessionId).then(() => {
7176
+ let page = this._traces.$(`vitest.browser.open`, {
7177
+ context: this._otel.context,
7178
+ attributes: { "vitest.browser.session_id": sessionId }
7179
+ }, () => this.openPage(sessionId));
7180
+ page = page.then(() => {
7176
7181
  // start running tests on the page when it's ready
7177
7182
  this.runNextTest(method, sessionId);
7178
7183
  });
@@ -7187,6 +7192,8 @@ class BrowserPool {
7187
7192
  const browser = this.project.browser;
7188
7193
  const url = new URL("/__vitest_test__/", this.options.origin);
7189
7194
  url.searchParams.set("sessionId", sessionId);
7195
+ const otelCarrier = this._traces.getContextCarrier();
7196
+ if (otelCarrier) url.searchParams.set("otelCarrier", JSON.stringify(otelCarrier));
7190
7197
  const pagePromise = browser.provider.openPage(sessionId, url.toString());
7191
7198
  await Promise.all([sessionPromise, pagePromise]);
7192
7199
  }
@@ -7199,6 +7206,7 @@ class BrowserPool {
7199
7206
  this.readySessions.add(sessionId);
7200
7207
  // the last worker finished running tests
7201
7208
  if (this.readySessions.size === this.orchestrators.size) {
7209
+ this._otel.span.end();
7202
7210
  this._promise?.resolve();
7203
7211
  this._promise = void 0;
7204
7212
  debug?.("[%s] all tests finished running", sessionId);
@@ -7221,11 +7229,16 @@ class BrowserPool {
7221
7229
  const orchestrator = this.getOrchestrator(sessionId);
7222
7230
  debug?.("[%s] run test %s", sessionId, file);
7223
7231
  this.setBreakpoint(sessionId, file.filepath).then(() => {
7224
- // this starts running tests inside the orchestrator
7225
- orchestrator.createTesters({
7226
- method,
7227
- files: [file],
7228
- providedContext: this._providedContext || "[{}]"
7232
+ this._traces.$(`vitest.browser.run`, {
7233
+ context: this._otel.context,
7234
+ attributes: { "code.file.path": file.filepath }
7235
+ }, async () => {
7236
+ return orchestrator.createTesters({
7237
+ method,
7238
+ files: [file],
7239
+ providedContext: this._providedContext || "[{}]",
7240
+ otelCarrier: this._traces.getContextCarrier()
7241
+ });
7229
7242
  }).then(() => {
7230
7243
  debug?.("[%s] test %s finished running", sessionId, file);
7231
7244
  this.runNextTest(method, sessionId);
@@ -7359,6 +7372,7 @@ var RunnerState = /* @__PURE__ */ function(RunnerState) {
7359
7372
  RunnerState["IDLE"] = "idle";
7360
7373
  RunnerState["STARTING"] = "starting";
7361
7374
  RunnerState["STARTED"] = "started";
7375
+ RunnerState["START_FAILURE"] = "start_failure";
7362
7376
  RunnerState["STOPPING"] = "stopping";
7363
7377
  RunnerState["STOPPED"] = "stopped";
7364
7378
  return RunnerState;
@@ -7420,6 +7434,14 @@ class PoolRunner {
7420
7434
  });
7421
7435
  this._offCancel = vitest.onCancel((reason) => this._rpc.onCancel(reason));
7422
7436
  }
7437
+ /**
7438
+ * "reconfigure" can only be called if `environment` is different, since different project always
7439
+ * requires a new PoolRunner instance.
7440
+ */
7441
+ reconfigure(task) {
7442
+ this.environment = task.context.environment;
7443
+ this._otel?.span.setAttribute("vitest.environment", this.environment.name);
7444
+ }
7423
7445
  postMessage(message) {
7424
7446
  // Only send messages when runner is active (not fully stopped)
7425
7447
  // Allow sending during STOPPING state for the 'stop' message itself
@@ -7495,7 +7517,7 @@ class PoolRunner {
7495
7517
  await startPromise;
7496
7518
  this._state = RunnerState.STARTED;
7497
7519
  } catch (error) {
7498
- this._state = RunnerState.IDLE;
7520
+ this._state = RunnerState.START_FAILURE;
7499
7521
  startSpan?.recordException(error);
7500
7522
  throw error;
7501
7523
  } finally {
@@ -7932,6 +7954,9 @@ class VmForksPoolWorker extends ForksPoolWorker {
7932
7954
  /** Loads {@link file://./../../../runtime/workers/vmForks.ts} */
7933
7955
  this.entrypoint = resolve$1(options.distPath, "workers/vmForks.js");
7934
7956
  }
7957
+ canReuse() {
7958
+ return true;
7959
+ }
7935
7960
  }
7936
7961
 
7937
7962
  /** @experimental */
@@ -7947,6 +7972,9 @@ class VmThreadsPoolWorker extends ThreadsPoolWorker {
7947
7972
  /** Loads {@link file://./../../../runtime/workers/vmThreads.ts} */
7948
7973
  this.entrypoint = resolve$1(options.distPath, "workers/vmThreads.js");
7949
7974
  }
7975
+ canReuse() {
7976
+ return true;
7977
+ }
7950
7978
  }
7951
7979
 
7952
7980
  const WORKER_START_TIMEOUT = 9e4;
@@ -8015,17 +8043,15 @@ class Pool {
8015
8043
  resolver.reject(new Error(`[vitest-pool]: Worker ${task.worker} emitted error.`, { cause: error }));
8016
8044
  });
8017
8045
  const id = setTimeout(() => resolver.reject(/* @__PURE__ */ new Error(`[vitest-pool]: Timeout starting ${task.worker} runner.`)), WORKER_START_TIMEOUT);
8018
- await runner.start({ workerId: task.context.workerId }).finally(() => clearTimeout(id));
8046
+ await runner.start({ workerId: task.context.workerId }).catch((error) => resolver.reject(new Error(`[vitest-pool]: Failed to start ${task.worker} worker for test files ${formatFiles(task)}.`, { cause: error }))).finally(() => clearTimeout(id));
8019
8047
  }
8020
- const span = runner.startTracesSpan(`vitest.worker.${method}`);
8021
- // Start running the test in the worker
8022
- runner.request(method, task.context);
8023
- await resolver.promise.catch((error) => {
8024
- span.recordException(error);
8025
- throw error;
8026
- }).finally(() => {
8027
- span.end();
8028
- });
8048
+ let span;
8049
+ if (!resolver.isRejected) {
8050
+ span = runner.startTracesSpan(`vitest.worker.${method}`);
8051
+ // Start running the test in the worker
8052
+ runner.request(method, task.context);
8053
+ }
8054
+ await resolver.promise.catch((error) => span?.recordException(error)).finally(() => span?.end());
8029
8055
  const index = this.activeTasks.indexOf(activeTask);
8030
8056
  if (index !== -1) this.activeTasks.splice(index, 1);
8031
8057
  if (!task.isolate && !isMemoryLimitReached && this.queue[0]?.task.isolate === false && isEqualRunner(runner, this.queue[0].task)) {
@@ -8036,7 +8062,7 @@ class Pool {
8036
8062
  // Runner termination can also already start from task cancellation.
8037
8063
  if (!runner.isTerminated) {
8038
8064
  const id = setTimeout(() => this.logger.error(`[vitest-pool]: Timeout terminating ${task.worker} worker for test files ${formatFiles(task)}.`), this.options.teardownTimeout);
8039
- this.exitPromises.push(runner.stop().then(() => clearTimeout(id)).catch((error) => this.logger.error(`[vitest-pool]: Failed to terminate ${task.worker} worker for test files ${formatFiles(task)}.`, error)));
8065
+ this.exitPromises.push(runner.stop({ force: resolver.isRejected }).then(() => clearTimeout(id)).catch((error) => this.logger.error(`[vitest-pool]: Failed to terminate ${task.worker} worker for test files ${formatFiles(task)}.`, error)));
8040
8066
  }
8041
8067
  this.freeWorkerId(poolId);
8042
8068
  }
@@ -8073,13 +8099,17 @@ catch (error) {
8073
8099
  getPoolRunner(task, method) {
8074
8100
  if (task.isolate === false) {
8075
8101
  const index = this.sharedRunners.findIndex((runner) => isEqualRunner(runner, task));
8076
- if (index !== -1) return this.sharedRunners.splice(index, 1)[0];
8102
+ if (index !== -1) {
8103
+ const runner = this.sharedRunners.splice(index, 1)[0];
8104
+ runner.reconfigure(task);
8105
+ return runner;
8106
+ }
8077
8107
  }
8078
8108
  const options = {
8079
8109
  distPath: this.options.distPath,
8080
8110
  project: task.project,
8081
8111
  method,
8082
- environment: task.environment,
8112
+ environment: task.context.environment,
8083
8113
  env: task.env,
8084
8114
  execArgv: task.execArgv
8085
8115
  };
@@ -8111,22 +8141,44 @@ catch (error) {
8111
8141
  function withResolvers() {
8112
8142
  let resolve = () => {};
8113
8143
  let reject = (_error) => {};
8114
- const promise = new Promise((res, rej) => {
8115
- resolve = res;
8116
- reject = rej;
8117
- });
8118
- return {
8144
+ const resolver = {
8145
+ promise: new Promise((res, rej) => {
8146
+ resolve = res;
8147
+ reject = rej;
8148
+ }),
8119
8149
  resolve,
8120
- reject,
8121
- promise
8150
+ reject: (reason) => {
8151
+ resolver.isRejected = true;
8152
+ reject(reason);
8153
+ },
8154
+ isRejected: false
8122
8155
  };
8156
+ return resolver;
8123
8157
  }
8124
8158
  function formatFiles(task) {
8125
8159
  return task.context.files.map((file) => file.filepath).join(", ");
8126
8160
  }
8127
8161
  function isEqualRunner(runner, task) {
8128
8162
  if (task.isolate) throw new Error("Isolated tasks should not share runners");
8129
- return runner.worker.name === task.worker && runner.project === task.project && runner.environment.name === task.environment.name && (!runner.worker.canReuse || runner.worker.canReuse(task));
8163
+ if (runner.worker.name !== task.worker || runner.project !== task.project) return false;
8164
+ // by default, check that the environments are the same
8165
+ // some workers (like vmThreads/vmForks) do not need this check
8166
+ if (!runner.worker.canReuse) return isEnvironmentEqual(task.context.environment, runner.environment);
8167
+ return runner.worker.canReuse(task);
8168
+ }
8169
+ function isEnvironmentEqual(env1, env2) {
8170
+ if (env1.name !== env2.name) return false;
8171
+ return deepEqual(env1.options, env2.options);
8172
+ }
8173
+ function deepEqual(obj1, obj2) {
8174
+ if (obj1 === obj2) return true;
8175
+ if (obj1 == null || obj2 == null) return obj1 === obj2;
8176
+ if (typeof obj1 !== "object" || typeof obj2 !== "object") return false;
8177
+ const keys1 = Object.keys(obj1);
8178
+ const keys2 = Object.keys(obj2);
8179
+ if (keys1.length !== keys2.length) return false;
8180
+ for (const key of keys1) if (!keys2.includes(key) || !deepEqual(obj1[key], obj2[key])) return false;
8181
+ return true;
8130
8182
  }
8131
8183
 
8132
8184
  const suppressWarningsPath = resolve(rootDir, "./suppress-warnings.cjs");
@@ -8199,9 +8251,9 @@ function createPool(ctx) {
8199
8251
  })),
8200
8252
  invalidates,
8201
8253
  providedContext: project.getProvidedContext(),
8202
- workerId: workerId++
8254
+ workerId: workerId++,
8255
+ environment
8203
8256
  },
8204
- environment,
8205
8257
  project,
8206
8258
  env,
8207
8259
  execArgv,
@@ -8468,7 +8520,8 @@ function serializeConfig(project) {
8468
8520
  serializedDefines: config.browser.enabled ? "" : project._serializedDefines || "",
8469
8521
  experimental: {
8470
8522
  fsModuleCache: config.experimental.fsModuleCache ?? false,
8471
- printImportBreakdown: config.experimental.printImportBreakdown
8523
+ printImportBreakdown: config.experimental.printImportBreakdown,
8524
+ openTelemetry: config.experimental.openTelemetry
8472
8525
  }
8473
8526
  };
8474
8527
  }
@@ -9550,6 +9603,7 @@ function WorkspaceVitestPlugin(project, options) {
9550
9603
  this.meta.watchMode = false;
9551
9604
  },
9552
9605
  config(viteConfig) {
9606
+ const originalDefine = { ...viteConfig.define };
9553
9607
  const defines = deleteDefineConfig(viteConfig);
9554
9608
  const testConfig = viteConfig.test || {};
9555
9609
  const root = testConfig.root || viteConfig.root || options.root;
@@ -9586,6 +9640,7 @@ function WorkspaceVitestPlugin(project, options) {
9586
9640
  }
9587
9641
  };
9588
9642
  config.test.defines = defines;
9643
+ config.test.viteDefine = originalDefine;
9589
9644
  const classNameStrategy = typeof testConfig.css !== "boolean" && testConfig.css?.modules?.classNameStrategy || "stable";
9590
9645
  if (classNameStrategy !== "scoped") {
9591
9646
  config.css ??= {};
@@ -10106,7 +10161,7 @@ class TestProject {
10106
10161
  _initParentBrowser = deduped(async (childProject) => {
10107
10162
  if (!this.isBrowserEnabled() || this._parentBrowser) return;
10108
10163
  const provider = this.config.browser.provider || childProject.config.browser.provider;
10109
- if (provider == null) throw new Error(`Proider was not specified in the "browser.provider" setting. Please, pass down playwright(), webdriverio() or preview() from "@vitest/browser-playwright", "@vitest/browser-webdriverio" or "@vitest/browser-preview" package respectively.`);
10164
+ if (provider == null) throw new Error(`Provider was not specified in the "browser.provider" setting. Please, pass down playwright(), webdriverio() or preview() from "@vitest/browser-playwright", "@vitest/browser-webdriverio" or "@vitest/browser-preview" package respectively.`);
10110
10165
  if (typeof provider.serverFactory !== "function") throw new TypeError(`The browser provider options do not return a "serverFactory" function. Are you using the latest "@vitest/browser-${provider.name}" package?`);
10111
10166
  const browser = await provider.serverFactory({
10112
10167
  project: this,
@@ -10159,6 +10214,7 @@ class TestProject {
10159
10214
  ...options,
10160
10215
  coverage: this.vitest.config.coverage
10161
10216
  }, server.config);
10217
+ this._config.api.token = this.vitest.config.api.token;
10162
10218
  this._setHash();
10163
10219
  for (const _providedKey in this.config.provide) {
10164
10220
  const providedKey = _providedKey;
@@ -10411,7 +10467,7 @@ async function resolveBrowserProjects(vitest, names, resolvedProjects) {
10411
10467
  return resolvedProjects.filter((project) => !removeProjects.has(project));
10412
10468
  }
10413
10469
  function cloneConfig(project, { browser, ...config }) {
10414
- const { locators, viewport, testerHtmlPath, headless, screenshotDirectory, screenshotFailures, browser: _browser, name, provider, ...overrideConfig } = config;
10470
+ const { locators, viewport, testerHtmlPath, headless, screenshotDirectory, screenshotFailures, fileParallelism, browser: _browser, name, provider, ...overrideConfig } = config;
10415
10471
  const currentConfig = project.config.browser;
10416
10472
  const clonedConfig = deepClone(project.config);
10417
10473
  return mergeConfig({
@@ -10425,6 +10481,7 @@ function cloneConfig(project, { browser, ...config }) {
10425
10481
  screenshotFailures: screenshotFailures ?? currentConfig.screenshotFailures,
10426
10482
  headless: headless ?? currentConfig.headless,
10427
10483
  provider: provider ?? currentConfig.provider,
10484
+ fileParallelism: fileParallelism ?? currentConfig.fileParallelism,
10428
10485
  name: browser,
10429
10486
  instances: []
10430
10487
  },
@@ -11767,6 +11824,12 @@ class TestRun {
11767
11824
  const task = this.vitest.state.idMap.get(id);
11768
11825
  const entity = task && this.vitest.state.getReportedEntity(task);
11769
11826
  assert$1(task && entity, `Entity must be found for task ${task?.name || id}`);
11827
+ if (event === "suite-failed-early" && entity.type === "module") {
11828
+ // the file failed during import
11829
+ await this.vitest.report("onTestModuleStart", entity);
11830
+ await this.vitest.report("onTestModuleEnd", entity);
11831
+ return;
11832
+ }
11770
11833
  if (event === "suite-prepare" && entity.type === "suite") return await this.vitest.report("onTestSuiteReady", entity);
11771
11834
  if (event === "suite-prepare" && entity.type === "module") return await this.vitest.report("onTestModuleStart", entity);
11772
11835
  if (event === "suite-finished") {
@@ -12401,7 +12464,7 @@ class Vitest {
12401
12464
  * @param filters String filters to match the test files
12402
12465
  */
12403
12466
  async start(filters) {
12404
- return this._traces.$("vitest.start", async (startSpan) => {
12467
+ return this._traces.$("vitest.start", { context: this._traces.getContextFromEnv(process.env) }, async (startSpan) => {
12405
12468
  startSpan.setAttributes({ config: this.vite.config.configFile });
12406
12469
  try {
12407
12470
  await this._traces.$("vitest.coverage.init", async () => {
@@ -12989,7 +13052,11 @@ async function VitestPlugin(options = {}, vitest = new Vitest("test", deepClone(
12989
13052
  // this is repeated in configResolved where the config is final
12990
13053
  const testConfig = deepMerge({}, configDefaults, removeUndefinedValues(viteConfig.test ?? {}), options);
12991
13054
  testConfig.api = resolveApiServerConfig(testConfig, defaultPort);
13055
+ // store defines for globalThis to make them
13056
+ // reassignable when running in worker in src/runtime/setup.ts
13057
+ const originalDefine = { ...viteConfig.define };
12992
13058
  options.defines = deleteDefineConfig(viteConfig);
13059
+ options.viteDefine = originalDefine;
12993
13060
  let open = false;
12994
13061
  if (testConfig.ui && testConfig.open) open = testConfig.uiBase ?? "/__vitest__/";
12995
13062
  const resolveOptions = getDefaultResolveOptions();
@@ -183,6 +183,11 @@ interface SerializedConfig {
183
183
  experimental: {
184
184
  fsModuleCache: boolean;
185
185
  printImportBreakdown: boolean | undefined;
186
+ openTelemetry: {
187
+ enabled: boolean;
188
+ sdkPath?: string;
189
+ browserSdkPath?: string;
190
+ } | undefined;
186
191
  };
187
192
  }
188
193
  interface SerializedCoverageConfig {
@@ -2798,6 +2798,10 @@ function resolveConfig$1(vitest, options, viteConfig) {
2798
2798
  const sdkPath = resolve(resolved.root, resolved.experimental.openTelemetry.sdkPath);
2799
2799
  resolved.experimental.openTelemetry.sdkPath = pathToFileURL$1(sdkPath).toString();
2800
2800
  }
2801
+ if (resolved.experimental.openTelemetry?.browserSdkPath) {
2802
+ const browserSdkPath = resolve(resolved.root, resolved.experimental.openTelemetry.browserSdkPath);
2803
+ resolved.experimental.openTelemetry.browserSdkPath = browserSdkPath;
2804
+ }
2801
2805
  if (resolved.experimental.fsModuleCachePath) resolved.experimental.fsModuleCachePath = resolve(resolved.root, resolved.experimental.fsModuleCachePath);
2802
2806
  return resolved;
2803
2807
  }
@@ -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.456_DGfR.js';
5
+ import { g as getStateSymbol, t as truncateString, F as F_RIGHT, D as DefaultReporter, f as formatProjectName, s as separator } from './index.M8mOzt4Y.js';
6
6
  import { stripVTControlCharacters } from 'node:util';
7
7
  import { notNullish } from '@vitest/utils/helpers';
8
8
 
@@ -603,7 +603,7 @@ function patchAddEventListener(window) {
603
603
  return abortControllers.get(signal);
604
604
  }
605
605
  window.EventTarget.prototype.addEventListener = function addEventListener(type, callback, options) {
606
- if (typeof options === "object" && options.signal != null) {
606
+ if (typeof options === "object" && options?.signal != null) {
607
607
  const { signal, ...otherOptions } = options;
608
608
  // - this happens because AbortSignal is provided by Node.js,
609
609
  // but jsdom APIs require jsdom's AbortSignal, while Node APIs