@rstest/core 0.9.2 → 0.9.4

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.
@@ -0,0 +1,127 @@
1
+ import "node:module";
2
+ import { existsSync, readFileSync, readdirSync, rmSync } from "node:fs";
3
+ import { createCoverageProvider } from "./7704.js";
4
+ import "./4411.js";
5
+ import { prettyTime, logger as logger_logger, relative, color as logger_color, join } from "./6830.js";
6
+ const DEFAULT_BLOB_DIR = '.rstest-reports';
7
+ function loadBlobFiles(blobDir) {
8
+ if (!existsSync(blobDir)) throw new Error(`Blob reports directory not found: ${logger_color.cyan(blobDir)}\nRun tests with --reporter=blob first to generate shard reports.`);
9
+ const files = readdirSync(blobDir).filter((f)=>/^blob(-\d+-\d+)?\.json$/.test(f)).sort();
10
+ if (0 === files.length) throw new Error(`No blob report files found in: ${logger_color.cyan(blobDir)}\nRun tests with --reporter=blob first to generate shard reports.`);
11
+ return files.map((file)=>{
12
+ const content = readFileSync(join(blobDir, file), 'utf-8');
13
+ return JSON.parse(content);
14
+ });
15
+ }
16
+ function mergeSnapshots(summaries) {
17
+ const merged = {
18
+ added: 0,
19
+ didUpdate: false,
20
+ failure: false,
21
+ filesAdded: 0,
22
+ filesRemoved: 0,
23
+ filesRemovedList: [],
24
+ filesUnmatched: 0,
25
+ filesUpdated: 0,
26
+ matched: 0,
27
+ total: 0,
28
+ unchecked: 0,
29
+ uncheckedKeysByFile: [],
30
+ unmatched: 0,
31
+ updated: 0
32
+ };
33
+ for (const s of summaries){
34
+ merged.added += s.added;
35
+ merged.filesAdded += s.filesAdded;
36
+ merged.filesRemoved += s.filesRemoved;
37
+ merged.filesRemovedList.push(...s.filesRemovedList);
38
+ merged.filesUnmatched += s.filesUnmatched;
39
+ merged.filesUpdated += s.filesUpdated;
40
+ merged.matched += s.matched;
41
+ merged.total += s.total;
42
+ merged.unchecked += s.unchecked;
43
+ merged.uncheckedKeysByFile.push(...s.uncheckedKeysByFile);
44
+ merged.unmatched += s.unmatched;
45
+ merged.updated += s.updated;
46
+ if (s.didUpdate) merged.didUpdate = true;
47
+ if (s.failure) merged.failure = true;
48
+ }
49
+ return merged;
50
+ }
51
+ function mergeDurations(durations) {
52
+ let totalTime = 0;
53
+ let buildTime = 0;
54
+ let testTime = 0;
55
+ for (const d of durations){
56
+ totalTime += d.totalTime;
57
+ buildTime += d.buildTime;
58
+ testTime += d.testTime;
59
+ }
60
+ return {
61
+ totalTime,
62
+ buildTime,
63
+ testTime
64
+ };
65
+ }
66
+ async function mergeReports(context, options) {
67
+ const { path, cleanup } = options || {};
68
+ const blobDir = path ? join(context.rootPath, path) : join(context.rootPath, DEFAULT_BLOB_DIR);
69
+ const blobs = loadBlobFiles(blobDir);
70
+ const relativeBlobDir = relative(context.rootPath, blobDir) || '.';
71
+ logger_logger.log(`\nMerging ${logger_color.bold(String(blobs.length))} blob ${1 === blobs.length ? 'report' : 'reports'} from ${logger_color.cyan(relativeBlobDir)}\n`);
72
+ const allResults = [];
73
+ const allTestResults = [];
74
+ const allDurations = [];
75
+ const shardDurations = [];
76
+ const allSnapshotSummaries = [];
77
+ const allUnhandledErrors = [];
78
+ for (const blob of blobs){
79
+ allResults.push(...blob.results);
80
+ allTestResults.push(...blob.testResults);
81
+ allDurations.push(blob.duration);
82
+ allSnapshotSummaries.push(blob.snapshotSummary);
83
+ const shardLabel = blob.shard ? `Shard ${blob.shard.index}/${blob.shard.count}` : 'Shard';
84
+ shardDurations.push({
85
+ label: shardLabel,
86
+ duration: blob.duration
87
+ });
88
+ if (blob.unhandledErrors) for (const e of blob.unhandledErrors){
89
+ const error = new Error(e.message);
90
+ error.name = e.name || 'Error';
91
+ error.stack = e.stack;
92
+ allUnhandledErrors.push(error);
93
+ }
94
+ if (blob.consoleLogs) for (const log of blob.consoleLogs)for (const reporter of context.reporters)reporter.onUserConsoleLog?.(log);
95
+ }
96
+ const mergedDuration = mergeDurations(allDurations);
97
+ const mergedSnapshotSummary = mergeSnapshots(allSnapshotSummaries);
98
+ const hasFailure = allResults.some((r)=>'fail' === r.status) || allUnhandledErrors.length > 0;
99
+ if (hasFailure) process.exitCode = 1;
100
+ for (const reporter of context.reporters)await reporter.onTestRunStart?.();
101
+ for (const { label, duration } of shardDurations)logger_logger.log(logger_color.gray(` ${label}: ${prettyTime(duration.totalTime)} (build ${prettyTime(duration.buildTime)}, tests ${prettyTime(duration.testTime)})`));
102
+ if (shardDurations.length > 0) logger_logger.log('');
103
+ for (const result of allResults)for (const reporter of context.reporters)reporter.onTestFileResult?.(result);
104
+ for (const reporter of context.reporters)await reporter.onTestRunEnd?.({
105
+ results: allResults,
106
+ testResults: allTestResults,
107
+ duration: mergedDuration,
108
+ snapshotSummary: mergedSnapshotSummary,
109
+ unhandledErrors: allUnhandledErrors.length ? allUnhandledErrors : void 0,
110
+ getSourcemap: async ()=>null
111
+ });
112
+ const { coverage } = context.normalizedConfig;
113
+ if (coverage.enabled && (!hasFailure || coverage.reportOnFailure)) {
114
+ const coverageProvider = await createCoverageProvider(coverage, context.rootPath);
115
+ if (coverageProvider) {
116
+ const { generateCoverage } = await import("./0~generate.js");
117
+ await generateCoverage(context, allResults, coverageProvider);
118
+ }
119
+ }
120
+ if (cleanup && existsSync(blobDir)) {
121
+ rmSync(blobDir, {
122
+ recursive: true
123
+ });
124
+ logger_logger.log(logger_color.gray(`Cleaned up blob reports directory: ${relativeBlobDir}\n`));
125
+ }
126
+ }
127
+ export { mergeReports };
package/dist/0~restart.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import "node:module";
2
2
  import { __webpack_require__ } from "./rslib-runtime.js";
3
3
  import node_path from "node:path";
4
- import { color, logger as logger_logger, isTTY } from "./6830.js";
4
+ import { color as logger_color, logger as logger_logger, isTTY } from "./6830.js";
5
5
  import { runRest } from "./3145.js";
6
6
  import "./4411.js";
7
7
  const GLOB_REGEX = /[*?{}[\]()!@+|]/;
8
8
  const isGlob = (str)=>GLOB_REGEX.test(str);
9
9
  async function createChokidar(pathOrGlobs, root, options) {
10
- const chokidar = await import("./0~esm.js");
10
+ const chokidar = await import("./0~chokidar.js");
11
11
  const watchFiles = new Set();
12
12
  const globPatterns = pathOrGlobs.filter((pathOrGlob)=>{
13
13
  if (isGlob(pathOrGlob)) return true;
@@ -36,7 +36,7 @@ const beforeRestart = async ({ filePath, root, clear = true })=>{
36
36
  if (clear) clearConsole();
37
37
  if (filePath) {
38
38
  const filename = node_path.relative(root, filePath);
39
- logger_logger.info(`restarting Rstest as ${color.yellow(filename)} changed\n`);
39
+ logger_logger.info(`restarting Rstest as ${logger_color.yellow(filename)} changed\n`);
40
40
  } else logger_logger.info('restarting Rstest...\n');
41
41
  for (const cleaner of cleaners)await cleaner();
42
42
  cleaners = [];
@@ -4,7 +4,7 @@ import { resolveShardedEntries, getTestEntries } from "./4411.js";
4
4
  import { createCoverageProvider } from "./7704.js";
5
5
  import { prepareRsbuild, createPool, createRsbuildServer, runGlobalTeardown, runGlobalSetup } from "./0~8843.js";
6
6
  import { loadBrowserModule } from "./0~browserLoader.js";
7
- import { logger as logger_logger, isTTY, color, clearScreen } from "./6830.js";
7
+ import { logger as logger_logger, isTTY, color as logger_color, clearScreen } from "./6830.js";
8
8
  const isCliShortcutsEnabled = ()=>isTTY('stdin');
9
9
  async function setupCliShortcuts({ closeServer, runAll, updateSnapshot, runFailedTests, runWithTestNamePattern, runWithFileFilters }) {
10
10
  const { createInterface, emitKeypressEvents } = await import("node:readline");
@@ -66,28 +66,28 @@ async function setupCliShortcuts({ closeServer, runAll, updateSnapshot, runFaile
66
66
  const shortcuts = [
67
67
  {
68
68
  key: 'f',
69
- description: `${color.bold('f')} ${color.dim('rerun failed tests')}`,
69
+ description: `${logger_color.bold('f')} ${logger_color.dim('rerun failed tests')}`,
70
70
  action: async ()=>{
71
71
  await runFailedTests();
72
72
  }
73
73
  },
74
74
  {
75
75
  key: 'a',
76
- description: `${color.bold('a')} ${color.dim('rerun all tests')}`,
76
+ description: `${logger_color.bold('a')} ${logger_color.dim('rerun all tests')}`,
77
77
  action: async ()=>{
78
78
  await runAll();
79
79
  }
80
80
  },
81
81
  {
82
82
  key: 'u',
83
- description: `${color.bold('u')} ${color.dim('update snapshot')}`,
83
+ description: `${logger_color.bold('u')} ${logger_color.dim('update snapshot')}`,
84
84
  action: async ()=>{
85
85
  await updateSnapshot();
86
86
  }
87
87
  },
88
88
  {
89
89
  key: 't',
90
- description: `${color.bold('t')} ${color.dim('filter by a test name regex pattern')}`,
90
+ description: `${logger_color.bold('t')} ${logger_color.dim('filter by a test name regex pattern')}`,
91
91
  action: ()=>{
92
92
  clearCurrentInputLine();
93
93
  promptInput('Enter test name pattern (empty to clear): ', async (pattern)=>{
@@ -97,7 +97,7 @@ async function setupCliShortcuts({ closeServer, runAll, updateSnapshot, runFaile
97
97
  },
98
98
  {
99
99
  key: 'p',
100
- description: `${color.bold('p')} ${color.dim('filter by a filename regex pattern')}`,
100
+ description: `${logger_color.bold('p')} ${logger_color.dim('filter by a filename regex pattern')}`,
101
101
  action: ()=>{
102
102
  clearCurrentInputLine();
103
103
  promptInput('Enter file name pattern (empty to clear): ', async (input)=>{
@@ -108,14 +108,14 @@ async function setupCliShortcuts({ closeServer, runAll, updateSnapshot, runFaile
108
108
  },
109
109
  {
110
110
  key: 'c',
111
- description: `${color.bold('c')} ${color.dim('clear screen')}`,
111
+ description: `${logger_color.bold('c')} ${logger_color.dim('clear screen')}`,
112
112
  action: ()=>{
113
113
  clearScreen(true);
114
114
  }
115
115
  },
116
116
  {
117
117
  key: 'q',
118
- description: `${color.bold('q')} ${color.dim('quit process')}`,
118
+ description: `${logger_color.bold('q')} ${logger_color.dim('quit process')}`,
119
119
  action: async ()=>{
120
120
  try {
121
121
  await closeServer();
@@ -139,7 +139,7 @@ async function setupCliShortcuts({ closeServer, runAll, updateSnapshot, runFaile
139
139
  }
140
140
  if ('h' === str) {
141
141
  clearCurrentInputLine();
142
- let message = ` ${color.bold(color.blue('Shortcuts:'))}\n`;
142
+ let message = ` ${logger_color.bold(logger_color.blue('Shortcuts:'))}\n`;
143
143
  for (const shortcut of shortcuts)message += ` ${shortcut.description}\n`;
144
144
  logger_logger.log(message);
145
145
  }
@@ -175,7 +175,7 @@ async function runTests(context) {
175
175
  const shouldUnifyReporter = !isWatchMode && hasBrowserProjects && hasNodeProjects;
176
176
  if (hasBrowserProjects && !hasNodeProjects) {
177
177
  const { coverage } = context.normalizedConfig;
178
- if (coverage.enabled) logger_logger.log(` ${color.gray('Coverage enabled with')} %s\n`, color.yellow(coverage.provider));
178
+ if (coverage.enabled) logger_logger.log(` ${logger_color.gray('Coverage enabled with')} %s\n`, logger_color.yellow(coverage.provider));
179
179
  const browserResult = await runBrowserModeTests(context, browserProjects, {
180
180
  skipOnTestRunEnd: false
181
181
  });
@@ -275,7 +275,7 @@ async function runTests(context) {
275
275
  recommendWorkerCount
276
276
  });
277
277
  const coverageProvider = coverage.enabled ? await createCoverageProvider(coverage, context.rootPath) : null;
278
- if (coverageProvider) logger_logger.log(` ${color.gray('Coverage enabled with')} %s\n`, color.yellow(coverage.provider));
278
+ if (coverageProvider) logger_logger.log(` ${logger_color.gray('Coverage enabled with')} %s\n`, logger_color.yellow(coverage.provider));
279
279
  const run = async ({ fileFilters, mode = 'all', buildStart = Date.now() } = {})=>{
280
280
  for (const reporter of reporters)await reporter.onTestRunStart?.();
281
281
  let testStart;
@@ -292,8 +292,12 @@ async function runTests(context) {
292
292
  if (entries.length && globalSetupEntries.length && !p._globalSetups) {
293
293
  p._globalSetups = true;
294
294
  const files = globalSetupEntries.flatMap((e)=>e.files);
295
- const assetFiles = await getAssetFiles(files);
296
- const sourceMaps = await getSourceMaps(files);
295
+ const assetFilesPromise = getAssetFiles(files);
296
+ const sourceMapsPromise = getSourceMaps(files);
297
+ const [assetFiles, sourceMaps] = await Promise.all([
298
+ assetFilesPromise,
299
+ sourceMapsPromise
300
+ ]);
297
301
  const { success, errors } = await runGlobalSetup({
298
302
  globalSetupEntries,
299
303
  assetFiles,
@@ -312,10 +316,10 @@ async function runTests(context) {
312
316
  currentDeletedEntries.push(...deletedEntries);
313
317
  let finalEntries = entries;
314
318
  if ('on-demand' === mode) {
315
- if (0 === affectedEntries.length) logger_logger.debug(color.yellow(`No test files need re-run in project(${p.environmentName}).`));
316
- else logger_logger.debug(color.yellow(`Test files to re-run in project(${p.environmentName}):\n`) + affectedEntries.map((e)=>e.testPath).join('\n') + '\n');
319
+ if (0 === affectedEntries.length) logger_logger.debug(logger_color.yellow(`No test files need re-run in project(${p.environmentName}).`));
320
+ else logger_logger.debug(logger_color.yellow(`Test files to re-run in project(${p.environmentName}):\n`) + affectedEntries.map((e)=>e.testPath).join('\n') + '\n');
317
321
  finalEntries = affectedEntries;
318
- } else logger_logger.debug(color.yellow(fileFilters?.length ? `Run filtered tests in project(${p.environmentName}).\n` : `Run all tests in project(${p.environmentName}).\n`));
322
+ } else logger_logger.debug(logger_color.yellow(fileFilters?.length ? `Run filtered tests in project(${p.environmentName}).\n` : `Run all tests in project(${p.environmentName}).\n`));
319
323
  currentEntries.push(...finalEntries);
320
324
  const { results, testResults } = await pool.runTests({
321
325
  entries: finalEntries,
@@ -370,25 +374,25 @@ async function runTests(context) {
370
374
  const nodeHasFailure = results.some((r)=>'fail' === r.status) || errors.length;
371
375
  const browserHasFailure = shouldUnifyReporter && browserResult?.hasFailure;
372
376
  if (0 === results.length && !errors.length) {
373
- if ('watch' === command) if ('on-demand' === mode) logger_logger.log(color.yellow('No test files need re-run.'));
374
- else logger_logger.log(color.yellow('No test files found.'));
377
+ if ('watch' === command) if ('on-demand' === mode) logger_logger.log(logger_color.yellow('No test files need re-run.'));
378
+ else logger_logger.log(logger_color.yellow('No test files found.'));
375
379
  else {
376
380
  const code = context.normalizedConfig.passWithNoTests ? 0 : 1;
377
381
  const message = `No test files found, exiting with code ${code}.`;
378
- if (0 === code) logger_logger.log(color.yellow(message));
379
- else logger_logger.error(color.red(message));
382
+ if (0 === code) logger_logger.log(logger_color.yellow(message));
383
+ else logger_logger.error(logger_color.red(message));
380
384
  process.exitCode = code;
381
385
  }
382
386
  if ('all' === mode) {
383
- if (context.fileFilters?.length) logger_logger.log(color.gray('filter: '), context.fileFilters.join(color.gray(', ')));
387
+ if (context.fileFilters?.length) logger_logger.log(logger_color.gray('filter: '), context.fileFilters.join(logger_color.gray(', ')));
384
388
  allProjects.forEach((p)=>{
385
389
  if (allProjects.length > 1) {
386
390
  logger_logger.log('');
387
- logger_logger.log(color.gray('project:'), p.name);
391
+ logger_logger.log(logger_color.gray('project:'), p.name);
388
392
  }
389
- logger_logger.log(color.gray('root:'), p.rootPath);
390
- logger_logger.log(color.gray('include:'), p.normalizedConfig.include.join(color.gray(', ')));
391
- logger_logger.log(color.gray('exclude:'), p.normalizedConfig.exclude.patterns.join(color.gray(', ')));
393
+ logger_logger.log(logger_color.gray('root:'), p.rootPath);
394
+ logger_logger.log(logger_color.gray('include:'), p.normalizedConfig.include.join(logger_color.gray(', ')));
395
+ logger_logger.log(logger_color.gray('exclude:'), p.normalizedConfig.exclude.patterns.join(logger_color.gray(', ')));
392
396
  });
393
397
  }
394
398
  }
@@ -409,7 +413,7 @@ async function runTests(context) {
409
413
  }
410
414
  if (isFailure) {
411
415
  const bail = context.normalizedConfig.bail;
412
- if (bail && context.stateManager.getCountOfFailedTests() >= bail) logger_logger.log(color.yellow(`Test run aborted due to reaching the bail limit of ${bail} failed test(s).`));
416
+ if (bail && context.stateManager.getCountOfFailedTests() >= bail) logger_logger.log(logger_color.yellow(`Test run aborted due to reaching the bail limit of ${bail} failed test(s).`));
413
417
  }
414
418
  } finally{
415
419
  await browserClose?.();
@@ -426,11 +430,11 @@ async function runTests(context) {
426
430
  await pool.close();
427
431
  await closeServer();
428
432
  } catch (error) {
429
- logger_logger.log(color.red(`Error during cleanup: ${error}`));
433
+ logger_logger.log(logger_color.red(`Error during cleanup: ${error}`));
430
434
  }
431
435
  };
432
436
  const handleSignal = async (signal)=>{
433
- logger_logger.log(color.yellow(`\nReceived ${signal}, cleaning up...`));
437
+ logger_logger.log(logger_color.yellow(`\nReceived ${signal}, cleaning up...`));
434
438
  await cleanup();
435
439
  process.exit(getSignalExitCode(signal));
436
440
  };
@@ -438,9 +442,9 @@ async function runTests(context) {
438
442
  process.on('SIGTERM', handleSignal);
439
443
  process.on('SIGTSTP', handleSignal);
440
444
  const afterTestsWatchRun = ()=>{
441
- logger_logger.log(color.green(' Waiting for file changes...'));
442
- if (enableCliShortcuts) if (snapshotManager.summary.unmatched) logger_logger.log(` ${color.dim('press')} ${color.yellow(color.bold('u'))} ${color.dim('to update snapshot')}${color.dim(', press')} ${color.bold('h')} ${color.dim('to show help')}\n`);
443
- else logger_logger.log(` ${color.dim('press')} ${color.bold('h')} ${color.dim('to show help')}${color.dim(', press')} ${color.bold('q')} ${color.dim('to quit')}\n`);
445
+ logger_logger.log(logger_color.green(' Waiting for file changes...'));
446
+ if (enableCliShortcuts) if (snapshotManager.summary.unmatched) logger_logger.log(` ${logger_color.dim('press')} ${logger_color.yellow(logger_color.bold('u'))} ${logger_color.dim('to update snapshot')}${logger_color.dim(', press')} ${logger_color.bold('h')} ${logger_color.dim('to show help')}\n`);
447
+ else logger_logger.log(` ${logger_color.dim('press')} ${logger_color.bold('h')} ${logger_color.dim('to show help')}${logger_color.dim(', press')} ${logger_color.bold('q')} ${logger_color.dim('to quit')}\n`);
444
448
  };
445
449
  const { onBeforeRestart } = await import("./0~restart.js");
446
450
  onBeforeRestart(async ()=>{
@@ -479,20 +483,20 @@ async function runTests(context) {
479
483
  runWithTestNamePattern: async (pattern)=>{
480
484
  clearScreen();
481
485
  context.normalizedConfig.testNamePattern = pattern;
482
- if (pattern) logger_logger.log(`\n${color.dim('Applied testNamePattern:')} ${color.bold(pattern)}\n`);
483
- else logger_logger.log(`\n${color.dim('Cleared testNamePattern filter')}\n`);
486
+ if (pattern) logger_logger.log(`\n${logger_color.dim('Applied testNamePattern:')} ${logger_color.bold(pattern)}\n`);
487
+ else logger_logger.log(`\n${logger_color.dim('Cleared testNamePattern filter')}\n`);
484
488
  snapshotManager.clear();
485
489
  await run();
486
490
  afterTestsWatchRun();
487
491
  },
488
492
  runWithFileFilters: async (filters)=>{
489
493
  clearScreen();
490
- if (filters && filters.length > 0) logger_logger.log(`\n${color.dim('Applied file filters:')} ${color.bold(filters.join(', '))}\n`);
491
- else logger_logger.log(`\n${color.dim('Cleared file filters')}\n`);
494
+ if (filters && filters.length > 0) logger_logger.log(`\n${logger_color.dim('Applied file filters:')} ${logger_color.bold(filters.join(', '))}\n`);
495
+ else logger_logger.log(`\n${logger_color.dim('Cleared file filters')}\n`);
492
496
  snapshotManager.clear();
493
497
  context.fileFilters = filters;
494
498
  const entries = await Promise.all(projects.map(async (p)=>globTestSourceEntries(p.environmentName))).then((entries)=>entries.reduce((acc, entry)=>acc.concat(...Object.values(entry)), []));
495
- if (!entries.length) return void logger_logger.log(filters ? color.yellow(`\nNo matching test files to run with current file filters: ${filters.join(',')}\n`) : color.yellow('\nNo matching test files to run.\n'));
499
+ if (!entries.length) return void logger_logger.log(filters ? logger_color.yellow(`\nNo matching test files to run with current file filters: ${filters.join(',')}\n`) : logger_color.yellow('\nNo matching test files to run.\n'));
496
500
  await run({
497
501
  fileFilters: entries
498
502
  });
@@ -500,7 +504,7 @@ async function runTests(context) {
500
504
  },
501
505
  runFailedTests: async ()=>{
502
506
  const failedTests = context.reporterResults.results.filter((result)=>'fail' === result.status).map((r)=>r.testPath);
503
- if (!failedTests.length) return void logger_logger.log(color.yellow('\nNo failed tests were found that needed to be rerun.'));
507
+ if (!failedTests.length) return void logger_logger.log(logger_color.yellow('\nNo failed tests were found that needed to be rerun.'));
504
508
  clearScreen();
505
509
  snapshotManager.clear();
506
510
  await run({
@@ -510,7 +514,7 @@ async function runTests(context) {
510
514
  afterTestsWatchRun();
511
515
  },
512
516
  updateSnapshot: async ()=>{
513
- if (!snapshotManager.summary.unmatched) return void logger_logger.log(color.yellow('\nNo snapshots were found that needed to be updated.'));
517
+ if (!snapshotManager.summary.unmatched) return void logger_logger.log(logger_color.yellow('\nNo snapshots were found that needed to be updated.'));
514
518
  const failedTests = context.reporterResults.results.filter((result)=>result.snapshotResult?.unmatched).map((r)=>r.testPath);
515
519
  clearScreen();
516
520
  const originalUpdateSnapshot = snapshotManager.options.updateSnapshot;
@@ -538,21 +542,21 @@ async function runTests(context) {
538
542
  await pool.close();
539
543
  await closeServer();
540
544
  } catch (error) {
541
- logger_logger.log(color.red(`Error during cleanup: ${error}`));
545
+ logger_logger.log(logger_color.red(`Error during cleanup: ${error}`));
542
546
  }
543
547
  };
544
548
  const unExpectedExit = (code)=>{
545
- if (isTeardown) logger_logger.log(color.yellow(`Rstest exited unexpectedly with code ${code}, this is likely caused by test environment teardown.`));
549
+ if (isTeardown) logger_logger.log(logger_color.yellow(`Rstest exited unexpectedly with code ${code}, this is likely caused by test environment teardown.`));
546
550
  else {
547
- logger_logger.log(color.red(`Rstest exited unexpectedly with code ${code}, terminating test run.`));
551
+ logger_logger.log(logger_color.red(`Rstest exited unexpectedly with code ${code}, terminating test run.`));
548
552
  runGlobalTeardown().catch((error)=>{
549
- logger_logger.log(color.red(`Error in global teardown: ${error}`));
553
+ logger_logger.log(logger_color.red(`Error in global teardown: ${error}`));
550
554
  });
551
555
  process.exitCode = 1;
552
556
  }
553
557
  };
554
558
  const handleSignal = async (signal)=>{
555
- logger_logger.log(color.yellow(`\nReceived ${signal}, cleaning up...`));
559
+ logger_logger.log(logger_color.yellow(`\nReceived ${signal}, cleaning up...`));
556
560
  await cleanup();
557
561
  process.exit(getSignalExitCode(signal));
558
562
  };
package/dist/1949.js CHANGED
@@ -3,7 +3,7 @@ import "node:module";
3
3
  import * as __rspack_external_node_util_1b29d436 from "node:util";
4
4
  import { __webpack_require__ } from "./rslib-runtime.js";
5
5
  import { isatty } from "node:tty";
6
- import { getRealTimers, TestRegisterError, formatTestError, formatName } from "./7552.js";
6
+ import { parseTemplateTable, getRealTimers, TestRegisterError, formatTestError, formatName, isTemplateStringsArray } from "./7552.js";
7
7
  import { getTaskNameWithPrefix, isObject as helper_isObject, castArray, resolve as pathe_M_eThtNZ_resolve, normalize } from "./6830.js";
8
8
  import { ROOT_SUITE_NAME } from "./4411.js";
9
9
  import { parse } from "./1672.js";
@@ -190,7 +190,7 @@ __webpack_require__.add({
190
190
  }
191
191
  module.exports = valueToString;
192
192
  },
193
- "../../node_modules/.pnpm/@sinonjs+fake-timers@15.1.0/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js" (__unused_rspack_module, exports, __webpack_require__) {
193
+ "../../node_modules/.pnpm/@sinonjs+fake-timers@15.1.1/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js" (__unused_rspack_module, exports, __webpack_require__) {
194
194
  const globalObject = __webpack_require__("../../node_modules/.pnpm/@sinonjs+commons@3.0.1/node_modules/@sinonjs/commons/lib/index.js").global;
195
195
  let timersModule, timersPromisesModule;
196
196
  try {
@@ -15922,16 +15922,24 @@ const createRuntimeAPI = ({ testPath, runtimeConfig, project })=>{
15922
15922
  location: getLocation(),
15923
15923
  runMode: condition ? 'skip' : options.runMode
15924
15924
  });
15925
- testFn.each = (cases)=>runtimeInstance.each({
15925
+ testFn.each = (...args)=>{
15926
+ const location = getLocation();
15927
+ const cases = isTemplateStringsArray(args[0]) ? parseTemplateTable(args[0], ...args.slice(1)) : args[0];
15928
+ return runtimeInstance.each({
15926
15929
  cases,
15927
15930
  ...options,
15928
- location: getLocation()
15931
+ location
15929
15932
  });
15930
- testFn.for = (cases)=>runtimeInstance.for({
15933
+ };
15934
+ testFn.for = (...args)=>{
15935
+ const location = getLocation();
15936
+ const cases = isTemplateStringsArray(args[0]) ? parseTemplateTable(args[0], ...args.slice(1)) : args[0];
15937
+ return runtimeInstance.for({
15931
15938
  cases,
15932
15939
  ...options,
15933
- location: getLocation()
15940
+ location
15934
15941
  });
15942
+ };
15935
15943
  return testFn;
15936
15944
  };
15937
15945
  const it = createTestAPI();
@@ -16001,16 +16009,24 @@ const createRuntimeAPI = ({ testPath, runtimeConfig, project })=>{
16001
16009
  location: getLocation(),
16002
16010
  runMode: condition ? options.runMode : 'skip'
16003
16011
  });
16004
- describeFn.each = (cases)=>runtimeInstance.describeEach({
16012
+ describeFn.each = (...args)=>{
16013
+ const location = getLocation();
16014
+ const cases = isTemplateStringsArray(args[0]) ? parseTemplateTable(args[0], ...args.slice(1)) : args[0];
16015
+ return runtimeInstance.describeEach({
16005
16016
  cases,
16006
16017
  ...options,
16007
- location: getLocation()
16018
+ location
16008
16019
  });
16009
- describeFn.for = (cases)=>runtimeInstance.describeFor({
16020
+ };
16021
+ describeFn.for = (...args)=>{
16022
+ const location = getLocation();
16023
+ const cases = isTemplateStringsArray(args[0]) ? parseTemplateTable(args[0], ...args.slice(1)) : args[0];
16024
+ return runtimeInstance.describeFor({
16010
16025
  cases,
16011
16026
  ...options,
16012
- location: getLocation()
16027
+ location
16013
16028
  });
16029
+ };
16014
16030
  return describeFn;
16015
16031
  };
16016
16032
  const describe = createDescribeAPI();
@@ -16088,7 +16104,7 @@ function toTestInfo(test) {
16088
16104
  runMode: test.runMode
16089
16105
  };
16090
16106
  }
16091
- const fake_timers_src = __webpack_require__("../../node_modules/.pnpm/@sinonjs+fake-timers@15.1.0/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js");
16107
+ const fake_timers_src = __webpack_require__("../../node_modules/.pnpm/@sinonjs+fake-timers@15.1.1/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js");
16092
16108
  const fakeTimers_RealDate = Date;
16093
16109
  class FakeTimers {
16094
16110
  _clock;
package/dist/255.js CHANGED
@@ -2,7 +2,7 @@ import "node:module";
2
2
  import { existsSync } from "node:fs";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { rspack } from "@rsbuild/core";
5
- import { getAbsolutePath, color } from "./6830.js";
5
+ import { getAbsolutePath, color as logger_color } from "./6830.js";
6
6
  import { formatTestEntryName } from "./4411.js";
7
7
  import { posix } from "./7011.js";
8
8
  const tryResolve = (request, rootPath)=>{
@@ -24,8 +24,8 @@ const getSetupFiles = (setups, rootPath)=>{
24
24
  const setupFilePath = getAbsolutePath(rootPath, setupFile);
25
25
  try {
26
26
  if (!existsSync(setupFilePath)) {
27
- let errorMessage = `Setup file ${color.red(setupFile)} not found`;
28
- if (setupFilePath !== setupFile) errorMessage += color.gray(` (resolved path: ${setupFilePath})`);
27
+ let errorMessage = `Setup file ${logger_color.red(setupFile)} not found`;
28
+ if (setupFilePath !== setupFile) errorMessage += logger_color.gray(` (resolved path: ${setupFilePath})`);
29
29
  throw errorMessage;
30
30
  }
31
31
  const relativePath = posix.relative(rootPath, setupFilePath);