karate: Accept = 'application/xml' header not working as expected [duplicate] - karate

I have this header which is in a .js file and I am reading this header using
* configure headers = read('classpath:services/Headers/distheader.js')
Question #1
How can I edit one of the headers in this file at run-time using my scenario data?
I tried setting * header 'xyz' = 'value' but it doesn't edit it.
Question #2
If I want to delete one of the headers, how is it possible?

So 90% of your scenarios are "happy path", and you have a headers JS configured.
Now you need some scenarios to have more (or less headers). One option is to hard-code the headers for those scenarios, note that you can do * configure headers = null to disable the "auto" headers. Then use the header (or headers) keyword and build headers manually.
Another option is that you can invoke the headers function and get a JSON - and then mutate (add / remove keys) before setting headers manually. For example:
# you can disable headers if needed
* configure headers = null
# headers.feature is: function(){ return { a: 1, b: 2 } }
* def fun = read('headers.feature')
* def temp = fun()
* remove temp.a
* set temp.c = 3
Given url 'https://httpbin.org'
And path 'anything'
And headers temp
When method get
Then status 200
So the advantage above is in case your headers routine is complex, you can re-use it - but still have fine-grained control.

Related

Karate: How to check if any of the configured headers are missing [duplicate]

I have this header which is in a .js file and I am reading this header using
* configure headers = read('classpath:services/Headers/distheader.js')
Question #1
How can I edit one of the headers in this file at run-time using my scenario data?
I tried setting * header 'xyz' = 'value' but it doesn't edit it.
Question #2
If I want to delete one of the headers, how is it possible?
So 90% of your scenarios are "happy path", and you have a headers JS configured.
Now you need some scenarios to have more (or less headers). One option is to hard-code the headers for those scenarios, note that you can do * configure headers = null to disable the "auto" headers. Then use the header (or headers) keyword and build headers manually.
Another option is that you can invoke the headers function and get a JSON - and then mutate (add / remove keys) before setting headers manually. For example:
# you can disable headers if needed
* configure headers = null
# headers.feature is: function(){ return { a: 1, b: 2 } }
* def fun = read('headers.feature')
* def temp = fun()
* remove temp.a
* set temp.c = 3
Given url 'https://httpbin.org'
And path 'anything'
And headers temp
When method get
Then status 200
So the advantage above is in case your headers routine is complex, you can re-use it - but still have fine-grained control.

How do use the same variable in background and feature being called

With Karate 1.1.0, you could define a variable in the background, ex "* path = 'www.google.ca', call a "helper" feature at the top of of a scenario, which was using the same variable name inside it, then later in your scenario use the same variable again. Ex., helper feature would have "* path = 'www.google.ca' in it's 1 and only scenario, which would say something like "Given path '/help.html'". Then in your main feature, after you have called the helper feature you would use the variable again, something like "Given path '/fun.html'". When everything ran it would be fine, the helper feature would point to it's path and the main feature would point to it's path.
Now with Karate 1.2.0.RC6, I don't have to declare path in the helper feature, but with that change the path is being concatenated in the main feature/scenario. So when the scenario executes, it calls the helper feature fine, but then instead of it's path being "www.google.ca/fun.html" it comes "www.google.ca/help.html/fun.html". Any ideas why or better how to resolve it?
Here's the actual code:
Feature: Update calls on an account
Background:
* url url
* header Authorization = token
* path 'care/v1.1/account/'
Scenario: theScenario
* def fullResponse = call read('init/movein_ADD.feature') { payloadFilename: 'data/account_id_call_ADD_MOVEIN_No_GovtId.json'}
* def updatePayload = read('data/account_id_call_add_MOVEIN_Both_GovtId.json')
* set updatePayload.callNumber = fullResponse.response.callNumber
* set updatePayload.id = fullResponse.response.id
* set updatePayload.orderNumber = fullResponse.response.orderNumber
* set updatePayload.stagedServices = null
* header Accept = json
* header Content-Type = json
Given path ENCODE('16382-8') + '/call/update'
And request updatePayload
When method POST
Then status 200
Helper feature:
#ignore
Feature: Helper feature file to create Move-In Service order request
Scenario: helper Scenario
* url url
* path 'care/v1.1/account/'
* def payload = read(payloadFilename)
#set up request and execute
* header Accept = json
* header Content-Type = json
Given path 'MTYzODJAQDg=/call/add'
And request payload
When method POST
Then status 200
The answer, change to declare a variable in the background of the main feature file, set the path to that variable in the helper feature scenario and again the main feature scenario right after the call to the helper feature file has worked. Going to cause some big refactoring on our part based on this change.

How to call another features with headers on condition [duplicate]

This question already has an answer here:
How to compare 2 JSON objects that contains array using Karate tool and feature files
(1 answer)
Closed 1 year ago.
I have created a common library with steps.feature source that we used in different repos of tests.
But in one scope of tests we need to use header Datasource-Type: 'test' and in others not.
Sample of feature where we call other steps.feature:
Background:
* header Datasource-Type = 'test'
* def getToken = call read('classpath:com/coommons/karate/token-service.feature')
* configure headers = { Authorization: #(getToken), Datasource-Type : 'test'}
* def createSmth = call read('classpath:com/commons/karate/createSmth.feature')
* def accId = createSmth.accId
* def id = createSmth.id
Scenario: Do Smth
* def createSmthElse = call read('classpath:com/commons/karate/createSmthElse.feature') { Token: #(token) }
* call read('classpath:com/commons/karate/putSmth.feature')
* def createSmthElseAnother = call read('classpath:com/commons/karate/createSmthElseAnother.feature')
Given url featureService
And path '/.../details/employeeSorting'
And request {}
When method post
Then status 200
I am satisfied with the option to globally set this header in one of the projects in karate-config.js, but it does not work correctly.
karate.configure('headers', { 'Datasource-Type': 'test' });
Headers are passed for some reason only for the first call (only for * def getToken = call read('classpath:com/coommons/karate/token-service.feature') )
In case with *configure headers {} my header appears only in Given When Then post featureService, but not in other calling steps.feature.
Please, advice how to set this header Datasource-Type: 'test' everywhere from feature where we call other steps.feature and without hardcoded this header directly in steps.
If you do karate.configure() the headers should apply to all calls, so if it doesn't happen - it can be a bug, so please follow this process: https://github.com/karatelabs/karate/wiki/How-to-Submit-an-Issue
There was a bug related to this, so please ensure you are on the latest version: 1.1.0 or 1.2.0.RC1
Also note that if you set a header to null it will not be passed at all.
And finally let me say that too many calls and re-use can be a bad thing, so please read this: https://stackoverflow.com/a/54126724/143475

Use header in multiple calls in the same scenario in 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})

Edit(update, delete) one of headers in karate

I have this header which is in a .js file and I am reading this header using
* configure headers = read('classpath:services/Headers/distheader.js')
Question #1
How can I edit one of the headers in this file at run-time using my scenario data?
I tried setting * header 'xyz' = 'value' but it doesn't edit it.
Question #2
If I want to delete one of the headers, how is it possible?
So 90% of your scenarios are "happy path", and you have a headers JS configured.
Now you need some scenarios to have more (or less headers). One option is to hard-code the headers for those scenarios, note that you can do * configure headers = null to disable the "auto" headers. Then use the header (or headers) keyword and build headers manually.
Another option is that you can invoke the headers function and get a JSON - and then mutate (add / remove keys) before setting headers manually. For example:
# you can disable headers if needed
* configure headers = null
# headers.feature is: function(){ return { a: 1, b: 2 } }
* def fun = read('headers.feature')
* def temp = fun()
* remove temp.a
* set temp.c = 3
Given url 'https://httpbin.org'
And path 'anything'
And headers temp
When method get
Then status 200
So the advantage above is in case your headers routine is complex, you can re-use it - but still have fine-grained control.