Your XML response contains env:Header
element with content elements.
<env:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns="beep" xmlns:ns2="bop" xmlns:ns1="foo" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsu:Timestamp wsu:Id="timestamp" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Created>2021-09-15T19:23:13.688Z
</wsu:Created>
<wsu:Expires>2021-09-15T19:28:13.688Z
</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</env:Header>
<env:Body>
<ns:PreAutorizeResponse>
...
The <env:Header>
element makes WS.verifyElementText
keyword confused. Surprisingly enough, it expects the SOAP response to have <env:Body>
only.
Let me be precise. See https://github.com/katalon-studio/katalon-studio-testing-framework/blob/master/Include/scripts/groovy/com/kms/katalon/core/testobject/ResponseObject.java, Line #77:
Node node = (Node) xPath.evaluate("//*//*//*", doc, XPathConstants.NODE);
This is where the problem comes from. When the response XML contains no <env:Header>
element, the node
variable will be
<ns:PreAuthorizeResponse>....
which is as you exepect. But when the response XML contains a <env:Header>
element, the node
variable will be
<wsse:Security> ...
which is not what you expected. Here you would get an error:
? Expected text is 'Approved' but actual element text is:
I am sure that the Katalon programer who wrote WS.verifyElementText
keyword ignored a case where a SOAP response has a <env:Header>
element.
c/c @duyluong
When I made a search in this forum with keyword “WS.verifyElementText”, I found quite a lot of questions. People claimed that they can not get the expected value of XML nodes via this keyword.
- How to verify REST XML Response? - #11 by Niranjan @Brian_Ducson
- Verify element in response, strange behaviour @Paul_Reijling
- SOAP call has unbound prefix fault - #5 by jjbarser @Zarashima
- How to create VerifyElementText Test Case for MTOM Enabled SOAP Web Services? - #6 by Zarashima @Zarashima
- Katalon SOAPUI Validating Response @huynguyen
These questions are unresolved, outstanding. I am afraid that nobody has ever realised how bad the line #77 of https://github.com/katalon-studio/katalon-studio-testing-framework/blob/master/Include/scripts/groovy/com/kms/katalon/core/testobject/ResponseObject.java is. It will continue confusing people in future.
Also, I would argue that the keyword name WS.verifyElementText()
is inappropriate. This name does not express what it does actually. I would propose to Katalon Team
- it should be separated into 2 keywords: one for JSON response (e.g,
WS.verifyJsonElementText()
), another for SOAP response. - the keyword for SOAP response should be named “WS.verifySOAPBodyElementText()”, and clearly state that it works only with a SOAP response without a
Header
element. - also the documentation should clearly state that
WS.verifySOAPBodyElementText()
does not work for arbitrary XML responses like<data><a>A</a><b>B</b></data>
.
As for JSON response, WS.verifyElementText
might be OK. But for XML response, this keyword does not help. You shouldn’t use it.
If Katalon Team finds it difficult to change the codebase for the backward-compatibility concern, then, I would suggest, you should improve the documentation so that people do not waste their time.
What else can you do?
You should avoid the builtin WS.verifyElementText
keyword as long as your XML contains <env:Header>
element.
In Katalon Studio, you can get access to the XML response body, parse it and extract text content out of the XML elements; then you can make assertions: do these by your Groovy scripts (Test Case and Custom Keywords)
By the way, I looked at other API Testing tool Postman. I found that you have to write a bunch of custom codes (in Node.js) to process and verify SOAP messages in Postman. Now a question to you would be; which tool (which scripting language) you like?
Here is a sample Test Case script that can verify your XML Response.
import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
import com.kms.katalon.core.testobject.RequestObject
import com.kms.katalon.core.testobject.ResponseObject
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WS
import groovy.util.slurpersupport.GPathResult
ResponseObject response = WS.sendRequest((RequestObject)findTestObject('data'))
println "response.getResponseText() : " + response.getResponseText()
GPathResult envelope = new XmlSlurper().parseText(response.getResponseText())
.declareNamespace(env: "http://schemas.xmlsoap.org/soap/envelope/",
wsse: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
wsu: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd",
ns: "beep", ns2: "bop", ns1: "foo")
assert envelope.'env:Header'.'wsse:Security'.'wsu:Timestamp'.'wsu:Created'.text().contains('2021-09-15T19:23:13.688Z')
assert envelope.'env:Body'.'ns:PreAuthorizeResponse'.'ns:Receipt'.'ns1:TransactionResult'.text().contains('Approved')
The following post shows you an alternative approach to verify XML respose using XPath.
I think that a Test Case that uses XPath is the best approach to verify a SOAP message.