Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
- `[jest-mock]` [**BREAKING**] Improve the usage of `jest.fn` generic type argument ([#12489](https://github.com/facebook/jest/pull/12489))
- `[jest-mock]` Add support for auto-mocking async generator functions ([#11080](https://github.com/facebook/jest/pull/11080))
- `[jest-mock]` Add `contexts` member to mock functions ([#12601](https://github.com/facebook/jest/pull/12601))
- `[jest-reporters]` Add GitHub Actions reporter ([#11320](https://github.com/facebook/jest/pull/11320))
- `[jest-reporters]` Add GitHub Actions reporter ([#11320](https://github.com/facebook/jest/pull/11320), [#12658](https://github.com/facebook/jest/pull/12658)
- `[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))
- `[jest-resolve, jest-runtime]` Add support for `data:` URI import and mock ([#12392](https://github.com/facebook/jest/pull/12392))
- `[jest-resolve, jest-runtime]` Add support for async resolver ([#11540](https://github.com/facebook/jest/pull/11540))
Expand Down
1 change: 1 addition & 0 deletions jest.config.ci.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = {
...require('./jest.config'),
coverageReporters: ['json'],
reporters: [
'github-actions',
[
'jest-junit',
{outputDirectory: 'reports/junit', outputName: 'js-test-results.xml'},
Expand Down
2 changes: 1 addition & 1 deletion packages/jest-config/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
import * as path from 'path';

export const NODE_MODULES = `${path.sep}node_modules${path.sep}`;
export const BUILD_IN_REPORTERS = ['default', 'github-actions'];
export const DEFAULT_JS_PATTERN = '\\.[jt]sx?$';
export const DEFAULT_REPORTER_LABEL = 'default';
export const PACKAGE_JSON = 'package.json';
export const JEST_CONFIG_BASE_NAME = 'jest.config';
export const JEST_CONFIG_EXT_CJS = '.cjs';
Expand Down
4 changes: 2 additions & 2 deletions packages/jest-config/src/normalize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import DEPRECATED_CONFIG from './Deprecated';
import {validateReporters} from './ReporterValidationErrors';
import VALID_CONFIG from './ValidConfig';
import {getDisplayNameColor} from './color';
import {DEFAULT_JS_PATTERN, DEFAULT_REPORTER_LABEL} from './constants';
import {BUILD_IN_REPORTERS, DEFAULT_JS_PATTERN} from './constants';
import getMaxWorkers from './getMaxWorkers';
import {parseShardPair} from './parseShardPair';
import setFromArgv from './setFromArgv';
Expand Down Expand Up @@ -433,7 +433,7 @@ const normalizeReporters = (options: Config.InitialOptionsWithRootDir) => {
normalizedReporterConfig[0],
);

if (reporterPath !== DEFAULT_REPORTER_LABEL) {
if (!BUILD_IN_REPORTERS.includes(reporterPath)) {
const reporter = Resolver.findNodeModule(reporterPath, {
basedir: options.rootDir,
});
Expand Down
57 changes: 31 additions & 26 deletions packages/jest-core/src/TestScheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import exit = require('exit');
import {
CoverageReporter,
DefaultReporter,
GitHubActionsReporter,
NotifyReporter,
Reporter,
SummaryReporter,
Expand All @@ -28,6 +29,7 @@ import {
} from '@jest/test-result';
import {createScriptTransformer} from '@jest/transform';
import type {Config} from '@jest/types';
import {constants} from 'jest-config';
import {formatExecError} from 'jest-message-util';
import type {JestTestRunner, TestRunnerContext} from 'jest-runner';
import type {Context} from 'jest-runtime';
Expand Down Expand Up @@ -330,25 +332,40 @@ class TestScheduler {
}
}

private _shouldAddDefaultReporters(
reporters?: Array<string | Config.ReporterConfig>,
): boolean {
return (
!reporters ||
!!reporters.find(
reporter => this._getReporterProps(reporter).path === 'default',
)
);
}

async _setupReporters() {
const {collectCoverage, notify, reporters} = this._globalConfig;
const isDefault = this._shouldAddDefaultReporters(reporters);

if (notify) {
this.addReporter(
new NotifyReporter(
this._globalConfig,
this._options.startRun,
this._context,
),
);
}

if (!reporters) {
this._setupDefaultReporters(collectCoverage);
return;
}
Comment on lines +348 to +351
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding NotifyReporter first, allows to return early. Also later reporters && checks become unnecessary.


const reporterNames = reporters.map(
reporter => this._getReporterProps(reporter).path,
);

const isDefault = reporterNames?.includes('default');
const isGitHubActions =
process.env.GITHUB_ACTIONS && reporterNames?.includes('github-actions');

if (isDefault) {
this._setupDefaultReporters(collectCoverage);
}

if (isGitHubActions) {
this.addReporter(new GitHubActionsReporter());
}

if (!isDefault && collectCoverage) {
this.addReporter(
new CoverageReporter(this._globalConfig, {
Expand All @@ -359,19 +376,7 @@ class TestScheduler {
);
}

if (notify) {
this.addReporter(
new NotifyReporter(
this._globalConfig,
this._options.startRun,
this._context,
),
);
}

if (reporters && Array.isArray(reporters)) {
await this._addCustomReporters(reporters);
}
await this._addCustomReporters(reporters);
}

private _setupDefaultReporters(collectCoverage: boolean) {
Expand Down Expand Up @@ -400,7 +405,7 @@ class TestScheduler {
for (const reporter of reporters) {
const {options, path} = this._getReporterProps(reporter);

if (path === 'default') continue;
if (constants.BUILD_IN_REPORTERS.includes(path)) continue;

try {
const Reporter = await requireOrImportModule<any>(path, true);
Expand Down
40 changes: 39 additions & 1 deletion packages/jest-core/src/__tests__/TestScheduler.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
*
*/

import {SummaryReporter} from '@jest/reporters';
import {GitHubActionsReporter, SummaryReporter} from '@jest/reporters';
import {makeGlobalConfig, makeProjectConfig} from '@jest/test-utils';
import {createTestScheduler} from '../TestScheduler';
import * as testSchedulerHelper from '../testSchedulerHelper';

jest.mock('@jest/reporters');

const mockSerialRunner = {
isSerial: true,
runTests: jest.fn(),
Expand All @@ -29,10 +30,18 @@ jest.mock('jest-runner-parallel', () => jest.fn(() => mockParallelRunner), {

const spyShouldRunInBand = jest.spyOn(testSchedulerHelper, 'shouldRunInBand');

const original_GITHUB_ACTIONS = process.env.GITHUB_ACTIONS;

beforeEach(() => {
mockSerialRunner.runTests.mockClear();
mockParallelRunner.runTests.mockClear();
spyShouldRunInBand.mockClear();

process.env.GITHUB_ACTIONS = true;
});

afterEach(() => {
process.env.GITHUB_ACTIONS = original_GITHUB_ACTIONS;
});

test('config for reporters supports `default`', async () => {
Expand Down Expand Up @@ -78,6 +87,35 @@ test('config for reporters supports `default`', async () => {
expect(emptyReportersScheduler._dispatcher._reporters.length).toBe(0);
});

test('config for reporters supports `github-actions`', async () => {
await createTestScheduler(
makeGlobalConfig({
reporters: [],
}),
{},
{},
);
expect(GitHubActionsReporter).toHaveBeenCalledTimes(0);

await createTestScheduler(
makeGlobalConfig({
reporters: ['github-actions'],
}),
{},
{},
);
expect(GitHubActionsReporter).toHaveBeenCalledTimes(1);

await createTestScheduler(
makeGlobalConfig({
reporters: ['default', 'github-actions'],
}),
{},
{},
);
expect(GitHubActionsReporter).toHaveBeenCalledTimes(2);
});

test('.addReporter() .removeReporter()', async () => {
const scheduler = await createTestScheduler(makeGlobalConfig(), {}, {});
const reporter = new SummaryReporter();
Expand Down
4 changes: 3 additions & 1 deletion packages/jest-reporters/src/GitHubActionsReporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ function replaceEntities(s: string): string {
}

export default class GitHubActionsReporter extends BaseReporter {
static readonly filename = __filename;

override onRunComplete(
_contexts?: Set<Context>,
aggregatedResults?: AggregatedResult,
Expand All @@ -48,7 +50,7 @@ function getMessages(results: Array<TestResult> | undefined) {
.filter((m): m is RegExpExecArray => m !== null)
.map(
([message, line, col]) =>
`::error file=${testFilePath},line=${line},col=${col}::${message}`,
`\n::error file=${testFilePath},line=${line},col=${col}::${message}`,
),
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`reporter extracts the correct filename, line, and column 1`] = `
"::error file=/home/runner/work/jest/jest/some.test.js,line=4,col=17::%0A Error: expect(received).toBe(expected) // Object.is equality%0A%0A %0A%0A Expected: "b"%0A%0A Received: "a"%0A%0A at Object.<anonymous> (/home/runner/work/jest/jest/some.test.js:4:17)%0A%0A at Object.asyncJestTest (/home/runner/work/jest/jest/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:106:37)%0A%0A at /home/runner/work/jest/jest/node_modules/jest-jasmine2/build/queueRunner.js:45:12%0A%0A at new Promise (<anonymous>)%0A%0A at mapper (/home/runner/work/jest/jest/node_modules/jest-jasmine2/build/queueRunner.js:28:19)%0A%0A at /home/runner/work/jest/jest/node_modules/jest-jasmine2/build/queueRunner.js:75:41%0A%0A at processTicksAndRejections (internal/process/task_queues.js:93:5)%0A
"
::error file=/home/runner/work/jest/jest/some.test.js,line=4,col=17::%0A Error: expect(received).toBe(expected) // Object.is equality%0A%0A %0A%0A Expected: "b"%0A%0A Received: "a"%0A%0A at Object.<anonymous> (/home/runner/work/jest/jest/some.test.js:4:17)%0A%0A at Object.asyncJestTest (/home/runner/work/jest/jest/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:106:37)%0A%0A at /home/runner/work/jest/jest/node_modules/jest-jasmine2/build/queueRunner.js:45:12%0A%0A at new Promise (<anonymous>)%0A%0A at mapper (/home/runner/work/jest/jest/node_modules/jest-jasmine2/build/queueRunner.js:28:19)%0A%0A at /home/runner/work/jest/jest/node_modules/jest-jasmine2/build/queueRunner.js:75:41%0A%0A at processTicksAndRejections (internal/process/task_queues.js:93:5)%0A
"
`;