The notpresent keyword is not working in Karate - karate

I am trying to assert that a key is not in the JSON response. This is the response
{
"_type": "UserAccount",
"accountName": "Account_Name",
"accountType": "regular",
"whiteList": true,
"sfAccountId": "1",
"preferredLanguage": "english",
"imageSize": "highRes",
"_id": "775a8451-6a07-42da-a199-fe98f44bdc06"
}
I have tried both of these steps according to the documentation karate#null-and-notpresent and this answer from Peter Thomas
And match response.appClientId == '#notpresent'
And match response == {appClientId:'#notpresent'}
However this is the error I keep getting for the first step above
com.jayway.jsonpath.PathNotFoundException: No results for path: $['appClientId']
and for the second step
com.intuit.karate.KarateException: path: $, actual
Thanks in advance

Maybe your version is out of date, the below works for me in 0.9.1:
* def response =
"""
{
"_type": "UserAccount",
"accountName": "Account_Name",
"accountType": "regular",
"whiteList": true,
"sfAccountId": "1",
"preferredLanguage": "english",
"imageSize": "highRes",
"_id": "775a8451-6a07-42da-a199-fe98f44bdc06"
}
"""
* match response.appClientId == '#notpresent'
* match response contains { appClientId: '#notpresent' }

Related

How to use loop for response from another feature?

Іssue in the next.
I have a feature response which I check according to schema validation
{
"name": "#string",
"director_first_name": "##string",
"director_last_name": "##string",
"director_phone": "##string",
"director_email": "##string",
"language": {
"id": "#uuid",
"name": "#string",
"code": "#string? _.length == 2"
}
}
Also I have additional feature, which has list of languages
[
{
"id": "fde1312f-2ab2-4fdf-a4f3-a7095dd89a4d",
"name": "English",
"code": "EN"
},
{
"id": "0d4c6626-1010-4dda-8721-665071ec3b28",
"name": "Swedish",
"code": "SV"
}
]
And I need to check the next
Need to take response.language.id from first response and check if this id is represented in the second response. In this case I need to call this second feature.
If it is represented, need to match if id, name, code which belong to first reponse the same as in the second response.
You can do this in one line. I leave it as an exercise to you to get the data from a second feature file if you wish.
* def data =
"""
[
{
"id": "fde1312f-2ab2-4fdf-a4f3-a7095dd89a4d",
"name": "English",
"code": "EN"
},
{
"id": "0d4c6626-1010-4dda-8721-665071ec3b28",
"name": "Swedish",
"code": "SV"
}
]
"""
* def response =
"""
{
"language": {
"id": "fde1312f-2ab2-4fdf-a4f3-a7095dd89a4d",
"name": "English",
"code": "EN"
}
}
"""
* match response.language == data.find(x => x.code == response.language.code)
Take some time to read other answers (and follow the links) for ideas: https://stackoverflow.com/a/70055035/143475

How to match string and ignore the case in karate?

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'

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

Is there a if functionality in Karate framework?

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

Extract data from json array in Karate

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'