Karate - Variable to access request just like response - karate

Is there a variable like response for request in karate. I tried to look at the github issues and found the below example, but this does not seem to work for me.
* def temp = (karate.lastRequest)
* print '==============>' +(temp.body)

Its karate.prevRequest
* def temp = karate.prevRequest
* def requestMethod = temp.method
* def requestBody = temp.body
please find more example here

Related

calling A.feature from B.feature is returning com.intuit.karate.ScriptObjectMap#xxxxxx

I apologize if this has been answered in a previous thread, I tried searching and was not able to find any that were this specific problem.
I am trying to call A.feature from B.Feature - where A returns a specific value to be used in B
A.feature:
Given url endpoint
And header Content-Type = 'application/json,text/plain'
And request
"""
{
"prod": "xxxx"
}
"""
When method post
Then status 200
Then match response[0].acc.insType == 'xxx'
And def accKey = response[0].account.accKey
then in B.feature, i am calling it with the * call read:
* def key = call read('ReadRoundUpSubscription.feature');
* print 'Account Key is ' + key
But it is returning
[print] Account Key is com.intuit.karate.ScriptObjectMap#xxxxxx
UPDATE:
I changed this line:
And def accKey = response[0].account.accKey
to be
And set accKey = response[0].account.accKey
and now i am getting variable is null or not set 'accountToken'
Update 2:
I figured it out thanks to this post
A.feature ends with
* def accKey = response[0].account.accKey
Then in B.feature:
* def key = karate.call('ReadRoundUpSubscription.feature');
* def keyvalue = key.acckey
I realize my variable names are bad. real bad.
If there is a better way to accomplish this result please let me know!
I think you finally got it: * def keyvalue = key.acckey - so the result will contain an envelope of all variables in the "called" feature.
This is explained in detail in the documentation: https://github.com/karatelabs/karate#calling-other-feature-files

Using cURL for API automation in Karate

I'm new to Karate
I'm automating an API test where I need to upload a large file >50MB
When I do so with Karate I get an error "Broken Pipe" and according to this question
Broken pipe (Write failed) when testing > max allowed Content-Length I could use "cURL" for this request.
It's working fine as follows (with hardcoded data):
* def result = karate.exec('curl -L -X POST "URL" -H "Authorization: Bearer MYTOKEN" -F "file=#"PATH""')
However, I'm having issues with the syntax when passing variables
I need to pass the URL, token, and path as variables and not hardcoded text since I will be reusing this test for multiple landscapes.
How would I go about it?
Thanks,
Think of the Karate syntax as very close to JavaScript. So, string concatenation works. For example:
* def myUrl = 'https://httpbin.org/anything'
* def result = karate.exec('curl ' + myUrl)
And a nice thing is that JavaScript Template Literals work:
* def myUrl = 'https://httpbin.org/anything'
* def result = karate.exec(`curl ${myUrl}`)
Also note that the karate.exec() API takes an array of command-line arguments. This can make some things easier like not having to put quotes around arguments with white-space included etc.
* def myUrl = 'https://httpbin.org/anything'
* def result = karate.exec({ args: [ 'curl', myUrl ] })
You can build the arguments array as a second step for convenience:
* def myUrl = 'https://httpbin.org/anything'
* def args = ['curl']
* args.push(myUrl)
* def result = karate.exec({ args: args })
Note that conditional logic and even an if statement is possible in Karate: https://stackoverflow.com/a/50350442/143475
Also see: https://stackoverflow.com/a/62911366/143475

Karate websocket send request body replace token failed

I am using karate to test websocket, this worked:
Background:
* def token = TOKEN
* def handler = function(msg){ return msg.startsWith('a[')}
* def socket = karate.webSocket(WS_HOST + 'socket/761/f4t0so3p/websocket', handler)
Scenario: Demo Real
checking dcube-dev
* socket.send('{"type":"1ffe4b5d___AC_GET_MY_AVAILABLE_TASKS___N","token": "myhardcodedtoken","content":{"msg":null,"counter_api_enabled":false}}')
You can see here, I am hard coding the token inside the request body, not good, so I tried to move it out and use environment token instead as below:
Background:
* def token = TOKEN
* def handler = function(msg){ return msg.startsWith('a[')}
* def socket = karate.webSocket(WS_HOST + 'socket/761/f4t0so3p/websocket', handler)
Scenario: Demo Real
checking dcube-dev
* def body = {"type": "1ffe4b5d___AC_GET_MY_AVAILABLE_TASKS___N", "token": '#(token)', "content": {"msg":null,"counter_api_enabled":false} }
* print "Body:", body
* socket.send( '#(body)')
But this is always wrong, seemed the msg never sent out . Can anyone tell me how to resolve this issue?
Thanks
Actually I think you need to make this one change:
* socket.send(body)
Think of the round brackets as being JS - not standard Karate expressions: https://github.com/intuit/karate#enclosed-javascript
Also note, for strings (instead of JSON) you can use replace: https://github.com/intuit/karate#replace
* def text = 'hello <foo> world'
* replace text.foo = 'bar'
* match text == 'hello bar world'

Karate: How can we retrieve the value from called feature file

I have two parameter in feature file A and I pass those values to another feature file called B.
But I am unable to retrieve the values as expected in Feature file B
CODE:
Feature File A:
And def Response = response
And def token = response.metaData.paging.token
And def totalPages = response.metaData.paging.totalPages
* def xyz =
"""
function(times){
for(currentPage=1;currentPage<=times;currentPage++){
karate.log('Run test round: '+(currentPage));
karate.call('ABC.feature', {getToken:token, page:currentPage});
}
java.lang.Thread.sleep(1*1000);
}
"""
* call xyz totalPages
Feature File B:
* def token = '#(getToken)'
* def currentPage = '#(page)'
But the output was
#getToken
#page
What would be the best way? to these values for further utilization.
Try this:
* def token = getToken
* def currentPage = page
Here's another thing, any variable defined in the calling feature will be visible, e.g. token so most of the time you don't need to pass arguments:
* print token
* print totalPages
Please avoid JS for loops as far as possible: https://github.com/intuit/karate#loops - and actually you seem to have missed the data-driven testing approach that Karate recommends: https://github.com/intuit/karate#the-karate-way
If you are still stuck, please follow this process: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue

call the first feature from the second feature file, failed without specified clue

Run the first.feature file successfully,however, call it from the second.feature failed without any clue to analysis. Do you have any idea help me find the root cause?
The source of my first.feature:
Feature: 采样管理-样本登记
Background: 读取随机生成的条形码、手机号、采样类型等作为入参
* url baseURL
* def randomData = Java.type('utils.RandomData')
* def barcode = randomData.getRandom(11)
* def randomPhone = randomData.getTelephone()
* def sampletype = randomData.getNum(0,1)
Scenario: 输入合法参数进行正常样本登记,确认能够登记成功
Given path 'iEhr/PersonSample'
# * header Content-type = 'application/x-www-form-urlencoded; charset=UTF-8'
* cookies { JSESSIONID: '#(jsessionID)',SESSION: '#(sessionID)', ACMETMP: '#(acmetmpID)'}
* def autoMotherName = "autoMname"+ barcode
# * def confData = {mothername: "#(autoMotherName)", barcode: "#(barcode)", mobile: '#(randomPhone)', sampletype:"#(sampletype)" }
# 设置sampletype为1,已被采样
* def confData = {mothername: "#(autoMotherName)", barcode: "#(barcode)", mobile: '#(randomPhone)', sampletype:"1" }
# 打印入参变量输出
* print confData
# 用例与数据分离
* def paramObj = read('classpath:mainFlow/sampleSaveReqTest.json')
* print paramObj
* form field param = paramObj
When method post
Then status 200
* json result = response[0].result
* def personId = result[0].personid
* def sampleid = result[0].sampleid
* print personId
* print sampleid
The source of my second.feature:
Feature: 提交递送样本
Background:
* def sampleResult = call read('classpath:mainFlow/first.feature')
* print sampleResult
I run the first.feature singly, it works. However, karate reports the error below after running the second.feature. Any idea how can I debug to find the root cause? I have no idea what's wrong with the second read. Many thanks!
* def sampleResult = call read('classpath:mainFlow/first.feature')
-unknown-:14 - javascript evaluation failed: read('classpath:mainFlow/first.feature'), null
Look for some issue with karate-config.js. As Babu said in the comments, it is very hard to make out what the problem is, I suggest you follow this process: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue
Also try if the latest preview version 0.9.3.RC2 is better at showing what the error is.
If you can replicate the problem as a small example, it will help us - because we really need to do better at showing more useful error logs, instead of just null.