Use header in multiple calls in the same scenario in Karate - karate

Having a feature with only one scenario with more than one http calls, I want to use the same host and headers for all calls. However, although I am able to set the url to apply for all calls, the header seems to only be applied in the first call and then reset. Does someone have any info on why this is happening and/or a suggestion on how to do it correctly (besides adding them in each call separately)?
Either by setting them in the Background or with a generic Given, url is used in both calls, but the header is only included in the first:
1)
Feature: sample
Background:
* header Content-Type = 'application/json'
* url http://localhost:8080
Scenario: do multiple calls
Given path /sample/
When method GET
Then status 200
Given path /sample2/
When method GET
Then status 200
2)
Feature: sample2
Given header Content-Type = 'application/json'
And url http://localhost:8080
Scenario: do multiple calls
Given path /sample/
When method GET
Then status 200
Given path /sample2/
When method GET
Then status 200

You really really should read the documentation: https://github.com/intuit/karate#configure-headers
Just do:
Background:
* configure headers = { 'Content-Type': 'application/json' }
And there are many more options, just read the docs. Note that you typically never need to set the Content-Type because Karate does that automatically based on the request body.

I had the same problem. It was fixed when I added the "Header" informations I always use to the "karate-config.js".
var accessToken = karate.callSingle("classpath:helpers/authentication.feature").accessToken
karate.configure("headers",{Authorization: "Bearer " + accessToken})

Related

Mulesoft_ passing client id and Client_secret under HTTP header

I have a requirement where I need to add both client id and client_secret under HTTP headers(under attribute,headers)
I tried to use the below code and unfortunately, it is not working, so please check and guide us to get the expected code.
Transform message create an attribute and applied the below DataWeave code:
output application/java
---
{
headers: {
client_id: '68eee04d10774836b6e5c40189ed3efb',
client_secret: '149541B02E23487EBE517708496a2920'
}
And in the consume connector header part, I have added the below line code.
Attributes.headers
It is difficult to say without seeing exactly what the application is doing but I suspect you are mixing SOAP headers with HTTP headers. HTTP Headers go into the transport headers element.
Example assuming both kind of headers in different variables. Note that you can set each header individually or pass an object which contains them all:
<wsc:consume doc:name="Consume" config-ref="Web_Service_Consumer_Config" operation="GetContent">
<wsc:message>
<wsc:headers><![CDATA[#[vars.soapHeaders]]]></wsc:headers>
</wsc:message>
<wsc:transport-headers>
<wsc:transport-header key="client_id" value="#[vars.httpHeaders.client_id]" />
<wsc:transport-header key="client_secret" value="#[vars.httpHeaders.client_secret]" />
</wsc:transport-headers>
</wsc:consume>

How to execute a global feature file first every time when Karate suite is executed and store the outcome in variables to be used further? [duplicate]

So I've managed to write a bunch of tests and in every feature file I set the same request headers.
For example:
Given url appUrl
And path '/path'
* header Accept = 'application/json'
I'd like to know if there's a way to set a header once so that it is set before each scenario is run. I've read the documentation and tried the callSingle method as follows in karate-config.js:
karate.callSingle('classpath:api/Utilities/Feature/header.feature');
header.feature looks like:
Feature: common routing that sets the headers for all features
Background:
* configure headers = { Accept : 'application/json' }
And example feature where I expect the headers to be preset:
Feature: Header Preset
Scenario: I expect the header to be set
Given url appUrl
And path '/path'
When method get
Then status 200
* print response
#I expect the response to be returned in JSON format
However I'm unable to get this working. I don't think I've understood how the callSingle method works. Some pointers would be helpful. Thanks.
Ignore callSingle for now and focus on configure headers.
I think you are missing one step - which is to ensure that configure headers has been "applied" before each Scenario. If you are 100% sure that this applies "globally", just do this in karate-config.js:
karate.configure('headers', { Accept: 'application/json' });
Else you use the Background (in each feature):
* configure headers = { Accept: 'application/json' }
Typically you have more steps that are common, so you have them in a "common" feature file and call that for every test. Refer: https://github.com/intuit/karate#shared-scope

Can we pass method and path while calling feature from inside another feature

When you call a feature (with a few Scenarios) from inside another feature, I want to pass method and path
as these are common scenarios - called from two different endpoints where base url remain same but path and also the method differ.
This situation arise because I am trying to put the common scenarios in a feature and call that feature from other feature files where the scenarios are all common and they differ only in path and method.
I have referred to this issue: 'https://github.com/intuit/karate/issues/239' and know that it is possible but in my case I need to pass the path and method as arguments while calling the feature file because that is the only thing differing with two modules calling the common scenarios.
So the question is can we pass path and method as parameters while calling a feature file. Currently I am getting error but do not understand why it should fail.
I tried the following:
booking.feature
Background:
* def pathVar = '/bookings'
Scenario: Calling basic validation feature for create booking module
* call read('classpath:feature/basic-validations.feature') {path1: '#(pathVar)', action: 'post'}
basic-validations.feature
Background:
* url baseURL
* header Accept = 'application/json'
* def data = read(datafile)
* header API-Version = 1
* path '#(path1)'
* header Authorization = 'Bearer' + data.booking.token
Scenario: Empty request validation
Given request {}
When method '#(action)'
Then status 400
Scenario: Request-Body element is empty or null.
Given def req = ({ "request_body": null })
And request req
When method '#(action)'
Then status 400
Scenario: When parameter value for name in request body is incorrect.
Given def req = ({ "request_body": [ { "name": "shipment_standard_booking", "action":
"create", "path": "/standardBooking", "body": data.booking.standardBooking.requestBody }]
})
And def name = 'test'
And set req.request_body[*].name = name
And request req
When method '#(action)'
Then status 400
And match $.debugMessage == 'Validations failed due to bad input payload request. WorkItem
name (' +name+ ') is invalid'
The path step can take variables. The method step also can take a variable: https://github.com/intuit/karate#method
* def methodVar = 'post'
* url foo
* request bar
* method methodVar
But I totally don't recommend it - or the approach you are taking. Reasons are explained here, please take some time to read it: https://stackoverflow.com/a/54126724/143475
I think you also have mis-understood embedded expressions, so please read this: https://github.com/intuit/karate#rules-for-embedded-expressions
If you still decide to do this and get stuck, you can assume that either Karate does not support what you want to do - or that you need to contribute code.
Also read this for other ideas: https://stackoverflow.com/a/50350442/143475

How to run a setup feature only once before all other test case features correctly? [duplicate]

So I've managed to write a bunch of tests and in every feature file I set the same request headers.
For example:
Given url appUrl
And path '/path'
* header Accept = 'application/json'
I'd like to know if there's a way to set a header once so that it is set before each scenario is run. I've read the documentation and tried the callSingle method as follows in karate-config.js:
karate.callSingle('classpath:api/Utilities/Feature/header.feature');
header.feature looks like:
Feature: common routing that sets the headers for all features
Background:
* configure headers = { Accept : 'application/json' }
And example feature where I expect the headers to be preset:
Feature: Header Preset
Scenario: I expect the header to be set
Given url appUrl
And path '/path'
When method get
Then status 200
* print response
#I expect the response to be returned in JSON format
However I'm unable to get this working. I don't think I've understood how the callSingle method works. Some pointers would be helpful. Thanks.
Ignore callSingle for now and focus on configure headers.
I think you are missing one step - which is to ensure that configure headers has been "applied" before each Scenario. If you are 100% sure that this applies "globally", just do this in karate-config.js:
karate.configure('headers', { Accept: 'application/json' });
Else you use the Background (in each feature):
* configure headers = { Accept: 'application/json' }
Typically you have more steps that are common, so you have them in a "common" feature file and call that for every test. Refer: https://github.com/intuit/karate#shared-scope

in Karate DSL, is there a way to have redirects perform a POST request instead of a GET request? [duplicate]

This question already has an answer here:
Post method gets converted to GET after redirection
(1 answer)
Closed 2 years ago.
I have the following Karate script that by default has redirects turned on.
Scenario: First Test
Given path 'somePath'
And request ''
And header Content-Type = 'text/html'
And param _csrf = csrf
And param username = 'username'
And param password = 'password'
When method post
Then status 200
The issue is after getting a 302 from the API, the next request automatically submits a GET request. I would like it to submit a POST request instead.
in cURL, there is an existing parameter that allows users to do that. see below.
--post302 Do not switch to GET after following a 302
is there anyway to do that in Karate DSL?
Yes please read the docs for configure folowRedirects. There is also an example on how to read the Location response header to manually make the request you want.
Scenario: get redirects can be disabled
* configure followRedirects = false
Given path 'redirect'
When method get
Then status 302
And match header Location == demoBaseUrl + '/search'
* def location = responseHeaders['Location'][0]
Given url location