Skip to content

Commit 04d05e5

Browse files
authored
fix missing console.log messages (#3895)
* Ensure that console output is not lost in concurrent reporter * console.log integration test + naming
1 parent b2b1f79 commit 04d05e5

3 files changed

Lines changed: 85 additions & 5 deletions

File tree

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`prints console.logs when run with forceExit 1`] = `
4+
" PASS __tests__/a-banana.js
5+
✓ banana
6+
7+
"
8+
`;
9+
10+
exports[`prints console.logs when run with forceExit 2`] = `
11+
"Test Suites: 1 passed, 1 total
12+
Tests: 1 passed, 1 total
13+
Snapshots: 0 total
14+
Time: <<REPLACED>>
15+
Ran all test suites.
16+
"
17+
`;
18+
19+
exports[`prints console.logs when run with forceExit 3`] = `
20+
" console.log __tests__/a-banana.js:2
21+
Hey
22+
23+
"
24+
`;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
3+
*
4+
* This source code is licensed under the BSD-style license found in the
5+
* LICENSE file in the root directory of this source tree. An additional grant
6+
* of patent rights can be found in the PATENTS file in the same directory.
7+
*/
8+
9+
'use strict';
10+
11+
const path = require('path');
12+
const skipOnWindows = require('skipOnWindows');
13+
const {extractSummary, cleanup, writeFiles} = require('../utils');
14+
const runJest = require('../runJest');
15+
16+
const DIR = path.resolve(__dirname, '../console_log_output_when_run_in_band');
17+
18+
skipOnWindows.suite();
19+
20+
beforeEach(() => cleanup(DIR));
21+
afterAll(() => cleanup(DIR));
22+
23+
test('prints console.logs when run with forceExit', () => {
24+
writeFiles(DIR, {
25+
'__tests__/a-banana.js': `
26+
test('banana', () => console.log('Hey'));
27+
`,
28+
'package.json': '{}',
29+
});
30+
31+
const {stderr, stdout, status} = runJest(DIR, [
32+
'-i',
33+
'--ci=false',
34+
'--forceExit',
35+
]);
36+
const {rest, summary} = extractSummary(stderr);
37+
expect(status).toBe(0);
38+
expect(rest).toMatchSnapshot();
39+
expect(summary).toMatchSnapshot();
40+
expect(stdout).toMatchSnapshot();
41+
});

packages/jest-cli/src/reporters/DefaultReporter.js

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import getConsoleOutput from './getConsoleOutput';
2424
import getResultHeader from './getResultHeader';
2525

2626
type write = (chunk: string, enc?: any, cb?: () => void) => boolean;
27+
type FlushBufferedOutput = () => void;
2728

2829
const TITLE_BULLET = chalk.bold('\u25cf ');
2930

@@ -35,6 +36,7 @@ class DefaultReporter extends BaseReporter {
3536
_globalConfig: GlobalConfig;
3637
_out: write;
3738
_status: Status;
39+
_bufferedOutput: Set<FlushBufferedOutput>;
3840

3941
constructor(globalConfig: GlobalConfig) {
4042
super();
@@ -43,6 +45,7 @@ class DefaultReporter extends BaseReporter {
4345
this._out = process.stdout.write.bind(process.stdout);
4446
this._err = process.stderr.write.bind(process.stderr);
4547
this._status = new Status();
48+
this._bufferedOutput = new Set();
4649
this._wrapStdio(process.stdout);
4750
this._wrapStdio(process.stderr);
4851
this._status.onChange(() => {
@@ -57,25 +60,28 @@ class DefaultReporter extends BaseReporter {
5760
let buffer = [];
5861
let timeout = null;
5962

60-
const doFlush = () => {
63+
const flushBufferedOutput = () => {
6164
const string = buffer.join('');
6265
buffer = [];
6366
// This is to avoid conflicts between random output and status text
6467
this._clearStatus();
6568
originalWrite.call(stream, string);
6669
this._printStatus();
70+
this._bufferedOutput.delete(flushBufferedOutput);
6771
};
6872

69-
const flush = () => {
73+
this._bufferedOutput.add(flushBufferedOutput);
74+
75+
const debouncedFlush = () => {
7076
// If the process blows up no errors would be printed.
7177
// There should be a smart way to buffer stderr, but for now
7278
// we just won't buffer it.
7379
if (stream === process.stderr) {
74-
doFlush();
80+
flushBufferedOutput();
7581
} else {
7682
if (!timeout) {
7783
timeout = setTimeout(() => {
78-
doFlush();
84+
flushBufferedOutput();
7985
timeout = null;
8086
}, 100);
8187
}
@@ -85,11 +91,18 @@ class DefaultReporter extends BaseReporter {
8591
// $FlowFixMe
8692
stream.write = chunk => {
8793
buffer.push(chunk);
88-
flush();
94+
debouncedFlush();
8995
return true;
9096
};
9197
}
9298

99+
// Don't wait for the debounced call and flush all output immediately.
100+
forceFlushBufferedOutput() {
101+
for (const flushBufferedOutput of this._bufferedOutput) {
102+
flushBufferedOutput();
103+
}
104+
}
105+
93106
_clearStatus() {
94107
if (isInteractive) {
95108
this._out(this._clear);
@@ -116,6 +129,7 @@ class DefaultReporter extends BaseReporter {
116129
}
117130

118131
onRunComplete() {
132+
this.forceFlushBufferedOutput();
119133
this._status.runFinished();
120134
// $FlowFixMe
121135
process.stdout.write = this._out;
@@ -139,6 +153,7 @@ class DefaultReporter extends BaseReporter {
139153
test.context.config,
140154
testResult,
141155
);
156+
this.forceFlushBufferedOutput();
142157
}
143158

144159
_printTestFileSummary(

0 commit comments

Comments
 (0)