@rstest/core 0.8.5 → 0.9.1

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/dist/9131.js CHANGED
@@ -1,8 +1,6 @@
1
1
  import "node:module";
2
2
  import { __webpack_require__ } from "./rslib-runtime.js";
3
- import { EventEmitter } from "events";
4
3
  import { basename, isTTY, dirname as pathe_M_eThtNZ_dirname, resolve as pathe_M_eThtNZ_resolve, node_process, relative, getAbsolutePath, join, bgColor, formatRootStr, determineAgent, logger as logger_logger, castArray, prettyTime, isDebug, color, isAbsolute, getTaskNameWithPrefix, normalize, formatError } from "./3160.js";
5
- import "./721.js";
6
4
  import { isDynamicPattern, glob, DEFAULT_CONFIG_NAME, prettyTestPath, globalApis, promises, TEMP_RSTEST_OUTPUT_DIR_GLOB, formatTestPath, filterProjects, DEFAULT_CONFIG_EXTENSIONS, TS_CONFIG_FILE } from "./1157.js";
7
5
  import { rsbuild as __rspack_external__rsbuild_core_1b356efc } from "./4484.js";
8
6
  import { posix } from "./7011.js";
@@ -15,13 +13,13 @@ function toArr(any) {
15
13
  ];
16
14
  }
17
15
  function toVal(out, key, val, opts) {
18
- var x, old = out[key], nxt = ~opts.string.indexOf(key) ? null == val || true === val ? '' : String(val) : 'boolean' == typeof val ? val : ~opts.boolean.indexOf(key) ? 'false' === val ? false : 'true' === val || (out._.push((x = +val, 0 * x === 0) ? x : val), !!val) : (x = +val, 0 * x === 0) ? x : val;
16
+ var x, old = out[key], nxt = ~opts.string.indexOf(key) ? null == val || true === val ? "" : String(val) : "boolean" == typeof val ? val : ~opts.boolean.indexOf(key) ? "false" === val ? false : "true" === val || (out._.push((x = +val, 0 * x === 0) ? x : val), !!val) : (x = +val, 0 * x === 0) ? x : val;
19
17
  out[key] = null == old ? nxt : Array.isArray(old) ? old.concat(nxt) : [
20
18
  old,
21
19
  nxt
22
20
  ];
23
21
  }
24
- function mri2(args, opts) {
22
+ function lib_default(args, opts) {
25
23
  args = args || [];
26
24
  opts = opts || {};
27
25
  var k, arr, arg, name, val, out = {
@@ -57,26 +55,26 @@ function mri2(args, opts) {
57
55
  const keys = strict ? Object.keys(opts.alias) : [];
58
56
  for(i = 0; i < len; i++){
59
57
  arg = args[i];
60
- if ('--' === arg) {
58
+ if ("--" === arg) {
61
59
  out._ = out._.concat(args.slice(++i));
62
60
  break;
63
61
  }
64
62
  for(j = 0; j < arg.length && 45 === arg.charCodeAt(j); j++);
65
63
  if (0 === j) out._.push(arg);
66
- else if ('no-' === arg.substring(j, j + 3)) {
64
+ else if ("no-" === arg.substring(j, j + 3)) {
67
65
  name = arg.substring(j + 3);
68
66
  if (strict && !~keys.indexOf(name)) return opts.unknown(arg);
69
67
  out[name] = false;
70
68
  } else {
71
69
  for(idx = j + 1; idx < arg.length && 61 !== arg.charCodeAt(idx); idx++);
72
70
  name = arg.substring(j, idx);
73
- val = arg.substring(++idx) || i + 1 === len || 45 === ('' + args[i + 1]).charCodeAt(0) || args[++i];
71
+ val = arg.substring(++idx) || i + 1 === len || 45 === ("" + args[i + 1]).charCodeAt(0) || args[++i];
74
72
  arr = 2 === j ? [
75
73
  name
76
74
  ] : name;
77
75
  for(idx = 0; idx < arr.length; idx++){
78
76
  name = arr[idx];
79
- if (strict && !~keys.indexOf(name)) return opts.unknown('-'.repeat(j) + name);
77
+ if (strict && !~keys.indexOf(name)) return opts.unknown("-".repeat(j) + name);
80
78
  toVal(out, name, idx + 1 < arr.length || val, opts);
81
79
  }
82
80
  }
@@ -90,8 +88,10 @@ function mri2(args, opts) {
90
88
  }
91
89
  return out;
92
90
  }
93
- const removeBrackets = (v)=>v.replace(/[<[].+/, "").trim();
94
- const findAllBrackets = (v)=>{
91
+ function removeBrackets(v) {
92
+ return v.replace(/[<[].+/, "").trim();
93
+ }
94
+ function findAllBrackets(v) {
95
95
  const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g;
96
96
  const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g;
97
97
  const res = [];
@@ -113,8 +113,8 @@ const findAllBrackets = (v)=>{
113
113
  let squareMatch;
114
114
  while(squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v))res.push(parse(squareMatch));
115
115
  return res;
116
- };
117
- const getMriOptions = (options)=>{
116
+ }
117
+ function getMriOptions(options) {
118
118
  const result = {
119
119
  alias: {},
120
120
  boolean: []
@@ -122,53 +122,74 @@ const getMriOptions = (options)=>{
122
122
  for (const [index, option] of options.entries()){
123
123
  if (option.names.length > 1) result.alias[option.names[0]] = option.names.slice(1);
124
124
  if (option.isBoolean) if (option.negated) {
125
- const hasStringTypeOption = options.some((o, i)=>i !== index && o.names.some((name)=>option.names.includes(name)) && "boolean" == typeof o.required);
126
- if (!hasStringTypeOption) result.boolean.push(option.names[0]);
125
+ if (!options.some((o, i)=>i !== index && o.names.some((name)=>option.names.includes(name)) && "boolean" == typeof o.required)) result.boolean.push(option.names[0]);
127
126
  } else result.boolean.push(option.names[0]);
128
127
  }
129
128
  return result;
130
- };
131
- const findLongest = (arr)=>arr.sort((a, b)=>a.length > b.length ? -1 : 1)[0];
132
- const padRight = (str, length)=>str.length >= length ? str : `${str}${" ".repeat(length - str.length)}`;
133
- const camelcase = (input)=>input.replace(/([a-z])-([a-z])/g, (_, p1, p2)=>p1 + p2.toUpperCase());
134
- const setDotProp = (obj, keys, val)=>{
135
- let i = 0;
136
- let length = keys.length;
137
- let t = obj;
138
- let x;
139
- for(; i < length; ++i){
140
- x = t[keys[i]];
141
- t = t[keys[i]] = i === length - 1 ? val : null != x ? x : !~keys[i + 1].indexOf(".") && +keys[i + 1] > -1 ? [] : {};
129
+ }
130
+ function findLongest(arr) {
131
+ return arr.sort((a, b)=>a.length > b.length ? -1 : 1)[0];
132
+ }
133
+ function padRight(str, length) {
134
+ return str.length >= length ? str : `${str}${" ".repeat(length - str.length)}`;
135
+ }
136
+ function camelcase(input) {
137
+ return input.replaceAll(/([a-z])-([a-z])/g, (_, p1, p2)=>p1 + p2.toUpperCase());
138
+ }
139
+ function setDotProp(obj, keys, val) {
140
+ let current = obj;
141
+ for(let i = 0; i < keys.length; i++){
142
+ const key = keys[i];
143
+ if (i === keys.length - 1) {
144
+ current[key] = val;
145
+ return;
146
+ }
147
+ if (null == current[key]) {
148
+ const nextKeyIsArrayIndex = +keys[i + 1] > -1;
149
+ current[key] = nextKeyIsArrayIndex ? [] : {};
150
+ }
151
+ current = current[key];
142
152
  }
143
- };
144
- const setByType = (obj, transforms)=>{
153
+ }
154
+ function setByType(obj, transforms) {
145
155
  for (const key of Object.keys(transforms)){
146
156
  const transform = transforms[key];
147
157
  if (transform.shouldTransform) {
148
- obj[key] = Array.prototype.concat.call([], obj[key]);
158
+ obj[key] = [
159
+ obj[key]
160
+ ].flat();
149
161
  if ("function" == typeof transform.transformFunction) obj[key] = obj[key].map(transform.transformFunction);
150
162
  }
151
163
  }
152
- };
153
- const getFileName = (input)=>{
154
- const m = /([^\\\/]+)$/.exec(input);
164
+ }
165
+ function getFileName(input) {
166
+ const m = /([^\\/]+)$/.exec(input);
155
167
  return m ? m[1] : "";
156
- };
157
- const camelcaseOptionName = (name)=>name.split(".").map((v, i)=>0 === i ? camelcase(v) : v).join(".");
158
- class CACError extends Error {
168
+ }
169
+ function camelcaseOptionName(name) {
170
+ return name.split(".").map((v, i)=>0 === i ? camelcase(v) : v).join(".");
171
+ }
172
+ var CACError = class extends Error {
159
173
  constructor(message){
160
174
  super(message);
161
- this.name = this.constructor.name;
162
- if ("function" == typeof Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
163
- else this.stack = new Error(message).stack;
175
+ this.name = "CACError";
176
+ if ("function" != typeof Error.captureStackTrace) this.stack = new Error(message).stack;
164
177
  }
165
- }
166
- class Option {
178
+ };
179
+ var Option = class {
180
+ rawName;
181
+ description;
182
+ name;
183
+ names;
184
+ isBoolean;
185
+ required;
186
+ config;
187
+ negated;
167
188
  constructor(rawName, description, config){
168
189
  this.rawName = rawName;
169
190
  this.description = description;
170
191
  this.config = Object.assign({}, config);
171
- rawName = rawName.replace(/\.\*/g, "");
192
+ rawName = rawName.replaceAll(".*", "");
172
193
  this.negated = false;
173
194
  this.names = removeBrackets(rawName).split(",").map((v)=>{
174
195
  let name = v.trim().replace(/^-{1,2}/, "");
@@ -178,16 +199,36 @@ class Option {
178
199
  }
179
200
  return camelcaseOptionName(name);
180
201
  }).sort((a, b)=>a.length > b.length ? 1 : -1);
181
- this.name = this.names[this.names.length - 1];
202
+ this.name = this.names.at(-1);
182
203
  if (this.negated && null == this.config.default) this.config.default = true;
183
204
  if (rawName.includes("<")) this.required = true;
184
205
  else if (rawName.includes("[")) this.required = false;
185
206
  else this.isBoolean = true;
186
207
  }
187
- }
188
- const processArgs = process.argv;
189
- const platformInfo = `${process.platform}-${process.arch} node-${process.version}`;
190
- class Command {
208
+ };
209
+ let runtimeProcessArgs;
210
+ let runtimeInfo;
211
+ if ("u" > typeof process) {
212
+ let runtimeName;
213
+ runtimeName = "u" > typeof Deno && "string" == typeof Deno.version?.deno ? "deno" : "u" > typeof Bun && "string" == typeof Bun.version ? "bun" : "node";
214
+ runtimeInfo = `${process.platform}-${process.arch} ${runtimeName}-${process.version}`;
215
+ runtimeProcessArgs = process.argv;
216
+ } else runtimeInfo = "u" < typeof navigator ? "unknown" : `${navigator.platform} ${navigator.userAgent}`;
217
+ var Command = class {
218
+ rawName;
219
+ description;
220
+ config;
221
+ cli;
222
+ options;
223
+ aliasNames;
224
+ name;
225
+ args;
226
+ commandAction;
227
+ usageText;
228
+ versionNumber;
229
+ examples;
230
+ helpCallback;
231
+ globalCommand;
191
232
  constructor(rawName, description, config = {}, cli){
192
233
  this.rawName = rawName;
193
234
  this.description = description;
@@ -258,14 +299,12 @@ class Command {
258
299
  title: "Usage",
259
300
  body: ` $ ${name} ${this.usageText || this.rawName}`
260
301
  });
261
- const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0;
262
- if (showCommands) {
302
+ if ((this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0) {
263
303
  const longestCommandName = findLongest(commands.map((command)=>command.rawName));
264
304
  sections.push({
265
305
  title: "Commands",
266
306
  body: commands.map((command)=>` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`).join("\n")
267
- });
268
- sections.push({
307
+ }, {
269
308
  title: "For more info, run any command with the `--help` flag",
270
309
  body: commands.map((command)=>` $ ${name}${"" === command.name ? "" : ` ${command.name}`} --help`).join("\n")
271
310
  });
@@ -290,13 +329,12 @@ class Command {
290
329
  }).join("\n")
291
330
  });
292
331
  if (helpCallback) sections = helpCallback(sections) || sections;
293
- console.log(sections.map((section)=>section.title ? `${section.title}:
294
- ${section.body}` : section.body).join("\n\n"));
332
+ console.info(sections.map((section)=>section.title ? `${section.title}:\n${section.body}` : section.body).join("\n\n"));
295
333
  }
296
334
  outputVersion() {
297
335
  const { name } = this.cli;
298
336
  const { versionNumber } = this.cli.globalCommand;
299
- if (versionNumber) console.log(`${name}/${versionNumber} ${platformInfo}`);
337
+ if (versionNumber) console.info(`${name}/${versionNumber} ${runtimeInfo}`);
300
338
  }
301
339
  checkRequiredArgs() {
302
340
  const minimalArgsCount = this.args.filter((arg)=>arg.required).length;
@@ -322,14 +360,27 @@ ${section.body}` : section.body).join("\n\n"));
322
360
  }
323
361
  }
324
362
  }
325
- }
326
- class GlobalCommand extends Command {
363
+ checkUnusedArgs() {
364
+ const maximumArgsCount = this.args.some((arg)=>arg.variadic) ? 1 / 0 : this.args.length;
365
+ if (maximumArgsCount < this.cli.args.length) throw new CACError(`Unused args: ${this.cli.args.slice(maximumArgsCount).map((arg)=>`\`${arg}\``).join(", ")}`);
366
+ }
367
+ };
368
+ var GlobalCommand = class extends Command {
327
369
  constructor(cli){
328
370
  super("@@global@@", "", {}, cli);
329
371
  }
330
- }
331
- var __assign = Object.assign;
332
- class CAC extends EventEmitter {
372
+ };
373
+ var CAC = class extends EventTarget {
374
+ name;
375
+ commands;
376
+ globalCommand;
377
+ matchedCommand;
378
+ matchedCommandName;
379
+ rawArgs;
380
+ args;
381
+ options;
382
+ showHelpOnExit;
383
+ showVersionOnExit;
333
384
  constructor(name = ""){
334
385
  super();
335
386
  this.name = name;
@@ -387,7 +438,11 @@ class CAC extends EventEmitter {
387
438
  this.matchedCommand = void 0;
388
439
  this.matchedCommandName = void 0;
389
440
  }
390
- parse(argv = processArgs, { run = true } = {}) {
441
+ parse(argv, { run = true } = {}) {
442
+ if (!argv) {
443
+ if (!runtimeProcessArgs) throw new Error("No argv provided and runtime process argv is not available.");
444
+ argv = runtimeProcessArgs;
445
+ }
391
446
  this.rawArgs = argv;
392
447
  if (!this.name) this.name = argv[1] ? getFileName(argv[1]) : "cli";
393
448
  let shouldParse = true;
@@ -396,19 +451,24 @@ class CAC extends EventEmitter {
396
451
  const commandName = parsed.args[0];
397
452
  if (command.isMatched(commandName)) {
398
453
  shouldParse = false;
399
- const parsedInfo = __assign(__assign({}, parsed), {
454
+ const parsedInfo = {
455
+ ...parsed,
400
456
  args: parsed.args.slice(1)
401
- });
457
+ };
402
458
  this.setParsedInfo(parsedInfo, command, commandName);
403
- this.emit(`command:${commandName}`, command);
459
+ this.dispatchEvent(new CustomEvent(`command:${commandName}`, {
460
+ detail: command
461
+ }));
404
462
  }
405
463
  }
406
464
  if (shouldParse) {
407
- for (const command of this.commands)if ("" === command.name) {
465
+ for (const command of this.commands)if (command.isDefaultCommand) {
408
466
  shouldParse = false;
409
467
  const parsed = this.mri(argv.slice(2), command);
410
468
  this.setParsedInfo(parsed, command);
411
- this.emit("command:!", command);
469
+ this.dispatchEvent(new CustomEvent("command:!", {
470
+ detail: command
471
+ }));
412
472
  }
413
473
  }
414
474
  if (shouldParse) {
@@ -430,7 +490,9 @@ class CAC extends EventEmitter {
430
490
  options: this.options
431
491
  };
432
492
  if (run) this.runMatchedCommand();
433
- if (!this.matchedCommand && this.args[0]) this.emit("command:*");
493
+ if (!this.matchedCommand && this.args[0]) this.dispatchEvent(new CustomEvent("command:*", {
494
+ detail: this.args[0]
495
+ }));
434
496
  return parsedArgv;
435
497
  }
436
498
  mri(argv, command) {
@@ -441,12 +503,13 @@ class CAC extends EventEmitter {
441
503
  const mriOptions = getMriOptions(cliOptions);
442
504
  let argsAfterDoubleDashes = [];
443
505
  const doubleDashesIndex = argv.indexOf("--");
444
- if (doubleDashesIndex > -1) {
506
+ if (-1 !== doubleDashesIndex) {
445
507
  argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1);
446
508
  argv = argv.slice(0, doubleDashesIndex);
447
509
  }
448
- let parsed = mri2(argv, mriOptions);
449
- parsed = Object.keys(parsed).reduce((res, name)=>__assign(__assign({}, res), {
510
+ let parsed = lib_default(argv, mriOptions);
511
+ parsed = Object.keys(parsed).reduce((res, name)=>({
512
+ ...res,
450
513
  [camelcaseOptionName(name)]: parsed[name]
451
514
  }), {
452
515
  _: []
@@ -456,20 +519,17 @@ class CAC extends EventEmitter {
456
519
  "--": argsAfterDoubleDashes
457
520
  };
458
521
  const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue;
459
- let transforms = Object.create(null);
522
+ const transforms = Object.create(null);
460
523
  for (const cliOption of cliOptions){
461
524
  if (!ignoreDefault && void 0 !== cliOption.config.default) for (const name of cliOption.names)options[name] = cliOption.config.default;
462
- if (Array.isArray(cliOption.config.type)) {
463
- if (void 0 === transforms[cliOption.name]) {
464
- transforms[cliOption.name] = Object.create(null);
465
- transforms[cliOption.name]["shouldTransform"] = true;
466
- transforms[cliOption.name]["transformFunction"] = cliOption.config.type[0];
467
- }
525
+ if (Array.isArray(cliOption.config.type) && void 0 === transforms[cliOption.name]) {
526
+ transforms[cliOption.name] = Object.create(null);
527
+ transforms[cliOption.name].shouldTransform = true;
528
+ transforms[cliOption.name].transformFunction = cliOption.config.type[0];
468
529
  }
469
530
  }
470
531
  for (const key of Object.keys(parsed))if ("_" !== key) {
471
- const keys = key.split(".");
472
- setDotProp(options, keys, parsed[key]);
532
+ setDotProp(options, key.split("."), parsed[key]);
473
533
  setByType(options, transforms);
474
534
  }
475
535
  return {
@@ -483,6 +543,7 @@ class CAC extends EventEmitter {
483
543
  command.checkUnknownOptions();
484
544
  command.checkOptionValue();
485
545
  command.checkRequiredArgs();
546
+ command.checkUnusedArgs();
486
547
  const actionArgs = [];
487
548
  command.args.forEach((arg, index)=>{
488
549
  if (arg.variadic) actionArgs.push(args.slice(index));
@@ -491,9 +552,8 @@ class CAC extends EventEmitter {
491
552
  actionArgs.push(options);
492
553
  return command.commandAction.apply(this, actionArgs);
493
554
  }
494
- }
555
+ };
495
556
  const cac = (name = "")=>new CAC(name);
496
- const dist = cac;
497
557
  function initNodeEnv() {
498
558
  if (!process.env.NODE_ENV) process.env.NODE_ENV = 'test';
499
559
  }
@@ -504,13 +564,13 @@ function prepareCli() {
504
564
  if (!npm_execpath || npm_execpath.includes('npx-cli.js') || npm_execpath.includes('.bun')) logger_logger.log();
505
565
  }
506
566
  function showRstest() {
507
- logger_logger.greet(" Rstest v0.8.5");
567
+ logger_logger.greet(" Rstest v0.9.1");
508
568
  logger_logger.log('');
509
569
  }
510
570
  const applyCommonOptions = (cli)=>{
511
- cli.option('-c, --config <config>', 'Specify the configuration file, can be a relative or absolute path').option('--config-loader <loader>', 'Specify the loader to load the config file, can be `jiti` or `native`', {
512
- default: 'jiti'
513
- }).option('-r, --root <root>', 'Specify the project root directory, can be an absolute path or a path relative to cwd').option('--globals', 'Provide global APIs').option('--isolate', 'Run tests in an isolated environment').option('--include <include>', 'Match test files').option('--exclude <exclude>', 'Exclude files from test').option('-u, --update', 'Update snapshot files').option('--coverage', 'Enable code coverage collection').option('--project <name>', 'Run only projects that match the name, can be a full name or wildcards pattern').option('--passWithNoTests', 'Allows the test suite to pass when no files are found').option('--printConsoleTrace', 'Print console traces when calling any console method').option('--disableConsoleIntercept', 'Disable console intercept').option('--logHeapUsage', 'Log heap usage after each test').option('--slowTestThreshold <value>', 'The number of milliseconds after which a test or suite is considered slow').option('--reporter <reporter>', 'Specify the reporter to use').option('-t, --testNamePattern <value>', 'Run only tests with a name that matches the regex').option('--testEnvironment <name>', 'The environment that will be used for testing').option('--testTimeout <value>', 'Timeout of a test in milliseconds').option('--hookTimeout <value>', 'Timeout of hook in milliseconds').option('--hideSkippedTests', 'Hide skipped tests from the output').option('--hideSkippedTestFiles', 'Hide skipped test files from the output').option('--retry <retry>', 'Number of times to retry a test if it fails').option('--bail [number]', 'Stop running tests after n failures. Set to 0 to run all tests regardless of failures').option('--shard <index/count>', 'Split tests into several shards. This is useful for running tests in parallel on multiple machines.').option('--maxConcurrency <value>', 'Maximum number of concurrent tests').option('--clearMocks', 'Automatically clear mock calls, instances, contexts and results before every test').option('--resetMocks', 'Automatically reset mock state before every test').option('--restoreMocks', 'Automatically restore mock state and implementation before every test').option('--browser', 'Run tests in browser mode').option('--browser.enabled', 'Run tests in browser mode').option('--browser.name <name>', 'Browser to use: chromium, firefox, webkit (default: chromium)').option('--browser.headless', 'Run browser in headless mode (default: true in CI)').option('--browser.port <port>', 'Port for the browser mode dev server').option('--browser.strictPort', 'Exit if the specified port is already in use').option('--unstubGlobals', 'Restores all global variables that were changed with `rstest.stubGlobal` before every test').option('--unstubEnvs', 'Restores all `process.env` values that were changed with `rstest.stubEnv` before every test').option('--includeTaskLocation', 'Collect test and suite locations. This might increase the running time.');
571
+ cli.option('-c, --config <config>', 'Specify the configuration file, can be a relative or absolute path').option('--config-loader <loader>', 'Specify the loader to load the config file (auto | jiti | native)', {
572
+ default: 'auto'
573
+ }).option('-r, --root <root>', 'Specify the project root directory, can be an absolute path or a path relative to cwd').option('--globals', 'Provide global APIs').option('--isolate', 'Run tests in an isolated environment').option('--include <include>', 'Match test files').option('--exclude <exclude>', 'Exclude files from test').option('-u, --update', 'Update snapshot files').option('--coverage', 'Enable code coverage collection').option('--project <name>', 'Run only projects that match the name, can be a full name or wildcards pattern').option('--passWithNoTests', 'Allows the test suite to pass when no files are found').option('--printConsoleTrace', 'Print console traces when calling any console method').option('--disableConsoleIntercept', 'Disable console intercept').option('--logHeapUsage', 'Log heap usage after each test').option('--slowTestThreshold <value>', 'The number of milliseconds after which a test or suite is considered slow').option('--reporter <reporter>', 'Specify the reporter to use').option('-t, --testNamePattern <value>', 'Run only tests with a name that matches the regex').option('--testEnvironment <name>', 'The environment that will be used for testing').option('--testTimeout <value>', 'Timeout of a test in milliseconds').option('--hookTimeout <value>', 'Timeout of hook in milliseconds').option('--hideSkippedTests', 'Hide skipped tests from the output').option('--hideSkippedTestFiles', 'Hide skipped test files from the output').option('--retry <retry>', 'Number of times to retry a test if it fails').option('--bail [number]', 'Stop running tests after n failures. Set to 0 to run all tests regardless of failures').option('--shard <index/count>', 'Split tests into several shards. This is useful for running tests in parallel on multiple machines.').option('--maxConcurrency <value>', 'Maximum number of concurrent tests').option('--clearMocks', 'Automatically clear mock calls, instances, contexts and results before every test').option('--resetMocks', 'Automatically reset mock state before every test').option('--restoreMocks', 'Automatically restore mock state and implementation before every test').option('--browser', 'Run tests in browser mode').option('--browser.enabled', 'Run tests in browser mode').option('--browser.name <name>', 'Browser to use: chromium, firefox, webkit (default: chromium)').option('--browser.headless', 'Run browser in headless mode (default: true in CI)').option('--browser.port <port>', 'Port for the browser mode dev server').option('--browser.strictPort', 'Exit if the specified port is already in use').option('--unstubGlobals', 'Restores all global variables that were changed with `rstest.stubGlobal` before every test').option('--unstubEnvs', 'Restores all runtime env values that were changed with `rstest.stubEnv` before every test').option('--includeTaskLocation', 'Collect test and suite locations. This might increase the running time.');
514
574
  cli.option('--pool <type>', 'Shorthand for --pool.type').option('--pool.type <type>', 'Specify the test pool type (e.g. forks)').option('--pool.maxWorkers <value>', 'Maximum number or percentage of workers (e.g. 4 or 50%)').option('--pool.minWorkers <value>', 'Minimum number or percentage of workers (e.g. 1 or 25%)').option('--pool.execArgv <arg>', 'Additional Node.js execArgv passed to worker processes (can be specified multiple times)');
515
575
  };
516
576
  const handleUnexpectedExit = (rstest, err)=>{
@@ -560,9 +620,9 @@ const runRest = async ({ options, filters, command })=>{
560
620
  }
561
621
  };
562
622
  function setupCommands() {
563
- const cli = dist('rstest');
623
+ const cli = cac('rstest');
564
624
  cli.help();
565
- cli.version("0.8.5");
625
+ cli.version("0.9.1");
566
626
  applyCommonOptions(cli);
567
627
  cli.command('[...filters]', 'run tests').option('-w, --watch', 'Run tests in watch mode').action(async (filters, options)=>{
568
628
  if (!determineAgent().isAgent) showRstest();
@@ -624,9 +684,9 @@ function setupCommands() {
624
684
  try {
625
685
  let selectedProject = project;
626
686
  if (!selectedProject) {
627
- const { select, isCancel } = await import("./0~9348.js").then((mod)=>({
628
- select: mod.ve,
629
- isCancel: mod.pD
687
+ const { select, isCancel } = await import("./0~9744.js").then((mod)=>({
688
+ select: mod.Jt,
689
+ isCancel: mod.Ct
630
690
  }));
631
691
  console.log();
632
692
  const selected = await select({
@@ -1110,7 +1170,6 @@ const createDefaultConfig = ()=>({
1110
1170
  coverage: {
1111
1171
  exclude: [
1112
1172
  '**/node_modules/**',
1113
- '**/dist/**',
1114
1173
  '**/test/**',
1115
1174
  '**/__tests__/**',
1116
1175
  '**/__mocks__/**',
@@ -1384,7 +1443,7 @@ async function init_initCli(options) {
1384
1443
  projects
1385
1444
  };
1386
1445
  }
1387
- async function runCLI() {
1446
+ function runCLI() {
1388
1447
  process.title = 'rstest-node';
1389
1448
  prepareCli();
1390
1449
  try {
@@ -1546,6 +1605,9 @@ class WindowRenderer {
1546
1605
  windowHeight = 0;
1547
1606
  finished = false;
1548
1607
  cleanups = [];
1608
+ exitHandler = ()=>{
1609
+ this.finish();
1610
+ };
1549
1611
  constructor(options){
1550
1612
  this.options = {
1551
1613
  interval: DEFAULT_RENDER_INTERVAL_MS,
@@ -1557,6 +1619,7 @@ class WindowRenderer {
1557
1619
  };
1558
1620
  this.cleanups.push(this.interceptStream(process.stdout, 'output'), this.interceptStream(process.stderr, 'error'));
1559
1621
  this.start();
1622
+ process.once('exit', this.exitHandler);
1560
1623
  }
1561
1624
  start() {
1562
1625
  this.finished = false;
@@ -1570,6 +1633,7 @@ class WindowRenderer {
1570
1633
  this.finished = true;
1571
1634
  this.flushBuffer();
1572
1635
  clearInterval(this.renderInterval);
1636
+ process.removeListener('exit', this.exitHandler);
1573
1637
  }
1574
1638
  schedule() {
1575
1639
  if (!this.renderScheduled) {
@@ -1800,7 +1864,7 @@ class DefaultReporter {
1800
1864
  logOutput(log.content);
1801
1865
  logOutput('');
1802
1866
  }
1803
- async onExit() {
1867
+ onExit() {
1804
1868
  this.statusRenderer?.clear();
1805
1869
  }
1806
1870
  async onTestRunEnd({ results, testResults, duration, getSourcemap, snapshotSummary, filterRerunTestPaths, unhandledErrors }) {
@@ -2193,6 +2257,7 @@ function traceSegmentInternal(segments, memo, line, column, bias) {
2193
2257
  }
2194
2258
  const external_node_path_ = __webpack_require__("path");
2195
2259
  const isRelativePath = (p)=>/^\.\.?\//.test(p);
2260
+ const isHttpLikeFile = (file)=>/^https?:\/\//.test(file);
2196
2261
  const hintNotDefinedError = (message)=>{
2197
2262
  const [, varName] = message.match(/(\w+) is not defined/) || [];
2198
2263
  if (varName) {
@@ -2239,7 +2304,7 @@ async function printCodeFrame(frame) {
2239
2304
  if (!filePath) return;
2240
2305
  const source = external_node_fs_["default"].existsSync(filePath) ? external_node_fs_["default"].readFileSync(filePath, 'utf-8') : void 0;
2241
2306
  if (!source) return;
2242
- const { codeFrameColumns } = await import("./0~3919.js").then(__webpack_require__.bind(__webpack_require__, "../../node_modules/.pnpm/@babel+code-frame@7.27.1/node_modules/@babel/code-frame/lib/index.js"));
2307
+ const { codeFrameColumns } = await import("./0~262.js").then(__webpack_require__.bind(__webpack_require__, "../../node_modules/.pnpm/@babel+code-frame@7.29.0/node_modules/@babel/code-frame/lib/index.js"));
2243
2308
  const result = codeFrameColumns(source, {
2244
2309
  start: {
2245
2310
  line: frame.lineNumber,
@@ -2298,7 +2363,14 @@ async function error_parseErrorStacktrace({ stack, getSourcemap, fullStack = isD
2298
2363
  }
2299
2364
  return frame;
2300
2365
  })).then((frames)=>frames.filter((frame)=>null !== frame));
2301
- return stackFrames;
2366
+ if (fullStack) return stackFrames;
2367
+ const filteredFrames = stackFrames.filter((frame)=>{
2368
+ if (!frame.file) return false;
2369
+ if (isHttpLikeFile(frame.file)) return false;
2370
+ const normalizedFile = frame.file.replace(/\\/g, '/');
2371
+ return !stackIgnores.some((entry)=>normalizedFile.match(entry));
2372
+ });
2373
+ return filteredFrames;
2302
2374
  }
2303
2375
  class JUnitReporter {
2304
2376
  rootPath;
@@ -3011,6 +3083,7 @@ const defaultOptions = {
3011
3083
  env: true
3012
3084
  },
3013
3085
  reproduction: 'file+name',
3086
+ testLists: 'auto',
3014
3087
  failures: {
3015
3088
  max: 50
3016
3089
  },
@@ -3118,6 +3191,7 @@ const resolveOptions = (userOptions = {})=>{
3118
3191
  preset: presetName,
3119
3192
  header: resolveHeader(userOptions.header),
3120
3193
  reproduction: resolveReproduction(userOptions.reproduction),
3194
+ testLists: userOptions.testLists ?? defaultOptions.testLists,
3121
3195
  failures: resolveFailures(userOptions.failures, preset),
3122
3196
  codeFrame: resolveCodeFrame(userOptions.codeFrame, preset),
3123
3197
  stack: resolveStack(userOptions.stack, preset),
@@ -3452,7 +3526,7 @@ class MdReporter {
3452
3526
  }
3453
3527
  renderFrontMatter(lines) {
3454
3528
  const frontMatter = {
3455
- tool: "@rstest/core@0.8.5",
3529
+ tool: "@rstest/core@0.9.1",
3456
3530
  timestamp: new Date().toISOString()
3457
3531
  };
3458
3532
  if (this.options.header.env) frontMatter.runtime = {
@@ -3541,7 +3615,7 @@ class MdReporter {
3541
3615
  pushHeading(lines, 1, 'Rstest Test Execution Report');
3542
3616
  pushHeading(lines, 2, 'Summary');
3543
3617
  pushFencedBlock(lines, 'json', stringifyJson(summaryPayload));
3544
- if ('pass' === status && focusedRun) this.renderTestsSection(lines, {
3618
+ if ('always' === this.options.testLists || 'pass' === status && focusedRun) this.renderTestsSection(lines, {
3545
3619
  passed: passedTests,
3546
3620
  skipped: skippedTests,
3547
3621
  todo: todoTests
@@ -3676,7 +3750,7 @@ class MdReporter {
3676
3750
  }
3677
3751
  } else {
3678
3752
  lines.push('No test failures reported.');
3679
- if ('pass' === status && !focusedRun) {
3753
+ if ('pass' === status && !focusedRun && 'always' !== this.options.testLists) {
3680
3754
  ensureSingleBlankLine(lines);
3681
3755
  lines.push('Note: all tests passed. Lists omitted for brevity.');
3682
3756
  }
@@ -3763,7 +3837,11 @@ class TestStateManager {
3763
3837
  });
3764
3838
  }
3765
3839
  getCountOfFailedTests() {
3766
- const testResults = Array.from(this.runningModules.values()).flatMap(({ results })=>results).concat(this.testModules.flatMap((mod)=>mod.results));
3840
+ const testResults = Array.from(this.runningModules.values()).flatMap(({ results })=>results).concat(this.testModules.flatMap((mod)=>mod.results.length > 0 ? mod.results : [
3841
+ {
3842
+ status: mod.status
3843
+ }
3844
+ ]));
3767
3845
  return testResults.filter((t)=>'fail' === t.status).length;
3768
3846
  }
3769
3847
  onTestFileResult(test) {
@@ -3822,7 +3900,7 @@ class Rstest {
3822
3900
  updateSnapshot: rstestConfig.update ? 'all' : T ? 'none' : 'new'
3823
3901
  });
3824
3902
  this.snapshotManager = snapshotManager;
3825
- this.version = "0.8.5";
3903
+ this.version = "0.9.1";
3826
3904
  this.rootPath = rootPath;
3827
3905
  this.originalConfig = userConfig;
3828
3906
  this.normalizedConfig = rstestConfig;
@@ -3918,7 +3996,7 @@ function createReporters(reporters, initConfig = {}) {
3918
3996
  }
3919
3997
  });
3920
3998
  }
3921
- throw new Error(`Reporter ${reporter} not found. Please install it or use a built-in reporter.`);
3999
+ throw new Error(`Reporter ${name} not found. Please install it or use a built-in reporter.`);
3922
4000
  }
3923
4001
  return reporter;
3924
4002
  });
@@ -3956,4 +4034,4 @@ function defineConfig(config) {
3956
4034
  function defineProject(config) {
3957
4035
  return config;
3958
4036
  }
3959
- export { EventEmitter, core_createRstest as createRstest, defineConfig, defineProject, detect, error_printError, init_initCli as initCli, loadConfig, mergeProjectConfig, mergeRstestConfig, resolveCommand, runCLI, runRest };
4037
+ export { core_createRstest as createRstest, defineConfig, defineProject, detect, error_printError, init_initCli as initCli, loadConfig, mergeProjectConfig, mergeRstestConfig, resolveCommand, runCLI, runRest };