Skip to content

Commit 36ac37f

Browse files
timgrohmanntimgrohmann
authored andcommitted
feat: Add Requirement Tag for XRay Import
1 parent b8b6838 commit 36ac37f

File tree

4 files changed

+45
-16
lines changed

4 files changed

+45
-16
lines changed

java/src/main/java/io/cucumber/junitxmlformatter/XmlReportData.java

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,15 @@
11
package io.cucumber.junitxmlformatter;
22

33
import io.cucumber.messages.Convertor;
4-
import io.cucumber.messages.types.Envelope;
5-
import io.cucumber.messages.types.Feature;
6-
import io.cucumber.messages.types.Pickle;
7-
import io.cucumber.messages.types.PickleStep;
8-
import io.cucumber.messages.types.Step;
9-
import io.cucumber.messages.types.TestCaseStarted;
10-
import io.cucumber.messages.types.TestRunStarted;
11-
import io.cucumber.messages.types.TestStep;
12-
import io.cucumber.messages.types.TestStepFinished;
13-
import io.cucumber.messages.types.TestStepResult;
14-
import io.cucumber.messages.types.TestStepResultStatus;
4+
import io.cucumber.messages.types.*;
155
import io.cucumber.query.Lineage;
166
import io.cucumber.query.NamingStrategy;
177
import io.cucumber.query.Query;
188

199
import java.time.Duration;
10+
import java.util.*;
2011
import java.util.AbstractMap.SimpleEntry;
21-
import java.util.List;
22-
import java.util.Locale;
23-
import java.util.Map;
2412
import java.util.Map.Entry;
25-
import java.util.Optional;
2613

2714
import static io.cucumber.messages.types.TestStepResultStatus.PASSED;
2815
import static java.time.format.DateTimeFormatter.ISO_INSTANT;
@@ -83,6 +70,20 @@ String getFeatureName(TestCaseStarted testCaseStarted) {
8370
.orElseGet(() -> this.getPickle(testCaseStarted).getUri());
8471
}
8572

73+
/**
74+
* Extracts a requirement tag denoted by starting with "@Req:"
75+
*/
76+
List<String> getFeatureRequirements(TestCaseStarted testCaseStarted) {
77+
String requirementPrefix = "Req:";
78+
return query.findPickleBy(testCaseStarted)
79+
.map(Pickle::getTags)
80+
.orElse(Collections.emptyList())
81+
.stream()
82+
.filter(tag -> tag.getName().startsWith(requirementPrefix))
83+
.map(tag -> tag.getName().substring(requirementPrefix.length()))
84+
.collect(toList());
85+
}
86+
8687
List<Entry<String, String>> getStepsAndResult(TestCaseStarted testCaseStarted) {
8788
return query.findTestStepFinishedAndTestStepBy(testCaseStarted)
8889
.stream()

java/src/main/java/io/cucumber/junitxmlformatter/XmlReportWriter.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.util.EnumSet;
1313
import java.util.Map;
1414
import java.util.Optional;
15+
import java.util.stream.Collectors;
1516

1617
import static io.cucumber.messages.types.TestStepResultStatus.PASSED;
1718
import static io.cucumber.messages.types.TestStepResultStatus.SKIPPED;
@@ -78,6 +79,7 @@ private void writeTestcase(EscapingXmlStreamWriter writer, TestCaseStarted testC
7879
writer.writeStartElement("testcase");
7980
writeTestCaseAttributes(writer, testCaseStarted);
8081
writer.writeNewLine();
82+
writeRequirementProperties(writer, testCaseStarted);
8183
writeNonPassedElement(writer, testCaseStarted);
8284
writeStepAndResultList(writer, testCaseStarted);
8385
writer.writeEndElement();
@@ -90,6 +92,19 @@ private void writeTestCaseAttributes(EscapingXmlStreamWriter writer, TestCaseSta
9092
writer.writeAttribute("time", String.valueOf(data.getDurationInSeconds(testCaseStarted)));
9193
}
9294

95+
private void writeRequirementProperties(EscapingXmlStreamWriter writer, TestCaseStarted testCaseStarted) throws XMLStreamException {
96+
List<String> requirements = data.getFeatureRequirements(testCaseStarted);
97+
98+
if (!requirements.isEmpty()) {
99+
writer.writeStartElement("properties");
100+
writer.writeStartElement("property");
101+
writer.writeAttribute("name", "requirements");
102+
writer.writeAttribute("value", String.join(",", requirements));
103+
writer.writeNewLine();
104+
}
105+
106+
}
107+
93108
private void writeNonPassedElement(EscapingXmlStreamWriter writer, TestCaseStarted testCaseStarted) throws XMLStreamException {
94109
TestStepResult result = data.getTestCaseStatus(testCaseStarted);
95110
TestStepResultStatus status = result.getStatus();
@@ -164,4 +179,4 @@ private static String createStepResultList(List<Map.Entry<String, String>> resul
164179
});
165180
return sb.toString();
166181
}
167-
}
182+
}

javascript/src/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ export default {
4141
name: testCase.name,
4242
time: testCase.time,
4343
})
44+
if (testCase.requirements.length > 0) {
45+
const properties = testcaseElement.ele('properties')
46+
properties.ele('property', {
47+
name: 'requirements',
48+
value: testCase.requirements.join(",")
49+
})
50+
}
4451
if (testCase.failure) {
4552
const failureElement = testcaseElement.ele(testCase.failure.kind)
4653
if (testCase.failure.kind === 'failure' && testCase.failure.type) {

javascript/src/makeReport.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ const NAMING_STRATEGY = namingStrategy(
1515
NamingStrategyExampleName.NUMBER_AND_PICKLE_IF_PARAMETERIZED
1616
)
1717

18+
const REQUIREMENT_TAG_PREFIX = "Req:"
19+
1820
interface ReportSuite {
1921
time: number
2022
tests: number
@@ -31,6 +33,7 @@ interface ReportTestCase {
3133
time: number
3234
failure?: ReportFailure
3335
output: string
36+
requirements: string[]
3437
}
3538

3639
interface ReportFailure {
@@ -85,6 +88,9 @@ function makeTestCases(query: Query): ReadonlyArray<ReportTestCase> {
8588
return formatStep(gherkinStep, pickleStep, testStepFinished.testStepResult.status)
8689
})
8790
.join('\n'),
91+
requirements: pickle.tags
92+
.filter(tag => tag.name.startsWith(REQUIREMENT_TAG_PREFIX))
93+
.map(tag => tag.name.substring(REQUIREMENT_TAG_PREFIX.length)),
8894
}
8995
})
9096
}

0 commit comments

Comments
 (0)