Skip to content

Commit f23b047

Browse files
authored
Merge pull request #8 from mvtm-dn/mvtm-dn-patch-1
cucumber-js 6.x support Close #7
2 parents 76f6a4c + b579f99 commit f23b047

File tree

14 files changed

+1297
-1041
lines changed

14 files changed

+1297
-1041
lines changed

.babelrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"presets": [
33
["env",{ exclude: ["transform-es2015-classes"] }]
4-
]
4+
],
5+
"plugins": ["transform-object-rest-spread"]
56
}

.eslintrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module.exports = {
55
},
66
"extends": "eslint:recommended",
77
"parserOptions": {
8-
"ecmaVersion": 2017,
8+
"ecmaVersion": 2018,
99
"sourceType": "module"
1010
},
1111
"rules": {

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ package-lock.json
44
.nyc_output
55
coverage
66
*.lcov
7+
*.code-workspace

.travis.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
language: node_js
22
node_js:
33
- "8"
4+
before_script:
5+
- 'if [ "$CUCUMBER_VERSION" ]; then npm install cucumber@^$CUCUMBER_VERSION.0.0; fi'
46

7+
env:
8+
- CUCUMBER_VERSION=5
9+
- CUCUMBER_VERSION=6
10+
511
script:
612
- npm run test
713
- npm run coverage:ci

before6/index.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const {Formatter} = require('cucumber');
2+
const xml = require('xml');
3+
const {scenarioAsStep,scenarioAsSuite}=require("./scenarios");
4+
5+
class JUnitFormatter extends Formatter {
6+
/** @param {Options} options */
7+
constructor(options) {
8+
super(options);
9+
this._result=[];
10+
11+
options.eventBroadcaster.on('test-run-started', ()=>{
12+
this._result=[];
13+
});
14+
15+
options.eventBroadcaster.on('test-case-finished', (options.scenarioAsStep?scenarioAsStep:scenarioAsSuite)(options,this._result));
16+
17+
18+
options.eventBroadcaster.on('test-run-finished', ()=>{
19+
this._result.forEach((testSuite)=>{
20+
testSuite.testsuite[0]._attr.time=(testSuite.testsuite[0]._attr.time/1000).toFixed(3);
21+
});
22+
this.log(xml({ testsuites: this._result }, {indent:' ',declaration: { encoding: 'UTF-8' }}));
23+
});
24+
}
25+
26+
}
27+
28+
module.exports = JUnitFormatter;
29+

before6/scenarios.js

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/** Module for cucumber-junit-formatter before cucumber 6.0.0 */
2+
3+
"use strict;";
4+
5+
const {formatterHelpers} = require('cucumber');
6+
const {createProperty,convertNameToId}=require("../util");
7+
8+
/**
9+
* Create failure tag definition
10+
* @param {String} message failure message
11+
* @return {Object} failure tag
12+
*/
13+
const createFailure=(message)=>{
14+
return {
15+
failure: [
16+
{ _attr: { message: message.split("\n").shift() } },
17+
message
18+
]
19+
};
20+
},
21+
22+
/**
23+
* Create failure or error tag
24+
* @param {String} type tag name
25+
* @param {Error} exception exception
26+
* @return {Object} generated tag
27+
*/
28+
createFailureOrError=(type,exception)=>{
29+
let {name}=exception,
30+
ret ={};
31+
ret[type]=[
32+
{ _attr: { message: name } },
33+
formatterHelpers.formatError(exception)
34+
];
35+
return ret;
36+
};
37+
38+
39+
module.exports={
40+
scenarioAsSuite:(options,result)=>{return ({sourceLocation})=>{
41+
const { gherkinDocument, pickle, testCase } = options.eventDataCollector.getTestCaseData(sourceLocation);
42+
let testSuiteId=`${convertNameToId(gherkinDocument.feature.name)};${convertNameToId(pickle.name)}`;
43+
let attr={name:testSuiteId,tests:0,failures:0,skipped:0,errors:0,time:testCase.result.duration||0},
44+
testSuite=[{_attr:attr}];
45+
46+
if (options.withPackage) {
47+
attr.package=convertNameToId(pickle.name);
48+
}
49+
50+
if (pickle.tags.length) {
51+
testSuite.push({properties:pickle.tags.map(tag=>createProperty("tag",tag.name))});
52+
}
53+
54+
testCase.steps.forEach((step,index)=>{
55+
const {gherkinKeyword, pickleStep } = options.eventDataCollector.getTestStepData({testCase:testCase,index:index});
56+
if (gherkinKeyword || (step.result && step.result.status==='failed')) {
57+
let result=step.result || {};
58+
let testCaseId=convertNameToId(gherkinKeyword?pickleStep.text:`${pickle.name} ${index?'after':'before'}`);
59+
let testCase=[
60+
{
61+
_attr:{
62+
classname:testCaseId,
63+
name:gherkinKeyword?pickleStep.text:(pickle.name+(index?' after':' before')),
64+
time:((result.duration || 0)/1000).toFixed(3)
65+
}
66+
}
67+
];
68+
switch (result.status) {
69+
case 'passed':
70+
break;
71+
case 'failed':
72+
testCase.push(createFailureOrError(gherkinKeyword?"failure":"error",result.exception));
73+
if (gherkinKeyword) {
74+
attr.failures+=1;
75+
}
76+
else {
77+
attr.errors+=1;
78+
}
79+
break;
80+
case 'pending':
81+
case 'undefined':
82+
testCase.push(createFailure(result.status === 'pending' ? 'Pending'
83+
: `Undefined step. Implement with the following snippet:\n ${gherkinKeyword.trim()}(/^${pickleStep.text}$/, function(callback) {\n // Write code here that turns the phrase above into concrete actions\n callback(null, 'pending');\n });`
84+
));
85+
attr.failures+=1;
86+
break;
87+
case 'skipped':
88+
testCase.push({skipped: []});
89+
attr.skipped+=1;
90+
break;
91+
case 'ambiguous':
92+
testCase.push(createFailureOrError("error",result.exception));
93+
attr.errors+=1;
94+
break;
95+
default:
96+
break;
97+
// testCase.push(createFailure(`Unknown status - ${step.result.status}`));
98+
}
99+
attr.tests+=1;
100+
testSuite.push({testcase:testCase});
101+
}
102+
});
103+
result.push({testsuite:testSuite});
104+
105+
};
106+
},
107+
108+
scenarioAsStep:(options,result)=>{return ({sourceLocation})=>{
109+
const { gherkinDocument, pickle, testCase } = options.eventDataCollector.getTestCaseData(sourceLocation);
110+
let testSuiteId=`${convertNameToId(gherkinDocument.feature.name)}`,
111+
testCaseId=`${convertNameToId(pickle.name)}`;
112+
let attr,testSuite;
113+
if (result.length && result[result.length-1].testsuite[0]._attr.name===testSuiteId) {
114+
testSuite=result[result.length-1].testsuite;
115+
attr=testSuite[0]._attr;
116+
}
117+
else {
118+
attr={name:testSuiteId,tests:0,failures:0,skipped:0,errors:0,time:0};
119+
testSuite=[{_attr:attr}];
120+
result.push({testsuite:testSuite});
121+
}
122+
attr.time+=testCase.result.duration;
123+
attr.tests+=1;
124+
let testCaseTag=[
125+
{
126+
_attr:{
127+
classname:testCaseId,
128+
name:pickle.name,
129+
time:((testCase.result.duration ||0)/1000).toFixed(3)
130+
}
131+
}
132+
];
133+
134+
if (pickle.tags.length && options.propertiesInTestcase) {
135+
testCaseTag.push({properties:pickle.tags.map(tag=>createProperty("tag",tag.name))});
136+
}
137+
138+
testCase.steps.every((step,index)=>{
139+
const {gherkinKeyword, pickleStep } = options.eventDataCollector.getTestStepData({testCase:testCase,index:index});
140+
if (gherkinKeyword || (step.result && step.result.status==='failed')) {
141+
let result=step.result || {};
142+
switch (result.status) {
143+
case 'passed':
144+
break;
145+
case 'failed':
146+
testCaseTag.push(createFailureOrError(gherkinKeyword?"failure":"error",result.exception));
147+
attr[gherkinKeyword?"failures":"errors"]+=1;
148+
return false;
149+
case 'pending':
150+
case 'undefined':
151+
testCaseTag.push(createFailure(result.status === 'pending' ? 'Pending'
152+
: `Undefined step. Implement with the following snippet:\n ${gherkinKeyword.trim()}(/^${pickleStep.text}$/, function(callback) {\n // Write code here that turns the phrase above into concrete actions\n callback(null, 'pending');\n });`
153+
));
154+
attr.failures+=1;
155+
return false;
156+
case 'skipped':
157+
testCaseTag.push({skipped: []});
158+
attr.skipped+=1;
159+
return false;
160+
case 'ambiguous':
161+
testCaseTag.push(createFailureOrError("error",result.exception));
162+
attr.errors+=1;
163+
return false;
164+
default:
165+
break;
166+
// testCase.push(createFailure(`Unknown status - ${step.result.status}`));
167+
}
168+
}
169+
return true;
170+
});
171+
testSuite.push({testcase:testCaseTag});
172+
};
173+
}
174+
175+
};

0 commit comments

Comments
 (0)