Is there a way to set some values in the multiple dimensional json array - karate

Scenario Outline: Explore Karate '<ID>'
* karate.set($attributesFirstRun[*].created_timestamp,'#present')
* karate.set($attributesSecondRun[*].created_timestamp,'#present')
* match attributesFirstRun == attributesSecondRun
Examples:
| read('Sample.csv') |
I tried this. But I'm getting this error
org.graalvm.polyglot.PolyglotException: SyntaxError: Unnamed:1:42 Expected an operand but found *

I think you are over-thinking this. Karate is actually just plain JS. And sounds like you are trying to do a "bulk update" via JsonPath - sorry, that's not supported, perhaps you would be interested in contributing code.
Here's the solution for updating all elements of an array:
* def before = [{ a: 1 }, { a: 2 }]
* def after = before.map(x => ({ a: x.a * 5 }))
* match after == [{ a: 5 }, { a: 10 }]
Keep in mind updating JSON is easy:
* def data = {}
* data.a = 1
* match data == { a: 1 }
Refer the docs: https://github.com/karatelabs/karate#json-transforms

Related

how to count a value in a list based on the same value in another list. and the both are dynamic when i get the response in karate

list 1 ["ART - Run and Support","ART - Run and Support","Clt group","Clt group"]
list 2 ["ART - Run and Support","Clt group",]
I want to take the 1st value in list2 and count the occurrences in list 1.
"ART - Run and Support" = 2
I was able to take for 1 value, not sure how to pass this in loop. Please do help.
* def condition = function(x){ return x == "Application Development" }
* def output = karate.filter(Total_List_AssignmentGroup, condition).length
* print output
I was able to take for 1 value, not sure how to pass this in loop. Please do help.
This was a fun problem ! Here is the solution, and believe it or not it is just one line:
* def list1 = ["ART - Run and Support", "ART - Run and Support", "Clt group", "Clt group"]
* def list2 = ["ART - Run and Support", "Clt group"]
* def results = list2.map(x => ({ name: x, count: list1.filter(y => x === y).length }))
* print results
Which gives you:
[
{
"name": "ART - Run and Support",
"count": 2
},
{
"name": "Clt group",
"count": 2
}
]
This is just using JavaScript array operations such as map() and filter()

Null values in CSV Scenario Outline [duplicate]

I am able to read a csv file and convert it to json by
def expectedResponse = read('classpath:somefile.csv')
Suppose I have csv file as below
name,age
praveen,29
joseph,20
1.It is converting all elements as string and stores in the variable as json. How to keep the number as a number ? because it causes match failure which i do later with the actual response.
2.How to get the value 20. Like by specifying joseph, I want to get the age.
I got the jsonpath as
get expectedResponse $.[?(#.member == '<name>')].age
I get the name from examples. So I get it as joseph in runtime. But i get error as reason: not equal (Integer : JSONArray). It is not returning the age alone (Integer value)
Or is there any better way to get it ?
The CSV format does not contain any type information, so everything defaults to "string" and you have to convert it yourself. But this is easy using karate.map().
* text users =
"""
name,age
praveen,29
joseph,20
"""
* csv users = users
* match users == [{ name: 'praveen', age: '29' }, { name: 'joseph', age: '20' }]
* def fun = function(x){ x.age = ~~x.age; return x }
* def users = karate.map(users, fun)
* match users == [{ name: 'praveen', age: 29 }, { name: 'joseph', age: 20 }]

How to match against list of maps in Karate?

I have a list:
[{
"a": 1
"b": 2
}]
And I would like to match it this way:
And match response contains
"""
[{
"a": 1
}]
"""
However this does not work since the map inside of the list from the response has more keys. I just want to ignore them. Is there easy way to do it?
There are two ways to do this:
* def response = [{ a: 1, b: 2 }]
* def expected = { a: 1 }
* match response contains '#(^expected)'
Or you could use contains deep:
* match response contains deep { a: 1 }

Karate param on multi scenario [duplicate]

I am new to karate and read through most of the examples, but can't quite crack this. Your help is much appreciated! Assuming I have an array and I need to call a service and pass each value of this as a param, how do I do that please?
Thanks in advance.
How about this:
Scenario Outline:
Given url 'http://httpbin.org'
And path 'get'
And param foo = '<value>'
When method get
Then status 200
Examples:
| value |
| hello |
| world |
And in Karate 0.9.0 onwards you can do this:
Background:
* def data = [{ value: 'hello' }, { value: 'world' }]
Scenario Outline:
Given url 'http://httpbin.org'
And path 'get'
And param foo = '<value>'
When method get
Then status 200
Examples:
| data |
EDIT: and if you need to transform an existing primitive array:
Background:
* def array = ['hello', 'world']
* def data = karate.map(array, function(x){ return { value: x } })
Scenario Outline:
Given url 'http://httpbin.org'
And path 'get'
And param foo = '<value>'
When method get
Then status 200
Examples:
| data |

Can anyone explain how to get all the mismatch between two Array of JSON Object responses in karate? [duplicate]

Like if I have two JSON as below and I want to check the mismatch between those
JSON 1:
{
name:'john',
contact:'123',
country:'america'
}
JSON 2:
{
name:'vishal',
contact:'123',
country:'India'
}
Now it will return me with the mismatch between name and country not only the name?
No this is not supported. We feel this is not needed, because in your regular CI runs you only care if the test passed or failed, and you see the details in the log.
Also note that you can simulate this if you really want using a Scenario Outline: https://stackoverflow.com/a/54108755/143475
Finally, if you care so much about this, kindly contribute code, this is open-source after all.
EDIT: you can easily do this by iterating over keys. Here is the code:
EDIT2: Setting up data via a Background is no longer supported in version 1.3.0 onwards, please look at the #setup tag: https://github.com/karatelabs/karate#setup
Feature:
Background:
* def json1 = { name: 'john', contact: '123', country: 'america' }
* def json2 = { name: 'vishal', contact: '123', country: 'India' }
* def keys = karate.keysOf(json1)
* def data = karate.mapWithKey(keys, 'key')
Scenario Outline: <key>
* match (json1[key]) == json2[key]
Examples:
| data |
And here is the report: