@rstest/core 0.2.2 → 0.3.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/index.js CHANGED
@@ -2181,8 +2181,8 @@ var __webpack_modules__ = {
2181
2181
  },
2182
2182
  "./src/cli/commands.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
2183
2183
  __webpack_require__.d(__webpack_exports__, {
2184
- a8: ()=>runRest,
2185
- QF: ()=>setupCommands
2184
+ a: ()=>runRest,
2185
+ Q: ()=>setupCommands
2186
2186
  });
2187
2187
  var external_events_ = __webpack_require__("events");
2188
2188
  function toArr(any) {
@@ -2671,61 +2671,24 @@ ${section.body}` : section.body).join("\n\n"));
2671
2671
  const cac = (name = "")=>new CAC(name);
2672
2672
  const dist = cac;
2673
2673
  var external_pathe_ = __webpack_require__("pathe");
2674
- var src_config = __webpack_require__("./src/config.ts");
2675
2674
  var helper = __webpack_require__("./src/utils/helper.ts");
2676
2675
  var logger = __webpack_require__("./src/utils/logger.ts");
2677
2676
  var prepare = __webpack_require__("./src/cli/prepare.ts");
2678
2677
  const applyCommonOptions = (cli)=>{
2679
2678
  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`', {
2680
2679
  default: 'jiti'
2681
- }).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('--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('--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('--retry <retry>', 'Number of times to retry a test if it fails').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('--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');
2682
- };
2683
- async function initCli(options) {
2684
- const cwd = process.cwd();
2685
- const root = options.root ? (0, helper.FI)(cwd, options.root) : cwd;
2686
- const { content: config, filePath: configFilePath } = await (0, src_config.Z9)({
2687
- cwd: root,
2688
- path: options.config,
2689
- configLoader: options.configLoader
2690
- });
2691
- const keys = [
2692
- 'root',
2693
- 'globals',
2694
- 'isolate',
2695
- 'passWithNoTests',
2696
- 'update',
2697
- 'testNamePattern',
2698
- 'testTimeout',
2699
- 'hookTimeout',
2700
- 'clearMocks',
2701
- 'resetMocks',
2702
- 'restoreMocks',
2703
- 'unstubEnvs',
2704
- 'unstubGlobals',
2705
- 'retry',
2706
- 'slowTestThreshold',
2707
- 'maxConcurrency',
2708
- 'printConsoleTrace',
2709
- 'disableConsoleIntercept',
2710
- 'testEnvironment'
2711
- ];
2712
- for (const key of keys)if (void 0 !== options[key]) config[key] = options[key];
2713
- if (options.exclude) config.exclude = (0, helper.bg)(options.exclude);
2714
- if (options.reporter) config.reporters = (0, helper.bg)(options.reporter);
2715
- if (options.include) config.include = (0, helper.bg)(options.include);
2716
- return {
2717
- config,
2718
- configFilePath: configFilePath ?? void 0
2719
- };
2720
- }
2680
+ }).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('--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('--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('--retry <retry>', 'Number of times to retry a test if it fails').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('--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');
2681
+ };
2721
2682
  const runRest = async ({ options, filters, command })=>{
2722
2683
  let rstest;
2723
2684
  try {
2724
- const { config, configFilePath } = await initCli(options);
2725
- const { createRstest } = await __webpack_require__.e("698").then(__webpack_require__.bind(__webpack_require__, "./src/core/index.ts"));
2685
+ const { initCli } = await __webpack_require__.e("223").then(__webpack_require__.bind(__webpack_require__, "./src/cli/init.ts"));
2686
+ const { config, configFilePath, projects } = await initCli(options);
2687
+ const { createRstest } = await __webpack_require__.e("12").then(__webpack_require__.bind(__webpack_require__, "./src/core/index.ts"));
2726
2688
  rstest = createRstest({
2727
2689
  config,
2728
- configFilePath
2690
+ configFilePath,
2691
+ projects
2729
2692
  }, command, filters.map(external_pathe_.normalize));
2730
2693
  if ('watch' === command && configFilePath) {
2731
2694
  const { watchFilesForRestart } = await __webpack_require__.e("967").then(__webpack_require__.bind(__webpack_require__, "./src/core/restart.ts"));
@@ -2738,15 +2701,15 @@ ${section.body}` : section.body).join("\n\n"));
2738
2701
  await rstest.runTests();
2739
2702
  } catch (err) {
2740
2703
  for (const reporter of rstest?.context.reporters || [])reporter.onExit?.();
2741
- logger.v.error('Failed to run Rstest.');
2742
- logger.v.error((0, helper.Wk)(err));
2704
+ logger.vF.error('Failed to run Rstest.');
2705
+ logger.vF.error((0, helper.Wk)(err));
2743
2706
  process.exit(1);
2744
2707
  }
2745
2708
  };
2746
2709
  function setupCommands() {
2747
2710
  const cli = dist('rstest');
2748
2711
  cli.help();
2749
- cli.version("0.2.2");
2712
+ cli.version("0.3.1");
2750
2713
  applyCommonOptions(cli);
2751
2714
  cli.command('[...filters]', 'run tests').option('-w, --watch', 'Run tests in watch mode').action(async (filters, options)=>{
2752
2715
  (0, prepare.N)();
@@ -2779,19 +2742,21 @@ ${section.body}` : section.body).join("\n\n"));
2779
2742
  });
2780
2743
  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').action(async (filters, options)=>{
2781
2744
  try {
2782
- const { config, configFilePath } = await initCli(options);
2783
- const { createRstest } = await __webpack_require__.e("698").then(__webpack_require__.bind(__webpack_require__, "./src/core/index.ts"));
2745
+ const { initCli } = await __webpack_require__.e("223").then(__webpack_require__.bind(__webpack_require__, "./src/cli/init.ts"));
2746
+ const { config, configFilePath, projects } = await initCli(options);
2747
+ const { createRstest } = await __webpack_require__.e("12").then(__webpack_require__.bind(__webpack_require__, "./src/core/index.ts"));
2784
2748
  const rstest = createRstest({
2785
2749
  config,
2786
- configFilePath
2750
+ configFilePath,
2751
+ projects
2787
2752
  }, 'list', filters.map(external_pathe_.normalize));
2788
2753
  await rstest.listTests({
2789
2754
  filesOnly: options.filesOnly,
2790
2755
  json: options.json
2791
2756
  });
2792
2757
  } catch (err) {
2793
- logger.v.error('Failed to run Rstest list.');
2794
- logger.v.error((0, helper.Wk)(err));
2758
+ logger.vF.error('Failed to run Rstest list.');
2759
+ logger.vF.error((0, helper.Wk)(err));
2795
2760
  process.exit(1);
2796
2761
  }
2797
2762
  });
@@ -2814,8 +2779,8 @@ ${section.body}` : section.body).join("\n\n"));
2814
2779
  if (!npm_execpath || npm_execpath.includes('npx-cli.js') || npm_execpath.includes('.bun')) console.log();
2815
2780
  }
2816
2781
  function showRstest() {
2817
- _utils_logger__WEBPACK_IMPORTED_MODULE_0__.v.greet(" Rstest v0.2.2");
2818
- _utils_logger__WEBPACK_IMPORTED_MODULE_0__.v.log('');
2782
+ _utils_logger__WEBPACK_IMPORTED_MODULE_0__.vF.greet(" Rstest v0.3.1");
2783
+ _utils_logger__WEBPACK_IMPORTED_MODULE_0__.vF.log('');
2819
2784
  }
2820
2785
  },
2821
2786
  "./src/config.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
@@ -3095,15 +3060,18 @@ ${section.body}` : section.body).join("\n\n"));
3095
3060
  XJ: ()=>formatTestPath,
3096
3061
  zZ: ()=>constants.zZ,
3097
3062
  fN: ()=>helper.fN,
3098
- vF: ()=>logger.v,
3063
+ vF: ()=>logger.vF,
3099
3064
  vO: ()=>constants.vO,
3100
3065
  tG: ()=>getTestEntries,
3066
+ FI: ()=>helper.FI,
3101
3067
  kv: ()=>constants.kv,
3102
3068
  yW: ()=>helper.yW,
3103
3069
  EQ: ()=>prettyTestPath,
3104
- _o: ()=>logger._,
3070
+ _o: ()=>logger._o,
3105
3071
  pr: ()=>getSetupFiles,
3106
3072
  Kv: ()=>helper.Kv,
3073
+ zz: ()=>filterProjects,
3074
+ mT: ()=>logger.mT,
3107
3075
  t: ()=>constants.t,
3108
3076
  kV: ()=>helper.kV,
3109
3077
  EJ: ()=>constants.EJ,
@@ -3130,11 +3098,22 @@ ${section.body}` : section.body).join("\n\n"));
3130
3098
  });
3131
3099
  });
3132
3100
  };
3101
+ const filterProjects = (projects, options)=>{
3102
+ if (options.project) {
3103
+ const regexes = (0, helper.bg)(options.project).map((pattern)=>{
3104
+ const isNeg = pattern.startsWith('!');
3105
+ const escaped = (isNeg ? pattern.slice(1) : pattern).split('*').map((part)=>part.replace(/[.+?^${}()|[\]\\]/g, '\\$&')).join('.*');
3106
+ return new RegExp(isNeg ? `^(?!${escaped})` : `^${escaped}$`);
3107
+ });
3108
+ return projects.filter((proj)=>regexes.some((re)=>re.test(proj.config.name)));
3109
+ }
3110
+ return projects;
3111
+ };
3133
3112
  const hasInSourceTestCode = (code)=>code.includes('import.meta.rstest');
3134
3113
  const formatTestEntryName = (name)=>name.replace(/\.*[/\\]/g, '_').replace(/\./g, '~');
3135
- const getTestEntries = async ({ include, exclude, root, fileFilters, includeSource })=>{
3114
+ const getTestEntries = async ({ include, exclude, rootPath, projectRoot, fileFilters, includeSource })=>{
3136
3115
  const testFiles = await (0, dist.glob)(include, {
3137
- cwd: root,
3116
+ cwd: projectRoot,
3138
3117
  absolute: true,
3139
3118
  ignore: exclude,
3140
3119
  dot: true,
@@ -3142,7 +3121,7 @@ ${section.body}` : section.body).join("\n\n"));
3142
3121
  });
3143
3122
  if (includeSource?.length) {
3144
3123
  const sourceFiles = await (0, dist.glob)(includeSource, {
3145
- cwd: root,
3124
+ cwd: projectRoot,
3146
3125
  absolute: true,
3147
3126
  ignore: exclude,
3148
3127
  dot: true,
@@ -3157,8 +3136,8 @@ ${section.body}` : section.body).join("\n\n"));
3157
3136
  }
3158
3137
  }));
3159
3138
  }
3160
- return Object.fromEntries(filterFiles(testFiles, fileFilters, root).map((entry)=>{
3161
- const relativePath = external_pathe_["default"].relative(root, entry);
3139
+ return Object.fromEntries(filterFiles(testFiles, fileFilters, rootPath).map((entry)=>{
3140
+ const relativePath = external_pathe_["default"].relative(rootPath, entry);
3162
3141
  return [
3163
3142
  formatTestEntryName(relativePath),
3164
3143
  entry
@@ -3210,8 +3189,9 @@ ${section.body}` : section.body).join("\n\n"));
3210
3189
  },
3211
3190
  "./src/utils/logger.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
3212
3191
  __webpack_require__.d(__webpack_exports__, {
3213
- v: ()=>src_logger,
3214
- _: ()=>isDebug
3192
+ _o: ()=>isDebug,
3193
+ mT: ()=>clearScreen,
3194
+ vF: ()=>src_logger
3215
3195
  });
3216
3196
  var external_node_os_ = __webpack_require__("node:os");
3217
3197
  var external_node_tty_ = __webpack_require__("node:tty");
@@ -3486,6 +3466,9 @@ ${section.body}` : section.body).join("\n\n"));
3486
3466
  console.log(` ${helper.yW.magenta('rstest')} ${time} ${message}`, ...args);
3487
3467
  }
3488
3468
  });
3469
+ const clearScreen = (force = false)=>{
3470
+ if (!isDebug() || force) console.log('\x1Bc');
3471
+ };
3489
3472
  },
3490
3473
  "@rsbuild/core": function(module) {
3491
3474
  module.exports = __WEBPACK_EXTERNAL_MODULE__rsbuild_core_1b356efc__;
@@ -3546,6 +3529,7 @@ ${section.body}` : section.body).join("\n\n"));
3546
3529
  },
3547
3530
  "../../node_modules/.pnpm/tinyglobby@0.2.14/node_modules/tinyglobby/dist/index.mjs": function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
3548
3531
  __webpack_require__.d(__webpack_exports__, {
3532
+ ey: ()=>isDynamicPattern,
3549
3533
  glob: ()=>glob
3550
3534
  });
3551
3535
  var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("node:path");
@@ -3866,10 +3850,10 @@ var prepare = __webpack_require__("./src/cli/prepare.ts");
3866
3850
  async function runCLI() {
3867
3851
  (0, prepare.k)();
3868
3852
  try {
3869
- (0, commands.QF)();
3853
+ (0, commands.Q)();
3870
3854
  } catch (err) {
3871
- logger.v.error('Failed to start Rstest CLI.');
3872
- logger.v.error(err);
3855
+ logger.vF.error('Failed to start Rstest CLI.');
3856
+ logger.vF.error(err);
3873
3857
  }
3874
3858
  }
3875
3859
  var src_config = __webpack_require__("./src/config.ts");
package/dist/worker.js CHANGED
@@ -5002,7 +5002,9 @@ var __webpack_modules__ = {
5002
5002
  stack: error.stack
5003
5003
  };
5004
5004
  if (error instanceof TestRegisterError && test?.type === 'case') errObj.message = `Can't nest describe or test inside a test. ${error.message} because it is nested within test '${test.name}'`;
5005
- if (error.showDiff || void 0 === error.showDiff && void 0 !== error.expected && void 0 !== error.actual) errObj.diff = diff(err.expected, err.actual);
5005
+ if (error.showDiff || void 0 === error.showDiff && void 0 !== error.expected && void 0 !== error.actual) errObj.diff = diff(err.expected, err.actual, {
5006
+ expand: false
5007
+ });
5006
5008
  for (const key of [
5007
5009
  'actual',
5008
5010
  'expected'
@@ -5127,7 +5129,7 @@ var __webpack_modules__ = {
5127
5129
  },
5128
5130
  "./src/utils/logger.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
5129
5131
  __webpack_require__.d(__webpack_exports__, {
5130
- v: ()=>src_logger
5132
+ vF: ()=>src_logger
5131
5133
  });
5132
5134
  var external_node_os_ = __webpack_require__("node:os");
5133
5135
  var external_node_tty_ = __webpack_require__("node:tty");
@@ -5641,7 +5643,7 @@ const createRequire = (filename, distPath, rstestContext, assetFiles, interopDef
5641
5643
  interopDefault
5642
5644
  });
5643
5645
  } catch (err) {
5644
- logger.v.error(`load file ${joinedPath} failed:\n`, err instanceof Error ? err.message : err);
5646
+ logger.vF.error(`load file ${joinedPath} failed:\n`, err instanceof Error ? err.message : err);
5645
5647
  }
5646
5648
  const resolved = _require.resolve(id);
5647
5649
  return _require(resolved);
@@ -5949,7 +5951,7 @@ const onExit = ()=>{
5949
5951
  };
5950
5952
  const runInPool = async (options)=>{
5951
5953
  isTeardown = false;
5952
- const { entryInfo: { distPath, testPath }, setupEntries, assetFiles, type, context: { runtimeConfig: { isolate } } } = options;
5954
+ const { entryInfo: { distPath, testPath }, setupEntries, assetFiles, type, context: { project, runtimeConfig: { isolate } } } = options;
5953
5955
  const cleanups = [];
5954
5956
  const exit = process.exit.bind(process);
5955
5957
  process.exit = (code = process.exitCode || 0)=>{
@@ -5979,12 +5981,14 @@ const runInPool = async (options)=>{
5979
5981
  });
5980
5982
  const tests = await runner.collectTests();
5981
5983
  return {
5984
+ project,
5982
5985
  testPath,
5983
5986
  tests,
5984
5987
  errors: (0, util.o9)(unhandledErrors)
5985
5988
  };
5986
5989
  } catch (err) {
5987
5990
  return {
5991
+ project,
5988
5992
  testPath,
5989
5993
  tests: [],
5990
5994
  errors: (0, util.o9)(err)
@@ -6022,6 +6026,7 @@ const runInPool = async (options)=>{
6022
6026
  return results;
6023
6027
  } catch (err) {
6024
6028
  return {
6029
+ project,
6025
6030
  testPath,
6026
6031
  status: 'fail',
6027
6032
  name: '',
@@ -16,7 +16,11 @@ declare type AfterAllListener = (ctx: SuiteContext) => MaybePromise<void>;
16
16
 
17
17
  export declare const afterEach: Rstest['afterEach'];
18
18
 
19
- declare type AfterEachListener = () => MaybePromise<void>;
19
+ declare type AfterEachListener = (params: {
20
+ task: {
21
+ result: Readonly<TestResult>;
22
+ };
23
+ }) => MaybePromise<void>;
20
24
 
21
25
  export declare const assert: Rstest['assert'];
22
26
 
@@ -386,12 +390,13 @@ declare class DefaultReporter implements Reporter {
386
390
  onTestCaseResult(_result: TestResult): void;
387
391
  onUserConsoleLog(log: UserConsoleLog): void;
388
392
  onExit(): Promise<void>;
389
- onTestRunEnd({ results, testResults, duration, getSourcemap, snapshotSummary, }: {
393
+ onTestRunEnd({ results, testResults, duration, getSourcemap, snapshotSummary, filterRerunTestPaths, }: {
390
394
  results: TestFileResult[];
391
395
  testResults: TestResult[];
392
396
  duration: Duration;
393
397
  snapshotSummary: SnapshotSummary;
394
398
  getSourcemap: GetSourcemap;
399
+ filterRerunTestPaths?: string[];
395
400
  }): Promise<void>;
396
401
  }
397
402
 
@@ -653,6 +658,7 @@ declare class GithubActionsReporter {
653
658
  duration: Duration;
654
659
  snapshotSummary: SnapshotSummary;
655
660
  getSourcemap: GetSourcemap;
661
+ filterRerunTestPaths?: string[];
656
662
  }): Promise<void>;
657
663
  }
658
664
 
@@ -1561,7 +1567,7 @@ declare interface NewPlugin {
1561
1567
  test: Test;
1562
1568
  }
1563
1569
 
1564
- declare type NormalizedConfig = Required<Omit<RstestConfig, OptionalKeys | 'pool'>> & {
1570
+ declare type NormalizedConfig = Required<Omit<RstestConfig, OptionalKeys | 'pool' | 'projects'>> & {
1565
1571
  [key in OptionalKeys]?: RstestConfig[key];
1566
1572
  } & {
1567
1573
  pool: RstestPoolOptions;
@@ -1571,11 +1577,31 @@ declare type NormalizedProcedure<T extends Procedure> = (...args: Parameters<T>)
1571
1577
 
1572
1578
  declare type NormalizedProcedure_2<T extends Procedure_2> = (...args: Parameters<T>) => ReturnType<T>;
1573
1579
 
1580
+ declare type NormalizedProjectConfig = Required<Omit<RstestConfig, OptionalKeys | 'projects' | 'reporters' | 'pool'>> & {
1581
+ [key in OptionalKeys]?: RstestConfig[key];
1582
+ };
1583
+
1574
1584
  declare interface OldPlugin {
1575
1585
  print: (val: unknown, print: Print, indent: Indent, options: PluginOptions, colors: Colors) => string;
1576
1586
  test: Test;
1577
1587
  }
1578
1588
 
1589
+ export declare const onTestFailed: Rstest['onTestFailed'];
1590
+
1591
+ declare type OnTestFailedHandler = (params: {
1592
+ task: {
1593
+ result: Readonly<TestResult>;
1594
+ };
1595
+ }) => MaybePromise<void>;
1596
+
1597
+ export declare const onTestFinished: Rstest['onTestFinished'];
1598
+
1599
+ declare type OnTestFinishedHandler = (params: {
1600
+ task: {
1601
+ result: Readonly<TestResult>;
1602
+ };
1603
+ }) => MaybePromise<void>;
1604
+
1579
1605
  declare type OptionalKeys = 'setupFiles' | 'testNamePattern' | 'plugins' | 'source' | 'resolve' | 'output' | 'performance' | 'tools' | 'dev' | 'onConsoleLog';
1580
1606
 
1581
1607
  declare type OptionsReceived = PrettyFormatOptions;
@@ -1628,6 +1654,16 @@ declare type Procedure = (...args: any[]) => any;
1628
1654
 
1629
1655
  declare type Procedure_2 = (...args: any[]) => any;
1630
1656
 
1657
+ declare type ProjectConfig = Omit<RstestConfig, 'projects' | 'reporters' | 'pool' | 'isolate'>;
1658
+
1659
+ declare type ProjectContext = {
1660
+ name: string;
1661
+ environmentName: string;
1662
+ rootPath: string;
1663
+ configFilePath?: string;
1664
+ normalizedConfig: NormalizedProjectConfig;
1665
+ };
1666
+
1631
1667
  declare type Promisify<O> = { [K in keyof O] : O[K] extends (...args: infer A) => infer R ? Promisify<O[K]> & ((...args: A) => Promise<R>) : O[K] };
1632
1668
 
1633
1669
  declare type Promisify_2<O> = {
@@ -1675,6 +1711,7 @@ export declare interface Reporter {
1675
1711
  duration: Duration;
1676
1712
  getSourcemap: GetSourcemap;
1677
1713
  snapshotSummary: SnapshotSummary;
1714
+ filterRerunTestPaths?: string[];
1678
1715
  }) => MaybePromise<void>;
1679
1716
  /**
1680
1717
  * Called when console log is calling.
@@ -1722,6 +1759,10 @@ export declare interface RstestConfig {
1722
1759
  * @default process.cwd()
1723
1760
  */
1724
1761
  root?: string;
1762
+ /**
1763
+ * Run tests from one or more projects.
1764
+ */
1765
+ projects?: TestProject[];
1725
1766
  /**
1726
1767
  * Project name
1727
1768
  *
@@ -1887,6 +1928,10 @@ declare type RstestContext = {
1887
1928
  fileFilters?: string[];
1888
1929
  /** The config file path. */
1889
1930
  configFilePath?: string;
1931
+ /**
1932
+ * Run tests from one or more projects.
1933
+ */
1934
+ projects: ProjectContext[];
1890
1935
  /**
1891
1936
  * The command type.
1892
1937
  *
@@ -2047,6 +2092,8 @@ declare type RunnerAPI = {
2047
2092
  afterAll: (fn: AfterAllListener, timeout?: number) => MaybePromise<void>;
2048
2093
  beforeEach: (fn: BeforeEachListener, timeout?: number) => MaybePromise<void>;
2049
2094
  afterEach: (fn: AfterEachListener, timeout?: number) => MaybePromise<void>;
2095
+ onTestFinished: (fn: OnTestFinishedHandler, timeout?: number) => void;
2096
+ onTestFailed: (fn: OnTestFailedHandler, timeout?: number) => void;
2050
2097
  };
2051
2098
 
2052
2099
  declare type RuntimeConfig = Pick<RstestContext['normalizedConfig'], 'testTimeout' | 'testNamePattern' | 'globals' | 'passWithNoTests' | 'retry' | 'clearMocks' | 'resetMocks' | 'restoreMocks' | 'unstubEnvs' | 'unstubGlobals' | 'maxConcurrency' | 'printConsoleTrace' | 'disableConsoleIntercept' | 'testEnvironment' | 'isolate' | 'hookTimeout'>;
@@ -2276,6 +2323,8 @@ declare type TestCallbackFn<ExtraContext = object> = (context: TestContext & Ext
2276
2323
 
2277
2324
  declare type TestContext = {
2278
2325
  expect: RstestExpect;
2326
+ onTestFinished: RunnerAPI['onTestFinished'];
2327
+ onTestFailed: RunnerAPI['onTestFailed'];
2279
2328
  };
2280
2329
 
2281
2330
  declare interface TestEachFn {
@@ -2305,6 +2354,13 @@ declare type TestForFn<ExtraContext = object> = <T>(cases: readonly T[]) => (des
2305
2354
  /** The test file original path */
2306
2355
  declare type TestPath = string;
2307
2356
 
2357
+ /**
2358
+ * A list of glob patterns or files that match your test projects.
2359
+ *
2360
+ * eg. ['packages/*', 'examples/node/rstest.config.ts']
2361
+ */
2362
+ declare type TestProject = string | ProjectConfig;
2363
+
2308
2364
  export declare type TestResult = {
2309
2365
  status: TestResultStatus;
2310
2366
  name: string;
@@ -2313,6 +2369,7 @@ export declare type TestResult = {
2313
2369
  duration?: number;
2314
2370
  errors?: FormattedError[];
2315
2371
  retryCount?: number;
2372
+ project: string;
2316
2373
  };
2317
2374
 
2318
2375
  declare type TestResultStatus = 'skip' | 'pass' | 'fail' | 'todo';