karate-name not working for nested feature file calls [duplicate] - karate

I am doing a POC on karate-gatling to reuse my tests. I have referred to documentation and installed those versions. First of all awesome work as usual, very easy to setup and get going.
I am calling a feature file from MySimualtion.scala which has three other abstract feature calls as follows:
* def tranRef = TransactionReferenceUtils.generateTransactionReferenceStartWith('09')
* set payloadR /transaction_reference = tranRef
POST API >> /sending/v1/dm
* call read('classpath:../InitiateAbstract.feature')
* match responseStatus == 200
GET API By Reference >> /sending/v1/dm?ref={ref}
* call read('classpath:../RetrieveByRefAbstract.feature') {ref: #(tranRef)}
* match responseStatus == 200
GET API By Id>> /sending/v1/dm/{id}
* call read('classpath:../RetrieveByIdAbstract.feature') {id: #(pmId)}
* match responseStatus == 200
Abstract features use url keyword to invoke APIs.
MySimulation.scala looks like this
class MySimulation extends Simulation {
val protocol = karateProtocol(
"/sending/v1/dm?ref={ref}" -> Nil,
"/send/v1/dm/{id}" -> Nil,
"/sending/v1/dm" -> Nil
)
protocol.nameResolver = (req, ctx) => req.getUrlAndPath()
val create = scenario("create").exec(karateFeature("classpath:com/mastercard/send/xb/Testcases/Rem1Shot/Remit1ShotWithFrwdFeesRetrieve.feature"))
setUp(
create.inject(rampUsers(2) during (5 seconds)).protocols(protocol)
)
}
Now the issue is, in reports GET request with {id} and POST request is getting aggregated but GET requests with ref are reported individually.
I have also tried using nameResolver with getUrlAndPath, still no luck.
I am not sure if I am missing anything here.
Note:
There was another issue where I was not able to aggregate the GET request with id by using following protocol but now its fine when I include full uri.
"/dm/{id}" -> Nil,
"/dm" -> Nil

For that get request, pass a fake header and use that to control the nameResolver: https://github.com/intuit/karate/tree/master/karate-gatling#nameresolver
I would have expected /sending/v1/{dm} or something like that to work.
Note that in theory you can write some custom Scala code to parse the URL and do the name resolution. If you feel this should be made easier, submit a feature request, or better still, contribute code !

Related

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-Gatling: Requests with query parameter in reports are not getting aggregated

I am doing a POC on karate-gatling to reuse my tests. I have referred to documentation and installed those versions. First of all awesome work as usual, very easy to setup and get going.
I am calling a feature file from MySimualtion.scala which has three other abstract feature calls as follows:
* def tranRef = TransactionReferenceUtils.generateTransactionReferenceStartWith('09')
* set payloadR /transaction_reference = tranRef
POST API >> /sending/v1/dm
* call read('classpath:../InitiateAbstract.feature')
* match responseStatus == 200
GET API By Reference >> /sending/v1/dm?ref={ref}
* call read('classpath:../RetrieveByRefAbstract.feature') {ref: #(tranRef)}
* match responseStatus == 200
GET API By Id>> /sending/v1/dm/{id}
* call read('classpath:../RetrieveByIdAbstract.feature') {id: #(pmId)}
* match responseStatus == 200
Abstract features use url keyword to invoke APIs.
MySimulation.scala looks like this
class MySimulation extends Simulation {
val protocol = karateProtocol(
"/sending/v1/dm?ref={ref}" -> Nil,
"/send/v1/dm/{id}" -> Nil,
"/sending/v1/dm" -> Nil
)
protocol.nameResolver = (req, ctx) => req.getUrlAndPath()
val create = scenario("create").exec(karateFeature("classpath:com/mastercard/send/xb/Testcases/Rem1Shot/Remit1ShotWithFrwdFeesRetrieve.feature"))
setUp(
create.inject(rampUsers(2) during (5 seconds)).protocols(protocol)
)
}
Now the issue is, in reports GET request with {id} and POST request is getting aggregated but GET requests with ref are reported individually.
I have also tried using nameResolver with getUrlAndPath, still no luck.
I am not sure if I am missing anything here.
Note:
There was another issue where I was not able to aggregate the GET request with id by using following protocol but now its fine when I include full uri.
"/dm/{id}" -> Nil,
"/dm" -> Nil
For that get request, pass a fake header and use that to control the nameResolver: https://github.com/intuit/karate/tree/master/karate-gatling#nameresolver
I would have expected /sending/v1/{dm} or something like that to work.
Note that in theory you can write some custom Scala code to parse the URL and do the name resolution. If you feel this should be made easier, submit a feature request, or better still, contribute code !

How to send custom http response code back from spring cloud functions in gcp?

We are using the new gcp cloud functions using Java / Kotlin.
As in the current reference implementations, we are returning org.springframework.messaging.support.GenericMessage objects.
So our code looks like this (Kotlin):
fun generatePdfInBase64(message: Message<Map<String, Any>>): Message<*> {
val document = process(message)
val encoded = Base64.getEncoder().encodeToString(document.document)
return GenericMessage(encoded)
}
We were not able to find any way to include a custom http response code to our message, e.g. 201 or something. The function only responds 200 in case of no exception or 500.
Does someone know of a way to do this?
Best wishes
Andy
As it is mentioned at the official documentation, the HttpResponse class has a method called setStatusCode where you are able to set the number of the status as your convenience
For example:
switch (request.getMethod()) {
case "GET":
response.setStatusCode(HttpURLConnection.HTTP_OK);
writer.write("Hello world!");
break;
On the other hand the constructor of the GenericMessage receives as parameter a payload, therefore I think you can create a string with a json format and use the constructor for create your GenericMessage instance with the status response you need.
If you want to know more about the statuds codes take a look at this document.

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