Why karate dsl replace "space" for "+" in param - karate

i have this code:
Scenario: Get Token
Given url 'https://localhost/api/accessToken'
And param scope = 'collections payments'
Log:
1 > POST https://localhost/api/accessToken?scope=collections+payments
This Post faild for me.
Please, i need this:
https://localhost/api/accessToken?scope=collections%20payments

Karate is doing the right thing and your server probably has a bug.
Refer: https://stackoverflow.com/a/1634293/143475
But if you want to send it the way you are asking, put it as the URL itself, and don't use param:
* url 'https://httpbin.org/anything?foo=one%20two'
* method get
Explained here: https://stackoverflow.com/a/59977660/143475

Related

Karate : How to send query param without url encoding

I'm currently writing Automated REST API tests using Karate dsl and I'm encountering an issue when I try a kind of destructive test. Sending invalid query parameter.
I follow the recommendation from this post Karate: Query Param values are getting encoded who is to use the url only but it seems to not work with query parameter:
Scenario: Destructive testing - Illegal characters in parameters or payload
* def buildURL = 'http://127.0.0.1/identity/client?query={"idClient":{"$eq":9223372036854775807}}'
Given url buildURL
When method GET
Then status 400
error:
java.net.URISyntaxException: Illegal character in query at index 39: http://127.0.0.1/identity/client?query={"idClient":{"$eq":9223372036854775807}}
I have the same kind of test for url path where it works fine, but for query param, this way does not seems to work.
To be clear, my goal is to send query params or at least the character { without url encoding
Any idea to solve that ?
Thanks in advance
karate version : 0.9.6
First, you are trying illegal characters as per the spec, so you may need to manually "URL-encode" the URL - and you already seem to be aware of all this, based on the link in your question. Maybe your server is not compliant with the spec.
Recommend you try upgrading to 1.0 and also refer this open issue: https://github.com/intuit/karate/issues/1561
Anything beyond this will require you to help / contribute code.

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 |

How to handle different response for the same request on Karate api testing?

I have a question about how to handle different responses for the same request in Karate api test. E.g.
The same request:
Given path '/tickets/2000'
When method get
Response:
1> if ticket #2000 is not expired, then match response = expected result
2> if ticket #2000 is expired, then matching response.error = 'Ticket is expired'
So how to match the 2 different results. I need to handle both.
Can I use "Try... Catch", how to use it? Can you give me a syntax example in Karate, please?
Thanks
Karate discourages "conditional logic" like this. What I would do is just set that field to #ignore or #string:
* match response == { error: '#string' }
For conditional checks, you can refer this answer: https://stackoverflow.com/a/50676868/143475
Also please refer this answer for some extra guidance: https://stackoverflow.com/a/54126724/143475

Karate: Trying to get global headers working [duplicate]

This question already has an answer here:
Is there a way to update the headers in one feature file and use the Auth token from Karate.config.js?
(1 answer)
Closed 1 year ago.
I'm trying to setup a framework to run Graphql calls and create and E2E environment.
I've got the following setup so far but i can't seem to get the headers part of it working. i have managed to set the auth for each request and it all works but as it logs in for each request it doesn't really work as expected.
I want do the following steps:
run a login Test (different usernames valid/invalid)
run a logout test (Ensure token is removed)
Then login with correct user and extract the "set-cookie" header (to use globally for all future requests)
I was trying to use the following:
Karate-config.js
karate.callSingle('classpath:com/Auth/common-headers.feature', config);
headers.js
function fn() {
var headers = {}
headers["set-cookie"] = sessionAccessId
karate.log('Cookie Value: ', headers)
return headers
}
common-headers.feature
Feature: Login to Application and extract header
Background:
* url serverAuthenticateUri
* header Accept = 'application/json'
Scenario: 'Login to the system given credentials'
Given request { username: '#(username)', password: '#(password)'}
When method post
Then status 200
And match $.success == '#(result)'
And def myResult = response
* def sessionAccessId = responseHeaders['set-cookie'][0]
* configure headers = read('classpath:headers.js')
* print 'headers:', karate.prevRequest.headers
feature-file.feature
Feature: sample test script
Background:
* url serverBaseUri
* def caseResp = call read('classpath:com/E2E/POC/CommonFeatures/CreateCaseRequest.feature')
* def caseReqId = caseResp.response.data.createCaseAndRequest.siblings[0].id
* def caseId = caseResp.response.data.createCaseAndRequest.siblings[0].forensicCaseId
* def graphQlCallsPath = 'classpath:com/E2E/POC/GraphQl/intForensic/'
* def commmonFiles = 'classpath:E2E/CommonFiles/'
Scenario: TC1a - Request Server Details from Config DB (1st Run):
Should handle requesting Server Details Data from Config Database.
* def queryFile = graphQlCallsPath + '20-TC1a_req_req_valid_id.graphql'
* def responseFile = graphQlCallsPath + '20-TC1a_resp_req_valid_id.json'
Given def query = read(queryFile)
And replace query.reqId = caseReqId
And request { query: '#(query)' }
When method post
Then status 200
And json resp = read(responseFile)
And replace resp.reqId = caseReqId
And replace resp.caseID = caseId
And match resp == $
I can log in correctly and i get the set-cookie token but this isn't being passed on the feature-file.feature and i get an error saying "not logged in" in the response.
Any help appreciated! I might be looking at this totally wrong and i have tried to follow the shared-scope as much as i can but can't understand in.
Please make this change and hopefully that works !
headers["set-cookie"] = karate.get('sessionAccessId');
Why is explained here: (read the whole section carefully) https://github.com/intuit/karate#configure-headers
EDIT: one more suggestion:
var temp = karate.callSingle('classpath:com/Auth/common-headers.feature', config);
karate.configure('headers', { 'set-cookie': temp.sessionAccessId });
Some extra suggestions:
If you have just started with Karate - based on your question I would suggest you get one flow working in a single Scenario first without any use of call and with nothing whatsoever in karate-config.js. Hard-code everything and get it working first. Use the header keyword to set any headers you need. I also see you are trying to set a set-cookie header (which may work) but Karate has a special keyword for cookie.
And don't even think about callSingle() to start with :)
Once you get that first "hard-coded" flow working, then attempt to configure headers and then only finally try to do "framework" stuff. You seem to have jumped straight into super-complexity without getting the basics right.
Please read this other answer as well, because I suspect that you or someone in your team is attempting to introduce what I refer to as "too much re-use": https://stackoverflow.com/a/54126724/143475 - try not to do this.
Also note that your question is so complex that I have not been able to follow it, so please ask a simpler or more specifc question next time. If you still are stuck, kindly follow this process: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue