test/reporter.spec.js
import sinon from 'sinon'
import CucumberReporter from '../lib/reporter'
import { EventEmitter } from 'events'
const gherkinDocEvent = {
uri: './any.feature',
document: {
type: 'GherkinDocument',
feature: {
type: 'Feature',
tags: [
{ name: '@feature-tag1' },
{ name: '@feature-tag2' }
],
location: { line: 123, column: 1 },
keyword: 'Feature',
name: 'feature',
description: ' This is a feature description\n Second description',
children: [{
type: 'Background',
location: { line: 124, column: 0 },
keyword: 'Background',
name: 'background',
steps: [
{
location: { line: 125, column: 1 },
keyword: 'Given ',
text: 'background-title'
}
]
}, {
type: 'Scenario',
tags: [
{ name: '@scenario-tag1' },
{ name: '@scenario-tag2' }
],
location: { line: 126, column: 0 },
keyword: 'Scenario',
name: 'scenario',
description: ' This should be a scenario description',
steps: [
{
type: 'Step',
location: {line: 127, column: 1},
keyword: 'Given ',
text: 'step-title-passing',
argument: {
type: 'DataTable',
location: { line: 15, column: 13 },
rows: [
{
type: 'TableRow',
location: { line: 15, column: 13 },
cells: [
{
type: 'TableCell',
location: { line: 15, column: 15 },
value: 'Cucumber'
},
{
type: 'TableCell',
location: { line: 15, column: 30 },
value: 'Cucumis sativus'
}
]
},
{
type: 'TableRow',
location: { line: 16, column: 13 },
cells: [
{
type: 'TableCell',
location: { line: 16, column: 15 },
value: 'Burr Gherkin'
},
{
type: 'TableCell',
location: { line: 16, column: 30 },
value: 'Cucumis anguria'
}
]
}
]
}
},
{
type: 'Step',
location: { line: 128, column: 1 },
keyword: 'When ',
text: 'step-title-failing'
}
]
}]
}
}
}
const loadGherkin = (eventBroadcaster) => eventBroadcaster.emit('gherkin-document', gherkinDocEvent)
const acceptPickle = (eventBroadcaster) => eventBroadcaster.emit('pickle-accepted', {
uri: gherkinDocEvent.uri,
pickle: {
tags: [{ name: 'abc' }],
name: 'scenario',
locations: [{ line: 126, column: 1 }],
steps: [{
locations: [{ line: 127, column: 1 }],
keyword: 'Given ',
text: 'step-title-passing'
}]
}
})
const prepareSuite = (eventBroadcaster) => eventBroadcaster.emit('test-case-prepared', {
sourceLocation: { uri: gherkinDocEvent.uri, line: 126 },
steps: [
{
sourceLocation: { uri: gherkinDocEvent.uri, line: 125 },
actionLocation: { uri: gherkinDocEvent.uri, line: 126 }
},
{
sourceLocation: { uri: gherkinDocEvent.uri, line: 127 },
actionLocation: { uri: gherkinDocEvent.uri, line: 126 }
},
{
sourceLocation: { uri: gherkinDocEvent.uri, line: 128 },
actionLocation: { uri: gherkinDocEvent.uri, line: 126 }
}
]
})
const startSuite = (eventBroadcaster) => eventBroadcaster.emit('test-case-started', {})
describe('cucumber reporter', () => {
describe('emits messages for certain cucumber events', () => {
let send
let eventBroadcaster
let reporter
beforeEach(() => {
eventBroadcaster = new EventEmitter()
reporter = new CucumberReporter(eventBroadcaster, { failAmbiguousDefinitions: true }, '0-1', ['/foobar.js'])
send = reporter.send = sinon.stub()
send.returns(true)
})
it('should send proper data on `gherkin-document` event', () => {
loadGherkin(eventBroadcaster)
sinon.assert.calledWithMatch(send, {
event: 'suite:start',
type: 'suite',
uid: 'feature123',
file: './any.feature',
cid: '0-1',
tags: [
{ name: '@feature-tag1' },
{ name: '@feature-tag2' }
]
})
})
it('should not send any data on `pickle-accepted` event', () => {
loadGherkin(eventBroadcaster)
send.reset()
acceptPickle(eventBroadcaster)
sinon.assert.notCalled(send)
})
it('should send accepted pickle\'s data on `test-case-started` event', () => {
loadGherkin(eventBroadcaster)
acceptPickle(eventBroadcaster)
prepareSuite(eventBroadcaster)
send.reset()
startSuite(eventBroadcaster)
sinon.assert.calledWithMatch(send, {
event: 'suite:start',
type: 'suite',
cid: '0-1',
parent: 'feature123',
uid: 'scenario126',
file: './any.feature',
tags: [{ name: 'abc' }]
})
})
it('should send proper data on `test-step-started` event', () => {
loadGherkin(eventBroadcaster)
acceptPickle(eventBroadcaster)
prepareSuite(eventBroadcaster)
startSuite(eventBroadcaster)
send.reset()
eventBroadcaster.emit('test-step-started', {
index: 1,
testCase: {
sourceLocation: { uri: gherkinDocEvent.uri, line: 126 }
}
})
sinon.assert.calledWithMatch(send, {
event: 'test:start',
type: 'test',
title: 'step-title-passing',
cid: '0-1',
parent: 'scenario126',
uid: 'step-title-passing127',
file: './any.feature',
tags: [
{ name: '@scenario-tag1' },
{ name: '@scenario-tag2' }
],
featureName: 'feature',
scenarioName: 'scenario'
})
})
it('should send proper data on successful `test-step-finished` event', () => {
loadGherkin(eventBroadcaster)
acceptPickle(eventBroadcaster)
prepareSuite(eventBroadcaster)
startSuite(eventBroadcaster)
send.reset()
eventBroadcaster.emit('test-step-finished', {
index: 1,
result: { duration: 10, status: 'passed' },
testCase: {
sourceLocation: { uri: gherkinDocEvent.uri, line: 126 }
}
})
sinon.assert.calledWithMatch(send, {
event: 'test:pass',
type: 'test',
title: 'step-title-passing',
cid: '0-1',
parent: 'scenario126',
uid: 'step-title-passing127',
file: './any.feature',
tags: [
{ name: '@scenario-tag1' },
{ name: '@scenario-tag2' }
]
})
})
it('should send proper data on failing `test-step-finished` event with exception', () => {
loadGherkin(eventBroadcaster)
acceptPickle(eventBroadcaster)
prepareSuite(eventBroadcaster)
startSuite(eventBroadcaster)
send.reset()
eventBroadcaster.emit('test-step-finished', {
index: 2,
result: {
duration: 10,
status: 'failed',
exception: new Error('exception-error')
},
testCase: {
sourceLocation: { uri: gherkinDocEvent.uri, line: 126 }
}
})
sinon.assert.calledWithMatch(send, {
event: 'test:fail',
type: 'test',
title: 'step-title-failing',
cid: '0-1',
parent: 'scenario126',
uid: 'step-title-failing128',
file: './any.feature',
tags: [
{ name: '@scenario-tag1' },
{ name: '@scenario-tag2' }
]
})
send.args[send.args.length - 1][0].err.message.should.be.equal('exception-error')
})
it('should send proper data on failing `test-step-finished` event with string error', () => {
loadGherkin(eventBroadcaster)
acceptPickle(eventBroadcaster)
prepareSuite(eventBroadcaster)
startSuite(eventBroadcaster)
send.reset()
eventBroadcaster.emit('test-step-finished', {
index: 2,
result: {
duration: 10,
status: 'failed',
exception: 'string-error'
},
testCase: {
sourceLocation: { uri: gherkinDocEvent.uri, line: 126 }
}
})
sinon.assert.calledWithMatch(send, {
event: 'test:fail',
type: 'test',
title: 'step-title-failing',
cid: '0-1',
parent: 'scenario126',
uid: 'step-title-failing128',
file: './any.feature',
tags: [
{ name: '@scenario-tag1' },
{ name: '@scenario-tag2' }
]
})
send.args[send.args.length - 1][0].err.message.should.be.equal('string-error')
})
it('should send proper data on ambiguous `test-step-finished` event', () => {
loadGherkin(eventBroadcaster)
acceptPickle(eventBroadcaster)
prepareSuite(eventBroadcaster)
startSuite(eventBroadcaster)
send.reset()
eventBroadcaster.emit('test-step-finished', {
index: 2,
result: {
duration: 10,
status: 'ambiguous',
exception: 'cucumber-ambiguous-error-message'
},
testCase: {
sourceLocation: { uri: gherkinDocEvent.uri, line: 126 }
}
})
sinon.assert.calledWithMatch(send, {
event: 'test:fail',
type: 'test',
title: 'step-title-failing',
cid: '0-1',
parent: 'scenario126',
uid: 'step-title-failing128',
file: './any.feature',
tags: [
{ name: '@scenario-tag1' },
{ name: '@scenario-tag2' }
]
})
send.args[send.args.length - 1][0].err.message.should.be.equal('cucumber-ambiguous-error-message')
})
it('should send proper data on `test-case-finished` event', () => {
loadGherkin(eventBroadcaster)
acceptPickle(eventBroadcaster)
prepareSuite(eventBroadcaster)
startSuite(eventBroadcaster)
send.reset()
eventBroadcaster.emit('test-case-finished', {
result: { duration: 0, status: 'passed' },
sourceLocation: { uri: gherkinDocEvent.uri, line: 126 }
})
sinon.assert.calledWithMatch(send, {
event: 'suite:end',
type: 'suite',
cid: '0-1',
parent: 'feature123',
uid: 'scenario126',
file: './any.feature',
tags: [
{ name: '@scenario-tag1' },
{ name: '@scenario-tag2' }
]
})
})
it('should send proper data on `test-run-finished` event', () => {
loadGherkin(eventBroadcaster)
acceptPickle(eventBroadcaster)
prepareSuite(eventBroadcaster)
startSuite(eventBroadcaster)
send.reset()
eventBroadcaster.emit('test-run-finished', {
result: { duration: 0, success: true }
})
sinon.assert.calledWithMatch(send, {
event: 'suite:end',
type: 'suite',
title: 'feature',
file: './any.feature',
uid: 'feature123',
cid: '0-1',
parent: null,
tags: [
{ name: '@feature-tag1' },
{ name: '@feature-tag2' }
]
})
})
})
describe('make sure all commands are sent properly', () => {
const reporter = new CucumberReporter(new EventEmitter(), { failAmbiguousDefinitions: true }, '0-1', ['/foobar.js'])
reporter.send = (_0, _1, _2, callback) => setTimeout(callback, 500)
it('should wait until all events were sent', () => {
const start = (new Date()).getTime()
reporter.emit({}, {})
return reporter.waitUntilSettled().then(() => {
const end = (new Date()).getTime();
(end - start).should.be.greaterThan(500)
})
})
})
describe('provides a fail counter', () => {
let eventBroadcaster
let reporter
beforeEach(() => {
eventBroadcaster = new EventEmitter()
reporter = new CucumberReporter(eventBroadcaster, { failAmbiguousDefinitions: true, ignoreUndefinedDefinitions: false }, '0-1', ['/foobar.js'])
reporter.send = () => {}
})
it('should increment failed counter on `failed` status', () => {
loadGherkin(eventBroadcaster)
acceptPickle(eventBroadcaster)
prepareSuite(eventBroadcaster)
startSuite(eventBroadcaster)
eventBroadcaster.emit('test-step-finished', {
index: 2,
result: {
duration: 10,
status: 'failed',
exception: new Error('exception-error')
},
testCase: {
sourceLocation: { uri: gherkinDocEvent.uri, line: 126 }
}
})
reporter.failedCount.should.be.exactly(1)
})
it('should increment failed counter on `ambiguous` status', () => {
loadGherkin(eventBroadcaster)
acceptPickle(eventBroadcaster)
prepareSuite(eventBroadcaster)
startSuite(eventBroadcaster)
eventBroadcaster.emit('test-step-finished', {
index: 2,
result: {
duration: 10,
status: 'ambiguous',
exception: 'cucumber-ambiguous-error-message'
},
testCase: {
sourceLocation: { uri: gherkinDocEvent.uri, line: 126 }
}
})
reporter.failedCount.should.be.exactly(1)
})
it('should increment failed counter on `undefined` status', () => {
loadGherkin(eventBroadcaster)
acceptPickle(eventBroadcaster)
prepareSuite(eventBroadcaster)
startSuite(eventBroadcaster)
eventBroadcaster.emit('test-step-finished', {
index: 2,
result: {
duration: 10,
status: 'undefined'
},
testCase: {
sourceLocation: { uri: gherkinDocEvent.uri, line: 126 }
}
})
reporter.failedCount.should.be.exactly(1)
})
})
describe('tags in title', () => {
let eventBroadcaster
let reporter
let send
before(() => {
eventBroadcaster = new EventEmitter()
reporter = new CucumberReporter(eventBroadcaster, {
tagsInTitle: true
}, '0-1', ['/foobar.js'])
send = reporter.send = sinon.stub()
send.returns(true)
})
it('should add tags on handleBeforeFeatureEvent', () => {
eventBroadcaster.emit('gherkin-document', gherkinDocEvent)
sinon.assert.calledWithMatch(send, {
event: 'suite:start',
type: 'suite',
title: '@feature-tag1, @feature-tag2: feature',
uid: 'feature123',
file: './any.feature',
cid: '0-1'
})
})
it('should add tags on handleBeforeScenarioEvent', () => {
eventBroadcaster.emit('gherkin-document', gherkinDocEvent)
send.reset()
eventBroadcaster.emit('pickle-accepted', {
uri: gherkinDocEvent.uri,
pickle: {
tags: [
{ name: '@scenario-tag1' },
{ name: '@scenario-tag2' }
],
name: 'scenario',
locations: [{ line: 126, column: 1 }],
steps: [{
locations: [{ line: 127, column: 1 }],
keyword: 'Given ',
text: 'I go on the website "http://webdriver.io" the async way'
}]
}
})
eventBroadcaster.emit('test-case-started', {})
sinon.assert.calledWithMatch(send, {
event: 'suite:start',
type: 'suite',
title: '@scenario-tag1, @scenario-tag2: scenario',
uid: 'scenario126',
file: './any.feature',
cid: '0-1'
})
})
})
})