Here is the sample code
"xNotification": [
{
"code": "1234",
"text": "Invalid Data"
"yNotification": [
{
"code": "345",
"text": "Invalid Data"
}
]
}
]
}
yNotification array only exits sometimes in the response, when it exists I need to capture the code value and put it in a variable. I don't want assert just when it exists I need to put it in a variable. I am newbie to any testing frameworks. I appreciate any help with this issue. Thanks in advance.
Please read this part of the documentation: https://github.com/intuit/karate#conditional-logic
Example:
* def expected = zone == 'zone1' ? { foo: '#string' } : { bar: '#number' }
* match response == expected
EDIT: This is the complete solution to your question:
* def response =
"""
{ "xNotification": [
{
"code": "1234",
"text": "Invalid Data",
"yNotification": [
{
"code": "345",
"text": "Invalid Data"
}
]
}
]
}
"""
* def code = karate.get('$.xNotification[0].yNotification[0].code')
* print code
Related
I have a scenario where I need to call a secondary feature file that contains an API call where the response is a JSON object. However, I need to call this scenario multiple times, so I am using karate.repeat to achieve this. However, the resulting response is a malformed JSON that I cannot traverse.
This is what I am doing:
* def fun = function(i){ return karate.call('abc.feature#abc', value)}
* def loop = karate.repeat(2, fun)
* karate.log(loop)
The response I get is:
{
"Total_packages1": {
"package1": {
"tags": [
"kj21",
"j1",
"sj2",
"z1"
],
"expectedResponse": [
{
"firstName": "Name",
"lastName": "lastName",
"purchase": [
{
"title": "title",
"category": [
"a",
"b",
"c"
]
}
]
}
]
}
}
}
{
"Total_packages2": {
"package2": {
"tags": [
"kj212",
"j12",
"sj22",
"z12"
],
"expectedResponse": [
{
"firstName": "Name2",
"lastName": "lastName2",
"purchase": [
{
"title": "title2",
"category": [
"a2",
"b2",
"c2"
]
}
]
}
]
}
}
}
As you can see, Total_packages2 starts malformed. I need to grab the "tags" values from each package, however, I cannot simply do Total_packages1.package1.tags like I could with a single response in the JSON.
If I cannot achieve what I need by karate.repeat, is there another method that is recommended for looping like this? I haven't found anything in the documentation for this particular scenario.
Don't use karate.repeat() use call with a JSON array. Read this part of the docs: https://github.com/karatelabs/karate#data-driven-features
There is a case where one value sometimes is lower case and sometimes it's upper case. this is the response coming from an API and we have to match if every field in response is correct by ignoring some values. The error text in response sometimes has one keyword in lower and some scenarios it is upper case. How we can ignore one keyword in a string to not match? I don't want to ignore whole text as it works fine if I ignore whole string but is it possible to ignore one keyword only?
Scenario: string matching
* def test =
"""
{
"sourceType": "Error",
"id": "123456",
"type": "searchuser",
"total": 0,
"value": [
{
"details": "this is the user search case",
"source": {
"sourceType": "Error",
"id": "77200203043",
"issue": [
{
"severity": "high",
"code": "678",
"message": {
"text": "No matching User details found"
},
"errorCode": "ERROR401"
}
]
},
"user": {
"status": "active"
}
}
]
}
"""
* match test ==
"""
{
"sourceType": "Error",
"id": "#present",
"type": "searchuser",
"total": 0,
"value": [
{
"details": "#present",
"source": {
"sourceType": "Error",
"id": "#ignore",
"issue": [
{
"severity": "high",
"code": "678",
"message": {
"text": "No matching User details found"
},
"errorCode": "ERROR401"
}
]
},
"user": {
"status": "active"
}
}
]
}
"""
How to ignore the case only for user here? I tried below but it treats #ignore as a value.
"text": "No matching #ignore details found"
I'm not looking at your payload dump but providing a simple example. Use karate.lowerCase():
* def response = { foo: 'Bar' }
* match karate.lowerCase(response) == { foo: 'bar' }
EDIT: you can also extract one value at a time and do a check only for that:
* def response = { foo: 'Bar' }
* def foo = response.foo
* match karate.lowerCase(foo) == 'bar'
There are multiple keys present in x.details[0].user so how to compare in such condition. It works fine where there is only one key while when there are more than one key it fails with error as there are multiple keys for user.
Please guide
* def array =
"""
{
"type": "1",
"array": 2,
"details": [
{
"path": "path",
"user": {
"school": {
"name": [
{
"value": "this is school",
"codeable": {
"details": [
{
"hello": "yty",
"condition": "check1"
}
],
"text": "123S"
}
}
]
},
"sample": "test1",
"id": "22222"
},
"data": {
"check": "abc"
}
},
{
"path": "path",
"user": {
"school": {
"name": [
{
"value": "this is school",
"codeable": {
"details": [
{
"hello": "def",
"condition": "check2"
}
],
"text": "123O"
}
}
]
},
"sample": "test",
"id": "11111"
},
"data": {
"check": "xyz"
}
}
]
}
"""
* def lookup = { 'check1': 'yty', 'check2': 'def' }
* match each array.details contains { user: { school: { name[0]: { codeable: { details[0]: { hello: '#(lookup[_$.user.school.name[0].codeable.details[0].condition])' } } } } } }
I have tried multiple ways but not sure how to make it work when there are more than one keys getting returned.
First let me say this. Please, please do not try to be "too clever" in your tests. Read this please: https://stackoverflow.com/a/54126724/143475
Just have simple tests that test for specific, predictable responses and stop there. The maximum complexity should be match contains, that's it. What you are trying to do is in my opinion a waste of time, and will just cause grief for anyone who tries to maintain these tests in future.
That said, I'm giving you a completely different approach here. There are a few different ways, this is just one. Here we attack the problem piece by piece instead of trying to write one massive match.
* def allXyz = array.details.filter(x => x.data.check == 'xyz')
* match each allXyz..details == [{ hello: 'def', condition: 'check2' }]
You should be able to extend this to do all the weird assertions that you want. If you are wondering what allXyz..details does, you can print it like this:
* def temp = $allXyz..details
* print temp
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]
In the below JSON response, I need to extract the 'cid' for the record that has the 'nationalityDecription' as 'USA'. By using this query as a reference, I used the below loc in the karate feature file, but 1st line itself fails with syntax error(tried different combinations). For now, I'm using the custom javascript as a workaround which is working fine. I need help to check if i'm missing anything in syntax. Thanks
Response:
{
"header": {
"Id": "12345678",
"timeStamp": "2018-09-17T10:09:812.000"
},
"dataRecords": [
{
"cid": "31H678",
"cidMeta": "00",
"nationalityDecription": "CHINA"
},
{
"cid": "31S421",
"cidMeta": "01",
"nationalityDecription": "USA"
}
]
}
Feature file:
* def record= $response.dataRecords[?(#.nationalityDecription=='USA')]
* def cid = record.cid
* def response = { "header": { "Id": "12345678", "timeStamp": "2018-09-17T10:09:812.000" }, "dataRecords": [ { "cid": "31H678", "cidMeta": "00", "nationalityDecription": "CHINA" }, { "cid": "31S421", "cidMeta": "01", "nationalityDecription": "USA" } ] }
* def cid = get[0] response.dataRecords[?(#.nationalityDecription=='USA')].cid
* match cid == '31S421'