vitest 4.0.0-beta.11 → 4.0.0-beta.13

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 (55) hide show
  1. package/LICENSE.md +4 -101
  2. package/dist/browser.d.ts +3 -3
  3. package/dist/browser.js +2 -2
  4. package/dist/chunks/{benchmark.LXhJ0F0X.js → benchmark.DHKMYAts.js} +1 -1
  5. package/dist/chunks/{browser.d.Dx7DO_Ce.d.ts → browser.d.D9YV3JvA.d.ts} +1 -1
  6. package/dist/chunks/{cac.elvK37c9.js → cac.BBtYKH7y.js} +16 -9
  7. package/dist/chunks/{cli-api.C7plPyhs.js → cli-api.CeakdBUN.js} +95 -148
  8. package/dist/chunks/{config.d.B_LthbQq.d.ts → config.d.DGazh2r6.d.ts} +3 -1
  9. package/dist/chunks/{console.CiTi59Jy.js → console.CTJL2nuH.js} +3 -5
  10. package/dist/chunks/{coverage.CG6Uhorw.js → coverage.DabP7UTQ.js} +69 -80
  11. package/dist/chunks/{creator.08Gi-vCA.js → creator.DfXDsUyL.js} +6 -8
  12. package/dist/chunks/{global.d.BK3X7FW1.d.ts → global.d.BcFPD2LN.d.ts} +0 -13
  13. package/dist/chunks/{globals.BjvYA-AD.js → globals.DC4ntO86.js} +5 -5
  14. package/dist/chunks/{index.DIWhzsUh.js → index.Bt-upxGS.js} +6 -12
  15. package/dist/chunks/{index.BwBttQPf.js → index.CHrBLuEH.js} +33 -38
  16. package/dist/chunks/{index.X0nbfr6-.js → index.Dc3xnDvT.js} +48 -289
  17. package/dist/chunks/{index.AZOjjqWP.js → index.Dnl38iQ_.js} +2 -2
  18. package/dist/chunks/{index.BhY64fF0.js → index.uLUz1RDt.js} +1 -1
  19. package/dist/chunks/{inspector.CvQD-Nie.js → inspector.Br76Q2Mb.js} +1 -4
  20. package/dist/chunks/{moduleRunner.d.BNa-CL9e.d.ts → moduleRunner.d.CeYc7nZ0.d.ts} +1 -1
  21. package/dist/chunks/{node.BsdMi6DV.js → node.BwAWWjHZ.js} +2 -3
  22. package/dist/chunks/{plugin.d.C5phQR6o.d.ts → plugin.d.COyglhiI.d.ts} +1 -1
  23. package/dist/chunks/{reporters.d.CVzhsTvK.d.ts → reporters.d.xGvTJYG3.d.ts} +41 -4
  24. package/dist/chunks/{resolveSnapshotEnvironment.DQVamkje.js → resolveSnapshotEnvironment.BsJpmVZR.js} +7 -8
  25. package/dist/chunks/{rpc.jKGRSXIH.js → rpc.cD77ENhU.js} +12 -13
  26. package/dist/chunks/{setup-common.NAWRuMRP.js → setup-common.BewgbkTd.js} +5 -5
  27. package/dist/chunks/{startModuleRunner.oAuCu1yL.js → startModuleRunner.DPBo3mme.js} +40 -48
  28. package/dist/chunks/{test.KC5tH8hC.js → test.CTuWuHYH.js} +5 -5
  29. package/dist/chunks/{typechecker.gXq-5P3n.js → typechecker.BfOQ86_a.js} +54 -77
  30. package/dist/chunks/{utils.DGKhod2J.js → utils.CG9h5ccR.js} +1 -4
  31. package/dist/chunks/{vi.CiJ0Laa6.js → vi.B2--mG9U.js} +35 -144
  32. package/dist/chunks/{worker.rPGLlbkW.js → worker.DVTUM2IW.js} +11 -15
  33. package/dist/chunks/{worker.d.B_Fd9M_w.d.ts → worker.d.buwuBpBt.d.ts} +1 -1
  34. package/dist/cli.js +3 -3
  35. package/dist/config.d.ts +6 -6
  36. package/dist/coverage.d.ts +5 -5
  37. package/dist/coverage.js +3 -3
  38. package/dist/environments.js +1 -1
  39. package/dist/index.d.ts +8 -8
  40. package/dist/index.js +5 -5
  41. package/dist/module-evaluator.d.ts +3 -3
  42. package/dist/module-evaluator.js +10 -12
  43. package/dist/module-runner.js +2 -2
  44. package/dist/node.d.ts +8 -8
  45. package/dist/node.js +10 -10
  46. package/dist/reporters.d.ts +5 -5
  47. package/dist/reporters.js +3 -3
  48. package/dist/runners.d.ts +1 -1
  49. package/dist/runners.js +6 -6
  50. package/dist/snapshot.js +2 -2
  51. package/dist/suite.js +2 -2
  52. package/dist/worker-base.js +30 -32
  53. package/dist/worker-vm.js +19 -30
  54. package/dist/workers/runVmTests.js +10 -10
  55. package/package.json +18 -19
@@ -20,13 +20,13 @@ import { a as isWindows } from './env.D4Lgay0q.js';
20
20
  import * as nodeos from 'node:os';
21
21
  import nodeos__default, { tmpdir } from 'node:os';
22
22
  import { isatty } from 'node:tty';
23
+ import { rootDir } from '../path.js';
23
24
  import EventEmitter from 'node:events';
24
25
  import { c as createBirpc } from './index.Bgo3tNWt.js';
25
26
  import Tinypool$1, { Tinypool } from 'tinypool';
26
- import { w as wrapSerializableConfig, a as Typechecker } from './typechecker.gXq-5P3n.js';
27
+ import { w as wrapSerializableConfig, a as Typechecker } from './typechecker.BfOQ86_a.js';
27
28
  import { MessageChannel } from 'node:worker_threads';
28
29
  import { hasFailed } from '@vitest/runner/utils';
29
- import { rootDir } from '../path.js';
30
30
  import { isCI, provider } from 'std-env';
31
31
  import { r as resolveCoverageProviderModule } from './coverage.D_JHT54q.js';
32
32
 
@@ -2403,17 +2403,17 @@ async function groupFilesByEnv(files) {
2403
2403
  if (envOptionsJson?.endsWith("*/"))
2404
2404
  // Trim closing Docblock characters the above regex might have captured
2405
2405
  envOptionsJson = envOptionsJson.slice(0, -2);
2406
- const envOptions = JSON.parse(envOptionsJson || "null"), envKey = env === "happy-dom" ? "happyDOM" : env, environment = {
2407
- name: env,
2408
- options: envOptions ? { [envKey]: envOptions } : null
2409
- };
2406
+ const envOptions = JSON.parse(envOptionsJson || "null");
2410
2407
  return {
2411
2408
  file: {
2412
2409
  filepath,
2413
2410
  testLocations: testLines
2414
2411
  },
2415
2412
  project,
2416
- environment
2413
+ environment: {
2414
+ name: env,
2415
+ options: envOptions ? { [env === "happy-dom" ? "happyDOM" : env]: envOptions } : null
2416
+ }
2417
2417
  };
2418
2418
  }));
2419
2419
  return groupBy(filesWithEnv, ({ environment }) => environment.name);
@@ -2609,8 +2609,8 @@ function createMethodsRPC(project, options = {}) {
2609
2609
  async transform(id) {
2610
2610
  const environment = project.vite.environments.__vitest_vm__;
2611
2611
  if (!environment) throw new Error(`The VM environment was not defined in the Vite config. This is a bug in Vitest. Please, open a new issue with reproduction.`);
2612
- const url = normalizeResolvedIdToUrl(environment, fileURLToPath$1(id)), result = await environment.transformRequest(url).catch(handleRollupError);
2613
- return { code: result?.code };
2612
+ const url = normalizeResolvedIdToUrl(environment, fileURLToPath$1(id));
2613
+ return { code: (await environment.transformRequest(url).catch(handleRollupError))?.code };
2614
2614
  },
2615
2615
  async onQueued(file) {
2616
2616
  if (options.collect) ctx.state.collectFiles(project, [file]);
@@ -2675,15 +2675,13 @@ function createChildProcessChannel$1(project, collect = false) {
2675
2675
  },
2676
2676
  timeout: -1
2677
2677
  });
2678
- project.vitest.onCancel((reason) => rpc.onCancel(reason));
2679
- const channel = {
2678
+ return project.vitest.onCancel((reason) => rpc.onCancel(reason)), {
2680
2679
  onMessage: (callback) => emitter.on(events.message, callback),
2681
2680
  postMessage: (message) => emitter.emit(events.response, message),
2682
2681
  onClose: () => {
2683
2682
  emitter.removeAllListeners(), rpc.$close(/* @__PURE__ */ new Error("[vitest-pool]: Pending methods while closing rpc"));
2684
2683
  }
2685
2684
  };
2686
- return channel;
2687
2685
  }
2688
2686
  function createForksPool(vitest, { execArgv, env }, specifications) {
2689
2687
  const numCpus = typeof nodeos.availableParallelism === "function" ? nodeos.availableParallelism() : nodeos.cpus().length, threadsCount = vitest.config.watch ? Math.max(Math.floor(numCpus / 2), 1) : Math.max(numCpus - 1, 1), recommendedCount = vitest.config.watch ? threadsCount : Math.min(threadsCount, specifications.length), poolOptions = vitest.config.poolOptions?.forks ?? {}, maxThreads = poolOptions.maxForks ?? vitest.config.maxWorkers ?? recommendedCount, minThreads = vitest.config.watch ? Math.min(recommendedCount, maxThreads) : 0, options = {
@@ -2781,14 +2779,12 @@ function createWorkerChannel$1(project, collect) {
2781
2779
  },
2782
2780
  timeout: -1
2783
2781
  });
2784
- project.vitest.onCancel((reason) => rpc.onCancel(reason));
2785
- const onClose = () => {
2786
- port.close(), workerPort.close(), rpc.$close(/* @__PURE__ */ new Error("[vitest-pool]: Pending methods while closing rpc"));
2787
- };
2788
- return {
2782
+ return project.vitest.onCancel((reason) => rpc.onCancel(reason)), {
2789
2783
  workerPort,
2790
2784
  port,
2791
- onClose
2785
+ onClose: () => {
2786
+ port.close(), workerPort.close(), rpc.$close(/* @__PURE__ */ new Error("[vitest-pool]: Pending methods while closing rpc"));
2787
+ }
2792
2788
  };
2793
2789
  }
2794
2790
  function createThreadsPool(vitest, { execArgv, env }, specifications) {
@@ -2883,8 +2879,7 @@ function createTypecheckPool(vitest) {
2883
2879
  async function onParseEnd(project, { files, sourceErrors }) {
2884
2880
  const checker = project.typechecker, { packs, events } = checker.getTestPacksAndEvents();
2885
2881
  if (await vitest._testRun.updated(packs, events), !project.config.typecheck.ignoreSourceErrors) sourceErrors.forEach((error) => vitest.state.catchError(error, "Unhandled Source Error"));
2886
- const processError = !hasFailed(files) && !sourceErrors.length && checker.getExitCode();
2887
- if (processError) {
2882
+ if (!hasFailed(files) && !sourceErrors.length && checker.getExitCode()) {
2888
2883
  const error = new Error(checker.getOutput());
2889
2884
  error.stack = "", vitest.state.catchError(error, "Typecheck Error");
2890
2885
  }
@@ -2927,14 +2922,14 @@ function createTypecheckPool(vitest) {
2927
2922
  async function runTests(specs) {
2928
2923
  const specsByProject = groupBy(specs, (spec) => spec.project.name), promises = [];
2929
2924
  for (const name in specsByProject) {
2930
- const project = specsByProject[name][0].project, files = specsByProject[name].map((spec) => spec.moduleId), promise = createDefer(), _p = new Promise((resolve) => {
2925
+ const project = specsByProject[name][0].project, files = specsByProject[name].map((spec) => spec.moduleId), promise = createDefer(), triggered = await new Promise((resolve) => {
2931
2926
  const _i = setInterval(() => {
2932
2927
  if (!project.typechecker || rerunTriggered.has(project)) resolve(true), clearInterval(_i);
2933
2928
  });
2934
2929
  setTimeout(() => {
2935
2930
  resolve(false), clearInterval(_i);
2936
2931
  }, 500).unref();
2937
- }), triggered = await _p;
2932
+ });
2938
2933
  if (project.typechecker && !triggered) {
2939
2934
  const testFiles = project.typechecker.getTestFiles();
2940
2935
  for (const file of testFiles) await vitest._testRun.enqueued(project, file);
@@ -2963,14 +2958,10 @@ function getDefaultThreadsCount(config) {
2963
2958
  function getWorkerMemoryLimit(config, pool) {
2964
2959
  if (pool === "vmForks") {
2965
2960
  const opts = config.poolOptions?.vmForks ?? {};
2966
- if (opts.memoryLimit) return opts.memoryLimit;
2967
- const workers = opts.maxForks ?? getDefaultThreadsCount(config);
2968
- return 1 / workers;
2961
+ return opts.memoryLimit ? opts.memoryLimit : 1 / (opts.maxForks ?? getDefaultThreadsCount(config));
2969
2962
  } else {
2970
2963
  const opts = config.poolOptions?.vmThreads ?? {};
2971
- if (opts.memoryLimit) return opts.memoryLimit;
2972
- const workers = opts.maxThreads ?? getDefaultThreadsCount(config);
2973
- return 1 / workers;
2964
+ return opts.memoryLimit ? opts.memoryLimit : 1 / (opts.maxThreads ?? getDefaultThreadsCount(config));
2974
2965
  }
2975
2966
  }
2976
2967
  /**
@@ -3009,7 +3000,6 @@ function stringToBytes(input, percentageReference) {
3009
3000
  return null;
3010
3001
  }
3011
3002
 
3012
- const suppressWarningsPath$1 = resolve(rootDir, "./suppress-warnings.cjs");
3013
3003
  function createChildProcessChannel(project, collect) {
3014
3004
  const emitter = new EventEmitter(), events = {
3015
3005
  message: "message",
@@ -3039,15 +3029,13 @@ function createChildProcessChannel(project, collect) {
3039
3029
  },
3040
3030
  timeout: -1
3041
3031
  });
3042
- project.vitest.onCancel((reason) => rpc.onCancel(reason));
3043
- const channel = {
3032
+ return project.vitest.onCancel((reason) => rpc.onCancel(reason)), { channel: {
3044
3033
  onMessage: (callback) => emitter.on(events.message, callback),
3045
3034
  postMessage: (message) => emitter.emit(events.response, message),
3046
3035
  onClose: () => {
3047
3036
  emitter.removeAllListeners(), rpc.$close(/* @__PURE__ */ new Error("[vitest-pool]: Pending methods while closing rpc"));
3048
3037
  }
3049
- };
3050
- return { channel };
3038
+ } };
3051
3039
  }
3052
3040
  function createVmForksPool(vitest, { execArgv, env }, specifications) {
3053
3041
  const numCpus = typeof nodeos.availableParallelism === "function" ? nodeos.availableParallelism() : nodeos.cpus().length, threadsCount = vitest.config.watch ? Math.max(Math.floor(numCpus / 2), 1) : Math.max(numCpus - 1, 1), recommendedCount = vitest.config.watch ? threadsCount : Math.min(threadsCount, specifications.length), poolOptions = vitest.config.poolOptions?.vmForks ?? {}, maxThreads = poolOptions.maxForks ?? vitest.config.maxWorkers ?? recommendedCount, minThreads = vitest.config.watch ? Math.min(recommendedCount, maxThreads) : 0, options = {
@@ -3057,10 +3045,7 @@ function createVmForksPool(vitest, { execArgv, env }, specifications) {
3057
3045
  minThreads,
3058
3046
  env,
3059
3047
  execArgv: [
3060
- "--experimental-import-meta-resolve",
3061
3048
  "--experimental-vm-modules",
3062
- "--require",
3063
- suppressWarningsPath$1,
3064
3049
  ...poolOptions.execArgv ?? [],
3065
3050
  ...execArgv
3066
3051
  ],
@@ -3105,7 +3090,7 @@ function createVmForksPool(vitest, { execArgv, env }, specifications) {
3105
3090
  if (configs.has(project)) return configs.get(project);
3106
3091
  const _config = project.serializedConfig, config = wrapSerializableConfig(_config);
3107
3092
  return configs.set(project, config), config;
3108
- }, filesByEnv = await groupFilesByEnv(specs), promises = Object.values(filesByEnv).flat(), results = await Promise.allSettled(promises.map(({ file, environment, project }) => runFiles(project, getConfig(project), [file], environment, invalidates))), errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
3093
+ }, filesByEnv = await groupFilesByEnv(specs), promises = Object.values(filesByEnv).flat(), errors = (await Promise.allSettled(promises.map(({ file, environment, project }) => runFiles(project, getConfig(project), [file], environment, invalidates)))).filter((r) => r.status === "rejected").map((r) => r.reason);
3109
3094
  if (errors.length > 0) throw new AggregateError(errors, "Errors occurred while running tests. For more information, see serialized error.");
3110
3095
  };
3111
3096
  };
@@ -3122,7 +3107,6 @@ function getMemoryLimit$1(config) {
3122
3107
  return typeof memory === "number" ? stringToBytes(limit, config.watch ? memory / 2 : memory) : typeof limit === "number" && limit > 1 || typeof limit === "string" && limit.at(-1) !== "%" ? stringToBytes(limit) : null;
3123
3108
  }
3124
3109
 
3125
- const suppressWarningsPath = resolve(rootDir, "./suppress-warnings.cjs");
3126
3110
  function createWorkerChannel(project, collect) {
3127
3111
  const channel = new MessageChannel(), port = channel.port2, workerPort = channel.port1, rpc = createBirpc(createMethodsRPC(project, { collect }), {
3128
3112
  eventNames: ["onCancel"],
@@ -3151,10 +3135,7 @@ function createVmThreadsPool(vitest, { execArgv, env }, specifications) {
3151
3135
  minThreads,
3152
3136
  env,
3153
3137
  execArgv: [
3154
- "--experimental-import-meta-resolve",
3155
3138
  "--experimental-vm-modules",
3156
- "--require",
3157
- suppressWarningsPath,
3158
3139
  ...poolOptions.execArgv ?? [],
3159
3140
  ...execArgv
3160
3141
  ],
@@ -3200,7 +3181,7 @@ function createVmThreadsPool(vitest, { execArgv, env }, specifications) {
3200
3181
  if (configs.has(project)) return configs.get(project);
3201
3182
  const config = project.serializedConfig;
3202
3183
  return configs.set(project, config), config;
3203
- }, filesByEnv = await groupFilesByEnv(specs), promises = Object.values(filesByEnv).flat(), results = await Promise.allSettled(promises.map(({ file, environment, project }) => runFiles(project, getConfig(project), [file], environment, invalidates))), errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
3184
+ }, filesByEnv = await groupFilesByEnv(specs), promises = Object.values(filesByEnv).flat(), errors = (await Promise.allSettled(promises.map(({ file, environment, project }) => runFiles(project, getConfig(project), [file], environment, invalidates)))).filter((r) => r.status === "rejected").map((r) => r.reason);
3204
3185
  if (errors.length > 0) throw new AggregateError(errors, "Errors occurred while running tests. For more information, see serialized error.");
3205
3186
  };
3206
3187
  };
@@ -3217,6 +3198,7 @@ function getMemoryLimit(config) {
3217
3198
  return typeof memory === "number" ? stringToBytes(limit, config.watch ? memory / 2 : memory) : typeof limit === "number" && limit > 1 || typeof limit === "string" && limit.at(-1) !== "%" ? stringToBytes(limit) : null;
3218
3199
  }
3219
3200
 
3201
+ const suppressWarningsPath = resolve$1(rootDir, "./suppress-warnings.cjs");
3220
3202
  const builtinPools = [
3221
3203
  "forks",
3222
3204
  "threads",
@@ -3239,18 +3221,24 @@ function createPool(ctx) {
3239
3221
  vmThreads: null,
3240
3222
  vmForks: null,
3241
3223
  typescript: null
3242
- }, viteMajor = Number(version.split(".")[0]), potentialConditions = new Set(viteMajor >= 6 ? ctx.vite.config.ssr.resolve?.conditions ?? [] : [
3224
+ }, viteMajor = Number(version.split(".")[0]), conditions = [...new Set(viteMajor >= 6 ? ctx.vite.config.ssr.resolve?.conditions ?? [] : [
3243
3225
  "production",
3244
3226
  "development",
3245
3227
  ...ctx.vite.config.resolve.conditions
3246
- ]), conditions = [...potentialConditions].filter((condition) => {
3228
+ ])].filter((condition) => {
3247
3229
  return condition === "production" ? ctx.vite.config.isProduction : condition === "development" ? !ctx.vite.config.isProduction : true;
3248
3230
  }).map((condition) => {
3249
3231
  return viteMajor >= 6 && condition === "development|production" ? ctx.vite.config.isProduction ? "production" : "development" : condition;
3250
3232
  }).flatMap((c) => ["--conditions", c]), execArgv = process.execArgv.filter((execArg) => execArg.startsWith("--cpu-prof") || execArg.startsWith("--heap-prof") || execArg.startsWith("--diagnostic-dir"));
3251
3233
  async function executeTests(method, files, invalidate) {
3252
3234
  const options = {
3253
- execArgv: [...execArgv, ...conditions],
3235
+ execArgv: [
3236
+ ...execArgv,
3237
+ ...conditions,
3238
+ "--experimental-import-meta-resolve",
3239
+ "--require",
3240
+ suppressWarningsPath
3241
+ ],
3254
3242
  env: {
3255
3243
  TEST: "true",
3256
3244
  VITEST: "true",
@@ -3355,7 +3343,7 @@ class BaseSequencer {
3355
3343
  async shard(files) {
3356
3344
  const { config } = this.ctx, { index, count } = config.shard, [shardStart, shardEnd] = this.calculateShardRange(files.length, index, count);
3357
3345
  return [...files].map((spec) => {
3358
- const fullPath = resolve$1(slash(config.root), slash(spec.moduleId)), specPath = fullPath?.slice(config.root.length);
3346
+ const specPath = resolve$1(slash(config.root), slash(spec.moduleId))?.slice(config.root.length);
3359
3347
  return {
3360
3348
  spec,
3361
3349
  hash: hash("sha1", specPath, "hex")
@@ -3482,9 +3470,9 @@ function resolveConfig$1(vitest, options, viteConfig) {
3482
3470
  browser.instances = browser.instances.filter((instance) => instance.browser === browser.name);
3483
3471
  if (browser.instances && !browser.instances.length) throw new Error([`"browser.instances" was set in the config, but the array is empty. Define at least one browser config.`, browser.name && instances?.length ? ` The "browser.name" was set to "${browser.name}" which filtered all configs (${instances.map((c) => c.browser).join(", ")}). Did you mean to use another name?` : ""].join(""));
3484
3472
  }
3485
- const playwrightChromiumOnly = isPlaywrightChromiumOnly(vitest, resolved);
3486
- // Browser-mode "Playwright + Chromium" only features:
3487
- if (browser.enabled && !playwrightChromiumOnly) {
3473
+ const containsChromium = hasBrowserChromium(vitest, resolved), hasOnlyChromium = hasOnlyBrowserChromium(vitest, resolved);
3474
+ // Browser-mode "Chromium" only features:
3475
+ if (browser.enabled && (!containsChromium || !hasOnlyChromium)) {
3488
3476
  const browserConfig = `
3489
3477
  {
3490
3478
  browser: {
@@ -3494,17 +3482,18 @@ function resolveConfig$1(vitest, options, viteConfig) {
3494
3482
  ],
3495
3483
  },
3496
3484
  }
3497
- `.trim(), correctExample = `
3485
+ `.trim(), preferredProvider = !browser.provider?.name || browser.provider.name === "preview" ? "playwright" : browser.provider.name, correctExample = `
3498
3486
  {
3499
3487
  browser: {
3500
- provider: playwright(),
3488
+ provider: ${preferredProvider}(),
3501
3489
  instances: [
3502
- { browser: 'chromium' }
3490
+ { browser: '${preferredProvider === "playwright" ? "chromium" : "chrome"}' }
3503
3491
  ],
3504
3492
  },
3505
3493
  }
3506
3494
  `.trim();
3507
- if (resolved.coverage.enabled && resolved.coverage.provider === "v8") {
3495
+ // requires all projects to be chromium
3496
+ if (!hasOnlyChromium && resolved.coverage.enabled && resolved.coverage.provider === "v8") {
3508
3497
  const coverageExample = `
3509
3498
  {
3510
3499
  coverage: {
@@ -3514,7 +3503,8 @@ function resolveConfig$1(vitest, options, viteConfig) {
3514
3503
  `.trim();
3515
3504
  throw new Error(`@vitest/coverage-v8 does not work with\n${browserConfig}\n\nUse either:\n${correctExample}\n\n...or change your coverage provider to:\n${coverageExample}\n`);
3516
3505
  }
3517
- if (resolved.inspect || resolved.inspectBrk) {
3506
+ // ignores non-chromium browsers when there is at least one chromium project
3507
+ if (!containsChromium && (resolved.inspect || resolved.inspectBrk)) {
3518
3508
  const inspectOption = `--inspect${resolved.inspectBrk ? "-brk" : ""}`;
3519
3509
  throw new Error(`${inspectOption} does not work with\n${browserConfig}\n\nUse either:\n${correctExample}\n\n...or disable ${inspectOption}\n`);
3520
3510
  }
@@ -3578,10 +3568,8 @@ function resolveConfig$1(vitest, options, viteConfig) {
3578
3568
  maxForks: Number.parseInt(process.env.VITEST_MAX_FORKS)
3579
3569
  }
3580
3570
  };
3581
- const poolThreadsOptions = [["threads", "maxThreads"], ["vmThreads", "maxThreads"]];
3582
- for (const [poolOptionKey, workerOptionKey] of poolThreadsOptions) if (resolved.poolOptions?.[poolOptionKey]?.[workerOptionKey]) resolved.poolOptions[poolOptionKey][workerOptionKey] = resolveInlineWorkerOption(resolved.poolOptions[poolOptionKey][workerOptionKey]);
3583
- const poolForksOptions = [["forks", "maxForks"], ["vmForks", "maxForks"]];
3584
- for (const [poolOptionKey, workerOptionKey] of poolForksOptions) if (resolved.poolOptions?.[poolOptionKey]?.[workerOptionKey]) resolved.poolOptions[poolOptionKey][workerOptionKey] = resolveInlineWorkerOption(resolved.poolOptions[poolOptionKey][workerOptionKey]);
3571
+ for (const [poolOptionKey, workerOptionKey] of [["threads", "maxThreads"], ["vmThreads", "maxThreads"]]) if (resolved.poolOptions?.[poolOptionKey]?.[workerOptionKey]) resolved.poolOptions[poolOptionKey][workerOptionKey] = resolveInlineWorkerOption(resolved.poolOptions[poolOptionKey][workerOptionKey]);
3572
+ for (const [poolOptionKey, workerOptionKey] of [["forks", "maxForks"], ["vmForks", "maxForks"]]) if (resolved.poolOptions?.[poolOptionKey]?.[workerOptionKey]) resolved.poolOptions[poolOptionKey][workerOptionKey] = resolveInlineWorkerOption(resolved.poolOptions[poolOptionKey][workerOptionKey]);
3585
3573
  if (!builtinPools.includes(resolved.pool)) resolved.pool = resolvePath(resolved.pool, resolved.root);
3586
3574
  if (mode === "benchmark") {
3587
3575
  resolved.benchmark = {
@@ -3597,10 +3585,8 @@ function resolveConfig$1(vitest, options, viteConfig) {
3597
3585
  if (options.outputJson) resolved.benchmark.outputJson = options.outputJson;
3598
3586
  }
3599
3587
  if (typeof resolved.diff === "string") resolved.diff = resolvePath(resolved.diff, resolved.root), resolved.forceRerunTriggers.push(resolved.diff);
3600
- // the server has been created, we don't need to override vite.server options
3601
- const api = resolveApiServerConfig(options, defaultPort);
3602
3588
  if (resolved.api = {
3603
- ...api,
3589
+ ...resolveApiServerConfig(options, defaultPort),
3604
3590
  token: crypto.randomUUID()
3605
3591
  }, options.related) resolved.related = toArray(options.related).map((file) => resolve$1(resolved.root, file));
3606
3592
  /*
@@ -3671,14 +3657,16 @@ function resolveConfig$1(vitest, options, viteConfig) {
3671
3657
  `Set "browser.screenshotFailures" to false or remove it from the config to suppress this warning.`
3672
3658
  ].join(""))), resolved.browser.screenshotFailures = false;
3673
3659
  else resolved.browser.screenshotFailures ??= !isPreview && !resolved.browser.ui;
3660
+ if (resolved.browser.provider && resolved.browser.provider.options == null) resolved.browser.provider.options = {};
3674
3661
  // enable includeTaskLocation by default in UI mode
3675
3662
  if (resolved.browser.api = resolveApiServerConfig(resolved.browser, defaultBrowserPort) || { port: defaultBrowserPort }, resolved.browser.enabled) {
3676
3663
  if (resolved.browser.ui) resolved.includeTaskLocation ??= true;
3677
3664
  } else if (resolved.ui) resolved.includeTaskLocation ??= true;
3678
- const htmlReporter = toArray(resolved.reporters).some((reporter) => {
3665
+ if (typeof resolved.browser.trace === "string" || !resolved.browser.trace) resolved.browser.trace = { mode: resolved.browser.trace || "off" };
3666
+ if (resolved.browser.trace.tracesDir != null) resolved.browser.trace.tracesDir = resolvePath(resolved.browser.trace.tracesDir, resolved.root);
3667
+ if (toArray(resolved.reporters).some((reporter) => {
3679
3668
  return Array.isArray(reporter) ? reporter[0] === "html" : false;
3680
- });
3681
- if (htmlReporter) resolved.includeTaskLocation ??= true;
3669
+ })) resolved.includeTaskLocation ??= true;
3682
3670
  return resolved.server ??= {}, resolved.server.deps ??= {}, resolved.testTimeout ??= resolved.browser.enabled ? 15e3 : 5e3, resolved.hookTimeout ??= resolved.browser.enabled ? 3e4 : 1e4, resolved;
3683
3671
  }
3684
3672
  function isBrowserEnabled(config) {
@@ -3696,18 +3684,22 @@ function resolveCoverageReporters(configReporters) {
3696
3684
  resolvedReporters.push([reporter, {}]);
3697
3685
  return resolvedReporters;
3698
3686
  }
3699
- function isPlaywrightChromiumOnly(vitest, config) {
3687
+ function isChromiumName(provider, name) {
3688
+ return provider === "playwright" ? name === "chromium" : name === "chrome" || name === "edge";
3689
+ }
3690
+ function hasBrowserChromium(vitest, config) {
3700
3691
  const browser = config.browser;
3701
- if (!browser || !browser.provider || browser.provider.name !== "playwright" || !browser.enabled) return false;
3702
- if (browser.name) return browser.name === "chromium";
3703
- if (!browser.instances) return false;
3704
- for (const instance of browser.instances) {
3692
+ return !browser || !browser.provider || browser.provider.name === "preview" || !browser.enabled ? false : browser.name ? isChromiumName(browser.provider.name, browser.name) : browser.instances ? browser.instances.some((instance) => {
3705
3693
  const name = instance.name || (config.name ? `${config.name} (${instance.browser})` : instance.browser);
3706
- // browser config is filtered out
3707
- if (!vitest.matchesProjectFilter(name)) continue;
3708
- if (instance.browser !== "chromium") return false;
3709
- }
3710
- return true;
3694
+ return vitest.matchesProjectFilter(name) ? isChromiumName(browser.provider.name, instance.browser) : false;
3695
+ }) : false;
3696
+ }
3697
+ function hasOnlyBrowserChromium(vitest, config) {
3698
+ const browser = config.browser;
3699
+ return !browser || !browser.provider || browser.provider.name === "preview" || !browser.enabled ? false : browser.name ? isChromiumName(browser.provider.name, browser.name) : browser.instances ? browser.instances.every((instance) => {
3700
+ const name = instance.name || (config.name ? `${config.name} (${instance.browser})` : instance.browser);
3701
+ return vitest.matchesProjectFilter(name) ? isChromiumName(browser.provider.name, instance.browser) : true;
3702
+ }) : false;
3711
3703
  }
3712
3704
 
3713
3705
  const THRESHOLD_KEYS = [
@@ -3788,8 +3780,8 @@ Update your dependencies and make sure the versions match.`));
3788
3780
  }
3789
3781
  async getUntestedFiles(testedFiles) {
3790
3782
  if (this.options.include == null) return [];
3791
- const rootMapper = this.getUntestedFilesByRoot.bind(this, testedFiles, this.options.include), matrix = await Promise.all(this.roots.map(rootMapper));
3792
- return matrix.flatMap((files) => files);
3783
+ const rootMapper = this.getUntestedFilesByRoot.bind(this, testedFiles, this.options.include);
3784
+ return (await Promise.all(this.roots.map(rootMapper))).flatMap((files) => files);
3793
3785
  }
3794
3786
  createCoverageMap() {
3795
3787
  throw new Error("BaseReporter's createCoverageMap was not overwritten");
@@ -3850,10 +3842,7 @@ Update your dependencies and make sure the versions match.`));
3850
3842
  if (!this.options.reportOnFailure) await this.cleanAfterRun();
3851
3843
  }
3852
3844
  async reportCoverage(coverageMap, { allTestsRun }) {
3853
- await this.generateReports(coverageMap || this.createCoverageMap(), allTestsRun);
3854
- // In watch mode we need to preserve the previous results if cleanOnRerun is disabled
3855
- const keepResults = !this.options.cleanOnRerun && this.ctx.config.watch;
3856
- if (!keepResults) await this.cleanAfterRun();
3845
+ if (await this.generateReports(coverageMap || this.createCoverageMap(), allTestsRun), !(!this.options.cleanOnRerun && this.ctx.config.watch)) await this.cleanAfterRun();
3857
3846
  }
3858
3847
  async reportThresholds(coverageMap, allTestsRun) {
3859
3848
  const resolvedThresholds = this.resolveThresholds(coverageMap);
@@ -2,11 +2,12 @@ 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, f as findUp } from './index.X0nbfr6-.js';
5
+ import { p as prompt, a as any } from './index.Dc3xnDvT.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
+ import 'node:module';
10
11
  import 'node:url';
11
12
  import './_commonjsHelpers.BFTU3MAI.js';
12
13
  import 'readline';
@@ -297,12 +298,11 @@ async function generateExampleFiles(framework, lang) {
297
298
  // eslint-disable-next-line no-console
298
299
  const log = console.log;
299
300
  function getProviderOptions() {
300
- const providers = {
301
+ return Object.entries({
301
302
  playwright: "Playwright relies on Chrome DevTools protocol. Read more: https://playwright.dev",
302
303
  webdriverio: "WebdriverIO uses WebDriver protocol. Read more: https://webdriver.io",
303
304
  preview: "Preview is useful to quickly run your tests in the browser, but not suitable for CI."
304
- };
305
- return Object.entries(providers).map(([provider, description]) => {
305
+ }).map(([provider, description]) => {
306
306
  return {
307
307
  title: provider,
308
308
  description,
@@ -476,9 +476,7 @@ function getProviderDocsLink(provider) {
476
476
  }
477
477
  function sort(choices, value) {
478
478
  const index = choices.findIndex((i) => i.value === value);
479
- if (index === -1) return choices;
480
- const item = choices.splice(index, 1)[0];
481
- return [item, ...choices];
479
+ return index === -1 ? choices : [choices.splice(index, 1)[0], ...choices];
482
480
  }
483
481
  function fail() {
484
482
  process.exitCode = 1;
@@ -603,7 +601,7 @@ async function create() {
603
601
  if (frameworkPlugin) dependenciesToInstall.push(frameworkPlugin);
604
602
  const pkgManager = await detectPackageManager();
605
603
  log(), await installPackages(pkgManager, dependenciesToInstall.filter((pkg) => !dependencies[pkg]));
606
- const rootConfig = await findUp(configFiles, { cwd: process.cwd() });
604
+ const rootConfig = any(configFiles, { cwd: process.cwd() });
607
605
  let scriptCommand = "vitest";
608
606
  if (log(), rootConfig) {
609
607
  const configPath = resolve(dirname(rootConfig), `vitest.browser.config.${lang}`);
@@ -4,19 +4,6 @@ import { SnapshotState } from '@vitest/snapshot';
4
4
  import { B as BenchmarkResult } from './benchmark.d.DAaHLpsq.js';
5
5
  import { U as UserConsoleLog } from './environment.d.BsToaxti.js';
6
6
 
7
- declare global {
8
- namespace Chai {
9
- interface ContainSubset {
10
- (expected: any): Assertion;
11
- }
12
- interface Assertion {
13
- containSubset: ContainSubset;
14
- }
15
- interface Assert {
16
- containSubset(val: any, exp: any, msg?: string): void;
17
- }
18
- }
19
- }
20
7
  interface SnapshotMatcher<T> {
21
8
  <U extends { [P in keyof T] : any }>(snapshot: Partial<U>, hint?: string): void;
22
9
  (hint?: string): void;
@@ -1,20 +1,20 @@
1
1
  import { g as globalApis } from './constants.D_Q9UYh-.js';
2
- import { i as index } from './index.AZOjjqWP.js';
3
- import './vi.CiJ0Laa6.js';
2
+ import { i as index } from './index.Dnl38iQ_.js';
3
+ import './vi.B2--mG9U.js';
4
4
  import '@vitest/expect';
5
5
  import '@vitest/runner';
6
6
  import '@vitest/runner/utils';
7
- import './utils.DGKhod2J.js';
7
+ import './utils.CG9h5ccR.js';
8
8
  import '@vitest/utils/timers';
9
- import './_commonjsHelpers.BFTU3MAI.js';
10
9
  import '@vitest/snapshot';
11
10
  import '@vitest/utils/error';
12
11
  import '@vitest/utils/helpers';
13
12
  import '@vitest/spy';
14
13
  import '@vitest/utils/offset';
15
14
  import '@vitest/utils/source-map';
15
+ import './_commonjsHelpers.BFTU3MAI.js';
16
16
  import './date.-jtEtIeV.js';
17
- import './benchmark.LXhJ0F0X.js';
17
+ import './benchmark.DHKMYAts.js';
18
18
  import 'expect-type';
19
19
  import 'vite/module-runner';
20
20
 
@@ -238,10 +238,10 @@ const skipKeys = [
238
238
  "parent"
239
239
  ];
240
240
  function getWindowKeys(global, win, additionalKeys = []) {
241
- const keysArray = [...additionalKeys, ...KEYS], keys = new Set(keysArray.concat(Object.getOwnPropertyNames(win)).filter((k) => {
241
+ const keysArray = [...additionalKeys, ...KEYS];
242
+ return new Set(keysArray.concat(Object.getOwnPropertyNames(win)).filter((k) => {
242
243
  return skipKeys.includes(k) ? false : k in global ? keysArray.includes(k) : true;
243
244
  }));
244
- return keys;
245
245
  }
246
246
  function isClassLikeName(name) {
247
247
  return name[0] === name[0].toUpperCase();
@@ -393,23 +393,18 @@ var jsdom = {
393
393
  });
394
394
  const clearWindowErrors = catchWindowErrors(dom.window);
395
395
  dom.window.Buffer = Buffer, dom.window.jsdom = dom;
396
- // inject web globals if they missing in JSDOM but otherwise available in Nodejs
397
- // https://nodejs.org/dist/latest/docs/api/globals.html
398
- const globalNames = [
396
+ for (const name of [
399
397
  "structuredClone",
400
398
  "BroadcastChannel",
401
399
  "MessageChannel",
402
400
  "MessagePort",
403
401
  "TextEncoder",
404
402
  "TextDecoder"
405
- ];
406
- for (const name of globalNames) {
403
+ ]) {
407
404
  const value = globalThis[name];
408
405
  if (typeof value !== "undefined" && typeof dom.window[name] === "undefined") dom.window[name] = value;
409
406
  }
410
- // since we are providing Node.js's Fetch API,
411
- // we also should override other APIs they use
412
- const overrideGlobals = [
407
+ for (const name of [
413
408
  "fetch",
414
409
  "Request",
415
410
  "Response",
@@ -418,8 +413,7 @@ var jsdom = {
418
413
  "AbortSignal",
419
414
  "URL",
420
415
  "URLSearchParams"
421
- ];
422
- for (const name of overrideGlobals) {
416
+ ]) {
423
417
  const value = globalThis[name];
424
418
  if (typeof value !== "undefined") dom.window[name] = value;
425
419
  }