Can I run example in scenario outline for n times? - karate

I want to run examples for n times , n is the length of data of getHotelid.
Feature: match rates from ds api to pricing api.
Background:
* url ''
Scenario Outline: Calling production assert feature file.
* def DbNew = Java.type('DbNew')
* def dq = new DbNew()
* def activeHotels = <ds_hotel_id>
* def hotel_id = call read('StringConverter.js') { activeHotels:'#(activeHotels)'}
* print hotel_id
Examples:
|dq.getHotelid()|

This is look a like Karate - Not able to run dynamic scenario outline in a loop
Your Examples should be as below,
Examples:
|dq.getHotelid()|
please read this documentation : Karate dynamic scenario

Related

Calling common scenario from another scenario in same feature file where request body is store in json file in karate [duplicate]

This question already has an answer here:
how to dynamically set an value in json read from file in Karate
(1 answer)
Closed 1 year ago.
I am a bit confused and need some clarify on this
Background:
* def successBody = 'util/successRequestBody.json'
#test1 #ignore
Scenario: Verify user
Given url
* def id = id
* def requestBody = read (successBody)
And request requestBody
When method post
Then status 201
#test2
Scenario: First create new user and then delete same user
* def id = '123'
# First call POST user to create a new user
* def postuser = call read('user.feature#test1') {id: id}
Given url
When method delete
Then status 204
I am providing value in request body for creating new user like this in successRequestBody.json
{
"id": "#(id)",
"name": "abc"
}
The above doesn't work. But when I provide like this it works. Please guide how the parameters should be passed in calling a feature from another. I am passing variable name id from test2 while calling test1 but in test1 it is reading id1 not id? Can someone please explain?
Background:
* def successBody = 'util/successRequestBody.json'
#test1 #ignore
Scenario: Verify user
Given url
# I am setting variable name id from test2 but here it is reading id1 not id?
* def id = id1
* def requestBody = read (successBody)
And request requestBody
When method post
Then status 201
#test2
Scenario: First create new user and then delete same user
* def id1 = '123'
# First call POST user to create a new user
* def postuser = call read('user.feature#test1') {id: id1}
Given url
When method delete
Then status 204
The call syntax is wrong, you have to use embedded expressions:
* def postuser = call read('user.feature#test1') { id: '#(id1)' }
Here's a tip. It is not mandatory to pass parameters. Variables in the "caller" will be visible to the "called" feature. This below has the same effect as above.
* def id = id1
* def postuser = call read('user.feature#test1')
Please read the documentation and examples carefully. If still stuck, follow this process: https://github.com/karatelabs/karate/wiki/How-to-Submit-an-Issue

Scenario Outline for json in feature with Karate

Is it possible to use Scenario Outline as in this mode (which is really great!!):
Scenario Outline:
* print 'hello <name>'
Examples:
| (read('cats.json')) |
but with a json or a list in Background? Ex:
Background:
* json temp = cats_ids (ids that I get from an external job as here [111,222,333...])
or
* def temp = cats_ids
Scenario Outline:
* path id from temp
* method get
...
Examples:
| temp |
Yes, please look at karate.mapWithKey() explained here: https://github.com/intuit/karate#json-transforms
* def temp = karate.mapWithKey(cats_ids, 'id')
Scenario Outline:
* print id

Use variables in json path expressions [duplicate]

This question already has an answer here:
How to use a variable in JsonPath filter
(1 answer)
Closed 2 years ago.
I have a feature file to retrieve the data from csv file for the given parameter. In order to do it, I need to use a variable in the JsonPath expression to retrieve data for given parameter. I tried may ways, but using variable in jsonPath is not working. I'm using 0.9.4 version
I tried the below ways:
* def userId = get[0] testData[?(#.UserType=='${userType}')].UserId
* def userId = get[0] testData[?(#.UserType==userType)].UserId
* def userId = get[0] testData[?(#.UserType=='#(userType)')].UserId(I suppose this can only be used in json/xml)
Below hard coded value works fine:
* def userId = get[0] testData[?(#.UserType=='SuperAdmin')].UserId
Called feature:
Feature: Utility to extract the various types of data from excel datasource
Background:
* def DataUtility = Java.type('com.org.utils.DataUtility')
* def dataUtils = new DataUtility()
* def testData = read('classpath:testdata/TestData.csv')
Scenario: Retrieve userId for a given user type
* def userId = get[0] testData[?(#.UserType=='${userType}')].UserId
Calling feature:
* table params
| userType |
| 'SuperAdmin' |
* def extractedData = call read('DataExtractor.feature') params
* def userID = extractedData[0].userId
I have tried using variables in Json Path.
Example:
String elementPath = "$.[" + i + "].item.value";
In this statement, i is a loop variable. After this pass it to the read api of DocumentContext.
It has worked perfectly fine for me.
I am using JsonPath & DocumentContext from jayway to achieve this.
import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;

Karate expression to check if value exists in array

Here is my sample feature file:
Feature: Karate expression to check if status within array of status.
Scenario: Test
* def status = "ACTIVE"
* def possibleStatus = ["ACTIVE", "INACTIVE"]
* match status contains possibleStatus ?
Is there a way to check if status is either ACTIVE or INACTIVE using karate expression ?
NOTE: It can definitely be achieved by writing custome JS function.
This is an easy one.
* def status = "ACTIVE"
* def possibleStatus = ["ACTIVE", "INACTIVE"]
* match possibleStatus contains status
Any questions :)

Dynamically set a XML tag value while building payload

I am trying automate testing using Karate.
I have a XML payload.
I have a static XML payload which I am readying from a file and I want to call my service in loop.
For each call I would like to replace value for a tag name dynamically.
How would I achieve this?
e.g.
Below is my Main Feature which calls my common feature in loop
Feature: Loop Call
Background:
* def common = call read('classpath:CommonFeatures.feature')
Scenario:
* table table
| payload_file | field_tag | field_value |
| 'HappyPath.xml' | 'car_fuel' | 'Gas' |
| 'HappyPath.xml' | 'car_color'| 'Red' |
* def response = call read('classpath:Car.feature') table
Car.feature
Feature: Common
Scenario:
* print payload_file
* print field_tag
* print field_value
* xml payload = read('classpath:/payload/'+payload_file)
* print payload
* set payload/$field_tag = field_value
This is where I have issue setting the field_tag value.
I have other option to do this like writing a small java script method to replace the tag value or a small java class which use DOMParser or SAXParser to perform the same.
However I would like to know if there is any karate in build way to perform the same.
Also while using java script method to replace the tag value if I am using var parser = new DOMParser(); and it seems DOMParser is not available to use. Is there a way to make this available?
I think if you go through this sample, it will answer all your questions:
https://github.com/intuit/karate/blob/master/karate-junit4/src/test/java/com/intuit/karate/junit4/xml/xml.feature
For example this is how you can substitute values, as well replace a whole chunk of XML (which can include tags) using the set keyword:
Scenario: set xml chunks using xpath
* def req = read('envelope1.xml')
* def phone = '123456'
* def search =
"""
<acc:getAccountByPhoneNumber>
<acc:phoneNumber>#(phone)</acc:phoneNumber>
</acc:getAccountByPhoneNumber>
"""
* set req /Envelope/Body = search
* match req ==
"""
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:acc="http://foo/bar">
<soapenv:Header />
<soapenv:Body>
<acc:getAccountByPhoneNumber>
<acc:phoneNumber>123456</acc:phoneNumber>
</acc:getAccountByPhoneNumber>
</soapenv:Body>
</soapenv:Envelope>
"""
And please don't think of using DOMParser etc, you will be able to do anything you need via Karate syntax.
Thanks to Peter for all help and the examples.
I feel this is the best way to achieve this.
Wrote a small javascript function
"""
* def replaceTag =
"""
function(x){
karate.setXml('temp', x.payload);
karate.pretty(karate.get('temp'));
if (x.field_tag) karate.set('temp', x.field_tag, x.field_value);
return karate.get('temp');
}
"""
and calling the same from Car.feature like below and I get the dynamically replaced payload.
Feature: Common
Scenario:
* print payload_file
* print field_tag
* print field_value
* xml payload = read('classpath:/payload/'+payload_file)
* print payload
* def args = { payload: #(payload), field_tag: #(field_tag), field_value: #
(field_value)}
* print args
* xml payload = call common.replaceTag args
Note: I had to upgrade Karate 0.7.0 version in order to use karate.setXml method.