Karate websocket send request body replace token failed - karate

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'

Related

Escape response in karate framework [duplicate]

For some reason a variable with a / character get converted to a \/, how do I prevent this?
I start a echo server that listens on localhost:3000 by running npx http-echo-server
I execute the following:
code:
* def CHALLENGE_USER = '/abc/user'
* def loginJson = { user: '#(CHALLENGE_USER)' , name: 'Some Name'}
* print loginJson
* def TEST_URL = 'http://localhost:3000'
Given url TEST_URL+'/session/loginresponse'
And header Content-Type = 'application/json'
And request loginResponseJson
And method put
Then status 200
It prints { "user": "/abc/user", "name": "Some Name" } like I expect.
The http server logs show "--> {"user":"/schemes/ATT_5_55/CH_1","name":"Some Name"}"
Karate shows the result of the echo {"user":"\/abc\/user","name":"Some Name"}
I have tried:
def CHALLENGE_USER = '/abc/user'
def CHALLENGE_USER = "/abc/user"
def CHALLENGE_USER = '/abc/user'
def CHALLENGE_USER = '//abc//user'
also setting the variable after the fact does not work:
* def loginJson = { name: 'Some Name'}
* loginJson.user = CHALLENGE_USER
Yes this is legal as per the JSON spec: JSON: why are forward slashes escaped?
And the Java libraries we use does that.
Does your server have a problem ? If so - then you have a bug that Karate surfaced.
And if you really want to have full control over the request, please use text but IMO it may be a waste of time: https://stackoverflow.com/a/68344856/143475
A nasty workaround, please forgive me Peter Thomas.
You can convert the json to a string and then remove the \ characters.
I only have one use case for this thank goodness.
* def CHALLENGE_USER = '/abc/user'
* def loginJson = { user: '#(CHALLENGE_USER)' , name: 'Some Name'}
* string json = loginJson
* def loginJsonText = json.replaceAll("\\", "")
* print loginJson
* def TEST_URL = 'http://localhost:3000'
Given url TEST_URL+'/session/loginresponse'
And header Content-Type = 'application/json'
And request loginJsonText
And method put
Then status 200

In Karate - Feature file calling from another feature file along with variable value

My apologies it seems repetitive question but it is really troubling me.
I am trying to call one feature file from another feature file along with variable values. and it is not working at all.
Below is the structure I am using.
my request json having variable name. Filename:InputRequest.json
{
"transaction" : "123",
"transactionDateTime" : "#(sTransDateTime)"
}
my featurefile1 : ABC.Feature
Background:
* def envValue = env
* def config = { username: '#(dbUserName)', password: '#(dbPassword)', url: '#(dbJDBCUrl)', driverClassName: "oracle.jdbc.driver.OracleDriver"};
* def dbUtils = Java.type('Common.DbUtils')
* def request1= read(karate.properties['user.dir'] + 'InputRequest.json')
* def endpoint= '/v1/ABC'
* def appDb = new dbUtils(config);
Scenario: ABC call
* configure cookies = null
Given url endpoint
And request request1
When method Post
Then status 200
Feature file from which I am calling ABC.Feature
#tag1
**my featurefile1: XYZ.Feature**
`Background`:
* def envValue = env
Scenario: XYZ call
* def sTransDateTime = function() { var SimpleDateFormat = Java.type('java.text.SimpleDateFormat'); var sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'+00:00'"); return sdf.format(new java.util.Date()); }
* def result = call read(karate.properties['user.dir'] + 'ABC.feature') { sTransDateTime: sTransDateTime }
Problem is,
While executing it, runnerTest has tag1 configured to execute.
Currently, it is ignoring entire ABC.feature to execute and also not generating cucumber report.
If I mention the same tag for ABC.feature (Which is not expected for me as this is just reusable component for me ) then it is being executed but sTransDateTime value is not being passed from XYZ.feature to ABC.feature. Eventually, InputRequest.json should have that value while communicating with the server as a part of the request.
I am using 0.9.4 Karate version. Any help please.
Change to this:
{ sTransDateTime: '#(sTransDateTime)' }
And read this explanation: https://github.com/intuit/karate#call-vs-read
I'm sorry the other part doesn't make sense and shouldn't happen, please follow this process: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue

Karate - Variable to access request just like response

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

pass parameters to after-feature karate

I discovered after-feature in karate which is very useful. But I didn't find how to pass parameters to after-feature from main feature. Ex: access token to delete a user account or a user_id.
Here is call of after-feature.feature in my main feature:
* configure afterFeature = function(){ karate.call('classpath: AfterFeature.feature'); }
Here is my AfterFeature.feature
Scenario:
* url 'XXX'
* path 'YYY'
* param foo = bar which should come from main feature
* header Authorization = 'Bearer ' + accessToken which should come from main feature
* method delete
* status 204
karate.call() can take parameters.
karate.call('classpath: AfterFeature.feature', { some: 'value' });

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.