how to send payload and header parameters in a gherkin step - cucumber-jvm

new to cucumber.
I want to test rest api using cucumber jvm.
suppose , I have the following scenario
scenario:
* POST at "http://localhost:8080/x" with payload:
"""
<user>
<name>abc</name>
</user>
"""
with header:
|param1|value|
|param2|value|
But it is not working.
if I break the step into 2, one that gives payload and other that gives header,
I have to hold the first step (because it would be missing header) and do the actual post operation with the second step.
what are my options ?
thanks

There was a feature request for supporting both tables and docstrings, but it was closed because of the amount of work to support it in all cucumber implementations, not just the one for the jvm.
So the workaround would be to split this into multiple steps, collecting all data, and sending it at the end:
Scenario: Create a user
Given the following payload:
"""
<user><name>abc</name></user>
"""
And the following headers:
| param | value |
When the request is sent as "POST" to "http://example.com/users"
Then the user is created
I think this also helps with readability of the scenario, and both payload and headers would be optional, which might be useful for other (simpler) requests.

Related

Karate / Post Request : Unable to pass random generator variable in json payload

I am trying to create Karate feature file for API Testing.
It is a post request and we have to pass random number for 1 field i.e. order in request payload every time.
Now, I am trying to use this function in the same feature file to pass that random generated value in json payload before sending post request.
Could someone please have a look at my feature file and help.
Thanks
Also, Is there a way if i want to pass this same random value for a json payload created as a separate request.json payload file
Your requestPayload is within double quotes, so it became a string.
Here's an example that should get you going. Just paste it into a new Scenario and run it and see what happens.
* def temp1 = 'bar'
* url 'https://httpbin.org/anything'
* def payload = { foo: '#(temp1)' }
* request payload
* method post
And please read the documentation and examples, it will save a you a lot of time.

Karate Framework: GET method passing empty input parameters from Examples section

I have to validate a negative scenario where there are input parameters for GET call. My requirement is when input parameters are empty it should return proper error message as define by developer. My feature file looks like this:
Feature: Validate the response
Backgroud:
* url baseURL
* header Content-Type ='application/json'
Scenario Outline:<scenarioname>
Given url
And param param1 = <param1>
And param param2 = <param2>
When method <method>
Then status <statuscode>
Then print response
Examples:
|Scenario Number|scenarioname|method|statuscode|param1|param2|
|Scenario 1|validate the response|get|200|'abc'|'xyz'|
|Scenario 2|validate the response when both the params are blank|get|400|||
|Scenario 3||validate the response when both the params are blank|get|400|''|''|
When i execute scenario 1 my code executes successfully.
When i execute scenario 2 on console i can see as 16:43:44.41 [main] INFO com.intuit.karate.Runner - waiting for parallel feature to complete.... And nothing happens
When i execute scenario 3 it executes successfully,if same scenario i execute in Soap then i get proper error message in Soap UI.
You are trying to do too much in a Scenario Outline. Just write separate Scenario-s. Please read this answer very carefully, you have fallen into the same trap: https://stackoverflow.com/a/54126724/143475
The other issues don't make sense, so
a) please try version 0.9.6.RC4 - because there were some fixes
b) follow this process: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue

How to pass multiple json records using data driven approach in Karate DSL?

We have gone through the Karate documentation where we can compare the exact JSON object as a response (which contains multiple data records) but how can we pass and read the JSON in a single scenario?
Below is my sample.JSON and I want to read this in the request payload.
[{"name":"John","salary":"10000","age":"25"},
{"name":"Maria","salary":"20000","age":"27"}]
I have tried the JSON structure in the above format, however, I am getting below exception. Kindly help me in this.
status code was: 400, expected: 200, response time: 4315
Kindly suggest how to read and pass it in request payload of single scenario.
Thank you.
Status code 400 means you have made some other mistake with the request. Karate is working fine, it is just an HTTP client, maybe the request was not in the "shape" the server was expecting. Talk to the server-side team if you can or check the documentation of the API.
Here is a simple example that works, paste it and try:
* def body = [{"name":"John","salary":"10000","age":"25"}, {"name":"Maria","salary":"20000","age":"27"}]
* url 'https://httpbin.org/post'
* request body
* method post
* status 200
EDIT: for looping, please read the documentation.
The below example is just one way of doing it - please identify what best you are comfortable with: https://github.com/intuit/karate#data-driven-tests
Feature:
Background:
* def data = [{"name":"John","salary":"10000","age":"25"}, {"name":"Maria","salary":"20000","age":"27"}]
Scenario Outline:
* url 'https://httpbin.org/post'
* request __row
* method post
* status 200
Examples:
| data |

Declare Global variables in background of feature-karate Soap API

I am using karate for SOAP API services. How can I declare a global variable ?? as you can see in below feature file? after print response I have variable name def ourSession = /Envelope/Body/LoginReturn I am using this variable (ourSession) in next scenario but it's failing ? but it's not global.
So how can I declare "ourSession" as a global variable ?? so I can use into other scenarios?
Any help will be highly appreciated. Please have a look of my feature file below;
#
Feature:
SOAP calls to the following service:
Background:
* url baseUrl
* def configSS = Java.type('practice.utilities.Shellscripts')
##################################### LOG IN #########################################################
#DataAcquisition
Scenario: login
Given request
"""
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsh="http://www.informatica.com/wsh">
<soapenv:Header/>
<soapenv:Body>
<wsh:Login>
<RepositoryDomainName>Domain_Aqr_Dev_Powercenter</RepositoryDomainName>
<RepositoryName>Powercenter_Repository_Service</RepositoryName>
<UserName>#(AM_USERNAME)</UserName>
<Password>#(AM_PASSWORD)</Password>
<UserNameSpace/>
</wsh:Login>
</soapenv:Body>
</soapenv:Envelope>
"""
When soap action '/login'
Then assert responseStatus == 200
And print 'response: ', response
* def ourSession = /Envelope/Body/LoginReturn
* print ourSession
Do not create a new scenario for the subsequent call. A single scenario can have multiple requests.
i am using this variable (ourSession) in next scenario
You can't. There are many answers in Stack Overflow addressing this question, please find them and read them.
And please read the docs: https://github.com/intuit/karate#script-structure
To quote:
if you are expecting a variable in the Background to be modified by one Scenario so that later ones can see the updated value - that is not how you should think of them, and you should combine your 'flow' into one scenario.
There are many ways to "re-use" in Karate such as call. So you should be able to figure out how to do what you want.
Now if you really want a "global" variable, please use callonce that is most likely what you are looking for:

How to export response into a file or validate the tag value with the help of Karate Framework

I'm using the following feature file and it generates the response. How can we store the response into an XML file instead of showing the console?
Feature File:
Feature: Test soap end point
Background:
* url 'sample url'
Scenario: SmokeTest
Given request read('getMbrWksMembershipDetails.xml')
When soap action 'test url'
Then status 200
And print response
EDITED: The response I'm getting like this.
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:getMbrWksMembershipDetailsResponse xmlns:ns1="xxxxxxxxxx">
<ns4:WksMembershipSummaryResponse xmlns:ns2="xxxxxxxx" xmlns:ns3="xxxxxxxxxx" xmlns:ns4="xxxxxxxxxx">
<ns2:customerSummary>
<ns2:address>
<ns2:city>SOUTH CHESTERFIELD</ns2:city>
<ns2:country>USA</ns2:country>
<ns2:isoCountryCode>US</ns2:isoCountryCode>
<ns2:line1>9998, N. MICHIGAN ROAD.</ns2:line1>
<ns2:postalCode>23834</ns2:postalCode>
<ns2:state>VA</ns2:state>
</ns2:address>
<ns2:allowPasswordChange>true</ns2:allowPasswordChange>
<ns2:arpMember>false</ns2:arpMember>
<ns2:brandCode>ABC</ns2:brandCode>
<ns2:brandId>1</ns2:brandId>
<ns2:companyCode>ABC</ns2:companyCode>
<ns2:eliteMemberRewardStatus>false</ns2:eliteMemberRewardStatus>.....
Question:
How can I validate the tag values from this response?
Thanks,
First a question - why do you want to do this ? Karate is a testing framework, and besides being able to run assertions on responses, you can easily re-use responses (or some data from a response) in the next request. There is no need to ever save anything to a file.
And if you follow the instructions in the Karate documentation on logging you will also see responses logged to the file target/karate.log.
When you use the JUnit runner, you will see all responses in an HTML report.
Same case with the parallel runner.
Anyway, even after all this if you really really want to save responses to a file, use Java interop and write your own utility to save to a file, it will be a just a few lines of code. It is not built-in to Karate because of the above reasons.
EDIT: well, after all the typing above, turns out you just want to know how to validate (assert / match) the response ? Great, that is the whole selling point of Karate.
I assume you have read the Karate documentation. Also refer this example: soap.xml and this one for more ideas: xml.feature
Anyway here are some hints based on your XML sample to get you started. You can paste the below into a Scenario: and run this without needing to make HTTP requests and that way test and get comfortable with match:
* def response =
"""
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:getMbrWksMembershipDetailsResponse xmlns:ns1="xxxxxxxxxx">
<ns4:WksMembershipSummaryResponse xmlns:ns2="xxxxxxxx" xmlns:ns3="xxxxxxxxxx" xmlns:ns4="xxxxxxxxxx">
<ns2:customerSummary>
<ns2:address>
<ns2:city>SOUTH CHESTERFIELD</ns2:city>
<ns2:country>USA</ns2:country>
<ns2:isoCountryCode>US</ns2:isoCountryCode>
<ns2:line1>9998, N. MICHIGAN ROAD.</ns2:line1>
<ns2:postalCode>23834</ns2:postalCode>
<ns2:state>VA</ns2:state>
</ns2:address>
</ns2:customerSummary>
</ns4:WksMembershipSummaryResponse>
</ns1:getMbrWksMembershipDetailsResponse>
</soap:Body>
</soap:Envelope>
"""
* match //address/city == 'SOUTH CHESTERFIELD'
* match //customerSummary/address ==
"""
<ns2:address>
<ns2:city>SOUTH CHESTERFIELD</ns2:city>
<ns2:country>USA</ns2:country>
<ns2:isoCountryCode>US</ns2:isoCountryCode>
<ns2:line1>9998, N. MICHIGAN ROAD.</ns2:line1>
<ns2:postalCode>23834</ns2:postalCode>
<ns2:state>VA</ns2:state>
</ns2:address>
"""