1

I have some automation cucumber selenium tests that are run using JUnit in different browsers.

In order for the results to be more readable I would like to change the JUnit XML output so that I can append the browser used to the name attribute of the XML. I am trying to return all the attributes marked as name using XPath. However seems to be returning the wrong information.

Here is an example of the XML.

<?xml version="1.0" encoding="UTF-8"?>
<testsuite failures="1" name="cucumber.runtime.formatter.JUnitFormatter" skipped="0" tests="2" time="880.985693">
<testcase classname="ONLINE Regression Fibre Journey" name="ONLINE_Regression_Fibre_Naked_Journey_TC03" time="393.786644">
<system-out>
<![CDATA[
Given Im on the Spark Broadband Shop page...................................passed
 And select broadband plan...................................................passed
 And Add to cart accepting default selection.................................passed
 And Setup Tell us about where you live......................................passed
 And Delivery and Account setup..............................................passed
 And verify the confirmation page for Fiber new customer.....................passed
 And close the application...................................................passed
]]>
</system-out>
</testcase>
</testsuite>

Below is the Java code

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
org.w3c.dom.Document document = builder.parse(file);
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expression = xpath.compile("//testcase[@name]");
NodeList testsuite = (NodeList)expression.evaluate(document, XPathConstants.NODESET);

Using the inteliJ debugger I am able to see all the nodes in the document object. The Nodelist however only contains the text within the CDATA portion of the XML.

What am I doing wrong? Any help would be greatly appreciated.

Mads Hansen
  • 63,927
  • 12
  • 112
  • 147
M.Waddelow
  • 59
  • 1
  • 9

1 Answers1

0

Your current XPath //testcase[@name] is selecting all of the testcase elements that have a name attribute.

If you want to select all of the name attributes from the testcase elements, then your XPath should be

//testcase/@name

and then you can iterate over the name attributes and use getTextContent() to read it's value and setTextContent() to modify the attribute value.

XPathExpression expression = xpath.compile("//testcase/@name");
NodeList testcaseNames = (NodeList)expression.evaluate(document, XPathConstants.NODESET);
for (int i = 0; i < testcaseNames.getLength(); i++) {
  Node name = testcaseNames.item(i);
  name.setTextContent("browser XYZ " + name.getTextContent());
}
Mads Hansen
  • 63,927
  • 12
  • 112
  • 147
  • Thanks for that Mads much appreciated. I will still need to use a transformer after the loop statements for these to be applied permanently to the file after the loop correct? – M.Waddelow Nov 28 '18 at 02:44
  • You mean, to save that XML document after modifying? Yes. Changes made to the `document` object will be done in-memory. If you want to update the file, you will need to save the document and overwrite the file. https://stackoverflow.com/a/4561785/14419 – Mads Hansen Nov 28 '18 at 03:28