Calling scenario from different feature file using another variable - karate

I have feature file with a scenario that uses a variable eg: 1.
I am calling this scenario from another feature file but this time I want to pass another variable eg: 2
Feature file A: generateDocument.feature
#generatedoc
Scenario: Verify able to generate document for user
Given path somepath
And header Content-Type = 'application/json'
And request {"userId": "abc123"}
When method POST
Then status 200
* table documentId
| id | docTitle |
| '#notnull' | "ijk" |
| '#notnull' | "xyz" |
And match response[*].id == $documentId[*].id
And match response[*].title == $documentId[*].docTitle
Feature file B: useDocument.feature
call read('generateDocument.feature#generatedoc') { userId: 'abc456'}
So when I run feature file A, it should use the variable 'abc123', but when I run the feature file B, it should use the variable 'abc456'
But currently when I run feature file B, it still uses 'abc123'

Please do this in A - so it becomes a re-usable feature.
And request {"userId": "#(userId)"}
Now you need to call it 2 times (maybe in 2 different features and it will work):
Feature B:
call read('generateDocument.feature') { userId: 'abc456' }
Feature C:
call read('generateDocument.feature') { userId: 'abc123' }

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

Getting PolyglotException in karate API framework even though the request file exists on classpath

I am newbie in karate framework. I am trying to run my first karate test. However I am getting PolyglotException for request file even though the file exists on classpath. The error is "org.graalvm.polyglot.PolyglotException: not found: requests/first.json". The error goes away if I place request file in the features folder.
The script I have written is
Feature: Demoing scenario outline
Background:
* url 'https://reqres.in'
* def endpoint = '/api/users'
#TestId-43343
Scenario Outline: first test with scenario outline
* def name1 = <name>
* def job1 = <job>
* def requestBody = read('classpath:requests/first.json')
Given path endpoint
And request requestBody
And print requestBody
When method POST
Then status 201
And print response
And match $.job == <job>
And match $.name == <name>
Examples:
| name | job |
| 'abc' | 'DEV' |
| 'hjl' | 'DEVOPS' |
features and requests folders are present under java.
Your help is appreciated.
As mentioned here in the documentation, the default directory when you use classpath depends on how you have configured maven testResource. Try using the full path like
* def requestBody = read('classpath:src/test/java/requests/first.json')

Passing a variable from one feature file into another as a part of request URL(not query parameter) in Karate

I have a feature that generates a vehicle id and is stored as a variable in the feature. I want to pass this id as a part of the request URL in another feature as a sort of a teardown activity.
This is how I called it from a feature called activateVehicle.feature
Scenario : Activate a vehicle
* header X-API-Key = apiKey
* def result = callonce read('createVehicle.feature')
* def vehicleId = result.vId
# some workflow steps
........
........
........
# tear down - delete the vehicle created
* call read('deleteVehicle.feature'){ vehcileId: '#(vehicleId)' }
In the called feature - deleteVehicle.feature
Scenario: Delete a vehicle
* header X-API-Key = apiKey
* def myurl = 'https://xxx/vehicle'+ vehicleId +'?permanent=yes'
Given myurl
And request ''
When method delete
Then status 200
Am I right in the approach? I want to reuse deleteVehicle.feature in other workflows as well and hence not doing this operation in the same activateVehicle.feature(which would have been very easy). I referred to the documentation too but it shows how we can use the variables in in the request body but not as a variable that can be used anywhere in the called feature. I don't want to use it in the request body (but want to use it as a part of the request URL) For example:
Scenario:
Given url loginUrlBase
And request { userId: '#(username)', userPass: '#(password)' }
I also referred to How can I call a variable from one feature file to another feature file using Karate API Testing. I followed suit for a solution but am getting a javascript error:
feature.deleteVehicle: -unknown-:11 - javascript evaluation failed:
'https://xxx/vehicle'+ vehicleId +'?permanent=yes', ReferenceError: "vehicleId"
is not defined in <eval> at line number 1
feature.SVT: SVT.feature:80 - javascript evaluation failed: vehicleId: '#(vehicleId)' }, <eval>:1:14 Expected eof
but found }
vehicleId: '#(vehicleId)' }
^ in <eval> at line number 1 at column number 14
Can someone kindly help and advise please?
Can you simplify your example ? The only thing I can make out is you need a space after the call feature and before the call argument:
* call read('deleteVehicle.feature') { vehcileId: '#(vehicleId)' }
The pattern we generally recommend is to setUp not tearDown as tearDown has a risk of not executing if you had an error. That said, please see hooks: https://github.com/intuit/karate#hooks
Sometimes you should just keep it simple and call a feature (with args) only where you need it.

Karate How to save each response when running scenario outline/examples in parallel

Given i have something like this:
Scenario Outline: test
Given request {"movie":"<title>","age":"<age>"}
When method post
Then status 201
Then match response contains {"something": 52.0833} || {"something": 27.160493}
Examples:
| title | age
| test | 30
| test1 | 40
Now i'd like to verify that the given response 52.0833 and 27.160493 are present in each response body.
Given that these are run in parallel, does karate have a way of saving both requests to a variable or doing something like i tried above i.e using || operator or 'either'.
This will work, refer the docs: https://github.com/intuit/karate#self-validation-expressions
Given def response = { something: 52.0833 }
Then match response contains { something : '#? _ == 52.0833 || _ == 27.160493' }
You should never consider saving responses to a file, always validate then and there and move on.

How to replace variable in Karate

I need to replace a value inside the URL
test/lambda-migration/v1/quote'
The v1 needs to be parameterized to take different value, and these values will come from another feature file. My code looks kike this:
Feature file -1
Scenario Outline: Lambda API registration
Given url ApiAdminURL
json myReq = read('swagger-lambda.json')
And request myReq
When method post
Then status
def responsefromsubscriber = call read('Subscriber.feature') { InvokeStatus: '#(InvokeStatus)', version: '<version>' }
match responsefromsubscriber.InvokeStatus == 200
Examples:
| responseCode | version |
| 200 | v1 |
Feature File - 2
Given url internalGateway
print 'Version: ' , version
def LocalVersion = version
print 'LocalVersion: ' , LocalVersion
And path 'test/lambda-migration/#(LocalVersion)/quote'
And header Authorization = accessTokenforInvokation
When method get
This is not replacing #(LocalVersion) to v1
And path 'test/lambda-migration/#(LocalVersion)/quote'
This is wrong. Please read this part of the docs: https://github.com/intuit/karate#rules-for-embedded-expressions
Also note that path supports a comma-delimited form:
Try:
And path 'test/lambda-migration', LocalVersion, 'quote'