From c3ed2e1d9a9c40cf72df8ce659ce58f0bf8b147d Mon Sep 17 00:00:00 2001 From: SteveFlames Date: Fri, 10 Feb 2023 17:19:07 +0100 Subject: [PATCH 01/11] Add option to always print failure messages in summary --- docs/Configuration.md | 29 +++++++++++++++++++ packages/jest-core/src/TestScheduler.ts | 10 +++---- .../jest-reporters/src/SummaryReporter.ts | 12 ++++++-- packages/jest-reporters/src/types.ts | 4 +++ 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/docs/Configuration.md b/docs/Configuration.md index eebddd813855..ab468945376d 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -1322,6 +1322,35 @@ const config: Config = { export default config; ``` +The `summary` reporter accepts options. Since it is included in the `default` reporter you may also pass the options there. + +```js tab +/** @type {import('jest').Config} */ +const config = { + reporters: [ + ['default', {forceFailSummary: true}], + ], +}; + +module.exports = config; +``` + +```ts tab +import type {Config} from 'jest'; + +const config: Config = { + reporters: [ + ['default', {forceFailSummary: true}], + ], +}; + +export default config; +``` + +The `forceFailSummary` option will force to always print a summary of failed tests after executing all the tests. If not set the default behavior is to print this summary only if the number of test suites surpasses an internal threshold. + +For more information about the available options refer to `SummaryReporterOptions` type in the [reporter type definitions](https://github.com/facebook/jest/blob/main/packages/jest-reporters/src/types.ts). + #### Custom Reporters :::tip diff --git a/packages/jest-core/src/TestScheduler.ts b/packages/jest-core/src/TestScheduler.ts index 708f5ae86951..c4048f07f266 100644 --- a/packages/jest-core/src/TestScheduler.ts +++ b/packages/jest-core/src/TestScheduler.ts @@ -336,12 +336,12 @@ class TestScheduler { async _setupReporters() { const {collectCoverage: coverage, notify, verbose} = this._globalConfig; const reporters = this._globalConfig.reporters || [['default', {}]]; - let summary = false; + let summaryOptions; for (const [reporter, options] of reporters) { switch (reporter) { case 'default': - summary = true; + summaryOptions = options; verbose ? this.addReporter(new VerboseReporter(this._globalConfig)) : this.addReporter(new DefaultReporter(this._globalConfig)); @@ -353,7 +353,7 @@ class TestScheduler { ); break; case 'summary': - summary = true; + summaryOptions = options; break; default: await this._addCustomReporter(reporter, options); @@ -368,8 +368,8 @@ class TestScheduler { this.addReporter(new CoverageReporter(this._globalConfig, this._context)); } - if (summary) { - this.addReporter(new SummaryReporter(this._globalConfig)); + if (summaryOptions) { + this.addReporter(new SummaryReporter(this._globalConfig, summaryOptions)); } } diff --git a/packages/jest-reporters/src/SummaryReporter.ts b/packages/jest-reporters/src/SummaryReporter.ts index 90e8095b4d2f..9ce0f80338d9 100644 --- a/packages/jest-reporters/src/SummaryReporter.ts +++ b/packages/jest-reporters/src/SummaryReporter.ts @@ -17,7 +17,7 @@ import BaseReporter from './BaseReporter'; import getResultHeader from './getResultHeader'; import getSnapshotSummary from './getSnapshotSummary'; import getSummary from './getSummary'; -import type {ReporterOnStartOptions} from './types'; +import type {ReporterOnStartOptions, SummaryReporterOptions} from './types'; const TEST_SUMMARY_THRESHOLD = 20; @@ -54,12 +54,17 @@ const {npm_config_user_agent, npm_lifecycle_event, npm_lifecycle_script} = export default class SummaryReporter extends BaseReporter { private _estimatedTime: number; private readonly _globalConfig: Config.GlobalConfig; + private readonly _options: SummaryReporterOptions; static readonly filename = __filename; - constructor(globalConfig: Config.GlobalConfig) { + constructor( + globalConfig: Config.GlobalConfig, + options: SummaryReporterOptions = {}, + ) { super(); this._globalConfig = globalConfig; + this._options = options; this._estimatedTime = 0; } @@ -176,7 +181,8 @@ export default class SummaryReporter extends BaseReporter { const runtimeErrors = aggregatedResults.numRuntimeErrorTestSuites; if ( failedTests + runtimeErrors > 0 && - aggregatedResults.numTotalTestSuites > TEST_SUMMARY_THRESHOLD + (this._options.forceFailSummary || + aggregatedResults.numTotalTestSuites > TEST_SUMMARY_THRESHOLD) ) { this.log(chalk.bold('Summary of all failing tests')); aggregatedResults.testResults.forEach(testResult => { diff --git a/packages/jest-reporters/src/types.ts b/packages/jest-reporters/src/types.ts index dbf0361c7c1f..b8dcf704a687 100644 --- a/packages/jest-reporters/src/types.ts +++ b/packages/jest-reporters/src/types.ts @@ -63,3 +63,7 @@ export type SummaryOptions = { showSeed?: boolean; seed?: number; }; + +export type SummaryReporterOptions = { + forceFailSummary?: boolean; +}; From b011e750a2947b0a5cdf93ef6eba5f9b7e9b0bb3 Mon Sep 17 00:00:00 2001 From: SteveFlames Date: Fri, 10 Feb 2023 17:40:41 +0100 Subject: [PATCH 02/11] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce86f3d161fa..bc0176f1981f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Features - `[jest-message-util]` Add support for [error causes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause) +- `[jest-reporters]` Add `forceFailSummary` option to summary reporter to always print failure messages ### Fixes From 6cdffcb1d049b86b339c77eb4e6e18dd9ad42961 Mon Sep 17 00:00:00 2001 From: SteveFlames Date: Sat, 11 Feb 2023 18:47:52 +0100 Subject: [PATCH 03/11] Add summaryThreshold option to summary reporter --- CHANGELOG.md | 2 +- docs/Configuration.md | 10 +-- e2e/__tests__/summaryThreshold.test.ts | 29 +++++++ .../__tests__/summarySuite1.test.js | 11 +++ .../__tests__/summarySuite2.test.js | 11 +++ .../__tests__/summarySuite3.test.js | 11 +++ e2e/summary-threshold/package.json | 5 ++ .../jest-reporters/src/SummaryReporter.ts | 19 +++-- .../src/__tests__/SummaryReporter.test.js | 75 +++++++++++++++++++ .../SummaryReporter.test.js.snap | 33 ++++++++ packages/jest-reporters/src/types.ts | 2 +- 11 files changed, 193 insertions(+), 15 deletions(-) create mode 100644 e2e/__tests__/summaryThreshold.test.ts create mode 100644 e2e/summary-threshold/__tests__/summarySuite1.test.js create mode 100644 e2e/summary-threshold/__tests__/summarySuite2.test.js create mode 100644 e2e/summary-threshold/__tests__/summarySuite3.test.js create mode 100644 e2e/summary-threshold/package.json diff --git a/CHANGELOG.md b/CHANGELOG.md index bc0176f1981f..070d62ce30f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ### Features - `[jest-message-util]` Add support for [error causes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause) -- `[jest-reporters]` Add `forceFailSummary` option to summary reporter to always print failure messages +- `[jest-reporters]` Add `summaryThreshold` option to summary reporter to allow overriding the internal threshold that is used to print the summary of all failed tests when the number of test suites surpasses it ([#13895](https://github.com/facebook/jest/pull/13895)) ### Fixes diff --git a/docs/Configuration.md b/docs/Configuration.md index ab468945376d..45c1dcaa589f 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -1327,9 +1327,7 @@ The `summary` reporter accepts options. Since it is included in the `default` re ```js tab /** @type {import('jest').Config} */ const config = { - reporters: [ - ['default', {forceFailSummary: true}], - ], + reporters: [['default', {summaryThreshold: 10}]], }; module.exports = config; @@ -1339,15 +1337,13 @@ module.exports = config; import type {Config} from 'jest'; const config: Config = { - reporters: [ - ['default', {forceFailSummary: true}], - ], + reporters: [['default', {summaryThreshold: 10}]], }; export default config; ``` -The `forceFailSummary` option will force to always print a summary of failed tests after executing all the tests. If not set the default behavior is to print this summary only if the number of test suites surpasses an internal threshold. +The `summaryThreshold` option behaves in the following way, if the total number of test suites surpasses this threshold, a detailed summary of all failed tests will be printed after executing all the tests. If not set it defaults to an internal value. For more information about the available options refer to `SummaryReporterOptions` type in the [reporter type definitions](https://github.com/facebook/jest/blob/main/packages/jest-reporters/src/types.ts). diff --git a/e2e/__tests__/summaryThreshold.test.ts b/e2e/__tests__/summaryThreshold.test.ts new file mode 100644 index 000000000000..5d4c9e89ccef --- /dev/null +++ b/e2e/__tests__/summaryThreshold.test.ts @@ -0,0 +1,29 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import runJest from '../runJest'; + +['default', 'summary'].forEach(reporter => { + describe(`${reporter} reporter`, () => { + test('prints failure messages when total number of test suites is over summaryThreshold', () => { + const {exitCode, stderr} = runJest('summary-threshold', [ + '--config', + JSON.stringify({ + reporters: [[reporter, {summaryThreshold: 2}]], + }), + ]); + + expect(exitCode).toBe(1); + expect(stderr).toMatch( + /Summary of all failing tests(\n|.)*expect\(1\)\.toBe\(0\)/, + ); + expect(stderr).toMatch( + /Summary of all failing tests(\n|.)*expect\(2\)\.toBe\(0\)/, + ); + }); + }); +}); diff --git a/e2e/summary-threshold/__tests__/summarySuite1.test.js b/e2e/summary-threshold/__tests__/summarySuite1.test.js new file mode 100644 index 000000000000..87dda7f776f4 --- /dev/null +++ b/e2e/summary-threshold/__tests__/summarySuite1.test.js @@ -0,0 +1,11 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +test('fails', () => { + expect(1).toBe(0); +}); diff --git a/e2e/summary-threshold/__tests__/summarySuite2.test.js b/e2e/summary-threshold/__tests__/summarySuite2.test.js new file mode 100644 index 000000000000..ea74e07cd926 --- /dev/null +++ b/e2e/summary-threshold/__tests__/summarySuite2.test.js @@ -0,0 +1,11 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +test('fails', () => { + expect(2).toBe(0); +}); diff --git a/e2e/summary-threshold/__tests__/summarySuite3.test.js b/e2e/summary-threshold/__tests__/summarySuite3.test.js new file mode 100644 index 000000000000..ba43fbad6561 --- /dev/null +++ b/e2e/summary-threshold/__tests__/summarySuite3.test.js @@ -0,0 +1,11 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +test('passes', () => { + expect(1).toBe(1); +}); diff --git a/e2e/summary-threshold/package.json b/e2e/summary-threshold/package.json new file mode 100644 index 000000000000..148788b25446 --- /dev/null +++ b/e2e/summary-threshold/package.json @@ -0,0 +1,5 @@ +{ + "jest": { + "testEnvironment": "node" + } +} diff --git a/packages/jest-reporters/src/SummaryReporter.ts b/packages/jest-reporters/src/SummaryReporter.ts index 9ce0f80338d9..13463eb5cc6b 100644 --- a/packages/jest-reporters/src/SummaryReporter.ts +++ b/packages/jest-reporters/src/SummaryReporter.ts @@ -19,8 +19,6 @@ import getSnapshotSummary from './getSnapshotSummary'; import getSummary from './getSummary'; import type {ReporterOnStartOptions, SummaryReporterOptions} from './types'; -const TEST_SUMMARY_THRESHOLD = 20; - const NPM_EVENTS = new Set([ 'prepublish', 'publish', @@ -54,7 +52,7 @@ const {npm_config_user_agent, npm_lifecycle_event, npm_lifecycle_script} = export default class SummaryReporter extends BaseReporter { private _estimatedTime: number; private readonly _globalConfig: Config.GlobalConfig; - private readonly _options: SummaryReporterOptions; + private readonly _summaryThreshold: number; static readonly filename = __filename; @@ -64,8 +62,18 @@ export default class SummaryReporter extends BaseReporter { ) { super(); this._globalConfig = globalConfig; - this._options = options; this._estimatedTime = 0; + this.validateOptions(options); + this._summaryThreshold = options.summaryThreshold || 20; + } + + private validateOptions(options: SummaryReporterOptions) { + if ( + options.summaryThreshold && + typeof options.summaryThreshold !== 'number' + ) { + throw new TypeError('The option summaryThreshold should be a number'); + } } // If we write more than one character at a time it is possible that @@ -181,8 +189,7 @@ export default class SummaryReporter extends BaseReporter { const runtimeErrors = aggregatedResults.numRuntimeErrorTestSuites; if ( failedTests + runtimeErrors > 0 && - (this._options.forceFailSummary || - aggregatedResults.numTotalTestSuites > TEST_SUMMARY_THRESHOLD) + aggregatedResults.numTotalTestSuites > this._summaryThreshold ) { this.log(chalk.bold('Summary of all failing tests')); aggregatedResults.testResults.forEach(testResult => { diff --git a/packages/jest-reporters/src/__tests__/SummaryReporter.test.js b/packages/jest-reporters/src/__tests__/SummaryReporter.test.js index 159cb78d83f2..fb83c448194a 100644 --- a/packages/jest-reporters/src/__tests__/SummaryReporter.test.js +++ b/packages/jest-reporters/src/__tests__/SummaryReporter.test.js @@ -160,3 +160,78 @@ test('snapshots all have results (after update)', () => { testReporter.onRunComplete(new Set(), aggregatedResults); expect(results.join('').replace(/\\/g, '/')).toMatchSnapshot(); }); + +describe('summaryThreshold option', () => { + const aggregatedResults = { + numFailedTestSuites: 1, + numFailedTests: 1, + numPassedTestSuites: 2, + numRuntimeErrorTestSuites: 0, + numTotalTestSuites: 3, + numTotalTests: 3, + snapshot: { + filesRemovedList: [], + filesUnmatched: 0, + total: 0, + uncheckedKeysByFile: [], + unmatched: 0, + }, + startTime: 0, + testResults: [ + { + failureMessage: 'FailureMessage1', + numFailingTests: 1, + testFilePath: 'path1', + }, + { + failureMessage: 'FailureMessage2', + numFailingTests: 1, + testFilePath: 'path2', + }, + ], + }; + + it('Should print failure messages when number of test suites is over the threshold', () => { + const options = { + summaryThreshold: aggregatedResults.numTotalTestSuites - 1, + }; + + requireReporter(); + const testReporter = new SummaryReporter(globalConfig, options); + testReporter.onRunComplete(new Set(), aggregatedResults); + expect(results.join('').replace(/\\/g, '/')).toMatchSnapshot(); + }); + + it('Should not print failure messages when number of test suites is under the threshold', () => { + const options = { + summaryThreshold: aggregatedResults.numTotalTestSuites + 1, + }; + + requireReporter(); + const testReporter = new SummaryReporter(globalConfig, options); + testReporter.onRunComplete(new Set(), aggregatedResults); + expect(results.join('').replace(/\\/g, '/')).toMatchSnapshot(); + }); + + it('Should not print failure messages when number of test suites is equal to the threshold', () => { + const options = { + summaryThreshold: aggregatedResults.numTotalTestSuites, + }; + + requireReporter(); + const testReporter = new SummaryReporter(globalConfig, options); + testReporter.onRunComplete(new Set(), aggregatedResults); + expect(results.join('').replace(/\\/g, '/')).toMatchSnapshot(); + }); + + it('Should throw error if threshold is not a number', () => { + const options = { + summaryThreshold: 'not a number', + }; + + requireReporter(); + expect(() => new SummaryReporter(globalConfig, options)).toThrow( + 'The option summaryThreshold should be a number', + ); + }); +}); diff --git a/packages/jest-reporters/src/__tests__/__snapshots__/SummaryReporter.test.js.snap b/packages/jest-reporters/src/__tests__/__snapshots__/SummaryReporter.test.js.snap index 42e5e5366851..60b44ee0f551 100644 --- a/packages/jest-reporters/src/__tests__/__snapshots__/SummaryReporter.test.js.snap +++ b/packages/jest-reporters/src/__tests__/__snapshots__/SummaryReporter.test.js.snap @@ -59,3 +59,36 @@ exports[`snapshots needs update with yarn test 1`] = ` Ran all test suites. " `; + +exports[`summaryThreshold option Should not print failure messages when number of test suites is equal to the threshold 1`] = ` +"Test Suites: 1 failed, 2 passed, 3 total +Tests: 1 failed, 3 total +Snapshots: 0 total +Time: 0.01 s +Ran all test suites. +" +`; + +exports[`summaryThreshold option Should not print failure messages when number of test suites is under the threshold 1`] = ` +"Test Suites: 1 failed, 2 passed, 3 total +Tests: 1 failed, 3 total +Snapshots: 0 total +Time: 0.01 s +Ran all test suites. +" +`; + +exports[`summaryThreshold option Should print failure messages when number of test suites is over the threshold 1`] = ` +"Summary of all failing tests + FAIL ../path1 +FailureMessage1 + FAIL ../path2 +FailureMessage2 + +Test Suites: 1 failed, 2 passed, 3 total +Tests: 1 failed, 3 total +Snapshots: 0 total +Time: 0.01 s +Ran all test suites. +" +`; diff --git a/packages/jest-reporters/src/types.ts b/packages/jest-reporters/src/types.ts index b8dcf704a687..0c968a4c2c53 100644 --- a/packages/jest-reporters/src/types.ts +++ b/packages/jest-reporters/src/types.ts @@ -65,5 +65,5 @@ export type SummaryOptions = { }; export type SummaryReporterOptions = { - forceFailSummary?: boolean; + summaryThreshold?: number; }; From cf4990fe369f18aea593d5a6f230a0369098ad44 Mon Sep 17 00:00:00 2001 From: Stefanos Gkalgkouranas Date: Sat, 11 Feb 2023 23:19:54 +0100 Subject: [PATCH 04/11] Update docs/Configuration.md Co-authored-by: Tom Mrazauskas --- docs/Configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Configuration.md b/docs/Configuration.md index 45c1dcaa589f..f268acabac33 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -1343,7 +1343,7 @@ const config: Config = { export default config; ``` -The `summaryThreshold` option behaves in the following way, if the total number of test suites surpasses this threshold, a detailed summary of all failed tests will be printed after executing all the tests. If not set it defaults to an internal value. +The `summaryThreshold` option behaves in the following way, if the total number of test suites surpasses this threshold, a detailed summary of all failed tests will be printed after executing all the tests. It defaults to `20`. For more information about the available options refer to `SummaryReporterOptions` type in the [reporter type definitions](https://github.com/facebook/jest/blob/main/packages/jest-reporters/src/types.ts). From 9666de8906c350637de97085d0163c2d7152a5e0 Mon Sep 17 00:00:00 2001 From: Stefanos Gkalgkouranas Date: Sat, 11 Feb 2023 23:20:07 +0100 Subject: [PATCH 05/11] Update docs/Configuration.md Co-authored-by: Tom Mrazauskas --- docs/Configuration.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/Configuration.md b/docs/Configuration.md index f268acabac33..e67c176840a6 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -1345,8 +1345,6 @@ export default config; The `summaryThreshold` option behaves in the following way, if the total number of test suites surpasses this threshold, a detailed summary of all failed tests will be printed after executing all the tests. It defaults to `20`. -For more information about the available options refer to `SummaryReporterOptions` type in the [reporter type definitions](https://github.com/facebook/jest/blob/main/packages/jest-reporters/src/types.ts). - #### Custom Reporters :::tip From f46aa5238084f0776f5ea066ee2197b1f76b6936 Mon Sep 17 00:00:00 2001 From: Stefanos Gkalgkouranas Date: Thu, 16 Feb 2023 20:06:13 +0100 Subject: [PATCH 06/11] Minor improvements Co-authored-by: Tom Mrazauskas --- packages/jest-reporters/src/SummaryReporter.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/jest-reporters/src/SummaryReporter.ts b/packages/jest-reporters/src/SummaryReporter.ts index 13463eb5cc6b..d5e7ac66d789 100644 --- a/packages/jest-reporters/src/SummaryReporter.ts +++ b/packages/jest-reporters/src/SummaryReporter.ts @@ -58,18 +58,18 @@ export default class SummaryReporter extends BaseReporter { constructor( globalConfig: Config.GlobalConfig, - options: SummaryReporterOptions = {}, + options?: SummaryReporterOptions, ) { super(); this._globalConfig = globalConfig; this._estimatedTime = 0; - this.validateOptions(options); - this._summaryThreshold = options.summaryThreshold || 20; + this._validateOptions(options); + this._summaryThreshold = options?.summaryThreshold ?? 20; } - private validateOptions(options: SummaryReporterOptions) { + private _validateOptions(options?: SummaryReporterOptions) { if ( - options.summaryThreshold && + options?.summaryThreshold && typeof options.summaryThreshold !== 'number' ) { throw new TypeError('The option summaryThreshold should be a number'); From 13caa0f04e1999b8fd03da3fde1dc80585c0ae07 Mon Sep 17 00:00:00 2001 From: SteveFlames Date: Thu, 16 Feb 2023 20:07:30 +0100 Subject: [PATCH 07/11] Move summary options type closer to class --- packages/jest-reporters/src/SummaryReporter.ts | 6 +++++- packages/jest-reporters/src/types.ts | 4 ---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/jest-reporters/src/SummaryReporter.ts b/packages/jest-reporters/src/SummaryReporter.ts index d5e7ac66d789..d5de84ec4341 100644 --- a/packages/jest-reporters/src/SummaryReporter.ts +++ b/packages/jest-reporters/src/SummaryReporter.ts @@ -17,7 +17,7 @@ import BaseReporter from './BaseReporter'; import getResultHeader from './getResultHeader'; import getSnapshotSummary from './getSnapshotSummary'; import getSummary from './getSummary'; -import type {ReporterOnStartOptions, SummaryReporterOptions} from './types'; +import type {ReporterOnStartOptions} from './types'; const NPM_EVENTS = new Set([ 'prepublish', @@ -49,6 +49,10 @@ const NPM_EVENTS = new Set([ const {npm_config_user_agent, npm_lifecycle_event, npm_lifecycle_script} = process.env; +type SummaryReporterOptions = { + summaryThreshold?: number; +}; + export default class SummaryReporter extends BaseReporter { private _estimatedTime: number; private readonly _globalConfig: Config.GlobalConfig; diff --git a/packages/jest-reporters/src/types.ts b/packages/jest-reporters/src/types.ts index 0c968a4c2c53..dbf0361c7c1f 100644 --- a/packages/jest-reporters/src/types.ts +++ b/packages/jest-reporters/src/types.ts @@ -63,7 +63,3 @@ export type SummaryOptions = { showSeed?: boolean; seed?: number; }; - -export type SummaryReporterOptions = { - summaryThreshold?: number; -}; From 1b03d59703acab3fd46b0aa35b503060a8596ce7 Mon Sep 17 00:00:00 2001 From: SteveFlames Date: Thu, 16 Feb 2023 20:22:35 +0100 Subject: [PATCH 08/11] Add missing newline --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 785ed97c4ef4..49eaeddb03bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## main ### Features + - `[jest-reporters]` Add `summaryThreshold` option to summary reporter to allow overriding the internal threshold that is used to print the summary of all failed tests when the number of test suites surpasses it ([#13895](https://github.com/facebook/jest/pull/13895)) ### Fixes From 23301dec0c5f9b039f95873261241a880b387f50 Mon Sep 17 00:00:00 2001 From: Stefanos Gkalgkouranas Date: Tue, 21 Feb 2023 22:22:04 +0100 Subject: [PATCH 09/11] Improve condition Co-authored-by: Simen Bekkhus --- packages/jest-core/src/TestScheduler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest-core/src/TestScheduler.ts b/packages/jest-core/src/TestScheduler.ts index c4048f07f266..e62e75266e3f 100644 --- a/packages/jest-core/src/TestScheduler.ts +++ b/packages/jest-core/src/TestScheduler.ts @@ -368,7 +368,7 @@ class TestScheduler { this.addReporter(new CoverageReporter(this._globalConfig, this._context)); } - if (summaryOptions) { + if (summaryOptions != null) { this.addReporter(new SummaryReporter(this._globalConfig, summaryOptions)); } } From 11b8e9baf5f95868097998266090cd98ff88fb18 Mon Sep 17 00:00:00 2001 From: SteveFlames Date: Tue, 21 Feb 2023 22:24:01 +0100 Subject: [PATCH 10/11] Merge branch 'main' of https://github.com/facebook/jest into feature/add-option-to-always-print-failure-messages-in-summary --- CHANGELOG.md | 1 + docs/CLI.md | 4 ++++ packages/jest-worker/README.md | 8 ++++++- packages/jest-worker/__benchmarks__/test.js | 5 ++-- .../__typetests__/jest-worker.test.ts | 2 ++ .../jest-worker/src/__tests__/index.test.ts | 1 + .../jest-worker/src/base/BaseWorkerPool.ts | 24 +++++++++++++++++++ packages/jest-worker/src/index.ts | 4 ++++ packages/jest-worker/src/types.ts | 7 +++++- .../jest-worker/src/workers/processChild.ts | 23 ++++++++++++++++++ .../jest-worker/src/workers/threadChild.ts | 23 ++++++++++++++++++ website/versioned_docs/version-25.x/CLI.md | 4 ++++ website/versioned_docs/version-26.x/CLI.md | 4 ++++ website/versioned_docs/version-27.x/CLI.md | 4 ++++ website/versioned_docs/version-28.x/CLI.md | 4 ++++ website/versioned_docs/version-29.0/CLI.md | 4 ++++ website/versioned_docs/version-29.1/CLI.md | 4 ++++ website/versioned_docs/version-29.2/CLI.md | 4 ++++ website/versioned_docs/version-29.3/CLI.md | 4 ++++ website/versioned_docs/version-29.4/CLI.md | 4 ++++ 20 files changed, 133 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49eaeddb03bb..064a27a174f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Features - `[jest-reporters]` Add `summaryThreshold` option to summary reporter to allow overriding the internal threshold that is used to print the summary of all failed tests when the number of test suites surpasses it ([#13895](https://github.com/facebook/jest/pull/13895)) +- `[jest-worker]` Add `start` method to worker farms ([#13937](https://github.com/facebook/jest/pull/13937)) ### Fixes diff --git a/docs/CLI.md b/docs/CLI.md index b4e58977f82a..699076e2e85d 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -182,6 +182,10 @@ Alias: `-c`. The path to a Jest config file specifying how to find and execute t Alias: `--collectCoverage`. Indicates that test coverage information should be collected and reported in the output. Optionally pass `` to override option set in configuration. +### `--coverageDirectory=` + +The directory where Jest should output its coverage files. + ### `--coverageProvider=` Indicates which provider should be used to instrument code for coverage. Allowed values are `babel` (default) or `v8`. diff --git a/packages/jest-worker/README.md b/packages/jest-worker/README.md index 1277ed824bf2..f796d27889b5 100644 --- a/packages/jest-worker/README.md +++ b/packages/jest-worker/README.md @@ -140,11 +140,17 @@ Returns a `ReadableStream` where the standard output of all workers is piped. No Returns a `ReadableStream` where the standard error of all workers is piped. Note that the `silent` option of the child workers must be set to `true` to make it work. This is the default set by `jest-worker`, but keep it in mind when overriding options through `forkOptions`. +#### `start()` + +Starts up every worker and calls their `setup` function, if it exists. Returns a `Promise` which resolves when all workers are running and have completed their `setup`. + +This is useful if you want to start up all your workers eagerly before they are used to call any other functions. + #### `end()` Finishes the workers by killing all workers. No further calls can be done to the `Worker` instance. -Returns a Promise that resolves with `{ forceExited: boolean }` once all workers are dead. If `forceExited` is `true`, at least one of the workers did not exit gracefully, which likely happened because it executed a leaky task that left handles open. This should be avoided, force exiting workers is a last resort to prevent creating lots of orphans. +Returns a `Promise` that resolves with `{ forceExited: boolean }` once all workers are dead. If `forceExited` is `true`, at least one of the workers did not exit gracefully, which likely happened because it executed a leaky task that left handles open. This should be avoided, force exiting workers is a last resort to prevent creating lots of orphans. **Note:** diff --git a/packages/jest-worker/__benchmarks__/test.js b/packages/jest-worker/__benchmarks__/test.js index b2aae08a35f0..86ee6dcb7efb 100644 --- a/packages/jest-worker/__benchmarks__/test.js +++ b/packages/jest-worker/__benchmarks__/test.js @@ -87,11 +87,10 @@ function testJestWorker() { async function countToFinish() { if (++count === calls) { - farm.end(); const endTime = performance.now(); // Let all workers go down. - await sleep(2000); + await farm.end(); resolve({ globalTime: endTime - startTime - 2000, @@ -110,7 +109,7 @@ function testJestWorker() { farm.getStderr().pipe(process.stderr); // Let all workers come up. - await sleep(2000); + await farm.start(); const startProcess = performance.now(); diff --git a/packages/jest-worker/__typetests__/jest-worker.test.ts b/packages/jest-worker/__typetests__/jest-worker.test.ts index 14d634ea8068..e87be50c8edf 100644 --- a/packages/jest-worker/__typetests__/jest-worker.test.ts +++ b/packages/jest-worker/__typetests__/jest-worker.test.ts @@ -88,6 +88,8 @@ expectError(typedWorkerFarm.runTestAsync()); expectError(typedWorkerFarm.setup()); expectError(typedWorkerFarm.teardown()); +expectType>(typedWorkerFarm.start()); + expectError>(typedWorkerFarm.end()); expectType>(typedWorkerFarm.end()); diff --git a/packages/jest-worker/src/__tests__/index.test.ts b/packages/jest-worker/src/__tests__/index.test.ts index b1d1fc755fbc..35acffc3c197 100644 --- a/packages/jest-worker/src/__tests__/index.test.ts +++ b/packages/jest-worker/src/__tests__/index.test.ts @@ -89,6 +89,7 @@ it('exposes the right API using passed worker', () => { getStdout: jest.fn(), getWorkers: jest.fn(), send: jest.fn(), + start: jest.fn(), })); const farm = new WorkerFarm('/tmp/baz.js', { diff --git a/packages/jest-worker/src/base/BaseWorkerPool.ts b/packages/jest-worker/src/base/BaseWorkerPool.ts index 56394f4457f4..92896aab5b2c 100644 --- a/packages/jest-worker/src/base/BaseWorkerPool.ts +++ b/packages/jest-worker/src/base/BaseWorkerPool.ts @@ -7,6 +7,7 @@ import mergeStream = require('merge-stream'); import { + CHILD_MESSAGE_CALL_SETUP, CHILD_MESSAGE_END, PoolExitResult, WorkerInterface, @@ -87,6 +88,29 @@ export default class BaseWorkerPool { throw Error('Missing method createWorker in WorkerPool'); } + async start(): Promise { + await Promise.all( + this._workers.map(async worker => { + await worker.waitForWorkerReady(); + + await new Promise((resolve, reject) => { + worker.send( + [CHILD_MESSAGE_CALL_SETUP], + emptyMethod, + error => { + if (error) { + reject(error); + } else { + resolve(); + } + }, + emptyMethod, + ); + }); + }), + ); + } + async end(): Promise { // We do not cache the request object here. If so, it would only be only // processed by one of the workers, and we want them all to close. diff --git a/packages/jest-worker/src/index.ts b/packages/jest-worker/src/index.ts index ebc7e910834c..c5f5b46bf524 100644 --- a/packages/jest-worker/src/index.ts +++ b/packages/jest-worker/src/index.ts @@ -174,6 +174,10 @@ export class Worker { return this._workerPool.getStdout(); } + async start(): Promise { + await this._workerPool.start(); + } + async end(): Promise { if (this._ending) { throw new Error('Farm is ended, no more calls can be done to it'); diff --git a/packages/jest-worker/src/types.ts b/packages/jest-worker/src/types.ts index 4f6e1c1dac23..dbd1f2b430a1 100644 --- a/packages/jest-worker/src/types.ts +++ b/packages/jest-worker/src/types.ts @@ -36,6 +36,7 @@ export const CHILD_MESSAGE_INITIALIZE = 0; export const CHILD_MESSAGE_CALL = 1; export const CHILD_MESSAGE_END = 2; export const CHILD_MESSAGE_MEM_USAGE = 3; +export const CHILD_MESSAGE_CALL_SETUP = 4; export const PARENT_MESSAGE_OK = 0; export const PARENT_MESSAGE_CLIENT_ERROR = 1; @@ -61,6 +62,7 @@ export interface WorkerPoolInterface { getWorkers(): Array; createWorker(options: WorkerOptions): WorkerInterface; send: WorkerCallback; + start(): Promise; end(): Promise; } @@ -223,11 +225,14 @@ export type ChildMessageEnd = [ export type ChildMessageMemUsage = [type: typeof CHILD_MESSAGE_MEM_USAGE]; +export type ChildMessageCallSetup = [type: typeof CHILD_MESSAGE_CALL_SETUP]; + export type ChildMessage = | ChildMessageInitialize | ChildMessageCall | ChildMessageEnd - | ChildMessageMemUsage; + | ChildMessageMemUsage + | ChildMessageCallSetup; // Messages passed from the children to the parent. diff --git a/packages/jest-worker/src/workers/processChild.ts b/packages/jest-worker/src/workers/processChild.ts index 9eb1016ce715..647f5baa2a04 100644 --- a/packages/jest-worker/src/workers/processChild.ts +++ b/packages/jest-worker/src/workers/processChild.ts @@ -8,6 +8,7 @@ import {isPromise} from 'jest-util'; import { CHILD_MESSAGE_CALL, + CHILD_MESSAGE_CALL_SETUP, CHILD_MESSAGE_END, CHILD_MESSAGE_INITIALIZE, CHILD_MESSAGE_MEM_USAGE, @@ -61,6 +62,28 @@ const messageListener: NodeJS.MessageListener = (request: any) => { reportMemoryUsage(); break; + case CHILD_MESSAGE_CALL_SETUP: + if (initialized) { + reportSuccess(void 0); + } else { + const main = require(file!); + + initialized = true; + + if (main.setup) { + execFunction( + main.setup, + main, + setupArgs, + reportSuccess, + reportInitializeError, + ); + } else { + reportSuccess(void 0); + } + } + break; + default: throw new TypeError( `Unexpected request from parent process: ${request[0]}`, diff --git a/packages/jest-worker/src/workers/threadChild.ts b/packages/jest-worker/src/workers/threadChild.ts index d2703c9480a8..2380e1afd23c 100644 --- a/packages/jest-worker/src/workers/threadChild.ts +++ b/packages/jest-worker/src/workers/threadChild.ts @@ -9,6 +9,7 @@ import {isMainThread, parentPort} from 'worker_threads'; import {isPromise} from 'jest-util'; import { CHILD_MESSAGE_CALL, + CHILD_MESSAGE_CALL_SETUP, CHILD_MESSAGE_END, CHILD_MESSAGE_INITIALIZE, CHILD_MESSAGE_MEM_USAGE, @@ -63,6 +64,28 @@ const messageListener = (request: any) => { reportMemoryUsage(); break; + case CHILD_MESSAGE_CALL_SETUP: + if (initialized) { + reportSuccess(void 0); + } else { + const main = require(file!); + + initialized = true; + + if (main.setup) { + execFunction( + main.setup, + main, + setupArgs, + reportSuccess, + reportInitializeError, + ); + } else { + reportSuccess(void 0); + } + } + break; + default: throw new TypeError( `Unexpected request from parent process: ${request[0]}`, diff --git a/website/versioned_docs/version-25.x/CLI.md b/website/versioned_docs/version-25.x/CLI.md index 981b752111a6..e9808533acb7 100644 --- a/website/versioned_docs/version-25.x/CLI.md +++ b/website/versioned_docs/version-25.x/CLI.md @@ -180,6 +180,10 @@ Alias: `-c`. The path to a Jest config file specifying how to find and execute t Alias: `--collectCoverage`. Indicates that test coverage information should be collected and reported in the output. Optionally pass `` to override option set in configuration. +### `--coverageDirectory=` + +The directory where Jest should output its coverage files. + ### `--coverageProvider=` Indicates which provider should be used to instrument code for coverage. Allowed values are `babel` (default) or `v8`. diff --git a/website/versioned_docs/version-26.x/CLI.md b/website/versioned_docs/version-26.x/CLI.md index 61ce5eddf1ea..decbcfa29883 100644 --- a/website/versioned_docs/version-26.x/CLI.md +++ b/website/versioned_docs/version-26.x/CLI.md @@ -180,6 +180,10 @@ Alias: `-c`. The path to a Jest config file specifying how to find and execute t Alias: `--collectCoverage`. Indicates that test coverage information should be collected and reported in the output. Optionally pass `` to override option set in configuration. +### `--coverageDirectory=` + +The directory where Jest should output its coverage files. + ### `--coverageProvider=` Indicates which provider should be used to instrument code for coverage. Allowed values are `babel` (default) or `v8`. diff --git a/website/versioned_docs/version-27.x/CLI.md b/website/versioned_docs/version-27.x/CLI.md index 3e171549e94a..d6303efcb8d2 100644 --- a/website/versioned_docs/version-27.x/CLI.md +++ b/website/versioned_docs/version-27.x/CLI.md @@ -180,6 +180,10 @@ Alias: `-c`. The path to a Jest config file specifying how to find and execute t Alias: `--collectCoverage`. Indicates that test coverage information should be collected and reported in the output. Optionally pass `` to override option set in configuration. +### `--coverageDirectory=` + +The directory where Jest should output its coverage files. + ### `--coverageProvider=` Indicates which provider should be used to instrument code for coverage. Allowed values are `babel` (default) or `v8`. diff --git a/website/versioned_docs/version-28.x/CLI.md b/website/versioned_docs/version-28.x/CLI.md index 17e28d40a1c3..3306c6a202ab 100644 --- a/website/versioned_docs/version-28.x/CLI.md +++ b/website/versioned_docs/version-28.x/CLI.md @@ -182,6 +182,10 @@ Alias: `-c`. The path to a Jest config file specifying how to find and execute t Alias: `--collectCoverage`. Indicates that test coverage information should be collected and reported in the output. Optionally pass `` to override option set in configuration. +### `--coverageDirectory=` + +The directory where Jest should output its coverage files. + ### `--coverageProvider=` Indicates which provider should be used to instrument code for coverage. Allowed values are `babel` (default) or `v8`. diff --git a/website/versioned_docs/version-29.0/CLI.md b/website/versioned_docs/version-29.0/CLI.md index 4d18b88ccca6..63912d854daa 100644 --- a/website/versioned_docs/version-29.0/CLI.md +++ b/website/versioned_docs/version-29.0/CLI.md @@ -182,6 +182,10 @@ Alias: `-c`. The path to a Jest config file specifying how to find and execute t Alias: `--collectCoverage`. Indicates that test coverage information should be collected and reported in the output. Optionally pass `` to override option set in configuration. +### `--coverageDirectory=` + +The directory where Jest should output its coverage files. + ### `--coverageProvider=` Indicates which provider should be used to instrument code for coverage. Allowed values are `babel` (default) or `v8`. diff --git a/website/versioned_docs/version-29.1/CLI.md b/website/versioned_docs/version-29.1/CLI.md index 4d18b88ccca6..63912d854daa 100644 --- a/website/versioned_docs/version-29.1/CLI.md +++ b/website/versioned_docs/version-29.1/CLI.md @@ -182,6 +182,10 @@ Alias: `-c`. The path to a Jest config file specifying how to find and execute t Alias: `--collectCoverage`. Indicates that test coverage information should be collected and reported in the output. Optionally pass `` to override option set in configuration. +### `--coverageDirectory=` + +The directory where Jest should output its coverage files. + ### `--coverageProvider=` Indicates which provider should be used to instrument code for coverage. Allowed values are `babel` (default) or `v8`. diff --git a/website/versioned_docs/version-29.2/CLI.md b/website/versioned_docs/version-29.2/CLI.md index b4e58977f82a..699076e2e85d 100644 --- a/website/versioned_docs/version-29.2/CLI.md +++ b/website/versioned_docs/version-29.2/CLI.md @@ -182,6 +182,10 @@ Alias: `-c`. The path to a Jest config file specifying how to find and execute t Alias: `--collectCoverage`. Indicates that test coverage information should be collected and reported in the output. Optionally pass `` to override option set in configuration. +### `--coverageDirectory=` + +The directory where Jest should output its coverage files. + ### `--coverageProvider=` Indicates which provider should be used to instrument code for coverage. Allowed values are `babel` (default) or `v8`. diff --git a/website/versioned_docs/version-29.3/CLI.md b/website/versioned_docs/version-29.3/CLI.md index b4e58977f82a..699076e2e85d 100644 --- a/website/versioned_docs/version-29.3/CLI.md +++ b/website/versioned_docs/version-29.3/CLI.md @@ -182,6 +182,10 @@ Alias: `-c`. The path to a Jest config file specifying how to find and execute t Alias: `--collectCoverage`. Indicates that test coverage information should be collected and reported in the output. Optionally pass `` to override option set in configuration. +### `--coverageDirectory=` + +The directory where Jest should output its coverage files. + ### `--coverageProvider=` Indicates which provider should be used to instrument code for coverage. Allowed values are `babel` (default) or `v8`. diff --git a/website/versioned_docs/version-29.4/CLI.md b/website/versioned_docs/version-29.4/CLI.md index b4e58977f82a..699076e2e85d 100644 --- a/website/versioned_docs/version-29.4/CLI.md +++ b/website/versioned_docs/version-29.4/CLI.md @@ -182,6 +182,10 @@ Alias: `-c`. The path to a Jest config file specifying how to find and execute t Alias: `--collectCoverage`. Indicates that test coverage information should be collected and reported in the output. Optionally pass `` to override option set in configuration. +### `--coverageDirectory=` + +The directory where Jest should output its coverage files. + ### `--coverageProvider=` Indicates which provider should be used to instrument code for coverage. Allowed values are `babel` (default) or `v8`. From 6aa3a2aae411d5cfddc7abbe1813a53bb048ed46 Mon Sep 17 00:00:00 2001 From: SteveFlames Date: Fri, 24 Feb 2023 19:26:41 +0100 Subject: [PATCH 11/11] Add type anotation --- packages/jest-core/src/TestScheduler.ts | 3 ++- packages/jest-reporters/src/SummaryReporter.ts | 2 +- packages/jest-reporters/src/index.ts | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/jest-core/src/TestScheduler.ts b/packages/jest-core/src/TestScheduler.ts index e62e75266e3f..00ad2b053768 100644 --- a/packages/jest-core/src/TestScheduler.ts +++ b/packages/jest-core/src/TestScheduler.ts @@ -17,6 +17,7 @@ import { Reporter, ReporterContext, SummaryReporter, + SummaryReporterOptions, VerboseReporter, } from '@jest/reporters'; import { @@ -336,7 +337,7 @@ class TestScheduler { async _setupReporters() { const {collectCoverage: coverage, notify, verbose} = this._globalConfig; const reporters = this._globalConfig.reporters || [['default', {}]]; - let summaryOptions; + let summaryOptions: SummaryReporterOptions | null = null; for (const [reporter, options] of reporters) { switch (reporter) { diff --git a/packages/jest-reporters/src/SummaryReporter.ts b/packages/jest-reporters/src/SummaryReporter.ts index d5de84ec4341..ed7842fedebb 100644 --- a/packages/jest-reporters/src/SummaryReporter.ts +++ b/packages/jest-reporters/src/SummaryReporter.ts @@ -49,7 +49,7 @@ const NPM_EVENTS = new Set([ const {npm_config_user_agent, npm_lifecycle_event, npm_lifecycle_script} = process.env; -type SummaryReporterOptions = { +export type SummaryReporterOptions = { summaryThreshold?: number; }; diff --git a/packages/jest-reporters/src/index.ts b/packages/jest-reporters/src/index.ts index 37a75b11db2c..5e39dbdd477f 100644 --- a/packages/jest-reporters/src/index.ts +++ b/packages/jest-reporters/src/index.ts @@ -30,6 +30,7 @@ export {default as GitHubActionsReporter} from './GitHubActionsReporter'; export {default as NotifyReporter} from './NotifyReporter'; export {default as SummaryReporter} from './SummaryReporter'; export {default as VerboseReporter} from './VerboseReporter'; +export type {SummaryReporterOptions} from './SummaryReporter'; export type { Reporter, ReporterOnStartOptions,