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

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

Related

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

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

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

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

karate | xml post method exeuction

I’m having issue with xml post request where post method is not executed. When I try to post same request body in post man it worked.My test is success with 200 but actual request is not executed.
Please let me know if I’m missing
To pass the request body,I’m calling through java object and payload is correctly constructed and printed.In execution test is success and doesn’t print response.But actually test is not executed.
Only headers are printed.
***************** create-user.feature*****************
Feature: create ims user for provided country
Requires country code,
Background:
# load secrets from json
* def createuser = Java.type('com.user.JavaTestData')
* def create = createuser.createUser("US")
Scenario: get service token
Given url imscreateuserurl
And request create
When method post
Then status 200
* print response
***************** create-user.feature*****************
Here is java class
public class JavaTestData {
private static final Logger logger = LoggerFactory.getLogger(JavaTestData.class);
public static String createUser(String countryCodeInput) {
logger.debug("create user for country code input", countryCodeInput);
Unless you post a full working example, no one can help you. Pretty clear that the value of create is null or empty.
Also I personally think you are wasting your time using Java. The whole point of Karate is to avoid using Java as far as possible.
Look at these examples for ideas: https://github.com/intuit/karate/blob/master/karate-junit4/src/test/java/com/intuit/karate/junit4/xml/xml.feature
Edit: also refer to the doc on type-conversion: https://github.com/intuit/karate#type-conversion
#Peter, here is my feature file
Feature: create ims user for provided country
Requires country code,
Background:
# load secrets from json
* def createuser = Java.type('com.adobe.imscreateuser.JavaTestData')
* def create = createuser.createUser("US")
Scenario: get service token
Given url imscreateuserurl
And header Content-Type = 'application/xml; charset=utf-8'
And request create
When method post
Then status 200
* print response
I have performed print for create and showing complete payload.At when method post -> statement its going as null or empty...
Not sure where it is missing