How to pass response variable in path through examples table in karate - karate

I am trying to pass a variable value in URL path which is further stored in examples table.
Unfortunately, it gives me error.
Can any one please help.
Background:
* def challengeID = res.challengeID
* def version = '2'
Given url dispatch And path '/api/fire/v' + version + '/sms/otp/' + <challengeID>
And param code = <code>
And header Content-Type = 'application/json'
When method GET Then status 400
Examples:
| challengeID | code |
| #(challengeID) | 2121211 |
| 3434343434343 | 111111 |

Sorry, the Examples: table cannot be dynamic. This is standard "Cucumber" behavior. Use table instead: https://github.com/intuit/karate#table
But I think you are over-complicating things. You should just do this:
And path 'api/fire/v' + version + '/sms/otp', res.challengeID

Related

Unable to convert multiple API response into xml in single call

I am sending multiple API calls and getting their respective responses back. I am trying to convert each response into XML but it is failing with an error.
The setup:
* table requestTable
| nameTags| ageGroups| status |
| nameTag1| ageGroup1| 200 |
| nameTag2| ageGroup2| 200 |
| nameTag3| ageGroup3| 200 |
* def getRequest = call read('target.feature#getRequest') requestTable
* xml transformResponse = $getRequest[*].response
Getting the following error:
class com.sun.org.apache.xerces.internal.dom.DeferredDocumentImplAccAccess (in unnamed module #0x1414800e)
cannot access class com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl (in module java.xml) because
module java.xml does not export com.sun.org.apache.xerces.internal.dom to unnamed module #0x1414800e
If I do a single conversion such as: * xml transformResponse = $getRequest[0].response it works as expected.
Please advise.

Karate : Dynamic text value in xml file

I want to provide dynamic values in the XML
test.xml:
<name>
<first>#(first)</first>
<last>#(last)</last>
<version>this is the #(version) in the file</version>
</name>
I have a .csv file:
first,last,version
abc,pqr,1
lma,qwe,2
Feature file:
call the csv and xml file
For first and last variable it works but for version it doesn't take version value
Yes, changing the tag name (or key name in JSON) is an advanced operation which "embedded expressions" cannot be used for. I think you should just use XPath. You should also take some time to read the examples linked from the documentation.
Here is just one way to do it, there are many more:
Scenario Outline:
* def payload =
"""
<name>
<first>#(_first)</first>
<last>#(_last)</last>
</name>
"""
* set payload /name/version = _version
* match payload == <name><first>foo</first><last>bar</last><version>1</version></name>
Examples:
| _first | _last | _version |
| foo | bar | 1 |

Karate API-building dynamic request XML from csv file and I don't want tag to be created in request if resp tag value is blank in csv

I am trying to build xml from csv file and wanted to remove the xml tags from request if the respective tag value is blank in the csv. I have 2 feature files, 1 xml and 1 csv file.
Below is my code.
'''
request.xml:
<ROUTE>
<Name>
<FirstName></FirstName>
<LastName></LastName>
</Name>
</ROUTE>
getQuoteTest.feature:
#tag
Feature: Get Quote Test
Scenario Outline:
* call read('classpath:getQuote.feature') {'FirstName':"<FirstName>",'LastName':"<LastName>"}
Examples:
| read('classpath:TestData.csv') |
CSV file:
FirstName LastName
Matt Chat
(blank) John
Shane Bond
Andrew (blank)
getQuote.feature
#ignore
Feature: Get Quote
Background:
Scenario:
* xml req = read('classpath:request.xml')
* set req/ROUTE/Name/FirstName = FirstName
* set req/ROUTE/Name/LastName = LastName
Given request req
When method POST
Then status 200
And print response
'''
When FirstName is blank, I don't want <FirstName></FirstName> tags to be present in my request xml. It would be great if I can get the exact code.
Thanks in advance !
A self contained code which you can run and then customize for your needs:
Feature: Conditional Example
Background:
Scenario Outline:
* def req =
"""
<ROUTE>
<Name>
<FirstName><FN></FirstName>
<LastName><LN></LastName>
</Name>
</ROUTE>
"""
* xml req2 = req
* if (req2.ROUTE.Name.LastName == null) karate.remove("req2","//LastName")
* if (req2.ROUTE.Name.FirstName == null) karate.remove("req2","//FirstName")
* print req2
Examples:
| FN | LN |
| Matt | Chat |
| | John |
| Shane | Bond |
| Andrew | |

Refer defined variable in Scenario outline example [duplicate]

This question already has answers here:
Can we parameterize the request file name to the Read method in Karate?
(2 answers)
Closed 1 year ago.
Feature: Test Type
Background:
* url host
* def name = 'test_name'
* def label = name
Scenario Outline: Test 2
Given url homeLinks.groupTypesUrl
And headers { tenant: #(tenantId), Authorization: #(authToken) }
* def name = <name>
* def description = <description>
* def label = <label>
* json data = read('path/to/file/create_group_type_request.json')
And request data
When method POST
Then status 400
Examples:
| name | label | description |
| '\u0000' | 'label' | 'description' |
| #(name) | '\u0000'| 'description' |
I need to refer global name defined inside examples map. How to get that reference?
Getting Javascript evalution error when I tried to like above piece of code.
Yes, Examples do not support JS eval and variables. Use the table form and loop over it with a call to a second feature: https://github.com/intuit/karate#calling-other-feature-files
Or you can try to use a dynamic Scenario Outline by initializing the table in the background: https://github.com/intuit/karate#dynamic-scenario-outline

How to deserialize json payload passed to other feature file which accept multiple arguments

I am sending multiple arguments to .feature file one of the argument is request json payload generated by using karate table. How to iterate through request payload so that post request will get one payload at a time.
Scenario: post booking
* table payload
| firstname | lastname | totalprice | depositpaid |
| 'foo' | 'IN' | 10 | true |
| 'bar' | 'out' | 20 | true |
#date will calculate using js function in background and baseURL is configured in karate.config.js file
* set payload[*].bookingdates = { checkin: '#(date())', checkout: '#(date())' }
* def result = call read('createrecord.feature') {PayLoad: #(payload) , URL: #(baseURL)}
######################################
createrecord.feature file will have
#ignore
Feature: To create data
Background:
* header Accept = 'application/json'
Scenario:
Given url __arg.URL
And path 'booking'
And request __arg.PayLoad
When method post
Then status 200
Here in createrecord.feature file how I can iterate through passed payload so that single payload will be passed to post request.
The simple rule you are missing is that if the argument to call is a JSON array (of JSON objects) it will iterate automatically.
Read the docs carefully please: https://github.com/intuit/karate#data-driven-features
So make this change:
* def result = call read('createrecord.feature') payload
And baseURL will be available in createrecord.feature so you don't need to worry about passing it.
Note that this may not work: * set payload[*].bookingdates refer this answer: https://stackoverflow.com/a/54928848/143475