Passing token from get request to a header in SoapUI - groovy

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

Related

How to pass params to a HTTP request (teststep) in a SOAP UI Test case using groovy and run it

I am writing a groovy script to execute/automate my test suite. In one test case i have a HTTPRequest where i have a request URL, parameters( username and password) and method( GET) to get a token-id and then i would pass that token id to my next step( a SOAP request)to get the data.
I am stuck at a point where i need to pass the params(username and password), request URL and method(GET) using groovy.
I have a test step created manaully under a test case, i just need to pass the params
as i search online i got to know how to pass headers,url to a SOAP request which is like below
def headers = new StringToStringMap()
testRunner = new com.eviware............WsdlTestCaseRunner(myTestCase,null);
testStepContext = new com.eviware.soapui........WsdlTestRunContext(testsetp);
headers.put("apikey", "abcd")
teststep.getTestRequest().setRequestHeaders(headers)
teststep.getHttpRequest().setEndpoint(encpointurl);
testsetp.run(testRunner ,testStepContext )
but i looking to know how to pass params to a http request(test step) and run it.
Add a Properties teststep to your testcase. Just let it keep the default "Properties" name.
Add the properties to the Properties teststep, that you need to transfer
Inside your groovy teststep, you may set the properties using something like:
def properties = testRunner.testCase.getTestStepByName("Properties");
properties.setPropertyValue("name", "value");
Add the parameters directly in your request using variables in the format ${Properties#name} and replace "name" with the actual parameter name. This can be done both in the request body and in the URL if you should wish to do so.
It can be done completely in groovy by using groovy.json.JsonBuilder Class.
def body = new StringToStringMap()
def jsonbildr = new JsonBuilder()
body.put("username","Hackme")
body.put("password","LockUout")
def root = jsonbildr body
jsonbildr = jsonbildr.toPrettyString()
log.info(jsonbildr)
testStep.setPropertyValue("Request", jsonbildr)
Output :
{
"password": "LockUout",
"username": "Hackme"
}

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.

Soap UI: Groovy Script to call an API if the response is true

I am very new to use SoapUI. Writing test cases for my project APIs.
My requirement is to run a groovy script after an API call and if the response text of this API is "true", another API should call.
I found myself stuck to do this. Can anyone guide me to do this.
Thanks in advance!!!
I found answer but forgot to inform over here. I did asserted an script like this in TestStep:
def slurper = new groovy.json.JsonSlurper()
def responseJson = slurper.parseText(messageExchange.getResponseContent())
assert responseJson instanceof Map
assert responseJson.containsKey('authToken')
def id = "Bearer "+responseJson['authToken']
log.info(id.toString())
testRunner = new com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner(context.testCase.testSuite.project.getTestSuiteByName("TestSuite").getTestCaseByName("TestCas"), null)
def tcase = testRunner.testCase
def tstep = tcase.getTestStepByName("TestStep")
testContext = new com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext(tstep)
runner = tstep.run(testRunner, testContext)
Little idea for this :
def response = context.expand( '${TestRequest1#Response}' )
if ( response == 'true' )
{
testRunner.runTestStepByName( "TestRequest2")
}
Disable your first test Step(TestRequest1).

How to get testStep responseAsXml in groovyScript

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,

XmlSlurper.parse(uri) with HTTP basic authentication

I need to grab a data from XML-RPC web-service.
new XmlSlurper().parse("http://host/service") works fine, but now I have a particular service that requires basic HTTP authentication.
How can I set username and password for parse() method, or modify HTTP headers of the request?
Using http://username:password#host/service doesn't help - I still get java.io.IOException: Server returned HTTP response code: 401 for URL exception.
Thanks
I found this code over here which might help?
Editing this code to your situation, we get:
def addr = "http://host/service"
def authString = "username:password".getBytes().encodeBase64().toString()
def conn = addr.toURL().openConnection()
conn.setRequestProperty( "Authorization", "Basic ${authString}" )
if( conn.responseCode == 200 ) {
def feed = new XmlSlurper().parseText( conn.content.text )
// Work with the xml document
} else {
println "Something bad happened."
println "${conn.responseCode}: ${conn.responseMessage}"
}
This will work for you
Please remember to use this instead of the 'def authString' mentioned above:
def authString = "${usr}:${pwd}".getBytes().encodeBase64().toString()

Resources