In the below code, you can see variable defaultHeaders is copied to a new variable called myHeaders.
Now, When altering the value of myHeaders, is altering the value of defaultHeaders variable.
is this correct? am i missing something fundamental. Please explain.
I was hoping the original defaultHeaders would remain same for other scenarios to use.
Karate version: 0.9.4
Feature: test one
Background:
* def defaultHeaders = { 'app-Id' : "defaultApp" }
#ScenarioOne
Scenario: scenario one
* def myHeaders = defaultHeaders
* print myHeaders \\ prints { "app-Id": "defaultApp" }
* myHeaders["app-Id"] = 'MyNewAppId'
* print myHeaders \\ prints { "app-Id": "MyNewAppId" }
* print defaultHeaders \\ prints { "app-Id": "MyNewAppId" }
* print myHeaders \\ prints { "app-Id": "MyNewAppId" }
* def calltoSecond = call read('featureTwo.feature#ScenarioTwo') { customHeader: '#(myHeaders)'}
Please look at the copy keyword: https://github.com/intuit/karate#type-copy
* copy myHeaders = defaultHeaders
Related
I have variable cardholder in my karate-config file.
I assigned it to the new entrID variable.
The main thing that i am building JSON as a String..
* def entrID = cardholder
* def requestContactHistoryAdd =
"""
{
"RequestBody": "{ \"ENTR_ID\" : \"entrID\", \"BHVR_ID\" : \"VRU\", }"
}
"""
Now how can i provide it inside of my json RequestBody?
EDIT: since you seem to have a very badly designed API where the JSON has an embedded string (which looks like JSON).
Please note I am using a string type below: https://github.com/intuit/karate#type-conversion
You can do this:
* def entrID = 'foo'
* string temp = { "ENTR_ID" : "#(entrID)", "BHVR_ID" : "VRU" }
# note that you could have done this:
# def temp = '{ "ENTR_ID" : "' + entrID + '", "BHVR_ID" : "VRU" }'
* def body = { RequestBody: '#(temp)' }
* print body
Which gives you:
08:17:25.671 [main] INFO com.intuit.karate - [print] {
"RequestBody": "{\"ENTR_ID\":\"foo\",\"BHVR_ID\":\"VRU\"}"
}
i solved it also like this
* def entrID = someValueFromSomeWhere
* def bodyValue = "{ \"ENTR_ID\":\"" + entrID + "\", \"BHVR_ID\" : \"VRU\" }"
* def requestContactHistoryAdd =
"""
{
"RequestBody": "#(bodyValue)"
}
"""
we can also do this way
* def bodyValue = "{ \"ENTR_ID\":\"" + someValueFromSomeWhere + "\", \"BHVR_ID\" : \"VRU\" }"
* def requestContactHistoryAdd =
"""
{
"RequestBody": "#(bodyValue)"
}
"""
I have a Json response like below. The difference here is my Json body has a number as the parent node.
def response =
"""
{
"22388043":[
{
"firstName":"Romin",
"lastName":"Irani",
"phoneNumber":"408-1234567",
"emailAddress":"romin.k.irani#gmail.com"
}
]
}
"""
I want to return the mobileNumber attribute value from the response body. In this scenario I don't have that attribute in my response. So here I want to get a null value.
So when I use * def mobile = $.22388043[0].mobileNumber, I'm getting below error.
No results for path: $['22388043'][0]['mobileNumber']
Please advise on this.
Karate does give you a way to get the values of JSON keys.
Hopefully this example answers all your other questions as well:
* def response =
"""
{
"22388043":[
{
"firstName":"Romin",
"lastName":"Irani",
"phoneNumber":"408-1234567",
"emailAddress":"romin.k.irani#gmail.com"
}
]
}
"""
* def id = karate.keysOf(response)[0]
* match id == '22388043'
* def person = response[id][0]
* match person contains { firstName: 'Romin', lastName: 'Irani' }
* match person.mobileNumber == '#notpresent'
I have the following feature file that reads the input and appends the input id with the response and writes to a text file in the below format:
|123|{"products": [ { "pid": "1a"} ] }|
|124|{"products": [ { "pid": "1b"} ] }|
|125|{"products": [ { "pid": "1c"} ] }|
so that I can make the input table with it and dont need copy each response in text format and paste to make Examples:
I have tried the below:
Feature: sample karate test script
Background:
* url BaseUrl
* configure headers = read('classpath:headers.js')
* def jsonFromCsv = read('data.csv')
* def size = karate.sizeOf(jsonFromCsv)
* print size
Scenario Outline: Get All Tests
* def doStorage =
"""
function(args) {
var DataStorage = Java.type('DataStorage.DataStorage'); // Java class that writes to a text file
var dS = new DataStorage();
return dS.write(args);
}"""
Given path '/v1/path'
When method get
Then status 200
* def json = __row.expected
* def id = __row.id
* def app = '|'+<id>+'|'+json+'|'
* print app # prinst it in the expected format
* def result = call doStorage app
Examples:
| jsonFromCsv |
But the issue is only the last read data is being written to the file.
I had tried the below as well but gives the same result as above:
* def js = function (app){karate.write(app,'input.txt')}
DataStorage.java:
package DataStorage;
import java.io.*;
public class DataStorage {
public void write( String text) throws IOException {
BufferedWriter output = null;
try {
File file = new File("input");
output = new BufferedWriter(new FileWriter(file));
output.append(text);
output.close();
} catch ( IOException e ) {
e.printStackTrace();
} finally {
if ( output != null ) {
output.close();
}
}
}
}
You can use CSV files (have to be comma delimited): https://github.com/intuit/karate#csv-files
Also see this example:
Scenario Outline: cat name: <name>
Given url demoBaseUrl
And path 'cats'
And request { name: '<name>', age: <age> }
When method post
Then status 200
And match response == { id: '#number', name: '<name>' }
# the single cell can be any valid karate expression
# and even reference a variable defined in the Background
Examples:
| read('kittens.csv') |
I have a Json payload to validate. And It has a property which can be either null or a sub json object. But this property exists in the json.
I tried following methods:
01
And def dnyAssertionSchema = { denyAny: '#boolean', assertions: '##[]' }
And match each policyGResponse ==
"""
{
denyAssertions: '##(dnyAssertionSchema)'
}
"""
AND
And match each policyGResponse ==
"""
{
denyAssertions: '##null dnyAssertionSchema'
}
"""
AND
This does not work as the property is not an array so I tried above second method even I couldn't find an example as such.
And match each policyGResponse ==
"""
{
denyAssertions: '##[] dnyAssertionSchema'
}
"""
The Actual response can be either
{
denyAssertions=null
}
OR
{
denyAssertions={ denyAny: true, assertions: ["a","b"] }
}
I use Karate 0.9.1
Error message I get is 'reason: actual value has 1 more key(s) than expected: {denyAssertions=null}' in first try
In second try I get 'assertion failed: path: $[3].denyAssertions, actual: {denyAny=false, assertions=[]}, expected: '##null dnyAssertionSchema', reason: not equal'
Your JSON is still not valid but anyway. Here you go:
* def schema = { denyAny: '#boolean', assertions: '#[]' }
* def response1 = { denyAssertions: { denyAny: true, assertions: ["a","b"] } }
* match response1 == { denyAssertions: '##(schema)' }
* def response2 = { denyAssertions: null }
* match response1 == { denyAssertions: '##(schema)' }
How to retrieve partNumbers from below response. In below response
"10000061","10000062","10000063"
are dynamic in nature. I have to match these partNumbers with data table partnumbers.( In a response there could be more than 10 part numbers(based on input) and i have to validate them.)
{ "added": true, "lineItems": { "1111111": { "itemCore": { "partNumber":
"10000061" } }, "222222": { "itemCore": { "partNumber": "10000061" } },
"3333333": { "itemCore": { "partNumber": "10000063" } } } }
Tried below
def partNum= get[0] response..itemCore.partNumber[*] but getting empty array.
def partNum= get[0] response..itemCore.partNumber but getting empty value.
My below second approach also giving me empty value.
* def keys = function(obj){ return response.lineItems.keySet() }
* json dynamicValue= keys(response)
* print 'dynamic value '+dynamicValue
* def first = dynamicValue[0]
* print response.lineItems.dynamicValue[0].itemCore.partNumber
* print response.lineItems.first.itemCore.partNumber
For retrieving data for a particular key, you can use deep scan operator in jsonPath,
* def partNumbers = karate.jsonPath(response,"$..partNumber")
Here's another solution, using karate.forEach() which can also operate on a map, not just a list:
* def keys = []
* eval karate.forEach(response.lineItems, function(k){ keys.add(k) })
* print keys