Scope of variable is limited to scenario in Karate. How to bypass? - karate

I am defining a variable in scenario 1 to obtain a value from response and trying to insert this as param in another scenario.
But scope of variable is till scenario. How can I use my variable from scenario1 to use in scenario 2?

you can save this data into a variable and then read it in other .feature file.
Example:
Feature1
Given path '/api/mobile'
And header Authorization = Token
When method GET
Then status 200
And match response ==
"""
{
"passes": "#number"
}
"""
* def passesResponse = response.passes
Feature2
Scenario: Update Mobile Passes For The Account
* def mobilePasses = call read('classpath:helpers/scenarios/Feature1.feature')
* def passes = mobilePasses.passesResponse
Given path '/v2/update/passes'
And request {"addPass": passes}
Given header Authorization = Token
When method PUT
Then status 200
More info you could find here: link

Related

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

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

Karate API - stored response in def then reuse same in path next url

unable to pass stored response ID in next path
stored * def A = response.ActiveScriptJobID
Tried like And path '#A'
Given path 'admin/rest/activescript/createjob/86/'
When method get
Then status 200
And match response contains {ActiveScriptJobID: "#present"}
* def resp = response
* def A = response.ActiveScriptJobID
* print A
#here 'A' variable stores new created active script job ID
Given path 'admin/rest/activescript/startjob/'
And path '#A'
When method get
Then status 200
IT should reuse created job ID in next Testcase
try directly using the variable without embedded expression
* def A = response.ActiveScriptJobID
Given path 'admin/rest/activescript/startjob/'
And path A
When method get
Then status 200

KARATE - How to get data from response/by running another feature file

I have a feature file that connects to oracle database and gets data and prints in response. Below's the sample piece of code.
dbconnect.feature
def queryDATA = 'QueryData'
When def db = DBConnect.queryDB(host, port, serviceName, username, password, queryDATA)
Then print db
***Note that I have a few more lines of code before this which sets up jdbc and connects to DB with proper credentials
Post this, I need to run real test case which inturn should call dbconnect.feature to get DATA and feed to request. It goes like this;
UserDetails.feature
Background:
* url 'https://soaheader-env-name.com'
* header agent_uid = 'AUTO_TST'
* configure ssl = true
* header Authorization = call read('classpath:ABC/JSFiles/auth.js') {
username: 'XYZ', password: '123' }
* configure logPrettyResponse = true
* configure logPrettyRequest = true
#UserDetails
Scenario Outline: Get User Details
Given path 'somefooterurl/account/<accountno>/user-details-summary'
When method get
Then status 200
Then match response contains 'OK'
I really need to use the data from dbconnect.feature and provide in UserDetails.feature request.
Please suggest a way/ help me with the proper path in karate-github.
A simple example for you,
* def dbCall = call read('dbconnect.feature')
* def db = dbCall.db
please refer karate documentation
Other references if you want to pass values to your feature:
Properly calling an authorization Karate feature with arguments
karate - How to set specific values in a feature file which is called internally