I am making a SOAP request, and I am receiving the response that's returned as an array:
- [print] [
"M4205N",
"M4206U"
]
For each item in the array, I want to make another SOAP request. I've read how you can do this with tables and call a feature file, and I've read how to loop through an array, and call a js function. I cannot figure out how to loop through the array, and pass each value to another SOAP request XML (one at a time).
I want to do something like this:
Given soapURL
And method post
def responseArray = /xml path for the codes I want/
def result = call read('otherRequest.feature') responseArray
The otherRequest.feature file would look something like this:
#ignore
Feature:
Background:
* def myNewRequest = read('soap.xml')
Scenario:
Given soapURL
* replace myNewRequest
| token | value |
| ##refNum## | responseArrayValue |
When request myNewRequest
And method post
However, I get this error:
GetNewMessageList.feature:27 - argument not json or map for feature call loop array position: 0, M4205N
How can I loop through each item in the array, and pass each value to the other feature file?
The addition of this one line should do what you want. Yes there is a hard requirement that the "loop" array should be an array of JSON objects. But you can convert an array of primitives in one step:
* def responseArray = karate.mapWithKey(responseArray, 'responseArrayValue')
This is documented here: https://github.com/intuit/karate#json-transforms
Related
Let's say I want to use the range function (inside a ForEach loop) in Azure Data Factory to create an array which consists of integers. These integers represent API pages related to some ID which was given to us as a parameter in the ForEach loop.
I would use it like #range(1, int(varMaxApiPages)).
This gives me what I expect; an array of integers:
[1, 2, 3]
But would it be possible to append the related ID to these integers? So the result would be something like: [{"someID", 1},{"someID", 2},{"someID", 3}]?
Such as:
def appendToArray(varMaxApiPages):
arr1 = list(range(varMaxApiPages))
json_array = [];
for item in arr1:
jsonObejct = {"someID",item}
json_array.append(jsonObejct)
for item in json_array:
print(item)
appendToArray(3)
The correct json array should look like this [{"someID": 1},{"someID": 2},{"someID": 3}], we can achieve that. If you don’t want the colon, you can think of a way to replace it.
My debug result is as follows:
I declared 3 array type variables. Variable res is used to review the debug result.
In Set variable1 activity, assign the value to it via #range(1,3).
Then Foreach the arr1.
Inside Foreach activity, we can use Append variable activity, add expression #json(concat('{"someID":',item(),'}')). It will convert json string to json Object and append to the array jsonArray.
Outside Foreach activity, assign the value of array jsonArray to array res to review the result, you can omit this step and use array jsonArray directly.
That's all.
--Loop_controller
|--Http_Request_Sampler_One
--Http_Request_Sampler_Two
I have a sampler (Http_Request_Sampler_One) with a response body {"id": "12345"}.
This sampler is in a loop controller, which will run 3 times for example.
I want a string array variable named Ids to hold all the id.
in the form Ids = ["12345", "23421", "43546"]
I want to use this Ids variable in Http_Request_Sampler_Two once the loop controller ends.
Note: I'm able to extract the id from the response body using JSON-extractor, I'm more interested in knowing a way to push it in an array after each iteration ends.
Add JSR223 PostProcessor as a child of your Http_Request_Sampler_One
Put the following code into "Script" area
if (vars.get('__jm__Loop Controller__idx') == '0') {
def Ids = []
Ids.add(new groovy.json.JsonSlurper().parse(prev.getResponseData()).id)
vars.put('Ids', new groovy.json.JsonBuilder(Ids).toPrettyString())
}
else {
def Ids = new groovy.json.JsonSlurper().parseText(vars.get('Ids'))
Ids.add(new groovy.json.JsonSlurper().parse(prev.getResponseData()).id)
vars.put('Ids', new groovy.json.JsonBuilder(Ids).toString())
}
That's it, once your Loop Controller finishes you will get all the "ids" extracted from the Http_Request_Sampler_One as ${Ids} JMeter Variable.
More information:
Apache Groovy - Parsing and producing JSON
Apache Groovy - Why and How You Should Use It
I am executing a call that saves a lot of values into a Seq[(String)], it looks as follows:
.exec(session => {session.set("Ids", session("externalIds").as[Seq[String]])})
There is a reason why I have to create another session variable called Ids our of externalIds but I wont get into it now.
I than have to execute another call and paginate 10 values out of ${Ids} until I send them all.
(So in case of 100 values, I'll have to execute this call 10 times)
The JSON looks as follows:
..."Ids": [
"962950",
"962955",
"962959",
"962966",
"962971",
"962974",
"962978",
"962983",
"962988",
"962991"
],...
What I usually do when I have to iterate through one value each time is simply:
.foreach("${Ids}", "id") {
exec(getSomething)
}
But since I need to send a [...] Of 10 values each, I am not sure if it should even be in the scenario level. Help! :)
Use transform in your check to transform your Seq[String] into chunks, eg with Seq#grouped.
I couldn't figure out how to go about this within the session so I took it
outside to a function and here is the solution:
.exec(session => {session.set("idSeqList", convertFileIdSeqToFileIdSeqList(session("idsSeq").as[Seq[String]]))})
def convertFileIdSeqToFileIdSeqList(idSeq: Seq[String]): Seq[Seq[String]] = {
idSeq.grouped(10).toList
}
Note that when placing your list within a JSON body, you will need to use .jsonStringify() to format it correctly in the JSON context like so:
"ids": ${ids.jsonStringify()},
I have two JSON. In the both I have name. How can I get names from first JSON and add to array? Later I want do this same with second JSON later i want both array compare? How can I do this?
jsonArray1 = [{'name': "doug", 'id':5}, {'name': "dofug", 'id':23}];
jsonArray2 = [{'name': "goud", 'id':1}, {'name': "doaaug", 'id':52}];
for example I want:
a = [doug, dofug] b = [goud, doaaug]
and later check if these are the same arrays
i don't know how can i do this in jmeter, help
To convert one array to another:
Add JSR223 PostProcessor as a child of the request which returns first JSON Array
Put the following code into "Script" area:
def builder = new groovy.json.JsonBuilder()
builder(com.jayway.jsonpath.JsonPath.read(prev.getResponseDataAsString(),'$..name').collect())
vars.put('array1', builder.toPrettyString())
That's it, you should be able to access the newly generated JSON Array as ${array1} where required
Repeat the same steps for the second JSON array.
There are several options on how to compare 2 JSON entities, depending on what you're trying to achieve you can go for:
Response Assertion
a JSR223 Assertion and a 3rd-party library like:
Jackson
Gson
JSONassert
I Have an array like this :
var ProG = [[1,0,0,0],[1,0,0,0],[0,0,1,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]];
I have also a hidden field (id=prog-id) in a form, that I use to send this array to the server:
jQuery('#prog-id').val(JSON.stringify(ProG));
the sent array become:
"prog": "[[1,0,0,0],[1,0,0,0],[0,0,1,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]"
the next code take the array and other data from the server with ajax request:
value is the data that come from ajax
I create an object:
var obj = jQuery.parseJSON(value);
Now the problem:
if I console.log(ProG) the array before sent I get:
Array[7]0: Array[4]1: Array[4]2: Array[4]3: Array[4]4: Array[4]5: Array[4]6: Array[4]length: 7__proto__: Array[0]
that is ok.
But If I do the same after getting array I receive this:
[[1,0,0,0],[1,0,0,0],[0,0,1,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
How can I put the received array in original format?
Ok I find out:
jQuery.parseJSON(ProG).