Skip to content
This repository has been archived by the owner on Dec 18, 2019. It is now read-only.

Commit

Permalink
wait until all events has been sent to the main process - closes webd…
Browse files Browse the repository at this point in the history
  • Loading branch information
christian-bromann committed Dec 7, 2016
1 parent 062f7f2 commit c82ce95
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 1 deletion.
1 change: 1 addition & 0 deletions lib/adapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class CucumberAdapter {
})
})
await executeHooksWithArgs(this.config.after, [result, this.capabilities, this.specs])
await reporter.waitUntilSettled()

return result
}
Expand Down
20 changes: 19 additions & 1 deletion lib/reporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class CucumberReporter {
this.specs = specs
this.failedCount = 0

this.sentMessages = 0 // number of messages sent to the parent
this.receivedMessages = 0 // number of messages received by the parent

for (const fnName of CUCUMBER_EVENTS) {
this.listener[fnName] = CucumberReporter.prototype[fnName].bind(this)
}
Expand Down Expand Up @@ -196,13 +199,28 @@ class CucumberReporter {
}

message.runner[this.cid] = this.capabilities
this.send(message)

this.sentMessages++
this.send(message, null, {}, () => ++this.receivedMessages)
}

send (message) {
return process.send(message)
}

/**
* wait until all messages were sent to parent
*/
waitUntilSettled () {
return new Promise((resolve) => {
const interval = setInterval(() => {
if (this.sentMessages !== this.receivedMessages) return
clearInterval(interval)
resolve()
}, 100)
})
}

getListener () {
return this.listener
}
Expand Down
129 changes: 129 additions & 0 deletions test/reporter.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import sinon from 'sinon'
import CucumberReporter from '../lib/reporter'

/**
* create mocks
*/
let send
let reporter

function getEvent (name, status = 'pass', line = Math.round(Math.random() * 100)) {
return {
getPayloadItem: () => ({
getName: () => name,
getUriOf: () => 'foobar',
getUri: () => 'foobar2',
getStep: () => getEvent('step', status, line++).getPayloadItem(),
getStatus: () => status,
getFailureException: () => new Error('foobar-error'),
getLine: () => line
})
}
}

const NOOP = () => {}

describe.only('cucumber reporter', () => {
before(() => {
reporter = new CucumberReporter({}, {}, '0-1', ['/foobar.js'])
send = reporter.send = sinon.spy()
})

describe('emits messages for certain cucumber events', () => {
it('should send proper data on handleBeforeFeatureEvent', () => {
reporter.handleBeforeFeatureEvent(getEvent('feature', 'pass', 123), NOOP)
send.calledWithMatch({
event: 'suite:start',
type: 'suite',
uid: 'feature123',
file: 'foobar2',
cid: '0-1'
}).should.be.true()
})

it('should send proper data on handleBeforeScenarioEvent', () => {
reporter.handleBeforeScenarioEvent(getEvent('scenario', 'pass', 124), NOOP)
send.calledWithMatch({
event: 'suite:start',
type: 'suite',
cid: '0-1',
parent: 'feature123',
uid: 'scenario124',
file: 'foobar2'
}).should.be.true()
})

it('should send proper data on handleBeforeStepEvent', () => {
reporter.handleBeforeStepEvent(getEvent('step', 'fail', 125), NOOP)
send.calledWithMatch({
event: 'test:start',
type: 'test',
title: 'step',
cid: '0-1',
parent: 'scenario124',
uid: 'step125',
file: 'foobar2',
duration: 0
}).should.be.true()
})

it('should send proper data on handleStepResultEvent', () => {
reporter.handleStepResultEvent(getEvent('step', 'failed', 126), NOOP)
send.calledWithMatch({
event: 'test:fail',
type: 'test',
title: 'step',
cid: '0-1',
parent: 'scenario124',
uid: 'step126',
file: 'foobar2'
}).should.be.true()
send.args[send.args.length - 1][0].err.message.should.be.equal('foobar-error')
})

it('should send proper data on handleAfterScenarioEvent', () => {
reporter.handleAfterScenarioEvent(getEvent('scenario', null, 127), NOOP)
send.calledWithMatch({
event: 'suite:end',
type: 'suite',
cid: '0-1',
parent: 'feature123',
uid: 'scenario127',
file: 'foobar2'
}).should.be.true()
})

it('should send proper data on handleAfterFeatureEvent', () => {
reporter.handleAfterFeatureEvent(getEvent('feature', null, 128), NOOP)
send.calledWithMatch({
event: 'suite:end',
type: 'suite',
title: 'feature',
file: 'foobar2',
uid: 'feature128',
cid: '0-1',
parent: null
}).should.be.true()
})
})

describe('make sure all commands are sent properly', () => {
it('should wait until all events were sent', () => {
const start = (new Date()).getTime()
setTimeout(() => {
send.args.forEach((arg) => arg[3]())
}, 500)

return reporter.waitUntilSettled().then(() => {
const end = (new Date()).getTime();
(end - start).should.be.greaterThan(500)
})
})
})

describe('provides a fail counter', () => {
it('should have right fail count at the end', () => {
reporter.failedCount.should.be.exactly(1)
})
})
})

0 comments on commit c82ce95

Please sign in to comment.