Skip to content

Commit

Permalink
Merge pull request karma-runner#2664 from LoveIsGrief/feature-karma-2663
Browse files Browse the repository at this point in the history
feat(runner): Buffer stdout and stderr for output when errors occur
  • Loading branch information
dignifiedquire authored Apr 28, 2017
2 parents 722bbbb + 460d423 commit 14b6dfd
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
25 changes: 24 additions & 1 deletion lib/launchers/process.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ var ProcessLauncher = function (spawn, tempDir, timer, processKillTimeout) {
var self = this
var onExitCallback
var killTimeout = processKillTimeout || 2000
// Will hold output from the spawned child process
var streamedOutputs = {
stdout: '',
stderr: ''
}

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

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

this._onStdout = function (data) {
streamedOutputs.stdout += data
}

this._onStderr = function (data) {
streamedOutputs.stderr += data
}

this._execCommand = function (cmd, args) {
if (!cmd) {
log.error('No binary for %s browser on your platform.\n ' +
Expand All @@ -61,9 +74,12 @@ var ProcessLauncher = function (spawn, tempDir, timer, processKillTimeout) {

log.debug(cmd + ' ' + args.join(' '))
self._process = spawn(cmd, args)

var errorOutput = ''

self._process.stdout.on('data', self._onStdout)

self._process.stderr.on('data', self._onStderr)

self._process.on('exit', function (code) {
self._onProcessExit(code, errorOutput)
})
Expand Down Expand Up @@ -98,7 +114,14 @@ var ProcessLauncher = function (spawn, tempDir, timer, processKillTimeout) {
error = 'crashed'
}

if (error) {
log.error('%s stdout: %s', self.name, streamedOutputs.stdout)
log.error('%s stderr: %s', self.name, streamedOutputs.stderr)
}

self._process = null
streamedOutputs.stdout = ''
streamedOutputs.stderr = ''
if (self._killTimer) {
timer.clearTimeout(self._killTimer)
self._killTimer = null
Expand Down
15 changes: 15 additions & 0 deletions test/unit/launchers/process.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ describe('launchers/process.js', () => {

mockSpawn = sinon.spy(function (cmd, args) {
var process = new EventEmitter()
process.stdout = new EventEmitter()
process.stderr = new EventEmitter()
process.kill = sinon.spy()
process.exitCode = null
Expand Down Expand Up @@ -137,16 +138,30 @@ describe('launchers/process.js', () => {

// when the browser fails to get captured in default timeout, it should restart
it('start -> timeout -> restart', (done) => {
var stdOutSpy = sinon.spy(launcher, '_onStdout')
var stdErrSpy = sinon.spy(launcher, '_onStderr')

// start
launcher.start('http://localhost/')

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

var expectedStdoutString = 'starting...'
var expectedStderrString = 'Oops...there was a problem'
browserProcess.stdout.emit('data', expectedStdoutString)
browserProcess.stderr.emit('data', expectedStderrString)

// timeout
mockTimer.wind(101)

// We must've caught some output
expect(stdOutSpy).to.have.been.called
expect(stdErrSpy).to.have.been.called

stdOutSpy.calledWith(expectedStdoutString)

// expect killing browser
expect(browserProcess.kill).to.have.been.called
browserProcess.emit('exit', 0)
Expand Down

0 comments on commit 14b6dfd

Please sign in to comment.