Skip to content

Commit 8167899

Browse files
authored
feat(jest-reporters): pass reporterContext to custom reporter constructors as third argument (#12657)
1 parent 8a8eb36 commit 8167899

30 files changed

+405
-294
lines changed

.eslintrc.cjs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,6 @@ module.exports = {
101101
'packages/expect/src/print.ts',
102102
'packages/expect/src/toThrowMatchers.ts',
103103
'packages/expect-utils/src/utils.ts',
104-
'packages/jest-core/src/ReporterDispatcher.ts',
105-
'packages/jest-core/src/TestScheduler.ts',
106104
'packages/jest-core/src/collectHandles.ts',
107105
'packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts',
108106
'packages/jest-haste-map/src/index.ts',

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
- `[jest-mock]` Add support for auto-mocking async generator functions ([#11080](https://github.com/facebook/jest/pull/11080))
3939
- `[jest-mock]` Add `contexts` member to mock functions ([#12601](https://github.com/facebook/jest/pull/12601))
4040
- `[jest-reporters]` Add GitHub Actions reporter ([#11320](https://github.com/facebook/jest/pull/11320), [#12658](https://github.com/facebook/jest/pull/12658)
41+
- `[jest-reporters]` Pass `reporterContext` to custom reporter constructors as third argument ([#12657](https://github.com/facebook/jest/pull/12657))
4142
- `[jest-resolve]` [**BREAKING**] Add support for `package.json` `exports` ([#11961](https://github.com/facebook/jest/pull/11961), [#12373](https://github.com/facebook/jest/pull/12373))
4243
- `[jest-resolve, jest-runtime]` Add support for `data:` URI import and mock ([#12392](https://github.com/facebook/jest/pull/12392))
4344
- `[jest-resolve, jest-runtime]` Add support for async resolver ([#11540](https://github.com/facebook/jest/pull/11540))

docs/Configuration.md

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -822,73 +822,76 @@ When using multi-project runner, it's recommended to add a `displayName` for eac
822822

823823
Default: `undefined`
824824

825-
Use this configuration option to add custom reporters to Jest. A custom reporter is a class that implements `onRunStart`, `onTestStart`, `onTestResult`, `onRunComplete` methods that will be called when any of those events occurs.
826-
827-
If custom reporters are specified, the default Jest reporters will be overridden. To keep default reporters, `default` can be passed as a module name.
828-
829-
This will override default reporters:
825+
Use this configuration option to add reporters to Jest. It must be a list of reporter names, additional options can be passed to a reporter using the tuple form:
830826

831827
```json
832828
{
833-
"reporters": ["<rootDir>/my-custom-reporter.js"]
829+
"reporters": [
830+
"default",
831+
["<rootDir>/custom-reporter.js", {"banana": "yes", "pineapple": "no"}]
832+
]
834833
}
835834
```
836835

837-
This will use custom reporter in addition to default reporters that Jest provides:
836+
#### Default Reporter
837+
838+
If custom reporters are specified, the default Jest reporter will be overridden. If you wish to keep it, `'default'` must be passed as a reporters name:
838839

839840
```json
840841
{
841-
"reporters": ["default", "<rootDir>/my-custom-reporter.js"]
842+
"reporters": [
843+
"default",
844+
["jest-junit", {"outputDirectory": "reports", "outputName": "report.xml"}]
845+
]
842846
}
843847
```
844848

845-
Additionally, custom reporters can be configured by passing an `options` object as a second argument:
849+
#### GitHub Actions Reporter
850+
851+
If included in the list, the built-in GitHub Actions Reporter will annotate changed files with test failure messages:
846852

847853
```json
848854
{
849-
"reporters": [
850-
"default",
851-
["<rootDir>/my-custom-reporter.js", {"banana": "yes", "pineapple": "no"}]
852-
]
855+
"reporters": ["default", "github-actions"]
853856
}
854857
```
855858

856-
Custom reporter modules must define a class that takes a `GlobalConfig` and reporter options as constructor arguments:
859+
#### Custom Reporters
857860

858-
Example reporter:
861+
:::tip
862+
863+
Hungry for reporters? Take a look at long list of [awesome reporters](https://github.com/jest-community/awesome-jest/blob/main/README.md#reporters) from Awesome Jest.
864+
865+
:::
859866

860-
```js title="my-custom-reporter.js"
861-
class MyCustomReporter {
862-
constructor(globalConfig, options) {
867+
Custom reporter module must export a class that takes `globalConfig`, `reporterOptions` and `reporterContext` as constructor arguments and implements at least `onRunComplete()` method (for the full list of methods and argument types see `Reporter` interface in [packages/jest-reporters/src/types.ts](https://github.com/facebook/jest/blob/main/packages/jest-reporters/src/types.ts)):
868+
869+
```js title="custom-reporter.js"
870+
class CustomReporter {
871+
constructor(globalConfig, reporterOptions, reporterContext) {
863872
this._globalConfig = globalConfig;
864-
this._options = options;
873+
this._options = reporterOptions;
874+
this._context = reporterContext;
865875
}
866876

867-
onRunComplete(contexts, results) {
877+
onRunComplete(testContexts, results) {
868878
console.log('Custom reporter output:');
869-
console.log('GlobalConfig: ', this._globalConfig);
870-
console.log('Options: ', this._options);
879+
console.log('global config: ', this._globalConfig);
880+
console.log('options for this reporter from Jest config: ', this._options);
881+
console.log('reporter context passed from test scheduler: ', this._context);
871882
}
872-
}
873883

874-
module.exports = MyCustomReporter;
875-
// or export default MyCustomReporter;
876-
```
877-
878-
Custom reporters can also force Jest to exit with non-0 code by returning an Error from `getLastError()` methods
879-
880-
```js
881-
class MyCustomReporter {
882-
// ...
884+
// Optionally, reporters can force Jest to exit with non zero code by returning
885+
// an `Error` from `getLastError()` method.
883886
getLastError() {
884887
if (this._shouldFail) {
885-
return new Error('my-custom-reporter.js reported an error');
888+
return new Error('Custom error reported!');
886889
}
887890
}
888891
}
889-
```
890892

891-
For the full list of methods and argument types see `Reporter` interface in [packages/jest-reporters/src/types.ts](https://github.com/facebook/jest/blob/main/packages/jest-reporters/src/types.ts)
893+
module.exports = CustomReporter;
894+
```
892895

893896
### `resetMocks` \[boolean]
894897

e2e/__tests__/__snapshots__/customReporters.test.ts.snap

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ Object {
2727
"called": true,
2828
"path": false,
2929
},
30-
"options": Object {
30+
"reporterContext": Object {
31+
"firstRun": true,
32+
"previousSuccess": true,
33+
},
34+
"reporterOptions": Object {
3135
"christoph": "pojer",
3236
"dmitrii": "abramov",
3337
"hello": "world",
@@ -55,7 +59,11 @@ Object {
5559
"called": true,
5660
"path": false,
5761
},
58-
"options": Object {
62+
"reporterContext": Object {
63+
"firstRun": true,
64+
"previousSuccess": true,
65+
},
66+
"reporterOptions": Object {
5967
"christoph": "pojer",
6068
"dmitrii": "abramov",
6169
"hello": "world",
@@ -97,7 +105,11 @@ Object {
97105
"called": true,
98106
"path": false,
99107
},
100-
"options": Object {},
108+
"reporterContext": Object {
109+
"firstRun": true,
110+
"previousSuccess": true,
111+
},
112+
"reporterOptions": Object {},
101113
}
102114
`;
103115
@@ -146,7 +158,11 @@ exports[`Custom Reporters Integration valid array format for adding reporters 1`
146158
"called": true,
147159
"path": false
148160
},
149-
"options": {
161+
"reporterContext": {
162+
"firstRun": true,
163+
"previousSuccess": true
164+
},
165+
"reporterOptions": {
150166
"Aaron Abramov": "Awesome"
151167
}
152168
}"

e2e/custom-reporters/reporters/IncompleteReporter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* This only implements one method onRunComplete which should be called
1616
*/
1717
class IncompleteReporter {
18-
onRunComplete(contexts, results) {
18+
onRunComplete(testContexts, results) {
1919
console.log('onRunComplete is called');
2020
console.log(`Passed Tests: ${results.numPassedTests}`);
2121
console.log(`Failed Tests: ${results.numFailedTests}`);

e2e/custom-reporters/reporters/TestReporter.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
* to get the output.
1616
*/
1717
class TestReporter {
18-
constructor(globalConfig, options) {
19-
this._options = options;
18+
constructor(globalConfig, reporterOptions, reporterContext) {
19+
this._context = reporterContext;
20+
this._options = reporterOptions;
2021

2122
/**
2223
* statsCollected property
@@ -30,7 +31,8 @@ class TestReporter {
3031
onRunStart: {},
3132
onTestResult: {times: 0},
3233
onTestStart: {},
33-
options,
34+
reporterContext,
35+
reporterOptions,
3436
};
3537
}
3638

@@ -66,7 +68,7 @@ class TestReporter {
6668
onRunStart.options = typeof options;
6769
}
6870

69-
onRunComplete(contexts, results) {
71+
onRunComplete(testContexts, results) {
7072
const onRunComplete = this._statsCollected.onRunComplete;
7173

7274
onRunComplete.called = true;
@@ -75,9 +77,9 @@ class TestReporter {
7577
onRunComplete.numFailedTests = results.numFailedTests;
7678
onRunComplete.numTotalTests = results.numTotalTests;
7779

78-
if (this._statsCollected.options.maxWorkers) {
80+
if (this._statsCollected.reporterOptions.maxWorkers) {
7981
// Since it's a different number on different machines.
80-
this._statsCollected.options.maxWorkers = '<<REPLACED>>';
82+
this._statsCollected.reporterOptions.maxWorkers = '<<REPLACED>>';
8183
}
8284
// The Final Call
8385
process.stdout.write(JSON.stringify(this._statsCollected, null, 4));

packages/jest-config/src/__tests__/__snapshots__/normalize.test.ts.snap

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,74 @@ exports[`preset throws when preset not found 1`] = `
200200
<red></>"
201201
`;
202202

203+
exports[`reporters throws an error if first value in the tuple is not a string 1`] = `
204+
"<red><bold><bold>● </><bold>Reporter Validation Error</>:</>
205+
<red></>
206+
<red> Unexpected value for Path at index 0 of reporter at index 0</>
207+
<red> Expected:</>
208+
<red> <bold><red>string</><red></></>
209+
<red> Got:</>
210+
<red> <bold><green>number</><red></></>
211+
<red> Reporter configuration:</>
212+
<red> <bold><green>[</><red></></>
213+
<red><bold><green> 123</><red></></>
214+
<red><bold><green> ]</><red></></>
215+
<red></>
216+
<red> <bold>Configuration Documentation:</></>
217+
<red> https://jestjs.io/docs/configuration</>
218+
<red></>"
219+
`;
220+
221+
exports[`reporters throws an error if second value in the tuple is not an object 1`] = `
222+
"<red><bold><bold>● </><bold>Reporter Validation Error</>:</>
223+
<red></>
224+
<red> Unexpected value for Reporter Configuration at index 1 of reporter at index 0</>
225+
<red> Expected:</>
226+
<red> <bold><red>object</><red></></>
227+
<red> Got:</>
228+
<red> <bold><green>boolean</><red></></>
229+
<red> Reporter configuration:</>
230+
<red> <bold><green>[</><red></></>
231+
<red><bold><green> "some-reporter",</><red></></>
232+
<red><bold><green> true</><red></></>
233+
<red><bold><green> ]</><red></></>
234+
<red></>
235+
<red> <bold>Configuration Documentation:</></>
236+
<red> https://jestjs.io/docs/configuration</>
237+
<red></>"
238+
`;
239+
240+
exports[`reporters throws an error if second value is missing in the tuple 1`] = `
241+
"<red><bold><bold>● </><bold>Reporter Validation Error</>:</>
242+
<red></>
243+
<red> Unexpected value for Reporter Configuration at index 1 of reporter at index 0</>
244+
<red> Expected:</>
245+
<red> <bold><red>object</><red></></>
246+
<red> Got:</>
247+
<red> <bold><green>undefined</><red></></>
248+
<red> Reporter configuration:</>
249+
<red> <bold><green>[</><red></></>
250+
<red><bold><green> "some-reporter"</><red></></>
251+
<red><bold><green> ]</><red></></>
252+
<red></>
253+
<red> <bold>Configuration Documentation:</></>
254+
<red> https://jestjs.io/docs/configuration</>
255+
<red></>"
256+
`;
257+
258+
exports[`reporters throws an error if value is neither string nor array 1`] = `
259+
"<red><bold><bold>● </><bold>Reporter Validation Error</>:</>
260+
<red></>
261+
<red> Reporter at index 0 must be of type:</>
262+
<red> <bold><green>array or string</><red></></>
263+
<red> but instead received:</>
264+
<red> <bold><red>number</><red></></>
265+
<red></>
266+
<red> <bold>Configuration Documentation:</></>
267+
<red> https://jestjs.io/docs/configuration</>
268+
<red></>"
269+
`;
270+
203271
exports[`rootDir throws if the options is missing a rootDir property 1`] = `
204272
"<red><bold><bold>● </><bold>Validation Error</>:</>
205273
<red></>

0 commit comments

Comments
 (0)