Skip to content

Commit 580d4b7

Browse files
authored
fix(jest-reporters): print out console log for GHA reporter and group by test file (#15864)
1 parent 6813dfa commit 580d4b7

File tree

4 files changed

+218
-21
lines changed

4 files changed

+218
-21
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
### Fixes
99

10+
- `[jest-reporters]` Fix issue where console output not displayed for GHA reporter even with `silent: false` option ([#15864](https://github.com/jestjs/jest/pull/15864))
1011
- `[jest-runtime]` Fix issue where user cannot utilize dynamic import despite specifying `--experimental-vm-modules` Node option ([#15842](https://github.com/jestjs/jest/pull/15842))
1112
- `[jest-test-sequencer]` Fix issue where failed tests due to compilation errors not getting re-executed even with `--onlyFailures` CLI option ([#15851](https://github.com/jestjs/jest/pull/15851))
1213

packages/jest-reporters/src/GitHubActionsReporter.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import {stripVTControlCharacters as stripAnsi} from 'util';
99
import chalk from 'chalk';
10+
import {type ConsoleBuffer, getConsoleOutput} from '@jest/console';
1011
import type {
1112
AggregatedResult,
1213
AssertionResult,
@@ -66,12 +67,14 @@ type ResultTree = {
6667
export default class GitHubActionsReporter extends BaseReporter {
6768
static readonly filename = __filename;
6869
private readonly options: {silent: boolean};
70+
private readonly globalConfig: Config.GlobalConfig;
6971

7072
constructor(
71-
_globalConfig: Config.GlobalConfig,
73+
globalConfig: Config.GlobalConfig,
7274
reporterOptions: {silent?: boolean} = {},
7375
) {
7476
super();
77+
this.globalConfig = globalConfig;
7578
this.options = {
7679
silent:
7780
typeof reporterOptions.silent === 'boolean'
@@ -90,7 +93,7 @@ export default class GitHubActionsReporter extends BaseReporter {
9093
this.printFullResult(test.context, testResult);
9194
}
9295
if (this.isLastTestSuite(aggregatedResults)) {
93-
this.printFailedTestLogs(test, aggregatedResults);
96+
this.printFailedTestLogs(test, testResult.console, aggregatedResults);
9497
}
9598
}
9699

@@ -179,7 +182,7 @@ export default class GitHubActionsReporter extends BaseReporter {
179182
testDir,
180183
results.perfStats,
181184
);
182-
this.printResultTree(resultTree);
185+
this.printResultTree(resultTree, context.config, results.console);
183186
}
184187

185188
private arrayEqual(a1: Array<any>, a2: Array<any>): boolean {
@@ -311,7 +314,11 @@ export default class GitHubActionsReporter extends BaseReporter {
311314
return node;
312315
}
313316

314-
private printResultTree(resultTree: ResultTree): void {
317+
private printResultTree(
318+
resultTree: ResultTree,
319+
config: Config.ProjectConfig,
320+
consoleLog: ConsoleBuffer | undefined,
321+
): void {
315322
let perfMs;
316323
if (resultTree.performanceInfo.slow) {
317324
perfMs = ` (${chalk.red.inverse(
@@ -324,6 +331,9 @@ export default class GitHubActionsReporter extends BaseReporter {
324331
this.startGroup(
325332
`${chalk.bold.green.inverse('PASS')} ${resultTree.name}${perfMs}`,
326333
);
334+
if (consoleLog && !this.options.silent) {
335+
this.log(getConsoleOutput(consoleLog, config, this.globalConfig));
336+
}
327337
for (const child of resultTree.children) {
328338
this.recursivePrintResultTree(child, true, 1);
329339
}
@@ -401,6 +411,7 @@ export default class GitHubActionsReporter extends BaseReporter {
401411

402412
private printFailedTestLogs(
403413
context: Test,
414+
consoleLog: ConsoleBuffer | undefined,
404415
testResults: AggregatedResult,
405416
): boolean {
406417
const rootDir = context.context.config.rootDir;
@@ -416,6 +427,15 @@ export default class GitHubActionsReporter extends BaseReporter {
416427
written = true;
417428
}
418429
this.startGroup(`Errors thrown in ${testDir}`);
430+
if (consoleLog && !this.options.silent) {
431+
this.log(
432+
getConsoleOutput(
433+
consoleLog,
434+
context.context.config,
435+
this.globalConfig,
436+
),
437+
);
438+
}
419439
this.log(result.failureMessage);
420440
this.endGroup();
421441
}

packages/jest-reporters/src/__tests__/GitHubActionsReporter.test.ts

Lines changed: 119 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ import type {
1313
TestCaseResult,
1414
TestResult,
1515
} from '@jest/test-result';
16-
import {normalizeIcons} from '@jest/test-utils';
17-
import type {Config} from '@jest/types';
16+
import {makeGlobalConfig, normalizeIcons} from '@jest/test-utils';
1817
import BaseGitHubActionsReporter from '../GitHubActionsReporter';
1918

2019
afterEach(() => {
@@ -32,7 +31,7 @@ const mockedStderrWrite = jest
3231
.mockImplementation(() => true);
3332

3433
describe('annotations', () => {
35-
const reporter = new GitHubActionsReporter({} as Config.GlobalConfig);
34+
const reporter = new GitHubActionsReporter(makeGlobalConfig());
3635

3736
const testMeta = {
3837
context: {config: {rootDir: '/user/project'}},
@@ -155,7 +154,7 @@ describe('annotations', () => {
155154

156155
describe('logs', () => {
157156
test('can be instantiated', () => {
158-
const gha = new GitHubActionsReporter({} as Config.GlobalConfig);
157+
const gha = new GitHubActionsReporter(makeGlobalConfig());
159158
expect(gha).toBeTruthy();
160159
expect(gha).toBeInstanceOf(GitHubActionsReporter);
161160
});
@@ -194,7 +193,7 @@ describe('logs', () => {
194193
start: 10,
195194
},
196195
};
197-
const gha = new GitHubActionsReporter({} as Config.GlobalConfig, {
196+
const gha = new GitHubActionsReporter(makeGlobalConfig(), {
198197
silent: false,
199198
});
200199

@@ -237,7 +236,7 @@ describe('logs', () => {
237236
start: 10,
238237
},
239238
};
240-
const gha = new GitHubActionsReporter({} as Config.GlobalConfig, {
239+
const gha = new GitHubActionsReporter(makeGlobalConfig(), {
241240
silent: false,
242241
});
243242

@@ -286,7 +285,7 @@ describe('logs', () => {
286285
start: 10,
287286
},
288287
};
289-
const gha = new GitHubActionsReporter({} as Config.GlobalConfig, {
288+
const gha = new GitHubActionsReporter(makeGlobalConfig(), {
290289
silent: false,
291290
});
292291

@@ -335,7 +334,7 @@ describe('logs', () => {
335334
start: 10,
336335
},
337336
};
338-
const gha = new GitHubActionsReporter({} as Config.GlobalConfig, {
337+
const gha = new GitHubActionsReporter(makeGlobalConfig(), {
339338
silent: false,
340339
});
341340

@@ -396,7 +395,7 @@ describe('logs', () => {
396395
start: 10,
397396
},
398397
};
399-
const gha = new GitHubActionsReporter({} as Config.GlobalConfig, {
398+
const gha = new GitHubActionsReporter(makeGlobalConfig(), {
400399
silent: false,
401400
});
402401

@@ -427,7 +426,7 @@ describe('logs', () => {
427426
start: 10,
428427
},
429428
};
430-
const gha = new GitHubActionsReporter({} as Config.GlobalConfig, {
429+
const gha = new GitHubActionsReporter(makeGlobalConfig(), {
431430
silent: false,
432431
});
433432

@@ -455,7 +454,7 @@ describe('logs', () => {
455454
start: 10,
456455
},
457456
};
458-
const gha = new GitHubActionsReporter({} as Config.GlobalConfig, {
457+
const gha = new GitHubActionsReporter(makeGlobalConfig(), {
459458
silent: false,
460459
});
461460

@@ -489,7 +488,7 @@ describe('logs', () => {
489488
start: 10,
490489
},
491490
};
492-
const gha = new GitHubActionsReporter({} as Config.GlobalConfig, {
491+
const gha = new GitHubActionsReporter(makeGlobalConfig(), {
493492
silent: false,
494493
});
495494

@@ -523,7 +522,7 @@ describe('logs', () => {
523522
start: 10,
524523
},
525524
};
526-
const gha = new GitHubActionsReporter({} as Config.GlobalConfig, {
525+
const gha = new GitHubActionsReporter(makeGlobalConfig(), {
527526
silent: false,
528527
});
529528

@@ -557,7 +556,7 @@ describe('logs', () => {
557556
start: 10,
558557
},
559558
};
560-
const gha = new GitHubActionsReporter({} as Config.GlobalConfig, {
559+
const gha = new GitHubActionsReporter(makeGlobalConfig(), {
561560
silent: false,
562561
});
563562

@@ -591,7 +590,7 @@ describe('logs', () => {
591590
start: 10,
592591
},
593592
};
594-
const gha = new GitHubActionsReporter({} as Config.GlobalConfig, {
593+
const gha = new GitHubActionsReporter(makeGlobalConfig(), {
595594
silent: false,
596595
});
597596

@@ -630,7 +629,7 @@ describe('logs', () => {
630629
numPassedTestSuites: 1,
631630
numTotalTestSuites: 3,
632631
};
633-
const gha = new GitHubActionsReporter({} as Config.GlobalConfig, {
632+
const gha = new GitHubActionsReporter(makeGlobalConfig(), {
634633
silent: false,
635634
});
636635
gha.generateAnnotations = jest.fn();
@@ -674,7 +673,110 @@ describe('logs', () => {
674673
numTotalTestSuites: 3,
675674
testResults: [mockTestResult],
676675
};
677-
const gha = new GitHubActionsReporter({} as Config.GlobalConfig, {
676+
const gha = new GitHubActionsReporter(makeGlobalConfig(), {
677+
silent: false,
678+
});
679+
gha.generateAnnotations = jest.fn();
680+
681+
gha.onTestResult(
682+
mockTest as Test,
683+
mockTestResult as unknown as TestResult,
684+
mockResults as unknown as AggregatedResult,
685+
);
686+
687+
expect(mockedStderrWrite.mock.calls).toMatchSnapshot();
688+
});
689+
690+
test('onTestResult last with console output for failed test', () => {
691+
const mockTest = {
692+
context: {
693+
config: {
694+
rootDir: '/testDir',
695+
},
696+
},
697+
};
698+
const mockTestResult = {
699+
console: [
700+
{
701+
message: 'bar',
702+
origin:
703+
' at Object.log (/tmp/jest-test/a.test.js:2:13)\n at Promise.finally.completed (/github.com/jestjs/jest/packages/jest-circus/build/jestAdapterInit.js:1557:28)',
704+
type: 'log',
705+
},
706+
],
707+
failureMessage: 'Failure message',
708+
perfStats: {
709+
runtime: 20,
710+
slow: false,
711+
},
712+
testFilePath: '/testDir/test1.js',
713+
testResults: [
714+
{
715+
ancestorTitles: [],
716+
duration: 10,
717+
status: 'passed',
718+
title: 'test1',
719+
},
720+
],
721+
};
722+
const mockResults = {
723+
numFailedTestSuites: 1,
724+
numPassedTestSuites: 2,
725+
numTotalTestSuites: 3,
726+
testResults: [mockTestResult],
727+
};
728+
const gha = new GitHubActionsReporter(makeGlobalConfig(), {
729+
silent: false,
730+
});
731+
gha.generateAnnotations = jest.fn();
732+
733+
gha.onTestResult(
734+
mockTest as Test,
735+
mockTestResult as unknown as TestResult,
736+
mockResults as unknown as AggregatedResult,
737+
);
738+
739+
expect(mockedStderrWrite.mock.calls).toMatchSnapshot();
740+
});
741+
742+
test('onTestResult last with console output for success test', () => {
743+
const mockTest = {
744+
context: {
745+
config: {
746+
rootDir: '/testDir',
747+
},
748+
},
749+
};
750+
const mockTestResult = {
751+
console: [
752+
{
753+
message: 'bar',
754+
origin:
755+
' at Object.log (/tmp/jest-test/a.test.js:2:13)\n at Promise.finally.completed (/github.com/jestjs/jest/packages/jest-circus/build/jestAdapterInit.js:1557:28)',
756+
type: 'log',
757+
},
758+
],
759+
perfStats: {
760+
runtime: 20,
761+
slow: false,
762+
},
763+
testFilePath: '/testDir/test1.js',
764+
testResults: [
765+
{
766+
ancestorTitles: [],
767+
duration: 10,
768+
status: 'passed',
769+
title: 'test1',
770+
},
771+
],
772+
};
773+
const mockResults = {
774+
numFailedTestSuites: 0,
775+
numPassedTestSuites: 1,
776+
numTotalTestSuites: 1,
777+
testResults: [mockTestResult],
778+
};
779+
const gha = new GitHubActionsReporter(makeGlobalConfig(), {
678780
silent: false,
679781
});
680782
gha.generateAnnotations = jest.fn();

0 commit comments

Comments
 (0)