vitest 2.0.0-beta.11 → 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 (56) 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.DSqYDthP.js +673 -0
  5. package/dist/chunks/{environments-node.39w4gmlF.js → environments-node.XE5FbRPQ.js} +1 -1
  6. package/dist/chunks/{integrations-globals.CC2ed6Py.js → integrations-globals.CzYWb38r.js} +6 -6
  7. package/dist/chunks/{runtime-console.Ckl0vEQr.js → runtime-console.O41g23Zj.js} +1 -1
  8. package/dist/chunks/{runtime-runBaseTests.BXW_BJeO.js → runtime-runBaseTests.DX3h28Mp.js} +15 -11
  9. package/dist/cli.js +2 -2
  10. package/dist/config.cjs +6 -4
  11. package/dist/config.d.ts +2 -1
  12. package/dist/config.js +6 -4
  13. package/dist/coverage.d.ts +4 -2
  14. package/dist/coverage.js +3 -2
  15. package/dist/environments.d.ts +2 -1
  16. package/dist/execute.d.ts +4 -3
  17. package/dist/execute.js +1 -1
  18. package/dist/index.d.ts +7 -6
  19. package/dist/index.js +6 -6
  20. package/dist/node.d.ts +19 -5
  21. package/dist/node.js +15 -14
  22. package/dist/{reporters-fiIq_dT9.d.ts → reporters-DrywOHjt.d.ts} +73 -23
  23. package/dist/reporters.d.ts +2 -1
  24. package/dist/reporters.js +5 -5
  25. package/dist/runners.d.ts +3 -1
  26. package/dist/runners.js +5 -4
  27. package/dist/snapshot.js +2 -2
  28. package/dist/{suite-D4aoU9rI.d.ts → suite-CrOPuDIk.d.ts} +1 -1
  29. package/dist/suite.d.ts +3 -2
  30. package/dist/suite.js +3 -3
  31. package/dist/vendor/{base.C2DbLEfT.js → base.CdA1i5tB.js} +4 -3
  32. package/dist/vendor/{benchmark.CMp8QfyL.js → benchmark.B6pblCp2.js} +1 -1
  33. package/dist/vendor/{cac.BcJW7n2j.js → cac.CpoEMnGk.js} +71 -14
  34. package/dist/vendor/{cli-api.C8t8m4__.js → cli-api.CXFLjKVN.js} +400 -6675
  35. package/dist/vendor/{constants.BWsVtsAj.js → constants.CsnA4eRy.js} +1 -2
  36. package/dist/vendor/env.2ltrQNq0.js +8 -0
  37. package/dist/vendor/{execute.T3gg2ZK6.js → execute.Dx503nGn.js} +12 -4
  38. package/dist/vendor/{index.BC5zhX9y.js → index.3x3MdmUV.js} +139 -82
  39. package/dist/vendor/{index.C9Thslzw.js → index.BJmtb_7W.js} +1 -1
  40. package/dist/vendor/{index.-dbR4KUi.js → index.CROIsoiT.js} +2 -2
  41. package/dist/vendor/index.D6GZqexG.js +6575 -0
  42. package/dist/vendor/{index.CQJ2m700.js → index.Hqvcg1pf.js} +2 -2
  43. package/dist/vendor/{setup-common.uqZOEWuR.js → setup-common.yHaxjRhz.js} +1 -1
  44. package/dist/vendor/{utils.DSO2UK15.js → utils.BVMrsl6E.js} +15 -5
  45. package/dist/vendor/{vi.BPjl8cAZ.js → vi.DXACdGTu.js} +1 -1
  46. package/dist/vendor/{vm.CycSoHnJ.js → vm.BrDS6p7h.js} +8 -6
  47. package/dist/worker.js +11 -4
  48. package/dist/workers/forks.js +10 -4
  49. package/dist/workers/runVmTests.js +14 -10
  50. package/dist/workers/threads.js +6 -3
  51. package/dist/workers/vmForks.js +12 -6
  52. package/dist/workers/vmThreads.js +8 -5
  53. package/dist/workers.d.ts +7 -4
  54. package/dist/workers.js +6 -6
  55. package/package.json +12 -12
  56. package/dist/vendor/env.bmJgw1qP.js +0 -7
@@ -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 };
@@ -0,0 +1,8 @@
1
+ import 'std-env';
2
+
3
+ var _a, _b;
4
+ const isNode = typeof process < "u" && typeof process.stdout < "u" && !((_a = process.versions) == null ? void 0 : _a.deno) && !globalThis.window;
5
+ const isDeno = typeof process < "u" && typeof process.stdout < "u" && ((_b = process.versions) == null ? void 0 : _b.deno) !== void 0;
6
+ const isWindows = (isNode || isDeno) && process.platform === "win32";
7
+
8
+ export { isDeno as a, isWindows as b, isNode as i };
@@ -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,15 +2,15 @@ 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
- import { i as isNode } from './env.bmJgw1qP.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';
7
+ import { i as isNode, a as isDeno } from './env.2ltrQNq0.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';
12
- import { r as relativePath } from './index.C9Thslzw.js';
13
- import { UNKNOWN_TEST_ID } from '../chunks/runtime-console.Ckl0vEQr.js';
12
+ import { r as relativePath } from './index.BJmtb_7W.js';
13
+ import { UNKNOWN_TEST_ID } from '../chunks/runtime-console.O41g23Zj.js';
14
14
  import { t as toArray, b as isPrimitive } from './base.CTYV4Gnz.js';
15
15
  import { isCI } from 'std-env';
16
16
  import nodeos__default, { hostname } from 'node:os';
@@ -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;
@@ -1057,7 +1062,7 @@ class BaseReporter {
1057
1062
  _offUnhandledRejection;
1058
1063
  constructor(options = {}) {
1059
1064
  var _a;
1060
- this.isTTY = options.isTTY ?? (isNode && ((_a = process.stdout) == null ? void 0 : _a.isTTY) && !isCI);
1065
+ this.isTTY = options.isTTY ?? ((isNode || isDeno) && ((_a = process.stdout) == null ? void 0 : _a.isTTY) && !isCI);
1061
1066
  this.registerUnhandledRejection();
1062
1067
  }
1063
1068
  get mode() {
@@ -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;
@@ -2,7 +2,7 @@ import { relative } from 'pathe';
2
2
  import '@vitest/runner/utils';
3
3
  import '@vitest/utils';
4
4
  import { g as getWorkerState } from './global.7bFbnyXl.js';
5
- import './env.bmJgw1qP.js';
5
+ import './env.2ltrQNq0.js';
6
6
 
7
7
  function getRunMode() {
8
8
  return getWorkerState().config.mode;
@@ -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.uqZOEWuR.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);
@@ -12,7 +12,7 @@ function setupChaiConfig(config) {
12
12
 
13
13
  async function resolveSnapshotEnvironment(config, executor) {
14
14
  if (!config.snapshotEnvironment) {
15
- const { VitestNodeSnapshotEnvironment } = await import('../chunks/environments-node.39w4gmlF.js');
15
+ const { VitestNodeSnapshotEnvironment } = await import('../chunks/environments-node.XE5FbRPQ.js');
16
16
  return new VitestNodeSnapshotEnvironment();
17
17
  }
18
18
  const mod = await executor.executeId(config.snapshotEnvironment);