karate : handling soap response from a called feature file - karate

first.feature
Given ur ''
def payload = read('')
request payload
soap action ''
value = /Envelope/Body/Response/Result/Num
print value # prints value correctly as expected
second.feature
Background:
*def fetch = read('first.feature')
*def data = call fetch
Scenario:
print data.response # prints the soap response in json format.
def res = data.response
print res["s:Envelope"][""]["s:Body"]["Response"][""]["Result"]["_"]["a:num']
first.feature works as expected ( response is in soap )
When I try to call this feature in another feature then the response is in json format.
I want to use a value from this response to pass it on to another request.
I had to use res["s:Envelope"]["_"]["s:Body"][][].. to get to that.
Is there a way to easily fetch a value from this response as we do in first.feature?
Please could anyone let me know how to achieve this.

Make this change:
* xml res = data.response
We will be improving this in the next version, it would be good if you can test the develop branch and confirm: https://github.com/intuit/karate/wiki/Developer-Guide

Related

Sending a SOAP request with a file attachment [duplicate]

I have an endpoint who consumes Json with 2 attributes, like
{id='12344', data=byte_array}
so I've wrote a test
Feature: submitted request
Scenario: submitted request
* def convertToBytes =
"""
function(arg) {
var StreamUtils = Java.type('my.utils.StreamUtils');
// it reads stream and convert it to a byte array
return StreamUtils.getBytes(arg);
}
"""
Given url 'http://my-server/post'
And def image = convertToBytes(read('classpath:images/image_1.jpg'));
And request {id:1, data: "#(image)"}
When method POST
Then status 200
However is got an exception form karate without much details
ERROR com.intuit.karate - http request failed: [B cannot be cast to [Ljava.lang.Object;
Any hits how to submit byte arrays as a part of Json with karate?
I don't think you can do that. Either the whole request should be binary (byte-array) or you do a multi-part request, where binary is Base64 encoded. As far as I know you can't put binary inside JSON. There is something called Binary JSON though.
EDIT: after assuming that the byte[] has to be Base64 encoded:
Background:
* url demoBaseUrl
* def Base64 = Java.type('java.util.Base64')
Scenario: json with byte-array
Given path 'echo', 'binary'
And def encoded = Base64.encoder.encodeToString('hello'.bytes);
And request { message: 'hello', data: '#(encoded)' }
When method post
Then status 200
And def expected = Base64.encoder.encodeToString('world'.bytes);
And match response == { message: 'world', data: '#(expected)' }
I just added this test to the Karate demos, and it is working fine. Here is the commit.

How to send a variable to a text file that calling to karate feature file...?

Step 01#: I am calling 'Request Date' from json file and saving as "RequestDate"
Background:
json req = read('classpath:XXX/XXX/API/02_Dataset/DataSet.json')
* def RequestDate = get req.GameEnq.RequestDate
Step 02#: I am also calling 'GameDetailsRequest' from json file which has the field called "RequestDate", I would like pass "RequestDate" into "GameDetailsRequest".
Scenario: GameEnq
Given request
"""
GameDetailsRequest
"""
* def GameDetailsRequest = read('classpath:XXX/XXX/API/02_Dataset/ServiceRequestData_GameEnq');
Note: I can able to print the "RequestDate" value correctly ,however i don't know how to call into "GameDetailsRequest"... Please assist me. Your suggestion highly appreciated
Kind Regards
Sudheer Bonam
I think you need to try replace for a text place holder replacement
Add a placeholder <PLACEHOLDER_NAME> in your text data in GameDetailsRequest where you want to insert RequestDate
eg:
* string GameDetailsRequest = "Game release data : <RequestDate>"
* replace GameDetailsRequest.RequestDate = "12-12-2020"
Now GameDetailsRequest will be "Game release data : 12-12-2020"
refer: karate doc for replace

How to pass the json list response of one feature file as parameter to another feature file

My requirement is, I want to pass the response of first feature file as input to second feature file. The first feature file response is a json list, so the expectation is second feature file should be called for each value of json list.
Feature:
Scenario: identify the reference account
* def initTestData = read('../inputData.feature')
* def accountData = $initTestData.response
* print “Account Details”+accountData // output of this is a json list [“SB987658”,”SB984345”]
* def reqRes = karate.call('../Request.feature', { accountData : accountData })
In Request.feature file we are constructing the url dynamically
Given url BaseUrl + '/account/'+'#(accountId)' - here am facing issue http://10.34.145.126/account/[“SB987658”,”SB984345”]
My requirement is Request.feature should be called for each value in ‘accountData’ Json list
I have tried:
* def resAccountList = karate.map(accountData, function(x){accountId.add(x) })
* def testcaseDetails = call read('../requests/scenarios.feature') resAccountList.accountId
Result is same, accountId got replaced as [“SB987658”,”SB984345”]
my I need to call Request.feature twice http://10.34.145.126/account/SB987658 http://10.34.145.126/account/SB984345 and use the response of each call to the subsequent feature file calls.
I think you have a mistake in karate.map() look at the below example:
* def array = ['SB987658', 'SB984345']
* def data = karate.map(array, function(x){ return { value: x } })
* def result = call read('called.feature') data
And called.feature is:
Feature:
Scenario:
Given url 'https://httpbin.org'
And path 'anything', value
When method get
Then status 200
Which makes 2 requests:
https://httpbin.org/anything/SB987658
https://httpbin.org/anything/SB984345

How to send a byte array as a part of Json with karate framework

I have an endpoint who consumes Json with 2 attributes, like
{id='12344', data=byte_array}
so I've wrote a test
Feature: submitted request
Scenario: submitted request
* def convertToBytes =
"""
function(arg) {
var StreamUtils = Java.type('my.utils.StreamUtils');
// it reads stream and convert it to a byte array
return StreamUtils.getBytes(arg);
}
"""
Given url 'http://my-server/post'
And def image = convertToBytes(read('classpath:images/image_1.jpg'));
And request {id:1, data: "#(image)"}
When method POST
Then status 200
However is got an exception form karate without much details
ERROR com.intuit.karate - http request failed: [B cannot be cast to [Ljava.lang.Object;
Any hits how to submit byte arrays as a part of Json with karate?
I don't think you can do that. Either the whole request should be binary (byte-array) or you do a multi-part request, where binary is Base64 encoded. As far as I know you can't put binary inside JSON. There is something called Binary JSON though.
EDIT: after assuming that the byte[] has to be Base64 encoded:
Background:
* url demoBaseUrl
* def Base64 = Java.type('java.util.Base64')
Scenario: json with byte-array
Given path 'echo', 'binary'
And def encoded = Base64.encoder.encodeToString('hello'.bytes);
And request { message: 'hello', data: '#(encoded)' }
When method post
Then status 200
And def expected = Base64.encoder.encodeToString('world'.bytes);
And match response == { message: 'world', data: '#(expected)' }
I just added this test to the Karate demos, and it is working fine. Here is the commit.

Capture json response value in karate api

How can I retrieve numeric value from json response in Karate API?
Here I want to retrieve 41651625424 this value in a variable as I have to pass this as input in another request body
{"items":{'41651625424': {itemCore: {partNumber: '1234567', productTitle: 'Karate API Testing'}}}}
Here you go. The trick is to convert this to a Java Map and then you have a lot of useful methods that do what you want:
* def response = {"items":{'41651625424': {itemCore: {partNumber: '1234567', productTitle: 'Karate API Testing'}}}}
* def map = karate.toBean(response.items, 'java.util.LinkedHashMap')
* def first = map.keySet().iterator().next()
* match first == '41651625424'