vitest 2.0.0-beta.12 → 2.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 (43) hide show
  1. package/LICENSE.md +0 -21
  2. package/dist/browser.d.ts +3 -2
  3. package/dist/browser.js +2 -2
  4. package/dist/chunks/{browser-creator.Bw94IHrL.js → browser-creator.DSqYDthP.js} +1 -1
  5. package/dist/chunks/{integrations-globals.DSNOaUHv.js → integrations-globals.CzYWb38r.js} +1 -1
  6. package/dist/chunks/{runtime-runBaseTests.BDt9gQFB.js → runtime-runBaseTests.DX3h28Mp.js} +9 -5
  7. package/dist/cli.js +2 -2
  8. package/dist/config.cjs +3 -2
  9. package/dist/config.d.ts +2 -1
  10. package/dist/config.js +3 -2
  11. package/dist/coverage.d.ts +2 -1
  12. package/dist/environments.d.ts +2 -1
  13. package/dist/execute.d.ts +4 -3
  14. package/dist/execute.js +1 -1
  15. package/dist/index.d.ts +4 -3
  16. package/dist/node.d.ts +18 -4
  17. package/dist/node.js +8 -8
  18. package/dist/{reporters-Cd1vkLMZ.d.ts → reporters-DrywOHjt.d.ts} +56 -19
  19. package/dist/reporters.d.ts +2 -1
  20. package/dist/reporters.js +2 -2
  21. package/dist/runners.d.ts +3 -1
  22. package/dist/runners.js +1 -0
  23. package/dist/{suite-BS2CV79a.d.ts → suite-CrOPuDIk.d.ts} +1 -1
  24. package/dist/suite.d.ts +3 -2
  25. package/dist/vendor/{base.Cy97mmVC.js → base.CdA1i5tB.js} +4 -3
  26. package/dist/vendor/{cac.DRNUX42m.js → cac.CpoEMnGk.js} +62 -15
  27. package/dist/vendor/{cli-api.Bu-PSdzx.js → cli-api.CXFLjKVN.js} +369 -97
  28. package/dist/vendor/{constants.BWsVtsAj.js → constants.CsnA4eRy.js} +1 -2
  29. package/dist/vendor/{execute.T3gg2ZK6.js → execute.Dx503nGn.js} +12 -4
  30. package/dist/vendor/{index.ZtQtNPP2.js → index.3x3MdmUV.js} +135 -78
  31. package/dist/vendor/{index.B7pSlOSa.js → index.CROIsoiT.js} +1 -1
  32. package/dist/vendor/{setup-common.CWnv_2-5.js → setup-common.yHaxjRhz.js} +1 -1
  33. package/dist/vendor/{utils.DSO2UK15.js → utils.BVMrsl6E.js} +15 -5
  34. package/dist/vendor/{vm.D9wVR14y.js → vm.BrDS6p7h.js} +6 -4
  35. package/dist/worker.js +11 -4
  36. package/dist/workers/forks.js +10 -4
  37. package/dist/workers/runVmTests.js +9 -5
  38. package/dist/workers/threads.js +6 -3
  39. package/dist/workers/vmForks.js +10 -4
  40. package/dist/workers/vmThreads.js +6 -3
  41. package/dist/workers.d.ts +7 -4
  42. package/dist/workers.js +4 -4
  43. package/package.json +12 -12
@@ -1,7 +1,6 @@
1
1
  const defaultPort = 51204;
2
2
  const defaultBrowserPort = 63315;
3
3
  const defaultInspectPort = 9229;
4
- const EXIT_CODE_RESTART = 43;
5
4
  const API_PATH = "/__vitest_api__";
6
5
  const extraInlineDeps = [
7
6
  /^(?!.*node_modules).*\.mjs$/,
@@ -46,4 +45,4 @@ const globalApis = [
46
45
  "onTestFailed"
47
46
  ];
48
47
 
49
- export { API_PATH as A, CONFIG_NAMES as C, EXIT_CODE_RESTART as E, defaultBrowserPort as a, defaultInspectPort as b, configFiles as c, defaultPort as d, extraInlineDeps as e, globalApis as g, workspacesFiles as w };
48
+ export { API_PATH as A, CONFIG_NAMES as C, defaultBrowserPort as a, defaultInspectPort as b, configFiles as c, defaultPort as d, extraInlineDeps as e, globalApis as g, workspacesFiles as w };
@@ -1,6 +1,6 @@
1
1
  import vm from 'node:vm';
2
2
  import { pathToFileURL } from 'node:url';
3
- import { existsSync, readdirSync, readFileSync } from 'node:fs';
3
+ import fs from 'node:fs';
4
4
  import { ViteNodeRunner, DEFAULT_REQUEST_STUBS } from 'vite-node/client';
5
5
  import { isNodeBuiltin, isInternalRequest, toFilePath, isPrimitive } from 'vite-node/utils';
6
6
  import { resolve, isAbsolute, dirname, join, basename, extname, normalize, relative } from 'pathe';
@@ -9,6 +9,7 @@ import { distDir } from '../path.js';
9
9
  import { highlight, getType } from '@vitest/utils';
10
10
  import { g as getAllMockableProperties } from './base.CTYV4Gnz.js';
11
11
 
12
+ const { existsSync, readdirSync } = fs;
12
13
  const spyModulePath = resolve(distDir, "spy.js");
13
14
  class RefTracker {
14
15
  idMap = /* @__PURE__ */ new Map();
@@ -444,6 +445,7 @@ If you need to partially mock a module, you can use "importOriginal" helper insi
444
445
  }
445
446
  }
446
447
 
448
+ const { readFileSync } = fs;
447
449
  async function createVitestExecutor(options) {
448
450
  const runner = new VitestExecutor(options);
449
451
  await runner.executeId("/@vite/env");
@@ -456,9 +458,15 @@ const dispose = [];
456
458
  function listenForErrors(state) {
457
459
  dispose.forEach((fn) => fn());
458
460
  dispose.length = 0;
459
- function catchError(err, type) {
461
+ function catchError(err, type, event) {
460
462
  var _a;
461
463
  const worker = state();
464
+ if (worker.current) {
465
+ const listeners = process.listeners(event);
466
+ if (listeners.length > 1) {
467
+ return;
468
+ }
469
+ }
462
470
  const error = processError(err);
463
471
  if (!isPrimitive(error)) {
464
472
  error.VITEST_TEST_NAME = (_a = worker.current) == null ? void 0 : _a.name;
@@ -469,8 +477,8 @@ function listenForErrors(state) {
469
477
  }
470
478
  state().rpc.onUnhandledError(error, type);
471
479
  }
472
- const uncaughtException = (e) => catchError(e, "Uncaught Exception");
473
- const unhandledRejection = (e) => catchError(e, "Unhandled Rejection");
480
+ const uncaughtException = (e) => catchError(e, "Uncaught Exception", "uncaughtException");
481
+ const unhandledRejection = (e) => catchError(e, "Unhandled Rejection", "unhandledRejection");
474
482
  process.on("uncaughtException", uncaughtException);
475
483
  process.on("unhandledRejection", unhandledRejection);
476
484
  dispose.push(() => {
@@ -2,10 +2,10 @@ import fs, { existsSync, promises, readFileSync } from 'node:fs';
2
2
  import c from 'picocolors';
3
3
  import * as pathe from 'pathe';
4
4
  import { basename, dirname, resolve, join, relative, extname, normalize } from 'pathe';
5
- import { a as getFullName, h as hasFailedSnapshot } from './tasks.DhVtQBtW.js';
5
+ import { g as getTestName, h as hasFailedSnapshot, a as getFullName } from './tasks.DhVtQBtW.js';
6
6
  import { getSafeTimers, notNullish, highlight, shuffle, inspect, positionToOffset, lineSplitRE } from '@vitest/utils';
7
7
  import { i as isNode, a as isDeno } from './env.2ltrQNq0.js';
8
- import { g as getStateSymbol, f as formatProjectName, p as pointer, F as F_RIGHT, a as F_POINTER, r as renderSnapshotSummary, b as getStateString, c as formatTimeString, d as countTestErrors, e as divider, s as stripAnsi, h as getCols, i as getHookStateSymbol } from './utils.DSO2UK15.js';
8
+ import { g as getStateSymbol, f as formatProjectName, t as taskFail, F as F_RIGHT, a as F_POINTER, r as renderSnapshotSummary, b as getStateString, c as formatTimeString, d as countTestErrors, e as divider, s as stripAnsi, h as getCols, i as getHookStateSymbol } from './utils.BVMrsl6E.js';
9
9
  import { generateHash, calculateSuiteHash, someTasksAreOnly, interpretTaskModes, getTasks, getTests, hasFailed, getSuites } from '@vitest/runner/utils';
10
10
  import { performance } from 'node:perf_hooks';
11
11
  import { TraceMap, generatedPositionFor, parseStacktrace, parseErrorStacktrace } from '@vitest/utils/source-map';
@@ -940,6 +940,7 @@ class Typechecker {
940
940
  var _a;
941
941
  await this.clear();
942
942
  (_a = this.process) == null ? void 0 : _a.kill();
943
+ this.process = void 0;
943
944
  }
944
945
  async ensurePackageInstalled(ctx, checker) {
945
946
  if (checker !== "tsc" && checker !== "vue-tsc") {
@@ -963,6 +964,9 @@ class Typechecker {
963
964
  }
964
965
  async start() {
965
966
  var _a, _b, _c;
967
+ if (this.process) {
968
+ return;
969
+ }
966
970
  if (!this.tempConfigPath) {
967
971
  throw new Error("tsconfig was not initialized");
968
972
  }
@@ -1046,6 +1050,7 @@ class BaseReporter {
1046
1050
  start = 0;
1047
1051
  end = 0;
1048
1052
  watchFilters;
1053
+ failedUnwatchedFiles = [];
1049
1054
  isTTY;
1050
1055
  ctx = void 0;
1051
1056
  verbose = false;
@@ -1085,54 +1090,60 @@ class BaseReporter {
1085
1090
  }
1086
1091
  }
1087
1092
  onTaskUpdate(packs) {
1088
- var _a, _b, _c, _d;
1089
1093
  if (this.isTTY) {
1090
1094
  return;
1091
1095
  }
1092
- const logger = this.ctx.logger;
1093
1096
  for (const pack of packs) {
1094
1097
  const task = this.ctx.state.idMap.get(pack[0]);
1095
- if (task && "filepath" in task && ((_a = task.result) == null ? void 0 : _a.state) && ((_b = task.result) == null ? void 0 : _b.state) !== "run") {
1096
- const tests = getTests(task);
1097
- const failed = tests.filter((t) => {
1098
- var _a2;
1099
- return ((_a2 = t.result) == null ? void 0 : _a2.state) === "fail";
1100
- });
1101
- const skipped = tests.filter(
1102
- (t) => t.mode === "skip" || t.mode === "todo"
1103
- );
1104
- let state = c.dim(`${tests.length} test${tests.length > 1 ? "s" : ""}`);
1105
- if (failed.length) {
1106
- state += ` ${c.dim("|")} ${c.red(`${failed.length} failed`)}`;
1107
- }
1108
- if (skipped.length) {
1109
- state += ` ${c.dim("|")} ${c.yellow(`${skipped.length} skipped`)}`;
1110
- }
1111
- let suffix = c.dim(" (") + state + c.dim(")");
1112
- if (task.result.duration) {
1113
- const color = task.result.duration > this.ctx.config.slowTestThreshold ? c.yellow : c.gray;
1114
- suffix += color(` ${Math.round(task.result.duration)}${c.dim("ms")}`);
1115
- }
1116
- if (this.ctx.config.logHeapUsage && task.result.heap != null) {
1117
- suffix += c.magenta(
1118
- ` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`
1119
- );
1120
- }
1121
- let title = ` ${getStateSymbol(task)} `;
1122
- if (task.projectName) {
1123
- title += formatProjectName(task.projectName);
1124
- }
1125
- title += `${task.name} ${suffix}`;
1126
- logger.log(title);
1127
- for (const test of failed) {
1128
- logger.log(c.red(` ${pointer} ${getFullName(test, c.dim(" > "))}`));
1129
- (_d = (_c = test.result) == null ? void 0 : _c.errors) == null ? void 0 : _d.forEach((e) => {
1130
- logger.log(c.red(` ${F_RIGHT} ${e == null ? void 0 : e.message}`));
1131
- });
1132
- }
1098
+ if (task) {
1099
+ this.printTask(task);
1133
1100
  }
1134
1101
  }
1135
1102
  }
1103
+ printTask(task) {
1104
+ var _a, _b, _c, _d;
1105
+ if (!("filepath" in task) || !((_a = task.result) == null ? void 0 : _a.state) || ((_b = task.result) == null ? void 0 : _b.state) === "run") {
1106
+ return;
1107
+ }
1108
+ const logger = this.ctx.logger;
1109
+ const tests = getTests(task);
1110
+ const failed = tests.filter((t) => {
1111
+ var _a2;
1112
+ return ((_a2 = t.result) == null ? void 0 : _a2.state) === "fail";
1113
+ });
1114
+ const skipped = tests.filter(
1115
+ (t) => t.mode === "skip" || t.mode === "todo"
1116
+ );
1117
+ let state = c.dim(`${tests.length} test${tests.length > 1 ? "s" : ""}`);
1118
+ if (failed.length) {
1119
+ state += ` ${c.dim("|")} ${c.red(`${failed.length} failed`)}`;
1120
+ }
1121
+ if (skipped.length) {
1122
+ state += ` ${c.dim("|")} ${c.yellow(`${skipped.length} skipped`)}`;
1123
+ }
1124
+ let suffix = c.dim(" (") + state + c.dim(")");
1125
+ if (task.result.duration) {
1126
+ const color = task.result.duration > this.ctx.config.slowTestThreshold ? c.yellow : c.gray;
1127
+ suffix += color(` ${Math.round(task.result.duration)}${c.dim("ms")}`);
1128
+ }
1129
+ if (this.ctx.config.logHeapUsage && task.result.heap != null) {
1130
+ suffix += c.magenta(
1131
+ ` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`
1132
+ );
1133
+ }
1134
+ let title = ` ${getStateSymbol(task)} `;
1135
+ if (task.projectName) {
1136
+ title += formatProjectName(task.projectName);
1137
+ }
1138
+ title += `${task.name} ${suffix}`;
1139
+ logger.log(title);
1140
+ for (const test of failed) {
1141
+ logger.log(c.red(` ${taskFail} ${getTestName(test, c.dim(" > "))}`));
1142
+ (_d = (_c = test.result) == null ? void 0 : _c.errors) == null ? void 0 : _d.forEach((e) => {
1143
+ logger.log(c.red(` ${F_RIGHT} ${e == null ? void 0 : e.message}`));
1144
+ });
1145
+ }
1146
+ }
1136
1147
  onWatcherStart(files = this.ctx.state.getFiles(), errors = this.ctx.state.getUnhandledErrors()) {
1137
1148
  this.resetLastRunLog();
1138
1149
  const failed = errors.length > 0 || hasFailed(files);
@@ -1184,6 +1195,9 @@ class BaseReporter {
1184
1195
  onWatcherRerun(files, trigger) {
1185
1196
  this.resetLastRunLog();
1186
1197
  this.watchFilters = files;
1198
+ this.failedUnwatchedFiles = this.ctx.state.getFiles().filter((file) => {
1199
+ return !files.includes(file.filepath) && hasFailed(file);
1200
+ });
1187
1201
  files.forEach((filepath) => {
1188
1202
  let reruns = this._filesInWatchMode.get(filepath) ?? 0;
1189
1203
  this._filesInWatchMode.set(filepath, ++reruns);
@@ -1220,10 +1234,16 @@ ${BADGE}${TRIGGER} ${c.blue(
1220
1234
  ${PROJECT_FILTER}${FILENAME_PATTERN}${TESTNAME_PATTERN}`
1221
1235
  );
1222
1236
  }
1237
+ if (!this.isTTY) {
1238
+ for (const task of this.failedUnwatchedFiles) {
1239
+ this.printTask(task);
1240
+ }
1241
+ }
1223
1242
  this._timeStart = /* @__PURE__ */ new Date();
1224
1243
  this.start = performance.now();
1225
1244
  }
1226
1245
  onUserConsoleLog(log) {
1246
+ var _a;
1227
1247
  if (!this.shouldLog(log)) {
1228
1248
  return;
1229
1249
  }
@@ -1242,10 +1262,7 @@ ${log.content}`);
1242
1262
  write("\n");
1243
1263
  }
1244
1264
  const project = log.taskId ? this.ctx.getProjectByTaskId(log.taskId) : this.ctx.getCoreWorkspaceProject();
1245
- const stack = parseStacktrace(log.origin, {
1246
- getSourceMap: (file) => project.getBrowserSourceMapModuleById(file),
1247
- frameFilter: project.config.onStackTrace
1248
- });
1265
+ const stack = log.browser ? ((_a = project.browser) == null ? void 0 : _a.parseStacktrace(log.origin)) || [] : parseStacktrace(log.origin);
1249
1266
  const highlight = task ? stack.find((i) => i.file === task.file.filepath) : null;
1250
1267
  for (const frame of stack) {
1251
1268
  const color = frame === highlight ? c.cyan : c.gray;
@@ -1292,7 +1309,11 @@ ${log.content}`);
1292
1309
  }
1293
1310
  }
1294
1311
  reportTestSummary(files, errors) {
1295
- const tests = getTests(files);
1312
+ const affectedFiles = [
1313
+ ...this.failedUnwatchedFiles,
1314
+ ...files
1315
+ ];
1316
+ const tests = getTests(affectedFiles);
1296
1317
  const logger = this.ctx.logger;
1297
1318
  const executionTime = this.end - this.start;
1298
1319
  const collectTime = files.reduce(
@@ -1341,7 +1362,7 @@ ${log.content}`);
1341
1362
  logger.log();
1342
1363
  }
1343
1364
  }
1344
- logger.log(padTitle("Test Files"), getStateString(files));
1365
+ logger.log(padTitle("Test Files"), getStateString(affectedFiles));
1345
1366
  logger.log(padTitle("Tests"), getStateString(tests));
1346
1367
  if (this.ctx.projects.some((c2) => c2.config.typecheck.enabled)) {
1347
1368
  const failed = tests.filter(
@@ -1503,8 +1524,20 @@ ${c.cyan(c.inverse(c.bold(" BENCH ")))} ${c.cyan("Summary")}
1503
1524
  )}${name}`
1504
1525
  );
1505
1526
  }
1527
+ const screenshots = tasks2.filter((t) => {
1528
+ var _a2;
1529
+ return (_a2 = t.meta) == null ? void 0 : _a2.failScreenshotPath;
1530
+ }).map((t) => {
1531
+ var _a2;
1532
+ return (_a2 = t.meta) == null ? void 0 : _a2.failScreenshotPath;
1533
+ });
1506
1534
  const project = this.ctx.getProjectByTaskId(tasks2[0].id);
1507
- this.ctx.logger.printError(error, { project, verbose: this.verbose });
1535
+ this.ctx.logger.printError(error, {
1536
+ project,
1537
+ verbose: this.verbose,
1538
+ screenshotPaths: screenshots,
1539
+ task: tasks2[0]
1540
+ });
1508
1541
  errorDivider();
1509
1542
  }
1510
1543
  }
@@ -1516,7 +1549,7 @@ ${c.cyan(c.inverse(c.bold(" BENCH ")))} ${c.cyan("Summary")}
1516
1549
  type: "Unhandled Rejection"
1517
1550
  });
1518
1551
  this.ctx.logger.error("\n\n");
1519
- process.exit(1);
1552
+ process.exit();
1520
1553
  };
1521
1554
  process.on("unhandledRejection", onUnhandledRejection);
1522
1555
  this._offUnhandledRejection = () => {
@@ -1526,7 +1559,10 @@ ${c.cyan(c.inverse(c.bold(" BENCH ")))} ${c.cyan("Summary")}
1526
1559
  }
1527
1560
 
1528
1561
  class BasicReporter extends BaseReporter {
1529
- isTTY = false;
1562
+ constructor() {
1563
+ super();
1564
+ this.isTTY = false;
1565
+ }
1530
1566
  reportSummary(files, errors) {
1531
1567
  this.ctx.logger.log();
1532
1568
  return super.reportSummary(files, errors);
@@ -2680,6 +2716,11 @@ class DefaultReporter extends BaseReporter {
2680
2716
  }
2681
2717
  }
2682
2718
  onFinished(files = this.ctx.state.getFiles(), errors = this.ctx.state.getUnhandledErrors()) {
2719
+ var _a;
2720
+ (_a = this.renderer) == null ? void 0 : _a.update([
2721
+ ...this.failedUnwatchedFiles,
2722
+ ...files
2723
+ ]);
2683
2724
  this.stopListRender();
2684
2725
  this.ctx.logger.log();
2685
2726
  super.onFinished(files, errors);
@@ -3111,8 +3152,8 @@ class TapReporter {
3111
3152
  if (((_b = task.result) == null ? void 0 : _b.state) === "fail" && task.result.errors) {
3112
3153
  this.logger.indent();
3113
3154
  task.result.errors.forEach((error) => {
3114
- const stacks = parseErrorStacktrace(error, {
3115
- getSourceMap: (file) => project.getBrowserSourceMapModuleById(file),
3155
+ var _a2;
3156
+ const stacks = task.file.pool === "browser" ? ((_a2 = project.browser) == null ? void 0 : _a2.parseErrorStacktrace(error)) || [] : parseErrorStacktrace(error, {
3116
3157
  frameFilter: this.ctx.config.onStackTrace
3117
3158
  });
3118
3159
  const stack = stacks[0];
@@ -4453,7 +4494,7 @@ class Logger {
4453
4494
  this.console.log(message);
4454
4495
  return;
4455
4496
  }
4456
- this.console.log(`${ERASE_SCROLLBACK}${CLEAR_SCREEN}${message}`);
4497
+ this.console.log(`${CLEAR_SCREEN}${ERASE_SCROLLBACK}${message}`);
4457
4498
  }
4458
4499
  clearScreen(message, force = false) {
4459
4500
  if (!this.ctx.config.clearScreen) {
@@ -4476,12 +4517,24 @@ class Logger {
4476
4517
  printError(err, options = {}) {
4477
4518
  const { fullStack = false, type } = options;
4478
4519
  const project = options.project ?? this.ctx.getCoreWorkspaceProject() ?? this.ctx.projects[0];
4479
- printError(err, project, {
4480
- fullStack,
4520
+ return printError(err, project, {
4481
4521
  type,
4482
- showCodeFrame: true,
4522
+ showCodeFrame: options.showCodeFrame ?? true,
4483
4523
  logger: this,
4484
- printProperties: options.verbose
4524
+ printProperties: options.verbose,
4525
+ screenshotPaths: options.screenshotPaths,
4526
+ parseErrorStacktrace: (error) => {
4527
+ var _a;
4528
+ if (((_a = options.task) == null ? void 0 : _a.file.pool) === "browser" && project.browser) {
4529
+ return project.browser.parseErrorStacktrace(error, {
4530
+ ignoreStackEntries: fullStack ? [] : void 0
4531
+ });
4532
+ }
4533
+ return parseErrorStacktrace(error, {
4534
+ frameFilter: project.config.onStackTrace,
4535
+ ignoreStackEntries: fullStack ? [] : void 0
4536
+ });
4537
+ }
4485
4538
  });
4486
4539
  }
4487
4540
  clearHighlightCache(filename) {
@@ -4650,7 +4703,7 @@ Vitest found ${errors.length} error${errors.length > 1 ? "s" : ""} not related t
4650
4703
  }
4651
4704
  }
4652
4705
 
4653
- function capturePrintError(error, ctx, project) {
4706
+ function capturePrintError(error, ctx, options) {
4654
4707
  let output = "";
4655
4708
  const writable = new Writable({
4656
4709
  write(chunk, _encoding, callback) {
@@ -4658,14 +4711,16 @@ function capturePrintError(error, ctx, project) {
4658
4711
  callback();
4659
4712
  }
4660
4713
  });
4661
- const result = printError(error, project, {
4714
+ const logger = new Logger(ctx, writable, writable);
4715
+ const result = logger.printError(error, {
4662
4716
  showCodeFrame: false,
4663
- logger: new Logger(ctx, writable, writable)
4717
+ ...options
4664
4718
  });
4665
4719
  return { nearest: result == null ? void 0 : result.nearest, output };
4666
4720
  }
4667
4721
  function printError(error, project, options) {
4668
- const { showCodeFrame = true, fullStack = false, type, printProperties = true } = options;
4722
+ var _a;
4723
+ const { showCodeFrame = true, type, printProperties = true } = options;
4669
4724
  const logger = options.logger;
4670
4725
  let e = error;
4671
4726
  if (isPrimitive(e)) {
@@ -4685,15 +4740,7 @@ function printError(error, project, options) {
4685
4740
  printErrorMessage(e, logger);
4686
4741
  return;
4687
4742
  }
4688
- const parserOptions = {
4689
- // only browser stack traces require remapping
4690
- getSourceMap: (file) => project.getBrowserSourceMapModuleById(file),
4691
- frameFilter: project.config.onStackTrace
4692
- };
4693
- if (fullStack) {
4694
- parserOptions.ignoreStackEntries = [];
4695
- }
4696
- const stacks = parseErrorStacktrace(e, parserOptions);
4743
+ const stacks = options.parseErrorStacktrace(e);
4697
4744
  const nearest = error instanceof TypeCheckError ? error.stacks[0] : stacks.find((stack) => {
4698
4745
  try {
4699
4746
  return project.server && project.getModuleById(stack.file) && existsSync(stack.file);
@@ -4701,11 +4748,19 @@ function printError(error, project, options) {
4701
4748
  return false;
4702
4749
  }
4703
4750
  });
4704
- const errorProperties = printProperties ? getErrorProperties(e) : {};
4705
4751
  if (type) {
4706
4752
  printErrorType(type, project.ctx);
4707
4753
  }
4708
4754
  printErrorMessage(e, logger);
4755
+ if ((_a = options.screenshotPaths) == null ? void 0 : _a.length) {
4756
+ const length = options.screenshotPaths.length;
4757
+ logger.error(`
4758
+ Failure screenshot${length > 1 ? "s" : ""}:`);
4759
+ logger.error(options.screenshotPaths.map((p) => ` - ${c.dim(relative(process.cwd(), p))}`).join("\n"));
4760
+ if (!e.diff) {
4761
+ logger.error();
4762
+ }
4763
+ }
4709
4764
  if (e.codeFrame) {
4710
4765
  logger.error(`${e.codeFrame}
4711
4766
  `);
@@ -4716,6 +4771,7 @@ function printError(error, project, options) {
4716
4771
  if (e.frame) {
4717
4772
  logger.error(c.yellow(e.frame));
4718
4773
  } else {
4774
+ const errorProperties = printProperties ? getErrorProperties(e) : {};
4719
4775
  printStack(logger, project, stacks, nearest, errorProperties, (s) => {
4720
4776
  if (showCodeFrame && s === nearest && nearest) {
4721
4777
  const sourceCode = readFileSync(nearest.file, "utf-8");
@@ -4762,9 +4818,9 @@ function printError(error, project, options) {
4762
4818
  if (typeof e.cause === "object" && e.cause && "name" in e.cause) {
4763
4819
  e.cause.name = `Caused by: ${e.cause.name}`;
4764
4820
  printError(e.cause, project, {
4765
- fullStack,
4766
4821
  showCodeFrame: false,
4767
- logger: options.logger
4822
+ logger: options.logger,
4823
+ parseErrorStacktrace: options.parseErrorStacktrace
4768
4824
  });
4769
4825
  }
4770
4826
  handleImportOutsideModuleError(e.stack || e.stackStr || "", logger);
@@ -5105,7 +5161,7 @@ class JUnitReporter {
5105
5161
  const result = capturePrintError(
5106
5162
  error,
5107
5163
  this.ctx,
5108
- this.ctx.getProjectByTaskId(task.id)
5164
+ { project: this.ctx.getProjectByTaskId(task.id), task }
5109
5165
  );
5110
5166
  await this.baseLog(
5111
5167
  escapeXML(stripAnsi(result.output.trim()))
@@ -5277,13 +5333,14 @@ class GithubActionsReporter {
5277
5333
  projectErrors.push({
5278
5334
  project,
5279
5335
  title,
5280
- error
5336
+ error,
5337
+ file
5281
5338
  });
5282
5339
  }
5283
5340
  }
5284
5341
  }
5285
- for (const { project, title, error } of projectErrors) {
5286
- const result = capturePrintError(error, this.ctx, project);
5342
+ for (const { project, title, error, file } of projectErrors) {
5343
+ const result = capturePrintError(error, this.ctx, { project, task: file });
5287
5344
  const stack = result == null ? void 0 : result.nearest;
5288
5345
  if (!stack) {
5289
5346
  continue;
@@ -4,7 +4,7 @@ import { distDir } from '../path.js';
4
4
  import { g as getWorkerState } from './global.7bFbnyXl.js';
5
5
  import { r as rpc } from './rpc.BGx7q_k2.js';
6
6
  import { t as takeCoverageInsideWorker } from './coverage.BhYSDdTT.js';
7
- import { l as loadDiffConfig, a as loadSnapshotSerializers } from './setup-common.CWnv_2-5.js';
7
+ import { l as loadDiffConfig, a as loadSnapshotSerializers } from './setup-common.yHaxjRhz.js';
8
8
 
9
9
  function setupChaiConfig(config) {
10
10
  Object.assign(chai.config, config);
@@ -13,7 +13,7 @@ async function setupCommonEnv(config) {
13
13
  globalSetup = true;
14
14
  setSafeTimers();
15
15
  if (config.globals) {
16
- (await import('../chunks/integrations-globals.DSNOaUHv.js')).registerApiGlobally();
16
+ (await import('../chunks/integrations-globals.CzYWb38r.js')).registerApiGlobally();
17
17
  }
18
18
  }
19
19
  function setupDefines(defines) {
@@ -37,6 +37,11 @@ const spinnerMap = /* @__PURE__ */ new WeakMap();
37
37
  const hookSpinnerMap = /* @__PURE__ */ new WeakMap();
38
38
  const pointer = c.yellow(F_POINTER);
39
39
  const skipped = c.dim(c.gray(F_DOWN));
40
+ const benchmarkPass = c.green(F_DOT);
41
+ const testPass = c.green(F_CHECK);
42
+ const taskFail = c.red(F_CROSS);
43
+ const suiteFail = c.red(F_POINTER);
44
+ const pending = c.gray("\xB7");
40
45
  function getCols(delta = 0) {
41
46
  var _a;
42
47
  let length = (_a = process.stdout) == null ? void 0 : _a.columns;
@@ -151,7 +156,7 @@ function getStateSymbol(task) {
151
156
  return skipped;
152
157
  }
153
158
  if (!task.result) {
154
- return c.gray("\xB7");
159
+ return pending;
155
160
  }
156
161
  if (task.result.state === "run") {
157
162
  if (task.type === "suite") {
@@ -165,10 +170,10 @@ function getStateSymbol(task) {
165
170
  return c.yellow(spinner());
166
171
  }
167
172
  if (task.result.state === "pass") {
168
- return ((_a = task.meta) == null ? void 0 : _a.benchmark) ? c.green(F_DOT) : c.green(F_CHECK);
173
+ return ((_a = task.meta) == null ? void 0 : _a.benchmark) ? benchmarkPass : testPass;
169
174
  }
170
175
  if (task.result.state === "fail") {
171
- return task.type === "suite" ? pointer : c.red(F_CROSS);
176
+ return task.type === "suite" ? suiteFail : taskFail;
172
177
  }
173
178
  return " ";
174
179
  }
@@ -211,6 +216,7 @@ function formatProjectName(name, suffix = " ") {
211
216
 
212
217
  var utils = /*#__PURE__*/Object.freeze({
213
218
  __proto__: null,
219
+ benchmarkPass: benchmarkPass,
214
220
  countTestErrors: countTestErrors,
215
221
  divider: divider,
216
222
  elegantSpinner: elegantSpinner,
@@ -222,11 +228,15 @@ var utils = /*#__PURE__*/Object.freeze({
222
228
  getStateString: getStateString,
223
229
  getStateSymbol: getStateSymbol,
224
230
  hookSpinnerMap: hookSpinnerMap,
231
+ pending: pending,
225
232
  pointer: pointer,
226
233
  renderSnapshotSummary: renderSnapshotSummary,
227
234
  skipped: skipped,
228
235
  spinnerFrames: spinnerFrames,
229
- spinnerMap: spinnerMap
236
+ spinnerMap: spinnerMap,
237
+ suiteFail: suiteFail,
238
+ taskFail: taskFail,
239
+ testPass: testPass
230
240
  });
231
241
 
232
- export { F_RIGHT as F, F_POINTER as a, getStateString as b, formatTimeString as c, countTestErrors as d, divider as e, formatProjectName as f, getStateSymbol as g, getCols as h, getHookStateSymbol as i, pointer as p, renderSnapshotSummary as r, stripAnsi as s, utils as u };
242
+ export { F_RIGHT as F, F_POINTER as a, getStateString as b, formatTimeString as c, countTestErrors as d, divider as e, formatProjectName as f, getStateSymbol as g, getCols as h, getHookStateSymbol as i, renderSnapshotSummary as r, stripAnsi as s, taskFail as t, utils as u };
@@ -2,10 +2,10 @@ import vm, { isContext } from 'node:vm';
2
2
  import { fileURLToPath, pathToFileURL } from 'node:url';
3
3
  import { dirname, basename, extname, normalize, join, resolve } from 'pathe';
4
4
  import { createCustomConsole } from '../chunks/runtime-console.O41g23Zj.js';
5
- import { g as getDefaultRequestStubs, s as startVitestExecutor } from './execute.T3gg2ZK6.js';
5
+ import { g as getDefaultRequestStubs, s as startVitestExecutor } from './execute.Dx503nGn.js';
6
6
  import { distDir } from '../path.js';
7
7
  import { dirname as dirname$1 } from 'node:path';
8
- import { statSync, existsSync, promises, readFileSync } from 'node:fs';
8
+ import fs from 'node:fs';
9
9
  import { isNodeBuiltin, isPrimitive, toArray, getCachedData, setCacheData } from 'vite-node/utils';
10
10
  import { createRequire, Module } from 'node:module';
11
11
  import { CSS_LANGS_RE, KNOWN_ASSET_RE } from 'vite-node/constants';
@@ -567,6 +567,7 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
567
567
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
568
568
  var _networkSupported;
569
569
  const SyntheticModule = vm.SyntheticModule;
570
+ const { existsSync, statSync } = fs;
570
571
  const nativeResolve = import.meta.resolve;
571
572
  class ExternalModulesExecutor {
572
573
  constructor(options) {
@@ -770,6 +771,7 @@ class ExternalModulesExecutor {
770
771
  }
771
772
  _networkSupported = new WeakMap();
772
773
 
774
+ const { promises, readFileSync } = fs;
773
775
  class FileMap {
774
776
  fsCache = /* @__PURE__ */ new Map();
775
777
  fsBufferCache = /* @__PURE__ */ new Map();
@@ -805,7 +807,7 @@ class FileMap {
805
807
  const entryFile = pathToFileURL(resolve(distDir, "workers/runVmTests.js")).href;
806
808
  const fileMap = new FileMap();
807
809
  const packageCache = /* @__PURE__ */ new Map();
808
- async function runVmTests(state) {
810
+ async function runVmTests(method, state) {
809
811
  var _a;
810
812
  const { environment, ctx, rpc } = state;
811
813
  if (!environment.setupVM) {
@@ -858,7 +860,7 @@ async function runVmTests(state) {
858
860
  entryFile
859
861
  );
860
862
  try {
861
- await run(ctx.files, ctx.config, executor);
863
+ await run(method, ctx.files, ctx.config, executor);
862
864
  } finally {
863
865
  await ((_a = vm.teardown) == null ? void 0 : _a.call(vm));
864
866
  state.environmentTeardownRun = true;
package/dist/worker.js CHANGED
@@ -62,7 +62,7 @@ async function loadEnvironment(ctx, rpc) {
62
62
  if (isChildProcess()) {
63
63
  setProcessTitle(`vitest ${workerId}`);
64
64
  }
65
- async function run(ctx) {
65
+ async function execute(mehtod, ctx) {
66
66
  const prepareStart = performance.now();
67
67
  const inspectorCleanup = setupInspect(ctx);
68
68
  process.env.VITEST_WORKER_ID = String(ctx.workerId);
@@ -107,17 +107,24 @@ async function run(ctx) {
107
107
  rpc,
108
108
  providedContext: ctx.providedContext
109
109
  };
110
- if (!worker.runTests || typeof worker.runTests !== "function") {
110
+ const methodName = mehtod === "collect" ? "collectTests" : "runTests";
111
+ if (!worker[methodName] || typeof worker[methodName] !== "function") {
111
112
  throw new TypeError(
112
113
  `Test worker should expose "runTests" method. Received "${typeof worker.runTests}".`
113
114
  );
114
115
  }
115
- await worker.runTests(state);
116
+ await worker[methodName](state);
116
117
  } finally {
117
118
  await rpcDone().catch(() => {
118
119
  });
119
120
  inspectorCleanup();
120
121
  }
121
122
  }
123
+ function run(ctx) {
124
+ return execute("run", ctx);
125
+ }
126
+ function collect(ctx) {
127
+ return execute("collect", ctx);
128
+ }
122
129
 
123
- export { run };
130
+ export { collect, run };
@@ -1,10 +1,10 @@
1
1
  import v8 from 'node:v8';
2
2
  import { c as createForksRpcOptions, u as unwrapSerializableConfig } from '../vendor/utils.DkxLWvS1.js';
3
- import { r as runBaseTests } from '../vendor/base.Cy97mmVC.js';
3
+ import { r as runBaseTests } from '../vendor/base.CdA1i5tB.js';
4
4
  import '@vitest/utils';
5
5
  import 'vite-node/client';
6
6
  import '../vendor/global.7bFbnyXl.js';
7
- import '../vendor/execute.T3gg2ZK6.js';
7
+ import '../vendor/execute.Dx503nGn.js';
8
8
  import 'node:vm';
9
9
  import 'node:url';
10
10
  import 'node:fs';
@@ -18,15 +18,21 @@ class ForksBaseWorker {
18
18
  getRpcOptions() {
19
19
  return createForksRpcOptions(v8);
20
20
  }
21
- async runTests(state) {
21
+ async executeTests(method, state) {
22
22
  const exit = process.exit;
23
23
  state.ctx.config = unwrapSerializableConfig(state.ctx.config);
24
24
  try {
25
- await runBaseTests(state);
25
+ await runBaseTests(method, state);
26
26
  } finally {
27
27
  process.exit = exit;
28
28
  }
29
29
  }
30
+ runTests(state) {
31
+ return this.executeTests("run", state);
32
+ }
33
+ collectTests(state) {
34
+ return this.executeTests("collect", state);
35
+ }
30
36
  }
31
37
  var forks = new ForksBaseWorker();
32
38