Karate: parametric json path expressions [duplicate] - karate

I'm attempting to use a variable in the RHS of an JsonPath filter expression in a Karate test, similar to this:
* def name = 'A Name'
* def ids = $response[?(#.name == '#(name)')].id
If I use the literal string 'A Name' in the RHS of the expression it works as expected.
I've tried various ways to get the variable to evaluate:
'<name>', "#(name)", etc.
I suspect it is because I'm mixing JsonPath parsing with Karate parsing perhaps?

Read this first: https://github.com/intuit/karate#rules-for-embedded-expressions
And what you are looking for is this: https://github.com/intuit/karate#jsonpath-filters
* def ids = karate.jsonPath(response, "$.kittens[?(#.name=='" + name + "')].id")

Related

Karate - How to get the value of a specific attribute based on multiple attribute values in the specifc json array [duplicate]

I'm attempting to use a variable in the RHS of an JsonPath filter expression in a Karate test, similar to this:
* def name = 'A Name'
* def ids = $response[?(#.name == '#(name)')].id
If I use the literal string 'A Name' in the RHS of the expression it works as expected.
I've tried various ways to get the variable to evaluate:
'<name>', "#(name)", etc.
I suspect it is because I'm mixing JsonPath parsing with Karate parsing perhaps?
Read this first: https://github.com/intuit/karate#rules-for-embedded-expressions
And what you are looking for is this: https://github.com/intuit/karate#jsonpath-filters
* def ids = karate.jsonPath(response, "$.kittens[?(#.name=='" + name + "')].id")

Use variables in json path expressions [duplicate]

This question already has an answer here:
How to use a variable in JsonPath filter
(1 answer)
Closed 2 years ago.
I have a feature file to retrieve the data from csv file for the given parameter. In order to do it, I need to use a variable in the JsonPath expression to retrieve data for given parameter. I tried may ways, but using variable in jsonPath is not working. I'm using 0.9.4 version
I tried the below ways:
* def userId = get[0] testData[?(#.UserType=='${userType}')].UserId
* def userId = get[0] testData[?(#.UserType==userType)].UserId
* def userId = get[0] testData[?(#.UserType=='#(userType)')].UserId(I suppose this can only be used in json/xml)
Below hard coded value works fine:
* def userId = get[0] testData[?(#.UserType=='SuperAdmin')].UserId
Called feature:
Feature: Utility to extract the various types of data from excel datasource
Background:
* def DataUtility = Java.type('com.org.utils.DataUtility')
* def dataUtils = new DataUtility()
* def testData = read('classpath:testdata/TestData.csv')
Scenario: Retrieve userId for a given user type
* def userId = get[0] testData[?(#.UserType=='${userType}')].UserId
Calling feature:
* table params
| userType |
| 'SuperAdmin' |
* def extractedData = call read('DataExtractor.feature') params
* def userID = extractedData[0].userId
I have tried using variables in Json Path.
Example:
String elementPath = "$.[" + i + "].item.value";
In this statement, i is a loop variable. After this pass it to the read api of DocumentContext.
It has worked perfectly fine for me.
I am using JsonPath & DocumentContext from jayway to achieve this.
import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;

Removing quotes from param values in karate request

Scenario: I get response from a karate request which is in the form as below:
idValues = ["123:ABCD-F", "345:CFGB-F", "678:DERF-F"]
I then need to make a further request in a scenario where the values from array above is passed in karate's request * param as below:
Given path 'users','details'
* param = 123:ABCD-F, 345:CFGB-F, 678:DERF-F
When method get
Then status 200
Issue: I need to send this list of ids as comma separated values without the " quotes to the param keyword. If the values are passed to params with quotes, karate further encloses the ids within quotes (which is the correct behaviour i think) and because of this i do not get the expected response.
Wanted to know if there is a way to:
1. Take the values out of the array, remove the quotes from start and end.
2. Pass these as comma separated values to `param' keyword (as shown in the example above).
Thanks
2 suggestions.
karate.forEach() can do any kind of conversion you want. Here is an example. If you find this too ugly, use Java (search the docs for Java Interop):
* def idValues = ["123:ABCD-F", "345:CFGB-F", "678:DERF-F"]
* def fun = function(x, i){ var s = karate.get('temp'); if (i) x = ',' + x; karate.set('temp', s + x) }
* def temp = ''
* karate.forEach(idValues, fun)
* print temp
param will always encode, and as you said - it is the right behavior. So use url and manually concatenate the path you need. Refer this answer for more:
https://stackoverflow.com/a/55357704/143475

How to use a variable in JsonPath filter

I'm attempting to use a variable in the RHS of an JsonPath filter expression in a Karate test, similar to this:
* def name = 'A Name'
* def ids = $response[?(#.name == '#(name)')].id
If I use the literal string 'A Name' in the RHS of the expression it works as expected.
I've tried various ways to get the variable to evaluate:
'<name>', "#(name)", etc.
I suspect it is because I'm mixing JsonPath parsing with Karate parsing perhaps?
Read this first: https://github.com/intuit/karate#rules-for-embedded-expressions
And what you are looking for is this: https://github.com/intuit/karate#jsonpath-filters
* def ids = karate.jsonPath(response, "$.kittens[?(#.name=='" + name + "')].id")

Certain expressions to validate json don't work

I am trying to print the following:
* print response.requests[?(#.friendlyId == '#(ORID)')]
where ORID is:
* def temp2 = response.teams[?(#.name == '<Name>')].requestedResources[0].resourceRequestFriendlyId
* def ORID = temp2[0]
The expression is giving value as null where as if i use JSON evaluator, I am getting the correct json.
Only JavaScript is supported on the right-hand-side of the print keyword. And JsonPath is not supported.
I will update the documentation to make this clear.