@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
package/dist/3145.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
import { __webpack_require__ } from "./rslib-runtime.js";
|
|
3
|
-
import node_fs, { existsSync, readFileSync, statSync } from "node:fs";
|
|
3
|
+
import node_fs, { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { loadConfig, mergeRsbuildConfig } from "@rsbuild/core";
|
|
5
5
|
import { stripVTControlCharacters } from "node:util";
|
|
6
6
|
import promises from "node:fs/promises";
|
|
7
7
|
import node_path, { dirname as external_node_path_dirname, resolve as external_node_path_resolve } from "node:path";
|
|
8
8
|
import { createRequire } from "node:module";
|
|
9
9
|
import node_process from "node:process";
|
|
10
|
-
import { basename, isTTY, dirname as pathe_M_eThtNZ_dirname, resolve as pathe_M_eThtNZ_resolve, relative, getAbsolutePath, join, bgColor, formatRootStr, determineAgent, logger as logger_logger, castArray, dist_m, prettyTime, isDebug, color, isAbsolute, getTaskNameWithPrefix, normalize, formatError } from "./6830.js";
|
|
10
|
+
import { basename, isTTY, dirname as pathe_M_eThtNZ_dirname, resolve as pathe_M_eThtNZ_resolve, relative, getAbsolutePath, join, bgColor, formatRootStr, determineAgent, logger as logger_logger, castArray, dist_m, prettyTime, isDebug, color as logger_color, isAbsolute, getTaskNameWithPrefix, normalize, formatError } from "./6830.js";
|
|
11
11
|
import { isDynamicPattern, glob, DEFAULT_CONFIG_NAME, prettyTestPath, globalApis, TEMP_RSTEST_OUTPUT_DIR_GLOB, formatTestPath, filterProjects, DEFAULT_CONFIG_EXTENSIONS, TS_CONFIG_FILE } from "./4411.js";
|
|
12
12
|
import { posix } from "./7011.js";
|
|
13
13
|
import { parse as stack_trace_parser_esm_parse } from "./1672.js";
|
|
@@ -16,12 +16,14 @@ import "./5040.js";
|
|
|
16
16
|
var init_namespaceObject = {};
|
|
17
17
|
__webpack_require__.r(init_namespaceObject);
|
|
18
18
|
__webpack_require__.d(init_namespaceObject, {
|
|
19
|
-
initCli: ()=>init_initCli
|
|
19
|
+
initCli: ()=>init_initCli,
|
|
20
|
+
resolveProjects: ()=>resolveProjects
|
|
20
21
|
});
|
|
21
|
-
var
|
|
22
|
-
__webpack_require__.r(
|
|
23
|
-
__webpack_require__.d(
|
|
24
|
-
createRstest: ()=>core_createRstest
|
|
22
|
+
var core_namespaceObject = {};
|
|
23
|
+
__webpack_require__.r(core_namespaceObject);
|
|
24
|
+
__webpack_require__.d(core_namespaceObject, {
|
|
25
|
+
createRstest: ()=>core_createRstest,
|
|
26
|
+
initCli: ()=>init_initCli
|
|
25
27
|
});
|
|
26
28
|
var error_namespaceObject = {};
|
|
27
29
|
__webpack_require__.r(error_namespaceObject);
|
|
@@ -587,7 +589,7 @@ function prepareCli() {
|
|
|
587
589
|
if (!npm_execpath || npm_execpath.includes('npx-cli.js') || npm_execpath.includes('.bun')) logger_logger.log();
|
|
588
590
|
}
|
|
589
591
|
function showRstest() {
|
|
590
|
-
logger_logger.greet(" Rstest v0.9.
|
|
592
|
+
logger_logger.greet(" Rstest v0.9.4");
|
|
591
593
|
logger_logger.log('');
|
|
592
594
|
}
|
|
593
595
|
const applyCommonOptions = (cli)=>{
|
|
@@ -602,15 +604,26 @@ const handleUnexpectedExit = (rstest, err)=>{
|
|
|
602
604
|
logger_logger.error(formatError(err));
|
|
603
605
|
process.exit(1);
|
|
604
606
|
};
|
|
607
|
+
const resolveCliRuntime = async (options)=>{
|
|
608
|
+
const [{ initCli }, { createRstest }] = await Promise.all([
|
|
609
|
+
Promise.resolve(init_namespaceObject),
|
|
610
|
+
Promise.resolve(core_namespaceObject)
|
|
611
|
+
]);
|
|
612
|
+
const { config, configFilePath, projects } = await initCli(options);
|
|
613
|
+
return {
|
|
614
|
+
config,
|
|
615
|
+
configFilePath,
|
|
616
|
+
projects,
|
|
617
|
+
createRstest
|
|
618
|
+
};
|
|
619
|
+
};
|
|
605
620
|
const runRest = async ({ options, filters, command })=>{
|
|
606
621
|
let rstest;
|
|
607
622
|
const unexpectedlyExitHandler = (err)=>{
|
|
608
623
|
handleUnexpectedExit(rstest, err);
|
|
609
624
|
};
|
|
610
625
|
try {
|
|
611
|
-
const {
|
|
612
|
-
const { config, configFilePath, projects } = await initCli(options);
|
|
613
|
-
const { createRstest } = await Promise.resolve(src_core_namespaceObject);
|
|
626
|
+
const { config, configFilePath, projects, createRstest } = await resolveCliRuntime(options);
|
|
614
627
|
rstest = createRstest({
|
|
615
628
|
config,
|
|
616
629
|
configFilePath,
|
|
@@ -638,7 +651,7 @@ const runRest = async ({ options, filters, command })=>{
|
|
|
638
651
|
function setupCommands() {
|
|
639
652
|
const cli = cac('rstest');
|
|
640
653
|
cli.help();
|
|
641
|
-
cli.version("0.9.
|
|
654
|
+
cli.version("0.9.4");
|
|
642
655
|
applyCommonOptions(cli);
|
|
643
656
|
cli.command('[...filters]', 'run tests').option('-w, --watch', 'Run tests in watch mode').action(async (filters, options)=>{
|
|
644
657
|
if (!determineAgent().isAgent) showRstest();
|
|
@@ -671,10 +684,8 @@ function setupCommands() {
|
|
|
671
684
|
});
|
|
672
685
|
cli.command('list [...filters]', 'lists all test files that Rstest will run').option('--filesOnly', 'only list the test files').option('--json [boolean/path]', 'print tests as JSON or write to a file').option('--includeSuites', 'include suites in output').option('--printLocation', 'print test case location').action(async (filters, options)=>{
|
|
673
686
|
try {
|
|
674
|
-
const {
|
|
675
|
-
const { config, configFilePath, projects } = await initCli(options);
|
|
687
|
+
const { config, configFilePath, projects, createRstest } = await resolveCliRuntime(options);
|
|
676
688
|
if (options.printLocation) config.includeTaskLocation = true;
|
|
677
|
-
const { createRstest } = await Promise.resolve(src_core_namespaceObject);
|
|
678
689
|
const rstest = createRstest({
|
|
679
690
|
config,
|
|
680
691
|
configFilePath,
|
|
@@ -692,6 +703,25 @@ function setupCommands() {
|
|
|
692
703
|
process.exit(1);
|
|
693
704
|
}
|
|
694
705
|
});
|
|
706
|
+
cli.command('merge-reports [path]', 'Merge blob reports from multiple shards into a unified report').option('--cleanup', 'Remove blob reports directory after merging').action(async (path, options)=>{
|
|
707
|
+
if (!determineAgent().isAgent) showRstest();
|
|
708
|
+
try {
|
|
709
|
+
const { config, configFilePath, projects, createRstest } = await resolveCliRuntime(options);
|
|
710
|
+
const rstest = createRstest({
|
|
711
|
+
config,
|
|
712
|
+
configFilePath,
|
|
713
|
+
projects
|
|
714
|
+
}, 'merge-reports', []);
|
|
715
|
+
await rstest.mergeReports({
|
|
716
|
+
path,
|
|
717
|
+
cleanup: options.cleanup
|
|
718
|
+
});
|
|
719
|
+
} catch (err) {
|
|
720
|
+
logger_logger.error('Failed to merge reports.');
|
|
721
|
+
logger_logger.error(formatError(err));
|
|
722
|
+
process.exit(1);
|
|
723
|
+
}
|
|
724
|
+
});
|
|
695
725
|
cli.command('init [project]', 'Initialize rstest configuration').option('--yes', 'Use default options (non-interactive)').action(async (project, options)=>{
|
|
696
726
|
try {
|
|
697
727
|
let selectedProject = project;
|
|
@@ -709,7 +739,7 @@ function setupCommands() {
|
|
|
709
739
|
]
|
|
710
740
|
});
|
|
711
741
|
if (isCancel(selected)) {
|
|
712
|
-
console.log(
|
|
742
|
+
console.log(logger_color.yellow('Operation cancelled.'));
|
|
713
743
|
process.exit(0);
|
|
714
744
|
}
|
|
715
745
|
selectedProject = selected;
|
|
@@ -736,7 +766,7 @@ const resolveConfigPath = (root, customConfig)=>{
|
|
|
736
766
|
if (customConfig) {
|
|
737
767
|
const customConfigPath = isAbsolute(customConfig) ? customConfig : join(root, customConfig);
|
|
738
768
|
if (node_fs.existsSync(customConfigPath)) return customConfigPath;
|
|
739
|
-
throw `Cannot find config file: ${
|
|
769
|
+
throw `Cannot find config file: ${logger_color.dim(customConfigPath)}`;
|
|
740
770
|
}
|
|
741
771
|
const configFilePath = findConfig(join(root, DEFAULT_CONFIG_NAME));
|
|
742
772
|
if (configFilePath) return configFilePath;
|
|
@@ -758,18 +788,29 @@ async function config_loadConfig({ cwd = process.cwd(), path, envMode, configLoa
|
|
|
758
788
|
loader: configLoader
|
|
759
789
|
});
|
|
760
790
|
let config = content;
|
|
761
|
-
|
|
762
|
-
const extendsConfig = 'function' == typeof config.extends ? await config.extends(Object.freeze({
|
|
763
|
-
...config
|
|
764
|
-
})) : config.extends;
|
|
765
|
-
delete extendsConfig.projects;
|
|
766
|
-
config = mergeRstestConfig(extendsConfig, config);
|
|
767
|
-
}
|
|
791
|
+
config = await resolveExtends(config);
|
|
768
792
|
return {
|
|
769
793
|
content: config,
|
|
770
794
|
filePath: configFilePath
|
|
771
795
|
};
|
|
772
796
|
}
|
|
797
|
+
const resolveExtendEntry = async (entry, userConfig)=>{
|
|
798
|
+
const resolved = 'function' == typeof entry ? await entry(userConfig) : entry;
|
|
799
|
+
if ('projects' in resolved) {
|
|
800
|
+
const { projects: _projects, ...rest } = resolved;
|
|
801
|
+
return rest;
|
|
802
|
+
}
|
|
803
|
+
return resolved;
|
|
804
|
+
};
|
|
805
|
+
const resolveExtends = async (config)=>{
|
|
806
|
+
if (!config.extends) return config;
|
|
807
|
+
const userConfig = Object.freeze({
|
|
808
|
+
...config
|
|
809
|
+
});
|
|
810
|
+
const extendsEntries = castArray(config.extends);
|
|
811
|
+
const resolvedExtends = await Promise.all(extendsEntries.map((entry)=>resolveExtendEntry(entry, userConfig)));
|
|
812
|
+
return mergeRstestConfig(...resolvedExtends, config);
|
|
813
|
+
};
|
|
773
814
|
const mergeProjectConfig = (...configs)=>mergeRstestConfig(...configs);
|
|
774
815
|
const mergeRstestConfig = (...configs)=>configs.reduce((result, config)=>{
|
|
775
816
|
const merged = mergeRsbuildConfig(result, {
|
|
@@ -848,7 +889,8 @@ const createDefaultConfig = ()=>({
|
|
|
848
889
|
provider: 'playwright',
|
|
849
890
|
browser: 'chromium',
|
|
850
891
|
headless: dist_m,
|
|
851
|
-
strictPort: false
|
|
892
|
+
strictPort: false,
|
|
893
|
+
providerOptions: {}
|
|
852
894
|
},
|
|
853
895
|
coverage: {
|
|
854
896
|
exclude: [
|
|
@@ -872,7 +914,8 @@ const createDefaultConfig = ()=>({
|
|
|
872
914
|
],
|
|
873
915
|
reportsDirectory: './coverage',
|
|
874
916
|
clean: true,
|
|
875
|
-
reportOnFailure: false
|
|
917
|
+
reportOnFailure: false,
|
|
918
|
+
allowExternal: false
|
|
876
919
|
}
|
|
877
920
|
});
|
|
878
921
|
const withDefaultConfig = (config)=>{
|
|
@@ -895,7 +938,8 @@ const withDefaultConfig = (config)=>{
|
|
|
895
938
|
headless: merged.browser?.headless ?? dist_m,
|
|
896
939
|
port: merged.browser?.port,
|
|
897
940
|
strictPort: merged.browser?.strictPort ?? false,
|
|
898
|
-
viewport: merged.browser?.viewport
|
|
941
|
+
viewport: merged.browser?.viewport,
|
|
942
|
+
providerOptions: merged.browser?.providerOptions ?? {}
|
|
899
943
|
};
|
|
900
944
|
return {
|
|
901
945
|
...merged,
|
|
@@ -947,7 +991,11 @@ function mergeWithCLIOptions(config, options) {
|
|
|
947
991
|
if (void 0 !== options.bail && ('number' == typeof options.bail || 'boolean' == typeof options.bail)) config.bail = Number(options.bail);
|
|
948
992
|
if (void 0 !== options.coverage) {
|
|
949
993
|
config.coverage ??= {};
|
|
950
|
-
config.coverage.enabled = options.coverage;
|
|
994
|
+
if ('boolean' == typeof options.coverage) config.coverage.enabled = options.coverage;
|
|
995
|
+
else {
|
|
996
|
+
if (void 0 !== options.coverage.enabled) config.coverage.enabled = options.coverage.enabled;
|
|
997
|
+
if (void 0 !== options.coverage.allowExternal) config.coverage.allowExternal = options.coverage.allowExternal;
|
|
998
|
+
}
|
|
951
999
|
}
|
|
952
1000
|
if (options.exclude) config.exclude = castArray(options.exclude);
|
|
953
1001
|
if (options.include) config.include = castArray(options.include);
|
|
@@ -1028,29 +1076,23 @@ async function resolveProjects({ config, root, options }) {
|
|
|
1028
1076
|
const getProjects = async (rstestConfig, root)=>{
|
|
1029
1077
|
const projectPaths = [];
|
|
1030
1078
|
const projectPatterns = [];
|
|
1031
|
-
const
|
|
1032
|
-
|
|
1079
|
+
const inlineProjectConfigPromises = [];
|
|
1080
|
+
for (const p of rstestConfig.projects || []){
|
|
1033
1081
|
if ('object' == typeof p) {
|
|
1034
1082
|
const projectRoot = p.root ? formatRootStr(p.root, root) : root;
|
|
1035
|
-
|
|
1083
|
+
inlineProjectConfigPromises.push(resolveExtends({
|
|
1036
1084
|
...p
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
...projectConfig,
|
|
1049
|
-
name: p.name ? p.name : getDefaultProjectName(projectRoot)
|
|
1050
|
-
}, options),
|
|
1051
|
-
configFilePath: void 0
|
|
1052
|
-
});
|
|
1053
|
-
return;
|
|
1085
|
+
}).then((projectConfig)=>({
|
|
1086
|
+
config: mergeWithCLIOptions({
|
|
1087
|
+
root: projectRoot,
|
|
1088
|
+
...projectConfig,
|
|
1089
|
+
name: p.name ? p.name : getDefaultProjectName(projectRoot)
|
|
1090
|
+
}, options),
|
|
1091
|
+
configFilePath: void 0
|
|
1092
|
+
}), (error)=>({
|
|
1093
|
+
error
|
|
1094
|
+
})));
|
|
1095
|
+
continue;
|
|
1054
1096
|
}
|
|
1055
1097
|
const projectStr = formatRootStr(p, root);
|
|
1056
1098
|
if (isDynamicPattern(projectStr)) projectPatterns.push(projectStr);
|
|
@@ -1059,8 +1101,16 @@ async function resolveProjects({ config, root, options }) {
|
|
|
1059
1101
|
if (!existsSync(absolutePath)) throw `Can't resolve project "${p}", please make sure "${p}" is a existing file or a directory.`;
|
|
1060
1102
|
projectPaths.push(absolutePath);
|
|
1061
1103
|
}
|
|
1062
|
-
}
|
|
1063
|
-
|
|
1104
|
+
}
|
|
1105
|
+
const [inlineProjectConfigResults, globbedProjectPaths] = await Promise.all([
|
|
1106
|
+
Promise.all(inlineProjectConfigPromises),
|
|
1107
|
+
globProjects(projectPatterns, root)
|
|
1108
|
+
]);
|
|
1109
|
+
const projectConfigs = inlineProjectConfigResults.map((result)=>{
|
|
1110
|
+
if ('error' in result) throw result.error;
|
|
1111
|
+
return result;
|
|
1112
|
+
});
|
|
1113
|
+
projectPaths.push(...globbedProjectPaths);
|
|
1064
1114
|
const projects = [];
|
|
1065
1115
|
await Promise.all(projectPaths.map(async (project)=>{
|
|
1066
1116
|
const isDirectory = statSync(project).isDirectory();
|
|
@@ -1088,8 +1138,8 @@ async function resolveProjects({ config, root, options }) {
|
|
|
1088
1138
|
const projects = await getProjects(config, root).then((p)=>filterProjects(p, options));
|
|
1089
1139
|
if (!projects.length) {
|
|
1090
1140
|
let errorMsg = `No projects found, please make sure you have at least one valid project.
|
|
1091
|
-
${
|
|
1092
|
-
if (options.project) errorMsg += `\n${
|
|
1141
|
+
${logger_color.gray('projects:')} ${JSON.stringify(config.projects, null, 2)}`;
|
|
1142
|
+
if (options.project) errorMsg += `\n${logger_color.gray('projectName filter:')} ${JSON.stringify(options.project, null, 2)}`;
|
|
1093
1143
|
throw errorMsg;
|
|
1094
1144
|
}
|
|
1095
1145
|
const names = new Set();
|
|
@@ -1195,53 +1245,53 @@ function addSnapshotResult(summary, result) {
|
|
|
1195
1245
|
summary.total += result.added + result.matched + result.unmatched + result.updated;
|
|
1196
1246
|
}
|
|
1197
1247
|
const getSummaryStatusString = (tasks, name = 'tests', showTotal = true)=>{
|
|
1198
|
-
if (0 === tasks.length) return
|
|
1248
|
+
if (0 === tasks.length) return logger_color.dim(`no ${name}`);
|
|
1199
1249
|
const passed = tasks.filter((result)=>'pass' === result.status);
|
|
1200
1250
|
const failed = tasks.filter((result)=>'fail' === result.status);
|
|
1201
1251
|
const skipped = tasks.filter((result)=>'skip' === result.status);
|
|
1202
1252
|
const todo = tasks.filter((result)=>'todo' === result.status);
|
|
1203
1253
|
const status = [
|
|
1204
|
-
failed.length ?
|
|
1205
|
-
passed.length ?
|
|
1206
|
-
skipped.length ?
|
|
1207
|
-
todo.length ?
|
|
1254
|
+
failed.length ? logger_color.bold(logger_color.red(`${failed.length} failed`)) : null,
|
|
1255
|
+
passed.length ? logger_color.bold(logger_color.green(`${passed.length} passed`)) : null,
|
|
1256
|
+
skipped.length ? logger_color.yellow(`${skipped.length} skipped`) : null,
|
|
1257
|
+
todo.length ? logger_color.gray(`${todo.length} todo`) : null
|
|
1208
1258
|
].filter(Boolean);
|
|
1209
|
-
return status.join(
|
|
1259
|
+
return status.join(logger_color.dim(' | ')) + (showTotal && status.length > 1 ? logger_color.gray(` (${tasks.length})`) : '');
|
|
1210
1260
|
};
|
|
1211
1261
|
const printSnapshotSummaryLog = (snapshots, rootDir)=>{
|
|
1212
1262
|
const summary = [];
|
|
1213
|
-
if (snapshots.added) summary.push(
|
|
1214
|
-
if (snapshots.unmatched) summary.push(
|
|
1215
|
-
if (snapshots.updated) summary.push(
|
|
1216
|
-
if (snapshots.filesRemoved) if (snapshots.didUpdate) summary.push(
|
|
1217
|
-
else summary.push(
|
|
1263
|
+
if (snapshots.added) summary.push(logger_color.bold(logger_color.green(`${snapshots.added} written`)));
|
|
1264
|
+
if (snapshots.unmatched) summary.push(logger_color.bold(logger_color.red(`${snapshots.unmatched} failed`)));
|
|
1265
|
+
if (snapshots.updated) summary.push(logger_color.bold(logger_color.green(`${snapshots.updated} updated `)));
|
|
1266
|
+
if (snapshots.filesRemoved) if (snapshots.didUpdate) summary.push(logger_color.bold(logger_color.green(`${snapshots.filesRemoved} files removed `)));
|
|
1267
|
+
else summary.push(logger_color.bold(logger_color.yellow(`${snapshots.filesRemoved} files obsolete `)));
|
|
1218
1268
|
if (snapshots.filesRemovedList?.length) {
|
|
1219
1269
|
const [head, ...tail] = snapshots.filesRemovedList;
|
|
1220
|
-
summary.push(`${
|
|
1270
|
+
summary.push(`${logger_color.gray("➜")} ${formatTestPath(rootDir, head)}`);
|
|
1221
1271
|
for (const key of tail)summary.push(` ${formatTestPath(rootDir, key)}`);
|
|
1222
1272
|
}
|
|
1223
1273
|
if (snapshots.unchecked) {
|
|
1224
|
-
if (snapshots.didUpdate) summary.push(
|
|
1225
|
-
else summary.push(
|
|
1274
|
+
if (snapshots.didUpdate) summary.push(logger_color.bold(logger_color.green(`${snapshots.unchecked} removed`)));
|
|
1275
|
+
else summary.push(logger_color.bold(logger_color.yellow(`${snapshots.unchecked} obsolete`)));
|
|
1226
1276
|
for (const uncheckedFile of snapshots.uncheckedKeysByFile){
|
|
1227
|
-
summary.push(`${
|
|
1277
|
+
summary.push(`${logger_color.gray("➜")} ${formatTestPath(rootDir, uncheckedFile.filePath)}`);
|
|
1228
1278
|
for (const key of uncheckedFile.keys)summary.push(` ${key}`);
|
|
1229
1279
|
}
|
|
1230
1280
|
}
|
|
1231
1281
|
for (const [index, snapshot] of summary.entries()){
|
|
1232
1282
|
const title = 0 === index ? 'Snapshots' : '';
|
|
1233
|
-
logger_logger.log(`${
|
|
1283
|
+
logger_logger.log(`${logger_color.gray(title.padStart(12))} ${snapshot}`);
|
|
1234
1284
|
}
|
|
1235
1285
|
};
|
|
1236
|
-
const TestFileSummaryLabel =
|
|
1237
|
-
const TestSummaryLabel =
|
|
1238
|
-
const DurationLabel =
|
|
1286
|
+
const TestFileSummaryLabel = logger_color.gray('Test Files'.padStart(11));
|
|
1287
|
+
const TestSummaryLabel = logger_color.gray('Tests'.padStart(11));
|
|
1288
|
+
const DurationLabel = logger_color.gray('Duration'.padStart(11));
|
|
1239
1289
|
const printSummaryLog = ({ results, testResults, snapshotSummary, duration, rootPath })=>{
|
|
1240
1290
|
logger_logger.log('');
|
|
1241
1291
|
printSnapshotSummaryLog(snapshotSummary, rootPath);
|
|
1242
1292
|
logger_logger.log(`${TestFileSummaryLabel} ${getSummaryStatusString(results)}`);
|
|
1243
1293
|
logger_logger.log(`${TestSummaryLabel} ${getSummaryStatusString(testResults)}`);
|
|
1244
|
-
logger_logger.log(`${DurationLabel} ${prettyTime(duration.totalTime)} ${
|
|
1294
|
+
logger_logger.log(`${DurationLabel} ${prettyTime(duration.totalTime)} ${logger_color.gray(`(build ${prettyTime(duration.buildTime)}, tests ${prettyTime(duration.testTime)})`)}`);
|
|
1245
1295
|
logger_logger.log('');
|
|
1246
1296
|
};
|
|
1247
1297
|
const printSummaryErrorLogs = async ({ testResults, results, rootPath, unhandledErrors, getSourcemap, filterRerunTestPaths })=>{
|
|
@@ -1251,7 +1301,7 @@ const printSummaryErrorLogs = async ({ testResults, results, rootPath, unhandled
|
|
|
1251
1301
|
];
|
|
1252
1302
|
if (0 === failedTests.length && !unhandledErrors?.length) return;
|
|
1253
1303
|
logger_logger.stderr('');
|
|
1254
|
-
logger_logger.stderr(
|
|
1304
|
+
logger_logger.stderr(logger_color.bold('Summary of all failing tests:'));
|
|
1255
1305
|
logger_logger.stderr('');
|
|
1256
1306
|
const { printError } = await Promise.resolve(error_namespaceObject);
|
|
1257
1307
|
for (const error of unhandledErrors || []){
|
|
@@ -1261,7 +1311,7 @@ const printSummaryErrorLogs = async ({ testResults, results, rootPath, unhandled
|
|
|
1261
1311
|
for (const test of failedTests){
|
|
1262
1312
|
const relativePath = posix.relative(rootPath, test.testPath);
|
|
1263
1313
|
const nameStr = getTaskNameWithPrefix(test);
|
|
1264
|
-
logger_logger.stderr(`${bgColor('bgRed', ' FAIL ')} ${prettyTestPath(relativePath)} ${nameStr.length ? `${
|
|
1314
|
+
logger_logger.stderr(`${bgColor('bgRed', ' FAIL ')} ${prettyTestPath(relativePath)} ${nameStr.length ? `${logger_color.dim(">")} ${nameStr}` : ''}`);
|
|
1265
1315
|
if (test.errors) {
|
|
1266
1316
|
const { printError } = await Promise.resolve(error_namespaceObject);
|
|
1267
1317
|
for (const error of test.errors)await printError(error, getSourcemap, rootPath);
|
|
@@ -1418,14 +1468,14 @@ class StatusRenderer {
|
|
|
1418
1468
|
const relativePath = relative(this.rootPath, module);
|
|
1419
1469
|
summary.push(`${bgColor('bgYellow', ' RUNS ')} ${prettyTestPath(relativePath)}`);
|
|
1420
1470
|
if (runningTests.length && shouldDisplayRunningTests(runningTests)) {
|
|
1421
|
-
let caseLog = ` ${
|
|
1422
|
-
if (runningTests.length > 1) caseLog +=
|
|
1471
|
+
let caseLog = ` ${logger_color.gray("➜")} ${getTaskNameWithPrefix(runningTests[0])} ${logger_color.magenta(prettyTime(now - runningTests[0].startTime))}`;
|
|
1472
|
+
if (runningTests.length > 1) caseLog += logger_color.gray(` and ${runningTests.length - 1} more cases`);
|
|
1423
1473
|
summary.push(caseLog);
|
|
1424
1474
|
}
|
|
1425
1475
|
}
|
|
1426
1476
|
summary.push('');
|
|
1427
1477
|
if (0 === testModules.length) summary.push(`${TestFileSummaryLabel} ${runningModules.size} total`);
|
|
1428
|
-
else summary.push(`${TestFileSummaryLabel} ${getSummaryStatusString(testModules, '', false)} ${
|
|
1478
|
+
else summary.push(`${TestFileSummaryLabel} ${getSummaryStatusString(testModules, '', false)} ${logger_color.dim('|')} ${runningModules.size + testModules.length} total`);
|
|
1429
1479
|
const testResults = Array.from(runningModules.values()).flatMap(({ results })=>results).concat(testModules.flatMap((mod)=>mod.results));
|
|
1430
1480
|
if (testResults.length) summary.push(`${TestSummaryLabel} ${getSummaryStatusString(testResults, '', false)}`);
|
|
1431
1481
|
summary.push(`${DurationLabel} ${prettyTime(Date.now() - this.startTime)}`);
|
|
@@ -1453,10 +1503,10 @@ const statusStr = {
|
|
|
1453
1503
|
skip: '-'
|
|
1454
1504
|
};
|
|
1455
1505
|
const statusColor = {
|
|
1456
|
-
fail:
|
|
1457
|
-
pass:
|
|
1458
|
-
todo:
|
|
1459
|
-
skip:
|
|
1506
|
+
fail: logger_color.red,
|
|
1507
|
+
pass: logger_color.green,
|
|
1508
|
+
todo: logger_color.gray,
|
|
1509
|
+
skip: logger_color.gray
|
|
1460
1510
|
};
|
|
1461
1511
|
const statusColorfulStr = {
|
|
1462
1512
|
fail: statusColor.fail(statusStr.fail),
|
|
@@ -1467,23 +1517,23 @@ const statusColorfulStr = {
|
|
|
1467
1517
|
const logCase = (result, options)=>{
|
|
1468
1518
|
const isSlowCase = (result.duration || 0) > options.slowTestThreshold;
|
|
1469
1519
|
if (options.hideSkippedTests && 'skip' === result.status) return;
|
|
1470
|
-
const icon = isSlowCase && 'pass' === result.status ?
|
|
1520
|
+
const icon = isSlowCase && 'pass' === result.status ? logger_color.yellow(statusStr[result.status]) : statusColorfulStr[result.status];
|
|
1471
1521
|
const nameStr = getTaskNameWithPrefix(result);
|
|
1472
1522
|
const duration = void 0 !== result.duration ? ` (${prettyTime(result.duration)})` : '';
|
|
1473
|
-
const retry = result.retryCount ?
|
|
1474
|
-
const heap = result.heap ? ` ${
|
|
1475
|
-
logger_logger.log(` ${icon} ${nameStr}${
|
|
1476
|
-
if (result.errors) for (const error of result.errors)logger_logger.log(
|
|
1523
|
+
const retry = result.retryCount ? logger_color.yellow(` (retry x${result.retryCount})`) : '';
|
|
1524
|
+
const heap = result.heap ? ` ${logger_color.magenta(formatHeapUsed(result.heap))}` : '';
|
|
1525
|
+
logger_logger.log(` ${icon} ${nameStr}${logger_color.gray(duration)}${retry}${heap}`);
|
|
1526
|
+
if (result.errors) for (const error of result.errors)logger_logger.log(logger_color.red(` ${error.message}`));
|
|
1477
1527
|
};
|
|
1478
1528
|
const formatHeapUsed = (heap)=>`${Math.floor(heap / 1024 / 1024)} MB heap used`;
|
|
1479
1529
|
const logFileTitle = (test, relativePath, alwaysShowTime = false, showProjectName = false)=>{
|
|
1480
|
-
let title = ` ${
|
|
1530
|
+
let title = ` ${logger_color.bold(statusColorfulStr[test.status])}`;
|
|
1481
1531
|
if (showProjectName && test.project) title += ` ${statusColor[test.status](`[${test.project}]`)}`;
|
|
1482
1532
|
title += ` ${prettyTestPath(relativePath)}`;
|
|
1483
|
-
const formatDuration = (duration)=>
|
|
1484
|
-
title += ` ${
|
|
1533
|
+
const formatDuration = (duration)=>logger_color.green(prettyTime(duration));
|
|
1534
|
+
title += ` ${logger_color.gray(`(${test.results.length})`)}`;
|
|
1485
1535
|
if (alwaysShowTime) title += ` ${formatDuration(test.duration)}`;
|
|
1486
|
-
if (test.heap) title += ` ${
|
|
1536
|
+
if (test.heap) title += ` ${logger_color.magenta(formatHeapUsed(test.heap))}`;
|
|
1487
1537
|
logger_logger.log(title);
|
|
1488
1538
|
};
|
|
1489
1539
|
class DefaultReporter {
|
|
@@ -1538,7 +1588,7 @@ class DefaultReporter {
|
|
|
1538
1588
|
} else titles.push(testPath);
|
|
1539
1589
|
const logOutput = 'stdout' === log.type ? logger_logger.log : logger_logger.stderr;
|
|
1540
1590
|
logOutput('');
|
|
1541
|
-
logOutput(`${log.name}${
|
|
1591
|
+
logOutput(`${log.name}${logger_color.gray(logger_color.dim(` | ${titles.join(logger_color.gray(logger_color.dim(' | ')))}`))}`);
|
|
1542
1592
|
logOutput(log.content);
|
|
1543
1593
|
logOutput('');
|
|
1544
1594
|
}
|
|
@@ -1565,6 +1615,44 @@ class DefaultReporter {
|
|
|
1565
1615
|
});
|
|
1566
1616
|
}
|
|
1567
1617
|
}
|
|
1618
|
+
const DEFAULT_OUTPUT_DIR = '.rstest-reports';
|
|
1619
|
+
class BlobReporter {
|
|
1620
|
+
config;
|
|
1621
|
+
outputDir;
|
|
1622
|
+
consoleLogs = [];
|
|
1623
|
+
constructor({ rootPath, config, options }){
|
|
1624
|
+
this.config = config;
|
|
1625
|
+
this.outputDir = options?.outputDir ? join(rootPath, options.outputDir) : join(rootPath, DEFAULT_OUTPUT_DIR);
|
|
1626
|
+
}
|
|
1627
|
+
onUserConsoleLog(log) {
|
|
1628
|
+
this.consoleLogs.push(log);
|
|
1629
|
+
}
|
|
1630
|
+
async onTestRunEnd({ results, testResults, duration, snapshotSummary, unhandledErrors }) {
|
|
1631
|
+
const shard = this.config.shard;
|
|
1632
|
+
const fileName = shard ? `blob-${shard.index}-${shard.count}.json` : 'blob.json';
|
|
1633
|
+
const blobData = {
|
|
1634
|
+
version: "0.9.4",
|
|
1635
|
+
shard: shard ? {
|
|
1636
|
+
index: shard.index,
|
|
1637
|
+
count: shard.count
|
|
1638
|
+
} : void 0,
|
|
1639
|
+
results,
|
|
1640
|
+
testResults,
|
|
1641
|
+
duration,
|
|
1642
|
+
snapshotSummary,
|
|
1643
|
+
unhandledErrors: unhandledErrors?.map((e)=>({
|
|
1644
|
+
message: e.message,
|
|
1645
|
+
stack: e.stack,
|
|
1646
|
+
name: e.name
|
|
1647
|
+
})),
|
|
1648
|
+
consoleLogs: this.consoleLogs.length > 0 ? this.consoleLogs : void 0
|
|
1649
|
+
};
|
|
1650
|
+
mkdirSync(this.outputDir, {
|
|
1651
|
+
recursive: true
|
|
1652
|
+
});
|
|
1653
|
+
writeFileSync(join(this.outputDir, fileName), JSON.stringify(blobData), 'utf-8');
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1568
1656
|
class GithubActionsReporter {
|
|
1569
1657
|
onWritePath;
|
|
1570
1658
|
rootPath;
|
|
@@ -1619,15 +1707,15 @@ function escapeData(s) {
|
|
|
1619
1707
|
}
|
|
1620
1708
|
function ansiRegex({ onlyFirst = false } = {}) {
|
|
1621
1709
|
const ST = '(?:\\u0007|\\u001B\\u005C|\\u009C)';
|
|
1622
|
-
const
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
].join('|');
|
|
1710
|
+
const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`;
|
|
1711
|
+
const csi = '[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]';
|
|
1712
|
+
const pattern = `${osc}|${csi}`;
|
|
1626
1713
|
return new RegExp(pattern, onlyFirst ? void 0 : 'g');
|
|
1627
1714
|
}
|
|
1628
1715
|
const regex = ansiRegex();
|
|
1629
1716
|
function stripAnsi(string) {
|
|
1630
1717
|
if ('string' != typeof string) throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
|
|
1718
|
+
if (!string.includes('\u001B') && !string.includes('\u009B')) return string;
|
|
1631
1719
|
return string.replace(regex, '');
|
|
1632
1720
|
}
|
|
1633
1721
|
const schemeRegex = /^[\w+.-]+:\/\//;
|
|
@@ -1941,7 +2029,7 @@ const hintNotDefinedError = (message)=>{
|
|
|
1941
2029
|
'jest',
|
|
1942
2030
|
'vitest'
|
|
1943
2031
|
].includes(varName)) return message.replace(`${varName} is not defined`, `${varName} is not defined. Did you mean rstest?`);
|
|
1944
|
-
if ('React' === varName) return message.replace(`${varName} is not defined`, `${varName} is not defined. Did you forget to install "${
|
|
2032
|
+
if ('React' === varName) return message.replace(`${varName} is not defined`, `${varName} is not defined. Did you forget to install "${logger_color.yellow('@rsbuild/plugin-react')}" plugin?`);
|
|
1945
2033
|
}
|
|
1946
2034
|
return message;
|
|
1947
2035
|
};
|
|
@@ -1951,14 +2039,14 @@ async function error_printError(error, getSourcemap, rootPath) {
|
|
|
1951
2039
|
const tips = [
|
|
1952
2040
|
'Error: not support import `vitest` in Rstest test environment.\n',
|
|
1953
2041
|
'Solution:',
|
|
1954
|
-
` - Update your code to use imports from "${
|
|
2042
|
+
` - Update your code to use imports from "${logger_color.yellow('@rstest/core')}" instead of "${logger_color.yellow('vitest')}".`,
|
|
1955
2043
|
' - Enable `globals` configuration and use global API.'
|
|
1956
2044
|
];
|
|
1957
|
-
logger_logger.stderr(`${
|
|
2045
|
+
logger_logger.stderr(`${logger_color.red(tips.join('\n'))}\n`);
|
|
1958
2046
|
return;
|
|
1959
2047
|
}
|
|
1960
2048
|
if (error.message.includes('is not defined')) error.message = hintNotDefinedError(error.message);
|
|
1961
|
-
logger_logger.stderr(`${
|
|
2049
|
+
logger_logger.stderr(`${logger_color.red(logger_color.bold(errorName))}${logger_color.red(`: ${error.message}`)}\n`);
|
|
1962
2050
|
if (error.diff) {
|
|
1963
2051
|
logger_logger.stderr(error.diff);
|
|
1964
2052
|
logger_logger.stderr('');
|
|
@@ -1969,7 +2057,7 @@ async function error_printError(error, getSourcemap, rootPath) {
|
|
|
1969
2057
|
fullStack: error.fullStack,
|
|
1970
2058
|
getSourcemap
|
|
1971
2059
|
});
|
|
1972
|
-
if (!stackFrames.length && !(error.fullStack || isDebug()) && !error.stack.endsWith(error.message)) logger_logger.stderr(
|
|
2060
|
+
if (!stackFrames.length && !(error.fullStack || isDebug()) && !error.stack.endsWith(error.message)) logger_logger.stderr(logger_color.gray("No error stack found, set 'DEBUG=rstest' to show fullStack."));
|
|
1973
2061
|
if (stackFrames[0]) await printCodeFrame(stackFrames[0]);
|
|
1974
2062
|
printStack(stackFrames, rootPath);
|
|
1975
2063
|
}
|
|
@@ -1996,7 +2084,7 @@ function formatStack(frame, rootPath) {
|
|
|
1996
2084
|
return '<unknown>' !== frame.methodName ? `at ${frame.methodName} (${formatTestPath(rootPath, frame.file)}:${frame.lineNumber}:${frame.column})` : `at ${formatTestPath(rootPath, frame.file)}:${frame.lineNumber}:${frame.column}`;
|
|
1997
2085
|
}
|
|
1998
2086
|
function printStack(stackFrames, rootPath) {
|
|
1999
|
-
for (const frame of stackFrames)logger_logger.stderr(
|
|
2087
|
+
for (const frame of stackFrames)logger_logger.stderr(logger_color.gray(` ${formatStack(frame, rootPath)}`));
|
|
2000
2088
|
stackFrames.length && logger_logger.stderr('');
|
|
2001
2089
|
}
|
|
2002
2090
|
const stackIgnores = [
|
|
@@ -3201,7 +3289,7 @@ class MdReporter {
|
|
|
3201
3289
|
}
|
|
3202
3290
|
renderFrontMatter(lines) {
|
|
3203
3291
|
const frontMatter = {
|
|
3204
|
-
tool: "@rstest/core@0.9.
|
|
3292
|
+
tool: "@rstest/core@0.9.4",
|
|
3205
3293
|
timestamp: new Date().toISOString()
|
|
3206
3294
|
};
|
|
3207
3295
|
if (this.options.header.env) frontMatter.runtime = {
|
|
@@ -3575,7 +3663,7 @@ class Rstest {
|
|
|
3575
3663
|
updateSnapshot: rstestConfig.update ? 'all' : dist_m ? 'none' : 'new'
|
|
3576
3664
|
});
|
|
3577
3665
|
this.snapshotManager = snapshotManager;
|
|
3578
|
-
this.version = "0.9.
|
|
3666
|
+
this.version = "0.9.4";
|
|
3579
3667
|
this.rootPath = rootPath;
|
|
3580
3668
|
this.originalConfig = userConfig;
|
|
3581
3669
|
this.normalizedConfig = rstestConfig;
|
|
@@ -3628,6 +3716,9 @@ class Rstest {
|
|
|
3628
3716
|
options: {
|
|
3629
3717
|
showProjectName: projects.length > 1
|
|
3630
3718
|
}
|
|
3719
|
+
}).filter((r)=>{
|
|
3720
|
+
if ('merge-reports' === command && r instanceof BlobReporter) return false;
|
|
3721
|
+
return true;
|
|
3631
3722
|
}) : [];
|
|
3632
3723
|
this.reporters = reporters;
|
|
3633
3724
|
}
|
|
@@ -3652,7 +3743,8 @@ const reportersMap = {
|
|
|
3652
3743
|
verbose: VerboseReporter,
|
|
3653
3744
|
'github-actions': GithubActionsReporter,
|
|
3654
3745
|
junit: JUnitReporter,
|
|
3655
|
-
md: MdReporter
|
|
3746
|
+
md: MdReporter,
|
|
3747
|
+
blob: BlobReporter
|
|
3656
3748
|
};
|
|
3657
3749
|
function createReporters(reporters, initConfig = {}) {
|
|
3658
3750
|
const result = castArray(reporters).map((reporter)=>{
|
|
@@ -3693,10 +3785,15 @@ function core_createRstest({ config, projects, configFilePath }, command, fileFi
|
|
|
3693
3785
|
const { listTests } = await import("./0~listTests.js");
|
|
3694
3786
|
return listTests(context, options);
|
|
3695
3787
|
};
|
|
3788
|
+
const mergeReports = async (options)=>{
|
|
3789
|
+
const { mergeReports } = await import("./0~mergeReports.js");
|
|
3790
|
+
await mergeReports(context, options);
|
|
3791
|
+
};
|
|
3696
3792
|
return {
|
|
3697
3793
|
context,
|
|
3698
3794
|
runTests,
|
|
3699
|
-
listTests
|
|
3795
|
+
listTests,
|
|
3796
|
+
mergeReports
|
|
3700
3797
|
};
|
|
3701
3798
|
}
|
|
3702
3799
|
function defineConfig(config) {
|
|
@@ -3705,4 +3802,4 @@ function defineConfig(config) {
|
|
|
3705
3802
|
function defineProject(config) {
|
|
3706
3803
|
return config;
|
|
3707
3804
|
}
|
|
3708
|
-
export { config_loadConfig as loadConfig, core_createRstest as createRstest, defineConfig, defineProject, detect, error_parseErrorStacktrace as parseErrorStacktrace, error_printError as printError, formatStack, init_initCli as initCli, mergeProjectConfig, mergeRstestConfig, resolveCommand, runCLI, runRest };
|
|
3805
|
+
export { config_loadConfig as loadConfig, core_createRstest as createRstest, core_namespaceObject, defineConfig, defineProject, detect, error_parseErrorStacktrace as parseErrorStacktrace, error_printError as printError, formatStack, init_initCli as initCli, init_namespaceObject, mergeProjectConfig, mergeRstestConfig, resolveCommand, runCLI, runRest };
|
package/dist/4411.js
CHANGED
|
@@ -5,7 +5,7 @@ import node_fs, * as __rspack_external_node_fs_5ea92f0c from "node:fs";
|
|
|
5
5
|
import node_path, { basename, dirname, normalize, posix, relative as external_node_path_relative, resolve, sep } from "node:path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
7
|
import { createRequire } from "module";
|
|
8
|
-
import { logger as logger_logger, parsePosix, color, castArray } from "./6830.js";
|
|
8
|
+
import { logger as logger_logger, parsePosix, color as logger_color, castArray } from "./6830.js";
|
|
9
9
|
import { posix as dist_posix } from "./7011.js";
|
|
10
10
|
__webpack_require__.add({
|
|
11
11
|
"../../node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/index.js" (module, __unused_rspack_exports, __webpack_require__) {
|
|
@@ -2266,7 +2266,7 @@ const getTestEntries = async ({ include, exclude, rootPath, projectRoot, fileFil
|
|
|
2266
2266
|
};
|
|
2267
2267
|
const prettyTestPath = (testPath)=>{
|
|
2268
2268
|
const { dir, base } = parsePosix(testPath);
|
|
2269
|
-
return `${'.' !== dir ?
|
|
2269
|
+
return `${'.' !== dir ? logger_color.gray(`${dir}/`) : ''}${logger_color.cyan(base)}`;
|
|
2270
2270
|
};
|
|
2271
2271
|
const formatTestPath = (root, testFilePath)=>{
|
|
2272
2272
|
let testPath = testFilePath;
|
|
@@ -2304,7 +2304,7 @@ async function resolveShardedEntries(context) {
|
|
|
2304
2304
|
const shardedEntries = getShardedFiles(allTestEntriesBeforeSharding, shard);
|
|
2305
2305
|
const totalTestFileCount = allTestEntriesBeforeSharding.length;
|
|
2306
2306
|
const testFilesInShardCount = shardedEntries.length;
|
|
2307
|
-
logger_logger.log(
|
|
2307
|
+
logger_logger.log(logger_color.green(`Running shard ${shard.index} of ${shard.count} (${testFilesInShardCount} of ${totalTestFileCount} test files)\n`));
|
|
2308
2308
|
const shardedEntriesByProject = new Map();
|
|
2309
2309
|
for (const { project, alias, testPath } of shardedEntries){
|
|
2310
2310
|
if (!shardedEntriesByProject.has(project)) shardedEntriesByProject.set(project, {});
|