Karate: can we get the response returned when scenario is called with parameter - api

I am trying to reuse a scenario in a feature file with call feature in the main feature file
the steps are as follows
main feature file calling the reusable features file with parameter input to the called scenario
ex:
def outputdata = call read('file:features/commonFeatures/commonFunctions.feature#customer') ({ 'customerId' : partyId })
Note: tried with karate.call as well, perhaps it does not provide the required outcome
and the customer id is passed as input to the called scenario of the feature file.
when i used the outputdata variable to get the output of the call scenario, not getting the response of API returned. getting polygot exception
could you please suggest me a way to get the response returned from a called scenario with parameterization

Related

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

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.

Jmeter: variable scope - How to use different random value for the same request

I'm willing to use 2 variables for random values with the same request.
I defined both in User Parameters as follows: var1=${__Random(1,100)}; var2=${__Random(1000,2000)} (Also I checked: Update once per iteration)
I have the requests:
Request1: GET user/${var1}
Request2: GET user/${var2}
During run-time, when it gets to request2 var2 equals var1!
How do I fix that?
Well, User Parameters is a PreProcessor so you should put it as a child of your HTTP Request in order to get correct behavior. You can use Debug Sampler and View Results Tree listener combination to validate variables values (see How to Debug your Apache JMeter Script article for more details)
I would recommend discarding this User Parameters and injecting the __Random() function directly into your HTTP Request sampler Path like
/user/${__Random(1,100,var1)}
/user/${__Random(1000,2000,var2)}
This is a simpler way to generate random numbers and get them stored into JMeter Variables.

How to test if my application does not send a message with SoapUI?

I have a Java EE application that processes a bunch of messages from different interfaces. (Some of the) functional tests are performed with SoapUI.
In one of the cases I have created a SOAP VirtResponse step that receives the output of my application and checks the values in the received message. The test has the following steps:
Datasource step to load input and expected output (multiple scenarios)
JMS step to send input to application on a specific interface.
SOAP step to receive application output on another interface (no validation).
Groovy script to check results (e.g. no message received or message received with specific values). See below for the script, couldn't get it to work in between the list items.
Datasource loop to step 2.
There is a scenario (well, there are more scenarios) in which the input should not generate an output. I want to check if my application did not send an output in such a scenario.
Strategy 1:
I have added a fourth groovy step in which I validate that the result of step 3 is an empty string. To make the test pass, I had to disable the checkbox in TestCase Options that says "Fail TestCase on Error". This works in cases of happy execution of tests. However if an error does occur (e.g. the application did send a response when it was not supposed to or the application send a wrong response), the entire TestCase is set to passed (because of the checkbox) and only the specific step deep down in the logs is failed. This makes it hard to see the results of the entire test suite.
Attempted strategy 2:
Started out by adding a conditional test step that will skip step 3 based on the input. However that way I no longer validate if my application does not send a message when it is not supposed to.
What is the best way to check these kinds of scenarios?
EDITS:
The entire testcase should fail if one of the scenarios from the datasource fails. (It is not a problem if this means that some scenarios were not evaluated yet)
Groovy script:
// Get flag from datasource that indicates if a message should be received
def soapBerichtOntvangen = context.expand('${DataSourceUISBerichten#SoapBerichtOntvangen}' );
// Get the message from the previous step.
def receivedSoapRequest = context.expand( '${SOAPVirtResponse#Request#declare namespace out=\'http://application/messageprocessing/outbound/out:SendOutboundMessage[1]/Message[1]}' )
// If we don't expect a message the flag is set to "N"
if(soapBerichtOntvangen=="N"){
assert(receivedSoapRequest=="")
} else if(receivedSoapRequest!=null && receivedSoapRequest!=""){
def slurpedMessage = new XmlSlurper().parseText(receivedSoapRequest)
def messageType=slurpedMessage.MessageHeader.MessageReference.MessageType
// Get expected values from context
def verwachtMessageType = context.expand('${DataSourceOutboundCIBerichten#messageType}' )
assert(String.valueOf(messageType)==verwachtMessageType)
} else {
// Should have received a message, but none came up.
assert(false)
}

getContentServiceInfo1 returns truncated data regardless of reqSpecifier

Calling the getContentServiceInfo1 REST API seems to return the same data regardless of provided reqSpecifier and notrim values. I am using this call as part of the refresh account flow to determine whether the service requires MFA. Is there another call that I can make to achieve the same thing?
I noticed that the values accepted for reqSpecifier are essentially binary bit masks but providing the flag as 10000000, or even 0b10000000 for that matter, instead of 128 does not change the results. What value and value type should I be providing for reqSpecifier to get more than the basic level information? Relevant request and return information when using this API call for E*Trade is below.
Request (cobrand token is omitted):
{"cobSessionToken":"",
"contentServiceId":24,
"reqSpecifier":128,
"notrim":true}
Response (this is always the response I get unless I provide arguments that result in an error):
{"contentServiceId":24,
"siteId":744,
"containerInfo":{"containerName":"stocks","assetType":1}}
This response comes when you pass "notrim" value as "false", if you are passing it "false" then please pass it as true. It should work.