How to get testStep responseAsXml in groovyScript - groovy

Concerning soapUI and groovy, I'm trying to get assertion (working) and response both in XML into a variable. I get the error
groovy.lang.MissingMethodException: No signature of method: com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep.getResponseAsXml() is applicable for argument types: () values: [] error at line: 6
I have tried adding import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep but still cant figure it. I did another attempt with message exchange, also to no avail - from what i understand you can't actually use messageExchange in this particular instance
import com.eviware.soapui.model.testsuite.Assertable.AssertionStatus
def TestCase = testRunner.getTestCase()
def StepList = TestCase.getTestStepList()
StepList.each
{
if(it.metaClass.hasProperty(it,'assertionStatus'))
{
if(it.assertionStatus == AssertionStatus.FAILED)
{
def ass = it.getAssertableContentAsXml()
def res = it.getResponseContentAsXml()
log.error "${it.name} " + "${it.assertionStatus}"
log.info ass + res
}
}
}

If you want to get the response from com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep, a possible way is first get the testStep from this class using getTestStep() method.
This method returns a object of class com.eviware.soapui.model.testsuite.TestStep, from this object you can get the testSteps properties like request, response, endpoint... using getPropertyValue(java.lang.string) method.
So in your case to get the response use:
def res = it.getTestStep().getPropertyValue('Response')
instead of:
def res = it.getResponseContentAsXml()
As #tim_yates comments the exception description in this case it's pretty clear, so please take a look at the SOAPUI api and at the links provided in the answer for the next time :).
Hope this helps,

Related

How to assert if item from response is equal to item from properties

I'd like to make assert to check that data which I sent by REST request with json is equal to item from test case properties. I dont know how to deliver it from test request properties.
Initialy I am traying wrote script assertion like below, but probbaly getProperty doesnt work:
import groovy.json.JsonSlurper
def responseMessage = messageExchange.response.responseContent
def json = new JsonSlurper().parseText(responseMessage)
assert json.items[0].agreementTypeID == testRunner.testCase.getPropertyValue('agreementTypeID').toInteger()
// Script assertion only context will work
log.info context.testCase.getPropertyValue("agreementTypeID")
// Script assertion testrunner will not work
log.info testRunner.testCase.getPropertyValue('agreementTypeID')
So if you replace the testRunner with context it should work in Script Assertion .
TestRunner is available in Groovy step and there is a special way of making testRunner available in Script Assertion , but above is better

Passing token from get request to a header in SoapUI

I have a getToken request in a test case get_Admin_Token in PassToken test suite, where I have as a response following JSON:
{
"access_token": "5701f536-0bd5-441f-a490-21aafeasdasdd",
"token_type": "bearer",
"refresh_token": "c53af657-8292-4aff-xxxx-xxxf0ffed310",
"expires_in": 80208,
"scope": "read write trust"
}
I need to use access_token value in uploadFile method, but I need to pass it in a header. I have a field Authorization with Bearer: $(access_token) value.
Using some google I found:
https://community.smartbear.com/t5/SoapUI-Open-Source/How-do-I-do-a-property-transfer-with-multiple-source-responses/td-p/106456 question, which was looking similar. I started to create a GroovyScript test step, where I used code to pass it to the Properties table, but no success. I was also trying to put it to assertions for the get_Admin_Token, but I got a message about incorrect object types. I also tried to use def accessToken = jsonSlurper.access_token.toString() to use strings, but now I got an error `
No signature of method:
com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase.setProperty() is
applicable for argument types: (java.lang.String, java.lang.String) values:
[AUTH_KEY, Bearer 5701f536-0bd5-441f-a490-21aafeasdasdd] Possible solutions:
getProperty(java.lang.String), addProperty(java.lang.String),
hasProperty(java.lang.String), hasProperty(java.lang.String), getProject(),
getProperties()
My groovy code:
import groovy.json.JsonSlurper
def response = messageExchange.response.responseContent
def jsonSlurper = new JsonSlurper().parseText(response)
assert !(jsonSlurper.isEmpty())
def accessToken = jsonSlurper.access_token.toString()
assert null != accessToken, "access_token does not have a value"
def authorizationKey = "${accessToken}"
context.testCase.setProperty('AUTH_KEY',"Bearer " + authorizationKey)
Is this code valid? I'm not sure what to put in next method as authorization value in header, I tried with ${#get_Admin_Token#AUTH_KEY}, but it doesn't work
EDIT: Easier way
Just pass Token to properties using transfer action and set in header Bearer ${Properties#AdminToken}. That's all
===================
Old version:
The following answer is correct if anyone is looking for the Groovy script:
Ok, I think I spotted a workaround.
Groovy code is as following:
import groovy.json.JsonSlurper
def response = messageExchange.response.responseContent
def jsonSlurper = new JsonSlurper().parseText(response)
assert !(jsonSlurper.isEmpty())
def accessToken = jsonSlurper.access_token.toString()
assert null != accessToken, "access_token does not have a value"
def authorizationKey = "${accessToken}"
context.testCase.testSuite.setPropertyValue("AUTH_KEY","Bearer " + authorizationKey)
log.info context.testCase.testSuite.getPropertyValue( "AUTH_KEY" )
And using answer presented here: How to transfer dynamic auth value in all requests instead of changing the value in every request's header in SOAPUI I created a new GroovyScript Test Case:
testRunner.testCase.testSteps.each{ name, testStep ->
log.info name
if(testStep.metaClass.getMetaMethod("getTestRequest")){
if(name=="UploadScreenshot"){
def request = testStep.getTestRequest()
def headers = request.getRequestHeaders()
headers.add('Authoritzation',context.testCase.testSuite.getPropertyValue( "AUTH_KEY" ))
request.setRequestHeaders(headers)
log.info "Added header to $name"
}
}
}
I know it's not a very good idea, to put an if to the loop instead if delete a loop, but I don't know yet how to do it and I need to proceed with work

Can't extract data from RESTClient response

I am writing my first Groovy script, where I am calling a REST API.
I have the following call:
def client = new RESTClient( 'http://myServer:9000/api/resources/?format=json' )
That returns:
[[msr:[[data:{"level":"OK"}]], creationDate:2017-02-14T16:44:11+0000, date:2017-02-14T16:46:39+0000, id:136]]
I am trying to get the field level, like this:
def level_value = client.get( path : 'msr/data/level' )
However, when I print the value of the variable obtained:
println level_value.getData()
I get the whole JSON object instead of the field:
[[msr:[[data:{"level":"OK"}]], creationDate:2017-02-14T16:44:11+0000, date:2017-02-14T16:46:39+0000, id:136]]
So, what am I doing wrong?
Haven't looked at the docs for RESTClient but like Tim notes you seem to have a bit of a confusion around the rest client instance vs the respons object vs the json data. Something along the lines of:
def client = new RESTClient('http://myServer:9000/api/resources/?format=json')
def response = client.get(path: 'msr/data/level')
def level = response.data[0].msr[0].data.level
might get you your value. The main point here is that client is an instance of RESTClient, response is a response object representing the http response from the server, and response.data contains the parsed json payload in the response.
You would need to experiment with the expression on the last line to pull out the 'level' value.

Getting context using groovyutils outside SoapUI

I am trying to hold the response of my request in a holder variable but I am not able to.
In SoapUI groovyutils is in-built and can be used easily. But I am sending my soap request using groovy and it is working fine. Now I want to get the response in a holder and put some assertions.
My piece of code for this is :
import com.eviware.soapui.*
def groovyUtils = new com.eviware.soapui.support.GroovyUtils()
def responseHolder = groovyUtils.getXmlHolder( messageExchange.responseContent )
Here I am not able to get as how I should pass the context in groovyutils and what all classes to call.
I'm not sure that I fully understand your problem, however seems that you want to check a SOAP response out of SOAPUI but using the facilities from SOAPUI jar isn't it?
If you want simply perform some assert in the response, then I would recommend you to avoid the use of GroovyUtils. Simply use XmlSlurper to parse the response, then get the desired values from the xml nodes and perform your asserts.
Since your Groovy code to you invoke the service and the response is missing I simply show you a possible example using XmlSlurper:
def response = '''<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope/">
<soap:Body>
<myResponse>
<someNode>myText</someNode>
</myResponse>
</soap:Body>
</soap:Envelope>'''
def xml = new XmlSlurper().parseText(response)
// find the <someNode> element
def someNode = xml.'**'.find { it.name() == 'someNode' }
// check that the <someNode> has a value equals of 'myText'
assert someNode.text() == 'myText'
Hope it helps,

Groovy Reusable Functions - Extract Node Value - groovy.lang.MissingMethodException:

I'm a Groovy noob and trying to get my head around using reusable functions to extract an xml node value for a given test step and node in SoapUI. It seems the class runs fine but the problem is when using the method. I get the following error:
groovy.lang.MissingMethodException: No signature of method: org.apache.log4j.Logger.info() is applicable for argument types: (java.lang.String, java.lang.String) values: [return TestStepName, Node] Possible solutions: info(java.lang.Object), info(java.lang.Object, java.lang.Throwable), any(), wait(), dump(), find(groovy.lang.Closure) error at line:
This is my class:
class Example
{
def log
def context
def responseSOAXmlStep
def resultValue
def responseNodePath
def storeProperty
// Class constructor with same case as Class name
def Example(logIn,contextIn,testRunnerIn)
{
this.log = logIn
this.context = contextIn
this.responseSOAXmlStep = responseSOAXmlStep
this.responseNodePath = responseNodePath
}
def execute(responseSOAXmlStep,responseNodePath)
{
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context );
// do some stuff to prove I've run with right context, etc.
log.info "return "+responseSOAXmlStep,responseNodePath
def holder = groovyUtils.getXmlHolder( responseSOAXmlStep+"#ResponseAsXml" );
resultValue = holder.getNodeValue( "//ns1:"+responseNodePath );
log.info("Node value: " + resultValue );
testRunner.testCase.testSuite.setPropertyValue(storeProperty, resultValue);
return execute
}
}
context.setProperty( "example", new Example( log, context, testRunner) )
log.info "Library Context:"+context
This is where I do the call in a step after the response step:
// get a reference to the library TestSuite
library = testRunner.testCase.testSuite.project.testSuites["Library"]
// find the module within the library
module = library.testCases["Library"].testSteps["Second Example_Class"]
// initialise the library; which places an instance of Example in the context
module.run(testRunner, context)
// get the instance of example from the context.
def example = context.example
// run the method, with parameter
log.info "example.execute(responseSOAXmlStep,responseNodePath) = " + example.execute("TestStepName","Node")
I've searched the forum but could not find an answer that suites my query. Any form of assistance is appreciated. Thanks.
Your error description says that you're invoking info() method on log passing two strings as and arguments, and this method doesn't exist.
The problem is easy to solve, pass one concatenated string with + as parameter instead of passing two strings. In your execute method inside your Example class use this:
def execute(responseSOAXmlStep,responseNodePath)
{
...
// USE + TO CONCATENATE STRINGS INSTEAD OF USE ,
log.info "return " + responseSOAXmlStep + responseNodePath
...
}
instead of:
def execute(responseSOAXmlStep,responseNodePath)
{
...
// do some stuff to prove I've run with right context, etc.
log.info "return " + responseSOAXmlStep,responseNodePath
...
}
EDIT:
As you said in your comment probably you've another problem storing properties in TestSuite level. You're using this code:
testRunner.testCase.testSuite.setPropertyValue(storeProperty, resultValue);
The problem is that setPropertyValue is expecting string as a first argument however at this line in your code storeProperty is not defined yet. Try for example defining storeProperty as:
def storeProperty = "myProperty" before using it in setPropertyValue call.
Hope this helps,

Resources