Getting JSON key as a text - karate

Trying to get the json key text within karate feature script.
HI, I am new to karate and going through all the documentation of karate..
When I am getting GET response as show below in the code, I am not sure what all keys a response will have. So whenever in the response there is key text is domain_name , then I want to retrieve domain_code
{
"status":"SUCCESS",
"totalCount":1,
"statusCode":"OK",
"ResultData":{
"data":[
{"domain_code":"X3","domain_name":"BMW"},
{"domain_code":"Q5","domain_name":"AUDI"},
{"domain_code":"G450","domain_name":"LEXUS"}
]
}

Here you go. Read the docs if any part is not clear, starting with JsonPath:
* def response =
"""
{
"status": "SUCCESS",
"totalCount": 1,
"statusCode": "OK",
"ResultData": {
"data": [
{"domain_code": "X3", "domain_name": "BMW" },
{"domain_code": "Q5", "domain_name": "AUDI" },
{"domain_code": "G450", "domain_name": "LEXUS" }
]
}
}
"""
* def data = get[0] response..data[?(#.domain_name)]
* def keys = karate.keysOf(data)
* keys.remove('domain_name')
* print keys[0]

Related

Karate- How can I pass a param as a key?

I have the following case and need to use firstKeyStr as a key, my code now is seeing "#firstKeyStr" as the key not the one stored in it
Code
Given path '/api/v1/sites'
When method get
Then status 200
And match response.success == true
And match response.data == "#object"
* def keys = karate.keysOf(response.data)
* def firstKeyStr = keys[0]
And match response.data."#firstKeyStr" == "#object"
Json Response Body
{
"success": true,
"data": {
"5ef34d0ca5a3c56ae14d2a23": {
"devices": [
"5f03192010a47f3e5b714193"
],
"groups": [
"5f0d9f30ef89e22778a2d230"
],
"users": [],
"triggers": [],
"alerts": [
"5f0d92b967bac60b84d3989b"
],
"name": "test",
"country": "US",
]
}
}
I'm looking for a way to pass this dynamic key (5ef34d0ca5a3c56ae14d2a23) in this line (And match response.data."#firstKeyStr" == "#object")
Since you are new to stack overflow, please read the following to best get help:
https://stackoverflow.com/help/how-to-ask
https://stackoverflow.com/help/someone-answers
As Peter said, your JSON is not well formed and the order of keys is not guaranteed (unless you have just a single key). The following code should get you going.
Sample Code:
Feature: firstKey
Scenario: firstKey
* def resp =
"""
{
"success": true,
"data": {
"5ef34d0ca5a3c56ae14d2a23": {
"devices": [
"5f03192010a47f3e5b714193"
],
"groups": [
"5f0d9f30ef89e22778a2d230"
],
"users": [],
"triggers": [],
"alerts": [
"5f0d92b967bac60b84d3989b"
],
"name": "test",
"country": "US"
}
}
}
"""
And match resp.data == "#object"
* def keys = karate.keysOf(resp.data)
* def firstKeyStr = keys[0]
* print firstKeyStr
* print (resp.data[firstKeyStr])
And match (resp.data[firstKeyStr]) == "#object"
Use round brackets so that JS is used instead of JsonPath:
* def response = { data: { a: 1, b: 2 } }
* def keys = karate.keysOf(response.data)
* def first = keys[0]
* match (response.data[first]) == 1

Comparing json array item against the response which has random order of the json arrary items

This file (getAllDomain.json) has known/valid response but the order of domain_name /domain_code is random which has to compare against api output..
means .. X3 may come first or last and there is no define order.
I was trying to verify each data array element against the response. But its not working.
IS there any way to just verify arrary and all other element other than "data" can be ignored.
* def expected = read('getAllDomain.json')
* def response =
"""
{
"status":"SUCCESS",
"totalCount":3,
"statusCode":"OK",
"ResultData":{
"data":[
{
"domain_code":"X3",
"domain_name":"BMW"
},
{
"domain_code":"Q5",
"domain_name":"AUDI"
},
{
"domain_code":"MDX",
"domain_name":"ACURA"
}
]
}
}
"""
And match response.ResultData.data[*] contains any expected.ResultData.data[0]
Here you go. And try to read the docs, it will actually help you:
* def expected =
"""
[
{
"domain_code": "MDX",
"domain_name": "ACURA"
},
{
"domain_code": "X3",
"domain_name": "BMW"
},
{
"domain_code": "Q5",
"domain_name": "AUDI"
}
]
"""
* def response =
"""
{
"status":"SUCCESS",
"totalCount":3,
"statusCode":"OK",
"ResultData":{
"data":[
{
"domain_code":"X3",
"domain_name":"BMW"
},
{
"domain_code":"Q5",
"domain_name":"AUDI"
},
{
"domain_code":"MDX",
"domain_name":"ACURA"
}
]
}
}
"""
* match response.ResultData.data contains only expected

Karate json path filter not working when trying to extract elements that meet some filter criteria in API response

I am trying to filter my API response using JSON Path filter using Karate framework to extract a specific value that meets one of the condition using a value from a variable but I am not able to map variable properly, so my filter not working properly. I looked at the documentation and tried multiple ways but couldn't resolve this issue.
Sample response JSON:
"slices": [
{
"id": 7591164138534052,
"duration": {
"value": 1675,
"unit": "MINUTE"
},
"segments": [
{
"id": 1,
"segmentRefId": 23783268357325705
},
{
"id": 2,
"segmentRefId": 7591164138531002
},
{
"id": 3,
"segmentRefId": 7591164138532394
}
]
}
],
"segments": [
{
"id": 23783268357325705,
"departDateTime": "2019-10-05T19:50:00",
"arrivalDateTime": "2019-10-06T14:25:00",
"originAirport": "LAX",
"destinationAirport": "LHR",
"duration": {
"value": 635,
"unit": "MINUTE"
},
"marketingAirline": "BA",
"operatingAirline": "AA",
"flightNumber": "1509",
"equipmentCode": "77W",
"subjectToGovtApproval": false,
"numOfStops": 0,
"stops": []
}
]
}```
I am using the below script where I am using variable 'originRefId':
* def originRefId = response.slices[0].segments[0].segmentRefId
* def origin = karate.jsonPath(response, "$.segments[?(#.id=='originRefId')]")
* print 'the value of Origin is:', origin
Expected results LAX but I am getting an empty array.
17:42:15.119 [main] INFO com.intuit.karate - [print] the value of Origin is: [
]
Here is your solution:
* def originRefId = response.slices[0].segments[0].segmentRefId
* def segment = karate.jsonPath(response, "$.segments[?(#.id==" + originRefId + ")]")[0]
* def origin = segment.originAirport
* match origin == 'LAX'

Un-named JSON array field validation in Karate

I have a un-named JSON array like this from the response and would like to check whether it contains "confirmationNumber": "pqrs" or not. May I know how can I check that in Karate?
[
{
"id": 145,
"confirmationNumber": "abcd"
},{
"id": 723
"confirmationNumber": "pqrs"
}
,{
"id": 7342
"confirmationNumber": "sfeq"
}
]
karate.filter() is good for these situations:
* def response =
"""
[
{
"id":145,
"confirmationNumber":"abcd"
},
{
"id":723,
"confirmationNumber":"pqrs"
},
{
"id":7342,
"confirmationNumber":"sfeq"
}
]
"""
* def fun = function(x){ return x.confirmationNumber == 'pqrs' }
* def found = karate.filter(response, fun)
* match found == '#[1]'
Also see examples of JsonPath: https://github.com/intuit/karate#jsonpath-filters
EDIT: apologies, there is a much simpler way, please read the docs !
* match response contains { id: '#number', confirmationNumber: 'pqrs' }
* def item = { confirmationNumber: 'pqrs' }
* match response contains '#(^item)'

How to access a particular set of keys in array of Json values which i get as response?

For a particular API , I get a response which is similar to the following .
[
{ "name":"Ford", "model":"Mustang" },
{ "name":"BMW", "model": "320" },
{ "name":"Fiat", "model": "500" }
]
I want to store the values for the key 'name' in a separate variable .
Please read the documentation on using JsonPath carefully: https://github.com/intuit/karate#get
Here is an example which works with your data:
* def response =
"""
[
{ "name":"Ford", "model":"Mustang" },
{ "name":"BMW", "model": "320" },
{ "name":"Fiat", "model": "500" }
]
"""
* def names = $[*].name
* match names == ['Ford', 'BMW', 'Fiat']