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 - 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()

Related

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

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

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 scenario outline - Create a dynamic example table based on JSON array index size

Here I would like to clarify about creating dynamic example table for a dynamic JSON index size
My JSON looks like
Env - Dev - 2 servers
"response": {
"abc": [{
"status": "pass"
.
.
},
{
"status": "pass"
.
.
}
]
}
Env - Uat - 3 servers
{
"response": {
"abc": [{
"status": "pass"
},
{
"status": "pass"
},
{
"status": "pass"
}
]
}
}
My scenario outline looks like
Scenario Outline: validating .....
When def result = callonce read('featurefilename#tagname')
Then print result
And print <status>
And print ...
And match ....
Examples:
|result.response.abc|
Errors for the above:
1) * dynamic expression evaluation failed:result.response.abc
2) com.intuit.karate.karateExpresion: ---- javascript evaluation failed result.response.abc, ReferenceError:"result" is not defined in at line number 1
Note - If I move step 'When def result = callonce read('featurefilename#tagname') to background it's working as expected but I can't use background in my feature file due to other factors.
Thanks in advance
Instead of providing index in a table you can leverage Dynamic Scenario Outline feature in karate.
In this case you you can pass the variable as a input to Examples. If the JSON provided above is from variable result then,
Examples:
| result.response.abc |
Refer the docs for more insights.

POSTMAN - Test failure false to be truthy

As a beginner I have few questions. I am using the Get request, which would populate json below.
https://reqres.in/api/users
{
"total": 12,
"total_pages": 4,
"data": [{
"id": 1,
"first_name": "George",
"last_name": "Bluth",
"avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/calebogden/128.jpg"
}]
}
for the 2 tests below while the 1st one passes the 2nd test fails with the message:
AssertionError: expected false to be truthy
//Verify Page number total is 12
var jsonData = JSON.parse(responseBody);
tests["Checking total page number-Manual"] = jsonData.total === 12;
//verify is exists and is 1
var jsonData = JSON.parse(responseBody);
tests["Checking ID exists and is 1"] = jsonData.id === 1;
Question 1:
A github post that I found says there may be an error and suggests to use
the new pm.* equivalent instead. However I do not see any difference between the 1st and the 2nd. So why does the 2nd test fail?
Question 2:
Is it possible to write test to verify that for ID:1 the firstname is George?
Thanks in advance for your time.
The reason that your 2nd test fails is because data is an array and in this case you must access the first element. You would want to do something like this (new syntax):
pm.test("Verify id is equal to 1", function() {
var jsonData = pm.response.json();
pm.expect(jsonData.data[0].id).to.equal(1);
});
Similarly for testing first name is George:
pm.test("Verify id is equal to 1", function() {
var jsonData = pm.response.json();
pm.expect(jsonData.data[0].first_name).to.equal("George");
});
If you always expect it to only be a single element in the array then you're safe to use index 0 i.e. data[0]. However if you expect there to be more elements in the data array then you would have to iterate through them to look for the correct element.
Here's a good reference for the API:
https://learning.getpostman.com/docs/postman/scripts/postman_sandbox_api_reference/

Adding new key-value pair into json using karate

My payload looks like this :
{
"override_source": "DS",
"property_code": "0078099",
"stay_date": "2018-11-26T00:00:00.000000",
"sku_prices": [
],
"persistent_override": false
}
There is an array dblist ["2","3"] , it would consists of numbers from 1 to 4. Based on the elements present in the list, I want to add key-values {"sku_price":"1500","sku_code":"2"} to my payload. I am using the following code :
* eval if(contains("3",dblist)) karate.set('pushRatesFromDS.sku_prices[]','{ "sku_price": "1500","sku_code":"3" }')
When I execute my feature file, I do not get any errors but, key-values are not added to my payload. However if I move this code to a new feature file and call it, key-value pairs get added to my payload. The code in my new feature file looks like : * set pushRatesFromDS.sku_prices[] = { "sku_price": "1500","sku_code":"2" }
Try this:
* def foo =
"""
{
"override_source": "DS",
"property_code": "0078099",
"stay_date": "2018-11-26T00:00:00.000000",
"sku_prices": [
],
"persistent_override": false
}
"""
* eval karate.set('foo', '$.sku_prices[]', { foo: 'bar' })