Karate framework variable usage - karate

I have this steps:
...
Then status 200
And match response.requests[0].request.url == "/endpoint"
And json body = response.requests[0].request.body
And match body == { "something": "something"}
To simplify, I tried to put response.requests[0].request in a variable called request:
...
Then status 200
And def request = response.requests[0].request
And match request.url == "/endpoint"
And json body = request.body
And match body == { "something": "something"}
I'm having the following error:
'request' is not a variable, use the form '* request <expression>' instead
I read the documentation and the use of request seems to be fine:
Given def color = 'red '
And def num = 5
Then assert color + num == 'red 5'
What am I doing wrong?
Thanks in advance.

Just make this change:
* def req = response.requests[0].request
# other steps
* request req
We simply disallow def request (using request as a variable name) because a lot of newbie users get confused. The error message has worked 99.9% of the time for users to understand what the problem is, but I guess you fall in the 0.1% :)

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

I got error from calling json() when trying to running

Hello i want asking somethin that i got when i tried to run my streamlit, so i got error like this on my frontend page, i import it from backend page:
i will show my code too
Predict = st.button('Predict Satisfacion Rate')
if Predict:
r = requests.post(URL, json=data)
res = r.json()
if res['code'] == 200:
res2 = (res['result']['description'])
if res2 == 'Not Satisfied':
st.markdown('**The Passenger is not Satisfied**')
col4,col5,col6 = st.columns([1,1,1])
with col5 :
st.image('Happy.jpg')
else:
st.markdown('**The Passenger is Satisfied**')
col7,col8,col9 = st.columns([1,1,1])
with col8 :
st.image('NotHappy.jpg')
else:
st.write('**Error**')
st.write(f"Details : {res['result']['description']}")
so how can i do to solve this error?
thank you.
In your code, the conversion res = r.json() is unnecessary. Unless you really need this as JSON somewhere else, you can test the status code directly from the r object as r.status_code.
After if r.status_code == 200:, you can then convert to JSON if you really need to, as you should be confident that the server returned a valid response.

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

How to pass single param to separate feature file

I've tried below to send a param to separate feature file ( by following this example ) but, it is not working as expected.
project.feature
* def id = '55000000005021'
* def result = call read('delete_project.feature')
delete_project.feature
Given path 'project', '#(id)'
When method DELETE
Then status 200
Then match response.status == 'success'
Getting below exception
com.intuit.karate.exception.KarateException: projects.feature:48 -
delete_project.feature:11 - status code was: 404, expected: 200,
response time: 239, url: https://localhost:8080/project/%23(id)
response:
{"status":"failure","data":{"error_code":"INVALID_URL_PATTERN","message":"Please
check if the URL trying to access is a correct one"}} at ✽.* def
result = call read('delete_project.feature') (projects.feature:48)
One more doubt, How to iterate this by passing list of ids. I've multiple id in foo variable, I would like call delete_project.feature for each id availble in that foo variable.
* def foo = get response.data[*].id
I think you over-complicated the path params, change to:
Given path 'project', id
And read this part of the docs: https://github.com/intuit/karate#rules-for-embedded-expressions

How to pass the json list response of one feature file as parameter to another feature file

My requirement is, I want to pass the response of first feature file as input to second feature file. The first feature file response is a json list, so the expectation is second feature file should be called for each value of json list.
Feature:
Scenario: identify the reference account
* def initTestData = read('../inputData.feature')
* def accountData = $initTestData.response
* print “Account Details”+accountData // output of this is a json list [“SB987658”,”SB984345”]
* def reqRes = karate.call('../Request.feature', { accountData : accountData })
In Request.feature file we are constructing the url dynamically
Given url BaseUrl + '/account/'+'#(accountId)' - here am facing issue http://10.34.145.126/account/[“SB987658”,”SB984345”]
My requirement is Request.feature should be called for each value in ‘accountData’ Json list
I have tried:
* def resAccountList = karate.map(accountData, function(x){accountId.add(x) })
* def testcaseDetails = call read('../requests/scenarios.feature') resAccountList.accountId
Result is same, accountId got replaced as [“SB987658”,”SB984345”]
my I need to call Request.feature twice http://10.34.145.126/account/SB987658 http://10.34.145.126/account/SB984345 and use the response of each call to the subsequent feature file calls.
I think you have a mistake in karate.map() look at the below example:
* def array = ['SB987658', 'SB984345']
* def data = karate.map(array, function(x){ return { value: x } })
* def result = call read('called.feature') data
And called.feature is:
Feature:
Scenario:
Given url 'https://httpbin.org'
And path 'anything', value
When method get
Then status 200
Which makes 2 requests:
https://httpbin.org/anything/SB987658
https://httpbin.org/anything/SB984345