Extract and comparing data from json array not working in karate - testing

I am trying to search a certain value in a JSON array using the value stored in a variable and then comparing somehow this is not working for me. Can you please help. BillerId1 is always returning a blank value
Given url buyerApi
Given url paymentHub
Then path '/BPAY/v' + version + '/billers'
And header Authorization = 'Bearer ' + token
When method get
Then status 200
* def id = response[0].savedBillerId
Then url paymentHub
Then path '/BPAY/v' + version + '/billers/' +id
And header Authorization = 'Bearer ' + token
And request {billerCode:<billerCode>, billerCRN:'<billerCRN>'}
When method put
Then status 200
Then url paymentHub
Then path '/BPAY/v' + version + '/billers'
And header Authorization = 'Bearer ' + token
When method get
Then status 200
* print id
* def billId1 = get[0] response[?(#.savedBillerId==**'#id'**)].savedBillerId
* print billId1
And match billId1 == id
Examples:
| billerCode | billerCRN |
| 65284 | 65112345675 |
Array looks like this
[
{
"savedBillerId": "ebfa2b9f-f49c-4b0c-c6ee-08d7e671944a",
"billerId": "26c67edb-b3dc-44ea-aa74-08d7d6890798",
"billerName": "test case 21c",
"billerCode": 65284,
"crn": "65112345675"
},
{
"savedBillerId": "500dfde7-e31c-408d-c6ef-08d7e671944a",
"billerId": "26c67edb-b3dc-44ea-aa74-08d7d6890798",
"billerName": "test case 21c",
"billerCode": 65284,
"crn": "65112345672"
}
]
#ptrthomas

Please read the docs: https://github.com/intuit/karate#jsonpath-filters
* def id = '500dfde7-e31c-408d-c6ef-08d7e671944a'
* def billId1 = karate.jsonPath(response, "$[?(#.savedBillerId=='" + id + "')].savedBillerId")[0]
* match billId1 == id
Also I feel this is a worthless check. You find by id and again check that id ?

Related

Is it possible to dynamically change an url with values in the array without storing the values in separate feature file

I need to array values say 10 values from the previous url response to get replace in the next url
*def k = [1,2,3]
Given url 'https://www.' + k + 'zzzz'
Tried this:
*def k = [1,2,3]
Given url 'https://www.' + k[*] + 'zzzz'
Expecting:
Given url 'https://www.+ 1 + zzzz'
need its response to store
Given url 'https://www.+ 2 + zzzz'
need its response to store
Given url 'https://www.+ 3 + zzzz'
need its response to store
Yes, in Karate 1.3.1 onwards: https://github.com/karatelabs/karate#setup
Try the below and see it work.
Feature:
#setup
Scenario:
# do some http stuff here and prepare the data to use in the loop
* def data = [{ myNum: 1 }, { myNum: 2 }, { myNum: 3 }]
Scenario Outline:
* url `https://httpbin.org/anything/${myNum}`
* method get
Examples:
| karate.setup().data |

Karate | String Split for CLI output [duplicate]

I'm unsure about how I can split the response string from an already created feature to obtain the response header "Location" value.
What I've tried
1)
Feature: Create Tariff
Background:
* def result = call read('../../get-user-token.feature')
* def serviceId = call read('create-service.feature')
Scenario: Create Tariff
Given url 'https://app-dev.topbox.pro/tariff-svc/api/v1/tariffs'
And header Authorization = result.response.token_type + " " + result.response.access_token
And request
"""
{
serviceTypeId: '#(serviceId.responseHeaders['Location'].split('/')[1])',
owner: 1,
type: 0,
pencePerMile: '69.69',
minMileage: '1.00',
minCost: 5,
zoneFrom: '',
zoneTo: '',
fixedCost: 0
}
"""
When method POST
Then status 201
Which resulted in...
IntegrationTests.TestSetup.create-tariff: create-tariff.feature:10 -
net.minidev.json.parser.ParseException: Unexpected token L at position
46.
2)
Feature: Create Tariff
Background:
* def result = call read('../../get-user-token.feature')
* def serviceId = call read('create-service.feature').responseHeaders['Location'].split('/')[1]
Scenario: Create Tariff
Given url 'https://app-dev.topbox.pro/tariff-svc/api/v1/tariffs'
And header Authorization = result.response.token_type + " " + result.response.access_token
And request
"""
{
serviceTypeId: '#(serviceId)',
owner: 1,
type: 0,
pencePerMile: '69.69',
minMileage: '1.00',
minCost: 5,
zoneFrom: '',
zoneTo: '',
fixedCost: 0
}
"""
When method POST
Then status 201
Which resulted in...
failed features: IntegrationTests.TestSetup.create-tariff: -unknown-:5
- javascript evaluation failed: read('create-service.feature').responseHeaders['Location'].split('/')1,
TypeError: Cannot read property "Location" from undefined in at
line number 1
NOTE
The specified feature "create-service.feature" does indeed work when isolated and does produce the response header, as shown below
Use lastIndexOf instead of split:
* def location = responseHeaders['Location'][0]
* def serviceId = location.substring(location.lastIndexOf('/') + 1)
You need to use a Javascript function : https://github.com/intuit/karate#javascript-functions
* def greeter = function(name){ return 'hello ' + name }
* assert greeter('Bob') == 'hello Bob'
EDIT:
* def service = { key : "someinfo/myServiceId"}
* def func = function(service){return service.key.split('/')[1]}
* def serviceId = func(service)
* match serviceId == "myServiceId"
I think the first error is due to single quotes inside your expression, try escaping that
like,
And request
"""
{
serviceTypeId: '#(serviceId.responseHeaders.Location[0].split(\'/\')[1])',
owner: 1,
type: 0,
pencePerMile: '69.69',
minMileage: '1.00',
minCost: 5,
zoneFrom: '',
zoneTo: '',
fixedCost: 0
}
"""
Edit: Just now noted each value in responseHeader has a list type value so access it like Location[0]
And your second Approach should be something like this,
* def serviceId = call read('create-service.feature').responseHeaders.Location[0].split('/')[1]
I just face the same issue (.split is not a function), and in my case, I need to convert the data to string first, before using split function.
Here is the custom code from adrien answer:
* def service = { key : "someinfo/myServiceId"}
* def func = function(service){return service.key.toString().split('/')[1]}

Karate: Replace variables in text type [duplicate]

When i am passing the value of a string json filter is working fine. But when I am passing embedded expression in the JSONPATH it is not replacing actual value.
Given url appServer +'/integration/rest/user'+'?page=0'+'&pageSize=10'+'&fieldList=first_name,last_name,id,username,last_login,active,date_created'+'&filter=user_type%20equals%20%27P%27%20'+'&getTotalRecordCount=true'
And header X-CSRF-TOKEN = csrfToken
* cookie JSESSIONID = jsessionid
* print routevalue
* cookie route = routevalue
* string searchUser = 'anupama'
* callonce sleep 10
Given request ' '
When method get
Then status 200
* def usernames = get response.integration.serviceData.record[*].username
* print usernames
* print searchUser
* def userNode = get[0] response.integration.serviceData.record[?(#.username== '#(searchUser)')]
* print userNode
Embedded expressions are only for JSONPath and XML: https://github.com/intuit/karate#embedded-expressions
Please use the karate API for dynamic JsonPath: https://github.com/intuit/karate#jsonpath-filters
* def userNode = karate.jsonPath(response, "$.integration.serviceData.record[?(#.username=='" + searchUser + "')]")

how to pass a string in parm request and loop it in my request path without saving to a file and creating table

so i created/def a object with
And def memeberIDs = $.users[*].id
And print memeberIDs
and i get a list like so
[
"eOVbGI0XSiabeiLZtB-ROQ",
"iK-Fz_NRSbSt-7AdodjDrA",
"dS2czwVFRZmy8a6oxO7JKw",
"yxH3bmF3THuCgLWLGh7eeQ",
"bqD41MgvSlC94EQH-r1H-Q",
"MrQihYjiR_WmWHA2-Y2cZQ",
"9N7uZdT_RTmePdJ5DMZ7sg",
"qo76PFcSS3-61FwgKCz6Ng",
"tjo3sdj3RMe8RoSBR3U_Ng",
"OuFxQR7KThCBPv2wHtKzhg",
"YmQKkv69Ts2yQ32LIjJN-g",
"A7kRauysQsCtle9G-bMV0g",
"zinHreHLTluUWdFzavssEA",
"UhZt8B_JSVaPBAJdIcPBsw",
"MtT_yR1iQqmDWMWlxXsWmQ",
"y2c9aK17Qouune_c_ZGlYQ",
"xGHOe7wxQru-NruIBPHL7Q",
"sTe8TADNTQ6nmg4UJeXiOQ",
"qC2FJUJeQJmOJPKkE_iehQ",
"4V0a93O8TCK-jjDujVVH-A",
"sk1tDsUmRYWUjyCMWFOqDw",
"ChmxrwHwTcS9I3u-RveBQA",
"ZL3uSx1oQbOc2c5qrFYRew",
"qjxFk-x9SVe-8XkzMbLrBw",
"7uIQVAXuSVe4tcWdv6S7MQ",
"V4mdzUj2SpyVpKlJfSdOEg",
"dU61-sNoQu6Q87hItkGcHw",
"enhFrWkfTDuaFqQCwPetAw",
"Txte_5FtTiaSfsc5k7-HmA",
"7tkMxEglS5qgx6bKObByKg",
"-uv0OuoNRlinnI4HkGsSSg",
"tLxWhEqSSiOcqyGJKsG6tQ",
"8tqnoZ1DQrq0DGzU_4OVmg",
"E9Rjy2euRbaKeaP1INxvGA",
]
My next request looks like
Given url 'https://api.someurl.com/v2/users//meetings?type=all&page_size=30&page_number=1'
Take some time and study this example. And read this part of the documentation: https://github.com/intuit/karate#dynamic-scenario-outline
Background:
* def list = ['foo', 'bar']
* def data = karate.mapWithKey(list, 'name')
Scenario Outline:
* url 'http://httpbin.org'
* path 'anything'
* param test = name
* method get
Examples:
| data |
This example will make 2 requests,
1) GET http://httpbin.org/anything?test=foo
2) GET http://httpbin.org/anything?test=bar

How to use js EXPR with XML in Karate

I have to modify an xml expression and match it to a json. Below is the code I have written. I need to validate ind is true or false. For this, I cannot use '#boolean' because <ns4:ind>true</ns4:ind> behaves as a string.
XML File:
<ns9:parent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns5:parent">
<ns4:ind>true</ns4:ind>
<ns4:description>Some text</ns4:description>
</ns9:parent>
Code:
* def Test = call read ('classpath:Path/Test.xml)
* def Check = $Test/parent
* set Downstream.parent
| path | value |
| ind | '#?_ == "true" || _== "false"' |
| description | $Check/parent/description |
* def Match =
"""
{
"parent": {
"ind": "true",
"description": "Some text"
}
}
"""
* match Match == Downstream
Tried with '#boolean' as well, doesn't work.
| ind | '#boolean' |
I get below error;
com.intuit.karate.exception.KarateException: Test.feature:20 - javascript evaluation failed: '#?_ == "true", <eval>:1:14 Missing close quote '#?_ == "true"
This should work,
* def Test = call read ('classpath:Path/Test.xml')
* def Check = $Test/parent
* xml Downstream = "<parent></parent>"
* def desc = $Check/parent/description
* set Downstream/parent/ind = '#?_ == "true" || _== "false"'
* set Downstream/parent/description = desc
* match $Test/parent/ind == $Downstream/parent/ind
* match $Test/parent/description == $Downstream/parent/description
Note:
set for XML doesn't seem to support table so use inline set.