Skip to content

Commit 14b6dfd

Browse files
Merge pull request #2664 from LoveIsGrief/feature-karma-2663
feat(runner): Buffer stdout and stderr for output when errors occur
2 parents 722bbbb + 460d423 commit 14b6dfd

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

lib/launchers/process.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ var ProcessLauncher = function (spawn, tempDir, timer, processKillTimeout) {
66
var self = this
77
var onExitCallback
88
var killTimeout = processKillTimeout || 2000
9+
// Will hold output from the spawned child process
10+
var streamedOutputs = {
11+
stdout: '',
12+
stderr: ''
13+
}
914

1015
this._tempDir = tempDir.getPath('/karma-' + this.id.toString())
1116

@@ -46,6 +51,14 @@ var ProcessLauncher = function (spawn, tempDir, timer, processKillTimeout) {
4651
return path.normalize(cmd)
4752
}
4853

54+
this._onStdout = function (data) {
55+
streamedOutputs.stdout += data
56+
}
57+
58+
this._onStderr = function (data) {
59+
streamedOutputs.stderr += data
60+
}
61+
4962
this._execCommand = function (cmd, args) {
5063
if (!cmd) {
5164
log.error('No binary for %s browser on your platform.\n ' +
@@ -61,9 +74,12 @@ var ProcessLauncher = function (spawn, tempDir, timer, processKillTimeout) {
6174

6275
log.debug(cmd + ' ' + args.join(' '))
6376
self._process = spawn(cmd, args)
64-
6577
var errorOutput = ''
6678

79+
self._process.stdout.on('data', self._onStdout)
80+
81+
self._process.stderr.on('data', self._onStderr)
82+
6783
self._process.on('exit', function (code) {
6884
self._onProcessExit(code, errorOutput)
6985
})
@@ -98,7 +114,14 @@ var ProcessLauncher = function (spawn, tempDir, timer, processKillTimeout) {
98114
error = 'crashed'
99115
}
100116

117+
if (error) {
118+
log.error('%s stdout: %s', self.name, streamedOutputs.stdout)
119+
log.error('%s stderr: %s', self.name, streamedOutputs.stderr)
120+
}
121+
101122
self._process = null
123+
streamedOutputs.stdout = ''
124+
streamedOutputs.stderr = ''
102125
if (self._killTimer) {
103126
timer.clearTimeout(self._killTimer)
104127
self._killTimer = null

test/unit/launchers/process.spec.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ describe('launchers/process.js', () => {
2222

2323
mockSpawn = sinon.spy(function (cmd, args) {
2424
var process = new EventEmitter()
25+
process.stdout = new EventEmitter()
2526
process.stderr = new EventEmitter()
2627
process.kill = sinon.spy()
2728
process.exitCode = null
@@ -137,16 +138,30 @@ describe('launchers/process.js', () => {
137138

138139
// when the browser fails to get captured in default timeout, it should restart
139140
it('start -> timeout -> restart', (done) => {
141+
var stdOutSpy = sinon.spy(launcher, '_onStdout')
142+
var stdErrSpy = sinon.spy(launcher, '_onStderr')
143+
140144
// start
141145
launcher.start('http://localhost/')
142146

143147
// expect starting the process
144148
expect(mockSpawn).to.have.been.calledWith(BROWSER_PATH, ['http://localhost/?id=fake-id'])
145149
var browserProcess = mockSpawn._processes.shift()
146150

151+
var expectedStdoutString = 'starting...'
152+
var expectedStderrString = 'Oops...there was a problem'
153+
browserProcess.stdout.emit('data', expectedStdoutString)
154+
browserProcess.stderr.emit('data', expectedStderrString)
155+
147156
// timeout
148157
mockTimer.wind(101)
149158

159+
// We must've caught some output
160+
expect(stdOutSpy).to.have.been.called
161+
expect(stdErrSpy).to.have.been.called
162+
163+
stdOutSpy.calledWith(expectedStdoutString)
164+
150165
// expect killing browser
151166
expect(browserProcess.kill).to.have.been.called
152167
browserProcess.emit('exit', 0)

0 commit comments

Comments
 (0)