How can I use location from Response Headers in the next request? [duplicate] - karate

This question already has an answer here:
How to get id in responseHeaders location?
(1 answer)
Closed last year.
I'm perfoming some test using Karate test.
1st a Post that is expecting a 201 and a location.
2nd use the location from response to perfom a get.
Does anyone know how can I do this with Karate?
The following code is my try, after many other.
Given path 'alpha/test'
And request
"""
{
"id": '#(uuid)',
"content": "test",
"isActive": true
}
"""
When method post
Then status 201
And def endpointLocation = responseHeaders['Location']
And print endpointLocation
Given url 'endpointLocation'
When method get
Then status 200
And match response ==
"""
{
"id": '#(uuid)'
}
"""
But i'm getting:
18:30:12.819 [main] ERROR com.intuit.karate - org.apache.http.client.ClientProtocolException, http call failed after 252 milliseconds for URL: endpointLocation
18:30:12.820 [main] ERROR com.intuit.karate - http request failed:
org.apache.http.client.ClientProtocolException
testApi.feature:263 -
org.apache.http.client.ClientProtocolException
I'm not figuring it out why.
[EDIT]
After sugestion from Peter, that I Thanks!
The print return:
08:59:33.610 [main] INFO com.intuit.karate - [print] [
"https://www.test.com/enpoint/4603b043-ea8c-470d-a5a9-2aa50aea4f75"]
Now I'm calling
Given url endpointLocation
and I'm getting
08:59:33.611 [main] ERROR com.intuit.karate - http request failed: java.net.URISyntaxException: Illegal character in scheme name at index 0: ["https://www.test.com/enpoint/4603b043-ea8c-470d-a5a9-2aa50aea4f75"]
fraudMgmtApi.feature:263 - java.net.URISyntaxException: Illegal character in scheme name at index 0: ["https://www.test.com/enpoint/4603b043-ea8c-470d-a5a9-2aa50aea4f75"]
I was trying also to trim the first and last caracters, creating a:
def trim =
"""
function(myText) { result = myText.substring(1, myText.length-1) }
"""
Or myText.slice(1,-1)

From the error message: http call failed after 252 milliseconds for URL: endpointLocation
It is clear you are setting the url wrong. First try hard-coding it, then make this change, if the endpointLocation variable is set correctly. You can print it to check.
Given url endpointLocation

Related

Karate: How to send variable to json file

I'm trying to create a dynamic request that should receive 2 parameters (username and password). To do so, I defined the below JSON file:
{
"grant_type": "password",
"client_id": "myClient",
"username": "#(username)",
"password": "#(password)"
}
To call my JSON, I set the below feature file where my intention is to define a variable for each parameter i want to send
Scenario: Get Sugar access token
Given url baseUrl
And path 'oauth2/token'
And def username = 'user'
And def password = 'password'
And def requestBody = read('classpath:jsonFiles/requests/authRequest.json')
When request requestBody
And method POST
Then status 200
* print 'Response: ', response
Unfortunately, when I run the scenario, i'm getting below error message
10:59:59.111 [main] INFO com.intuit.karate - Karate version: 1.4.0-SNAPSHOT
10:59:59.286 [main] INFO com.intuit.karate.Suite - backed up existing 'target\karate-reports' dir to: target\karate-reports_1672160399285
10:59:59.303 [main] INFO c.intuit.karate.core.FeatureRuntime - found scenario at line: 4
11:00:00.174 [main] ERROR com.intuit.karate - src/test/java/myCompany/testautomation/features/auth/getToken.feature:11
And def requestBody = read('classpath:jsonFiles/requests/authRequest.json')
js failed:
>>>>
01: read('classpath:jsonFiles/requests/authRequest.json')
<<<<
org.graalvm.polyglot.PolyglotException: not found: jsonFiles/requests/seugarAuth/authRequest.json
- com.intuit.karate.resource.ResourceUtils.getResource(ResourceUtils.java:126)
- com.intuit.karate.core.ScenarioFileReader.toResource(ScenarioFileReader.java:129)
- com.intuit.karate.core.ScenarioFileReader.readFileAsStream(ScenarioFileReader.java:99)
- com.intuit.karate.core.ScenarioFileReader.readFileAsString(ScenarioFileReader.java:95)
- com.intuit.karate.core.ScenarioFileReader.readFile(ScenarioFileReader.java:54)
- com.intuit.karate.core.ScenarioEngine.lambda$new$0(ScenarioEngine.java:120)
- <js>.:program(Unnamed:1)
src/test/java/myCompany/testautomation/features/auth/getToken.feature:11
The use of classpath: makes more sense for Java projects. It looks like you are using the Visual Studio code extension, in which case your workspace root folder will be the classpath unless to switch to "Maven mode" or equivalent: https://marketplace.visualstudio.com/items?itemName=karatelabs.karate#run-mode
Or another option is to use a Java "runner" and use the Java extension for VS Code.
If all that above doesn't make sense, for now just keep things simple and use relative paths. For example if authRequest.json is side-by-side with your feature file, this would work:
* def requestBody = read('authRequest.json')
Relative paths and the this: prefix can be used, but I leave that to you to research: https://github.com/karatelabs/karate#path-prefixes

Swagger API structure for POST request without body parameters

POST request without body parameter gives a JSON parse error. Mentioned the error below.
API Call
api.post('notification/seen')
Error:
{"message":{"name":"SyntaxError","msg":"Unexpected token n in JSON at position 0","stack":"SyntaxError: Unexpected token n in JSON at position 0\n at JSON.parse ()\n at createStrictSyntaxError (/app/node_modules/body-parser/lib/types/json.js:158:10)\n at parse (/app/node_modules/body-parser/lib/types/json.js:83:15)\n at /app/node_modules/body-parser/lib/read.js:121:18\n at invokeCallback (/app/node_modules/raw-body/index.js:224:16)\n at done (/app/node_modules/raw-body/index.js:213:7)\n at IncomingMessage.onEnd (/app/node_modules/raw-body/index.js:273:7)\n at IncomingMessage.emit (events.js:327:22)\n at IncomingMessage.EventEmitter.emit (domain.js:486:12)\n at endReadableNT (_stream_readable.js:1327:12)\n at processTicksAndRejections (internal/process/task_queues.js:80:21)"},"level":"error","timestamp":"2021-09-28T06:29:19.577Z"}
Swagger API structure
/notification/seen:
post:
tags:
- Notification
responses:
204:
description: Update Seen Notification Success
401:
description: Access Token Missing/Expired
500:
description: Something went wrong!
If same API I call with adding dummy body as below with changing the Swagger API structure I am not getting the error.
API Call
api.post('notification/seen',{id:"data"})
Swagger API structure
/notification/seen:
post:
tags:
- Notification
parameters:
- in: body
name: body
schema:
type: object
responses:
204:
description: Update Seen Notification Success
401:
description: Access Token Missing/Expired
500:
description: Something went wrong!
And also if I change POST to GET request then also I am not getting the error.
How to fix the error with the POST request without a body parameter?

Karate DSL - karate.info is not populated when used with Scenario outline

We are using Karate for testing our application. Since we need to run multiple test with different testdata we used scenario outline passing a json array in the examples. The tests are getting executed properly.
Post execution we need to publish the result to our test management tool. For that, we are trying to use the afterScenario hook as mentioned in karate documentation.
* configure afterScenario =
"""
function(){
var info = karate.info;
karate.log('after', info);
}
"""
After each scenario of the example executed, we see the info details printed, but the error message details, scenario name etc are not populated (title is a value from the json array passed in example section. title is printed in the karate execution report)
Karate.info printed when scenario outline is used:-
14:45:39.744 [main] ERROR com.intuit.karate - status code was: 400, expected: 200, response time: 754, url: ##url removed###, response: ##Response removed###
14:45:39.744 [main] INFO com.intuit.karate - after {
"featureDir": "C:\\Workspace\\Karate_Demo\\target\\test-classes\\com\\test\\Karate_Demo",
"scenarioType": "Scenario Outline",
"featureFileName": "TestIntegration.feature",
"errorMessage": null,
"scenarioDescription": "",
"scenarioName": "<title>"
}
Karate.info printed when scenario is used:-
13:15:54.772 [main] ERROR com.intuit.karate - status code was: 400, expected: 200, response time: 1540, url: ##url removed###, response: ##Response removed###
13:15:54.795 [main] INFO com.intuit.karate - after {
"featureDir": "C:\\Workspace\\Karate_Demo\\target\\test-classes\\com\\test\\Karate_Demo"
"scenarioType": "Scenario",
"featureFileName": "Test.feature",
"errorMessage": "Test.feature:32 - status code was: 400, expected: 200, response time: 1540, url: ##url removed###, response: ##Response removed###,
"scenarioDescription": "",
"scenarioName": "Sample Test"
}
How can i get the karate.info to be populated with errorMessage in case of failures when we use Scenario Outline
Maybe this is a bug. So please follow this process. Once we can replicate this, we will fix it: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue
Meanwhile see if the ExecutionHook gives you better results: https://stackoverflow.com/a/59080128/143475

How to check if ID in the URI is null and throw an error?

I tried to check if a specific URL doesn't specified an ID
This are what I've got so far:
http://localhost:8082/orders/1234 ---- Success!
http://localhost:8082/orders/ ---- URL not found!
I want to throw and error something like "Id not specified!" not a URL not found.
Look at Validation Module
Look at the "Matches Regex" section down.
I have not tried it
Hope it may help
the believe the best approach for you is to start using RAML. you can design the endpoint in RAML and specify what error to be thrown if the request is not a match.
/{order_id}:
get:
description: Get a Order by id
responses:
200:
body:
application/json:
type: Foo
example: !include examples/Order.json
400:
body:
application/json:
type: Error
example: !include examples/Error.json
in the above RAML definition if there is no orders/{order_id} you will get a http 400 returned.
Define a custom error handling and that will return error description alongside other required data
set status code 400 in a variable, map fields as per below example.
ex:
{
"error": {
"errorCode": "NOT_FOUND",
"errorDateTime": "2019-10-10T14:00:46",
"errorMessage": "The requested API cannot be found, ID is not specified",
"errorDescription": "Description: /orders"
}
}

Post request giving 400 bad request error in Karate with Json Parse error message

I am trying to post a json in the Body of a request.Before that i am reading it and then updating few keys using set method in Karate framework.however the test passses but in console i can see that its showing 400 bad request error
I verified all the required parameters in comparison with Postman . The same Post request set up in postman works as expected.
Background:
* json foojson = read ('foo.json')
* set foojson.foo = 'foo1'
* set foojson.foo4[0].foo7 = 'fooo8'
Scenario:
Given url
And headers
And json foo1json = foojson
And request foo1json
And print request
When method post
Then status 200
Please find the Json example as below
{
"foo": "",
"fooA": "",
"fooB": "",
"fooFoo": [
{
"foo1": "foo A",
"foo2": "foo AA",
"foo3": "foo AAAA",
"foo4": {
"foo5": " ",
"foo6": "foo AAAA",
"foo7": "foo AAAA"
},
"foo8": "foo AAAA",
"foo9": 0,
"foo10": 0,
"foo11": [
]
}
],
"fooC": "foo AAAA",
"fooD": [
],
"fooE": ""
}
Actual :
Scenario failed here
scenarios: 1 | passed: 0 | failed: 1 | time: 2.2143
but the trace shows the following:
DEBUG com.intuit.karate - response time in milliseconds: 2156.14
1 < 400
1 < Access-Control-Allow-Credentials: true
1 < Access-Control-Allow-Headers: Origin,Accept,X-Requested-With,Content-Type,Content-Disposition,Access-Control-Request-Method,Access-Control-Request-Headers,X-HTTP-Method-Override,
1 < Access-Control-Allow-Methods: POST, GET, HEAD, OPTIONS, PUT, PATCH, DELETE
1 < Access-Control-Max-Age: 3600
1 < Cache-Control: no-cache
1 < Connection: keep-alive
1 < Content-Security-Policy: child-src 'self'
1 < Content-Type: application/json;charset=UTF-8
The specific error as below:
{"timestamp":1557310988561,"traceId":"","path":"[POST] "",
"errors":[{"httpStatusCode":"BAD_REQUEST","code":"BAD_REQUEST",
"message":"JSON parse error: Cannot deserialize instance of foo out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of foo out of START_OBJECT token\n at [Source: (PushbackInputStream); line: 1, column: 1]"}]}
Please let me know if someone can help me on this
I verified all the required parameters in comparison with Postman
That is a very un-helpful statement. Now, regarding this error:
Cannot deserialize instance of foo out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException
It is very clear that the server has thrown this error, and it looks like Karate has sent JSON correctly, but you have not provided the request, so no-body can tell with the lack of information provided.
It really looks like Karate has found a bug in your server - which is the whole point of API testing :) So please check again.
If you still believe that there is some issue with Karate, please follow this process: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue