I have 2 different responses:
{
"id": "U204204",
"title": "Safety kit",
"categoryPath": "/equipment/accessories/null",
"keyFeature": false,
"description": "test",
"price": 24.5,
"availability": "optional-extra",
"technologyItems": [],
"bespoke": false
}
or/and
{
"id": "GWW1WW1",
"title": "Winter pack",
"categoryPath": "/comfort & convenience/packs/null",
"keyFeature": false,
"description": "test",
"price": 410,
"availability": "optional-extra",
"technologyItems": [],
"bespoke": false
}
Now what I'm trying to assert is as long as the key price in ANY of the 2 responses above has a value ending in '.5' pass it.
I have tried the following and similar things but not working:
Given path 'endpoint'
And multipart file pdbData = { read: 'json/PostRequest_201_3.json', filename: 'PostRequest_201_3.json', contentType: 'application/json'}
When method post
And status 201
* def NewpdbId = response.id
And path 'endpoint'+NewpdbId+'/V3FOY3DG'
And method GET
And status 200
* string aa = response.options[13].price
* string bb = response.options[16].price
* def expected = aa contains "#redgex .+[.5]+" ? { pass: true }
* def expected = bb contains "#regex .+[.5]+" ? { pass: true }
* string expected = expected
And match expected == { pass: true }
So if the key price ends in '.5' in any of the responses it should be a pass. If key price is a whole number in all of the responses then it should fail.
Any ideas? I have tried so many different ways
There are a few ways. Read the docs for match each also:
First extract only the price values into a list, convert to strings (read the docs for JSON transforms):
* def prices = $response.options[*].price
* def fun = function(x){ return x + '' }
* def prices = karate.map(prices, fun)
* match prices contains '#regex .+[.5]+'
Related
i have set continueOnStepFailure to true before match step, i am using karate core . i am still unbale to get desired result of each attribute validation of json. After the first failure next values are not getting compared. Do we need to take care of any additional settings apart of karate version 1.0 and above?
* def response1 =
"""
{
"name": "Tom",
"gender": "male",
"age": "20"
}
"""
* def response2 =
"""
{
"name": "Jon",
"gender": "female",
"age": "21"
}
"""
* configure continueOnStepFailure = { enabled: true, continueAfter: false, keywords: ['match'] }
* match response1 == response2
* configure continueOnStepFailure = false
Output of above code is ---------->
match failed: EQUALS
$ | not equal | match failed for name: 'name' (MAP:MAP)
{"name":"Tom","gender":"male","age":"20"}
{"name":"Jon","gender":"female","age":"21"}
$.name | not equal (STRING:STRING)
'Tom'
'Jon'
classpath:LIB_API/SampleTest.feature:51
I have following data.json file:
{
"ids": {
"id": "a2mx8m6yvksgu3605c7c1a61d"
},
"second": {
"name": "test2"
},
"third": {
"name": "test3"
}
}
I did fetch a variable for the id from the json.
* def id = data.ids.id
I want to use this variable id (defined above) to a request.
Request defined below is dynamically being sent to the xml file i.e xml request is being generated with but the below doesnt work when i try to pass the variable id.
This however works when i hardcode the id value.
* def ARG = {attr: [ { regex: '#(ids)', value: '<id>"#(id)"</id>'} ] }
Please help me how can i pass the data being read from json to the above line of code.
Read the docs: https://github.com/intuit/karate#rules-for-embedded-expressions
* def id = 'foo'
* def val = '<id>' + id + '</id>'
* def arg = { value: '#(val)' }
* match arg == { value: '<id>foo</id>' }
I am hitting an API end point and getting something like below.
{
"emp": {
"id": "123",
"firstNm": "test",
"lastNm": "last",
"dob": "200-01-01",
"gender": {
"code": "F",
"name": "Female",
"description": "Female"
},
"test1": [
{
"tes2": "F50045A3B994FB2BDF4E3D3FC906F592",
"t2": "a23",
"test3": {
"code": "432",
},
"ind": [
"ABC",
"BCD",
]
}
]
}
}
I want to match the elements in the array
"ind": [
"ABC",
"BCD",
]
I have tried the below:
Feature: test
Background:
* url BaseUrl
* configure headers = read('classpath:headers.js')
Scenario Outline: test
Given path '/path'
And param id = <id>
When method get
Then status 200
* def json = response
* def has = {ind:['#string'] }
* def indicator = { ind: '#[] has' }
* match json.member == '#[] indicator'
Examples:
| id |
| '1234' |
But observed the below exception:
expected: '#[] ind', reason: not an array or list
Can someone please help?
I am not really following your logic since indicators is not in the json response or defined variable but to get to the ind array the path is emp.test1[0].ind
if you want to match that the array has ABC and BCD you would do the following
* match response.emp.test1[0].ind == ['ABC', 'BCD']
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)'
I want to update a value of somewhereInJsonPath field in my JSON file.
I am using for this: * set myBody $..someWhereInJsonPath = 'AAA'. And when I run test I get: Path must not end with a '.'
But when I am using * set myBody $..firstHere.someWhereInJsonPath = 'AAA' it is working.
I think in first case, where we want to update first value in $.., it must working too.
To clarify:
For example we have JSON:
{
"store": {
"book": [
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"something": 12.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
And when I do: $.store.book[0].something = 13 it is working.
BUT when I do: $..something = 13 it is not working.
Why? And how can I update this?
At http://jsonpath.com/ when I want to find $..something it is find this value. But when I use $..something in karate it is not working.
Realted with https://stackoverflow.com/questions/54928387/karate-jsonpath-wildcards-didnt-work-or-partly-didnt-work
Actually the set command is not really designed for JsonPath wildcards. For example $[*].foo or $..foo are examples of wildcards. And $[0].foo, $.foo or response.foo are pure JS expressions.
So please stick to pure JS expressions like this. Here below, set is interchangeable with eval which is more useful in case you want to use dynamic / variables for e.g. * eval response[foo] where foo is a string.
* def response = { foo: { somePath: 'abc' } }
* eval response.foo.somePath = 'xyz'
* match response == { foo: { somePath: 'xyz' } }
If you really do need to do "bulk" updates, use a transform function:
* def response = [{}, {}]
* def fun = function(x, i){ return { foo: 'bar', index: ~~(i + 1) } }
* def res = karate.map(response, fun)
* match res == [{ foo: 'bar', index: 1 }, { foo: 'bar', index: 2 }]