@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.
- package/LICENSE.md +1 -1
- package/dist/0~8843.js +15 -9
- package/dist/0~browserLoader.js +8 -8
- package/dist/0~browser~1.js +31 -31
- package/dist/0~checkThresholds.js +5 -5
- package/dist/{0~esm.js → 0~chokidar.js} +61 -18
- package/dist/0~console.js +7 -7
- package/dist/0~generate.js +4 -0
- package/dist/0~listTests.js +13 -9
- package/dist/0~loadEsModule.js +3 -1
- package/dist/0~mergeReports.js +127 -0
- package/dist/0~restart.js +3 -3
- package/dist/0~runTests.js +47 -43
- package/dist/1949.js +27 -11
- package/dist/255.js +3 -3
- package/dist/3145.js +203 -106
- package/dist/4411.js +3 -3
- package/dist/6830.js +43 -28
- package/dist/7552.js +82 -65
- package/dist/7704.js +3 -4
- package/dist/browser-runtime/723.js +142 -93
- package/dist/browser-runtime/index.d.ts +40 -5
- package/dist/browser.d.ts +40 -5
- package/dist/globalSetupWorker.js +4 -2
- package/dist/index.d.ts +53 -6
- package/dist/worker.d.ts +30 -3
- package/dist/worker.js +23 -4
- package/package.json +19 -18
- /package/dist/{0~esm.js.LICENSE.txt → 0~chokidar.js.LICENSE.txt} +0 -0
|
@@ -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~
|
|
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 ${
|
|
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 = [];
|
package/dist/0~runTests.js
CHANGED
|
@@ -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: `${
|
|
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: `${
|
|
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: `${
|
|
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: `${
|
|
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: `${
|
|
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: `${
|
|
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: `${
|
|
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 = ` ${
|
|
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(` ${
|
|
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(` ${
|
|
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
|
|
296
|
-
const
|
|
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(
|
|
316
|
-
else logger_logger.debug(
|
|
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(
|
|
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(
|
|
374
|
-
else logger_logger.log(
|
|
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(
|
|
379
|
-
else logger_logger.error(
|
|
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(
|
|
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(
|
|
391
|
+
logger_logger.log(logger_color.gray('project:'), p.name);
|
|
388
392
|
}
|
|
389
|
-
logger_logger.log(
|
|
390
|
-
logger_logger.log(
|
|
391
|
-
logger_logger.log(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
442
|
-
if (enableCliShortcuts) if (snapshotManager.summary.unmatched) logger_logger.log(` ${
|
|
443
|
-
else logger_logger.log(` ${
|
|
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${
|
|
483
|
-
else logger_logger.log(`\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${
|
|
491
|
-
else logger_logger.log(`\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 ?
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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.
|
|
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 = (
|
|
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
|
|
15931
|
+
location
|
|
15929
15932
|
});
|
|
15930
|
-
|
|
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
|
|
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 = (
|
|
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
|
|
16018
|
+
location
|
|
16008
16019
|
});
|
|
16009
|
-
|
|
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
|
|
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.
|
|
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 ${
|
|
28
|
-
if (setupFilePath !== setupFile) errorMessage +=
|
|
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);
|