Getting Illegal character in query when doing a conditional GET with multiple parameters - karate

Code:
Feature: GET API headers feature
Scenario: pass GetWatchList with headers
Given header x-apisignatures = '543aba07839'
And header ssotoken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJ1bmlxdWUiOiJjYTM4MDAzZS0wYThiLTQ3YjktOWFjNS00YzMyN2MwNTUyMGYiLCJ1c2VyVHlwZSI6IlJJTHBlcnNvbiIsImF1dGhMZXZlbCI6IjIwIiwiZGV2aWNlSWQiOiJlZWIxOGRlOGRiNjE3MDg4MjViNTdjNGU5NDg1ZmFjYTU1MGE1OTBkY2Y1MjIzNzkyYzUwYjVhZWRjZGI5ZmUxNDQxZTFiMzhmZWI2NDFhZmUwNGI3NGY0NDA5OWMzZGQwZWI0OTRiZjgwMTYxOWYyNTAyNjI2YTJjZjdkMTZmZCIsImp0aSI6IjFmN2IwODkxLTJkMGUtNDBhZS04MWJiLWQwODVjY2NhOGYyZSIsImlhdCI6MTY2NDI3Njk0NH0.6Q7CPtQIN0uB1ZbVQBj5dshqioop3dJKEpla5DQS5K5qtRPw38SxTEJ1f1DJ_Ka_sgMp_fdh9EEABipTgtgMqg'
And header uniqueid = 'ca38003e-0a8b-47b9-9ac5-4c327c05520f'
And header x-page = 'Home'
When url 'https://jiocinemaqa-api.jio.ril.com/user/v1/watchlist?groups=[["Movie"],["Show"]]'
When method GET
Then status 200
* print response

Try this public API to test:
* url 'https://httpbin.org/anything'
* param groups = '[["Movie"],["Show"]]'
* method get
And you can verify in the response you see this:
"args": {
"groups": "[[\"Movie\"],[\"Show\"]]"
},
And also:
"url": "https://httpbin.org/anything?groups=[[\"Movie\"]%2C[\"Show\"]]"
This proves that Karate is sending the right thing. Keep in mind that your server may have a bug.

Related

Karate - Trouble passing correct headers for authorization

I am have some problems passing in the correct headers for my graphql endpoints
The use case in Postman:
call requestToken endpoint to obtain sessionToken value
requestToken response contains Key Value " and Token Value.
For subsequent calls, I set postman headers as:
Key = X_SESSION_TOKEN Value = Token Value
The user case in Karate
1st feature 'requestToken.feature' successfully calls and stores key + tokenValue
2nd feature successfully defines and prints the token value
here is my 2nd request:
Feature: version
Background:
* url 'http://api-dev.markq.com:5000/'
* def myFeature = call read('requestToken.feature')
* def authToken = myFeature.sessionToken
* configure headers = { 'X_SESSION_TOKEN': authToken , 'Content-Type': 'application/json' }
Scenario: get version
Given path 'query'
Given text query =
"""
query {
version
}
"""
And request { query: '#(query)' }
When method POST
Then status 200
And print authToken
And print response
I am not sure I send the headers right. Its coming back 200, but I keep getting a error 'token malformed' in the response message
Any suggestions? New at this, thanks!
Honestly this is hard to answer, a LOT depends on the specific server.
EDIT: most likely it is this change needed, explained here: https://github.com/intuit/karate#embedded-expressions
* configure headers = { 'X_SESSION_TOKEN': '#(authToken)' , 'Content-Type': 'application/json' }
2 things from experience:
should it be X-SESSION-TOKEN
add an Accept: 'application/json' header
And try to hardcode the headers before attempting call etc.
Here is an example that works for me:
* url 'https://graphqlzero.almansi.me/api'
* text query =
"""
{
user(id: 1) {
posts {
data {
id
title
}
}
}
}
"""
* request { query: '#(query)' }
* method post
* status 200

Karate Authentication only valid for the first request in scenario

My issue is that I am authorized for the first request (Create article) but not for the 2nd request (getById) although the authorization itself has not changed. What am I doing wrong?
Feature: Test Article Endpoint
Background:
* url 'http://localhost:8080/webapp/api/v1'
* header AuthenticationToken = 'sys-test-api-token'
Scenario: create article, get article ById, update article & delete article
And request {name: 'TestArtikel', unitName: 'Stk.', articleNumber: '0001'}
Given path 'article'
When method post
Then status 201
And match response.id == '#notnull'
* def articleId = response.id
Given path 'article/id/:id'
And param id = articleId
When method get
Then status 200
For headers that "span" requests, use configure headers:
* configure headers = { AuthenticationToken: 'sys-test-api-token' }
And refer the docs: https://github.com/intuit/karate#configure-headers

How to navigate and validate through all the pages of a api response

I have a scenario where the api returns payload response in pages if the payload has lot of data.
Request:
Background:
* url url
* call read('classpath:examples/common.feature')
And header accesstoken = accessToken
And header accept = '*/*'
And header Accept-Encoding = 'gzip, deflate, br'
Scenario: Get Scores
* param start = '2020-07-01'
Given path '/scores'
When method Get
Then status 200
* def totalPages = response.totalPages
* def response = {"requestId": "6a4287f35112",
"timestampMs": 1595228005245,
"totalMs": 51,
"page": 1,
"totalPages": 100,
"data": [.......]}
After this i am getting total pages, and need to navigate through all the pages by passing the same request with additional * param page = #page_number and validate response is 200. page_number has to be iterated from 2 to 100.
Thought of using Karate loop or calling feature file and building dynamic data and using dynamic data driven feature, but not sure how to proceed.
Please advise
I think the easiest option is to write a second feature file and call it in a loop.
* def totalPages = 10
* def pages = karate.repeat(totalPages, function(i){ return { page: i } })
* call read('second.feature') pages

Polling in Karate based on JSON response [duplicate]

This question already has an answer here:
Karate framework retry until not working as expected
(1 answer)
Closed 2 years ago.
I am creating an animal into a database and then attempting to retrieve the animal which I have just created. However, there is a time lag ~5-10secs in the database. Therefore, a sleep wait is not suitable for this scenario as the response time varies. 
I would like to poll the message until animalId is returned in the array. It is also important that the requestId header is re-generated when the request is re-tried. 
What is the most elegant way of achieving this? 
Scenario:
Given path '/animals'
And header requestId = uniqueString(5)
When method post
Then status 200
* def animalId = response.animalId
Given path '/animals'
And header requestId = uniqueString(5)
When method get
Then status 200
{
"animals": [
{
"animalId": "12219958",
"reference": [
"12345"
]
}
]
}
* def animalDetails = karate.jsonPath (response, "$.animals.[?(#.reference[0]== '" + animalId + "' )]")[0]
* def animalId = '12345'
The retry until syntax is what you are looking for: https://github.com/intuit/karate#retry-until
EDIT: regarding this requirement:
It is also important that the requestId header is re-generated when the request is re-tried.
You have to configure headers with a JavaScript function, so that it is fired for each re-try. Otherwise there is no-other option to tweak the body, please manually write a polling loop if needed (also explained in the docs).
EDIT: here is a simple example to see for yourself how the foo header is dynamic for each re-try. Paste this in a fresh Scenario and it will work.
* def counter = { value: 0 }
* configure headers = function(){ return { foo: counter.value } }
* url 'http://httpbin.org/get'
* retry until counter.value++ == 2
* method get

Karate doesn't recognize dashes

I wrote a simple mock that checks if a specific header exists then return a specif response based on that, but karate doesn't understand dashes(-) in my headers for an example Client-ID gives an error of ReferenceError: "ID" is not defined in <eval> at line number 1 but header Accept work fine. i'm passing this header through postman.
and this how the code looks
* def fun = function(){ var test = requestHeaders; for(i in test) if(test.Client-ID) return true}
When you have characters like - part of the JSON key, you need to use quotes.
* def foo = { 'Content-Type': 'application/json' }
* match foo['Content-Type'] == 'application/json'
Also try if this works for you, it may be simpler:
Scenario: pathMatches('/v1/headers') && karate.get("requestHeaders['Client-ID']")
And in case you are testing a value, headerContains() can be used: https://github.com/intuit/karate/tree/master/karate-netty#headercontains