Count child nodes of a JSON response using groovy in soapui - json

I have a JSON response due to security reasons I had to take a screenshot and post it here.
I need to find number of available itineraryPrice available. Each curly braces refers to a separate itinerary, how to I count those tags in a groovy script step.
Method I have tried
def holder = groovyUtils.getXmlHolder( "air-search#ResponseAsXml" )
def xpath = "//*:search/*:itineraryPrice"
def numberOfRecommendations = holder["count(//*:search/*:itineraryPrice)"]
log.info "Total no of recommendations : "+numberOfRecommendations
But I got the output as 1 :(
Kindly help ! Please refer screenshot as well.

def json = '''{
"pos":"...",
"search":{
"uri":"...",
"itineraryPrice":[
{"a":1},
{"a":22},
{"a":333},
{"a":4},
{"a":56}
]
}
}'''
json = new groovy.json.JsonSlurper().parseText(json)
def count = json.search.itineraryPrice.size()
output: 5

Related

facing difficulties in Json parsing in groovy

I have a json and its response is {"canMerge":false,"conflicted":true,"outcome":"CONFLICTED","vetoes":[{"summaryMessage":"Requires approvals","detailedMessage":"You need 2 more approvals before this pull request can be merged."}]}
and I want to filter out data on the basis of "outcome":"CONFLICTED" for this I have tried following ways-
def mergeResponse = readJSON file:mergeFileName
for(mergenew in mergeResponse.values)
{
if(mergenew.outcome == "CONFLICTED") {
echo "pull request can not merged"
}
when I am trying above it is skipping if loop directly eventhough condition match properly I am not getting why?
ALSO TRIED BELOW
import groovy.json.JsonSlurper
def slurper = new JsonSlurper().parseText(mergenew)
assert slurper.outcome == "CONFLICTED"
String id = mergenew.getString("id");
echo "pull request can not merged"
getting error for above is
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: groovy.json.JsonSlurper.parseFile() is applicable for argument types: (org.apache.commons.collections.map.ListOrderedMap$ListOrderedMapEntry) values: [canMerge=false]
Possible solutions: parse([B), parse([C), parse(java.io.File), parse(java.io.InputStream), parse(java.io.Reader), parse(java.net.URL)
I also approved script in jenkins script approval for JsonSlurper.parseText
Please help me. Any help is appreciated.
try this : (set the file name var to whatever the file is)
import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper()
data = jsonSlurper.parse(new File(mergeFileName))
assert data.outcome == "CONFLICTED"
println("pull request can not merged")
You can use Pipeline Utility Steps to read a json file. This works for me:
def data = readJSON file: "${WORKSPACE}/data.json" // here just read the json file
def outcome = "${data.outcome}"
if(outcome == "CONFLICTED") {
echo "pull request can not merged"
}

How to filter a complex response in karate dsl using jsonPath?

I am getting below response from a REST API, but I am finding it difficult to extract label value from the received response and assign it to a variable to use it later in script.
Here is the RESPONSE::
{
"result": "SUCCESS",
"rawAttr": "[{\"attributes\":[{\"name\":\"resourceid\",\"value\":\"7A7Q123456\"},{\"name\":\"physicalid\",\"value\":\"7A7Q123456\"},{\"name\":\"dsw:label\",\"value\":\"MY Product00004285\"},{\"name\":\"dsw:created\",\"value\":\"2019-11-06T08:39:39Z\"}]}]",
"physicalid": "7A7Q123456",
"contextPath": "/path",
"id": "7A7Q123456",
"message": null
}
I am able to get response.id and response.result which is helpful for validation but I am not able to get the dsw:label value which is MY Product00004285
When I do def Arr = response.rawAttr I get the below value whether it is Array or String I am confused. Seems like it is a string.
[{"attributes":[{"name":"resourceid","value":"7A7Q123456"},{"name":"physicalid","value":"7A7Q123456"},{"name":"dsw:label","value":"MY Product00004298"},{"name":"dsw:created","value":"2019-11-06T08:39:39Z"}]}]
It is very easy to extract the label in JMeter JSON Extractor using below JSON Path expression
$.attributes.value[2]
Refer Karate's type conversion capabilities: https://github.com/intuit/karate#type-conversion
So you can do this:
* json attr = response.rawAttr
And then you are all set.
Thanks to an example and documentation on converting string to json.
Got it how to do.
And def strVar = response.rawAttr
And json jsonVar = strVar
And def attrb = karate.jsonPath(jsonVar, '$..attributes.[2].value')[0]
And print '\n\n Attrb\n', attrb
Links I referred:
Json Path evaluator
Karate doc reference for type conversion
Karate example for type-conversion

Parsing JSON object in Groovy

Im Trying to write a Groovy script which performs a REST api call and gets an JSON object, then, i need to get a specific string out of this JSON and check if it matches another string that i provides in the script.
i did everything until the section of comparison,
the string that im getting from the JSON looks like
[AAAAAA/BBBBBB/CCCCCC/file.txt]
and this is my Groovy script:
/*Import Section*/
//--------------//
groovy.json.*
/*Var Declaration*/
//---------------//
String errMessage = "There were no Junit tests impacted in this PR,
Comparison is: "
String scssMessage = "There were Junit tests impacted in this PR,
Comparison is: "
usr= "USERNAME"
pass= "PASSWORD"
pr_num = 92
String validPath = "AAAAAA/BBBBBB/CCCCCC/DDDDDD/EEEEEE"
def copmarison = !false
/*REST API call*/
//------------//
url= "http://{$usr}:
{$pass}#XX.XXX.X.XX:PPPP/rest/api/1.0/projects/XX/repos/TTTTT/pull-
requests/+{$pr_num}/changes?changescope"
process = [ 'bash', '-c', "curl ${url}" ].execute()
process.waitFor()
/*JSON parsing*/
//------------//
def info = new JsonSlurper().parseText(process.text)
def path = info.values.path.toString
/*Impacted JUNIT verifycation*/
//---------------------------//
if(path==validPath){
println ("$scssMessage"+"Valid"+"\n")
comparison=true
}else{
println ("$errMessage"+"Not Valid"+"\n")
comparison=!false
}
Im sure that my comparison isnt good and im looking to compare and find
if part of my "path" contained in my "validPath".
for example, the following case means true:
AAAAAA/BBBBBB/CCCCCC/file.txt
contained in:
AAAAAA/BBBBBB/CCCCCC/DDDDDD/EEEEEE
and i need to find a way to make this comparison
please help
If I understand your question correctly, all you need to check is the path part of your file against a specific path. In that case, this will work:
// you should already have these; including here for clarity
​def file = "AAAAAA/BBBBBB/CCCCCC/file.txt"
def path = "AAAAAA/BBBBBB/CCCCCC/DDDDDD/EEEEEE"
return path.contains(file[0..file.lastIndexOf("/")]​​​)​

How to get specific content from JSON response using context.expand?

I'm trying to use context.expand to get response and specific content from within the response,
def response = context.expand( '${Ranks of documents with SSE hits reflects scores#Response}' )
I also need to get specific detail from within the response, say if response has an array of ranks:
"ranks":[2234, 1234]
How can get both values of ranks?
You can use JsonSlurper from the groovy script testStep, supposing you get the follow JSON:
{"ranks":[2234, 1234]}
from your code:
def response = context.expand( '${Ranks of documents with SSE hits reflects scores#Response}')
You can use the JsonSlurper as follows to get your "ranks" values:
import groovy.json.JsonSlurper
// here I use this JSON as example, but you can
// parse directly your response which you get with context.expand
def response = '{"ranks":[2234, 1234]}'
def jsonRoot = new JsonSlurper().parseText(response)
log.info jsonRoot.ranks[0]
log.info jsonRoot.ranks[1]
Hope this helps,
Internally, SoapUI will convert almost anything to XML. You could grab just that node with ${step_name#ResponseAsXml}, and then parse it however you need to. Something like:
def ranksString = context.expand( '${Ranks of documents with SSE hits reflects scores#ResponseAsXml#//*:ranks}' )
def ranksArray = ranksString.split(",").trim()
log.info ranksArray[0]
log.info ranksArray[1]

Groovy json string empty

I am working with SoapUI and are really new to this. I am supposed to make a few REST tests, a lot of them have to do with dynamic resources so I have to read some json results on runtime. This works fine the first time I do it:
...
def response = context.expand('${Get ContractModels#Response}')
def slurper = new JsonSlurper().parseText(response)
for (i in slurper.ContractModels){
testRunner.testCase.testSteps["ContractModelOptionStep"].setPropertyValue("id",sprintf('%d',i.ContractModelID));
testRunner.runTestStepByName("ContractModelOptionStep")
def innerResponse = context.expand('${Get ContractModelOptionStep#Response}')
log.info(response)
log.info(innerResponse)
def innerSlurper = new JsonSlurper().parseText(innerResponse);
...
}
This works well up to the last line, where it tells me The JSON input text should neither be null nor empty. Thanks to the log.info I found out the JSON Strong of innerResponse is actually empty. Now my problem is I have no clue why, runTestStepByName works perfectly fine and gives the expected response.
Cheers
In these two lines:
testRunner.runTestStepByName("ContractModelOptionStep")
def innerResponse = context.expand('${Get ContractModelOptionStep#Response}')
the name of the test step does not match! Try:
def innerResponse = context.expand('${ContractModelOptionStep#Response}')