It may be necessary to return values from XML strings in your automated tests. This article provides examples for common ways to use the Groovy programming language to output XML information.
Cycle includes steps to execute simple Groovy statements inline as well as execute complex Groovy scripts.
The 2 Cycle steps that execute Groovy are:
I execute Groovy "<GROOVY_STATEMENTS>"
I execute Groovy script "<GROOVY_SCRIPT_FILE>"
This article assumes a conceptual familiarity with Groovy/Java including general syntax, data types, import statements, class references and method usage.
For more information on Groovy see Apache Groovy
Two items of note regarding Cycle and Groovy.
This Groovy script, returnFirst.groovy, imports the necessary Classes, parses an XML string value, uses the node attributes to find and print the output in Notepad (just for visual validation).
The values passed in from Cycle are xml - the xml string and tag - the XML tag to search by.
import java.util.*
import groovy.xml.*
//Parse the input string to XML
def stringXML = new XmlParser().parseText(xml)
//Use XML Node attributes to find first occurrence of a tag
val = stringXML.depthFirst().find{it -> it.name() == tag}.text()
output = val.toString()
This is an example of a Scenario calling returnFirst.groovy. The expected output will be only the first occurrence of the tag WH_ID which is WMD1.
Scenario: Return first value for tag
Given I assign "<HDR><WH_ID>WMD1</WH_ID><CLIENT>CLT1</CLIENT><DTL><WH_ID>WMD1</WH_ID><ORDER>ORD1</ORDER><LINE>1</LINE><PART>WIDGET</PART></DTL></HDR>" to variable "xml"
And I assign "WH_ID" to variable "tag"
When I execute groovy script "scripts\returnFirst.groovy"
Then I execute process "notepad.exe"
And I wait 1 seconds
And I enter $output
To go from return first to specifying which node's value to return requires a small change to the original Groovy script.
The code below replaces the bold lines in the original Groovy script
//Use XML Node attributes to return value by tag and node
val = stringXML.depthFirst().findAll{it -> it.name() == tag}[node-1].text()
The Features simply requires the addition of setting a node variable:
And I assign 2 to variable "node"