Is there a way to assert and fail a request after polling in karate? - karate

I have a request where i get Processing or Submitted in a response parameter if the request is in process or passed respectively.
I am able to poll and get if the status is "Processing" or"Submitted" but after that I am unable to fail the request if still i am not getting the expected status after polling for 5 times.
How can i fail request after certain retries do not provide me expected response?

The answer is in your question,
I assume you are polling using a js function,
If so you can add a boolean return from that, if you condition not met return false or if condition met return true then assert the value returned from your feature file.
* def pollingFunc =
"""
function(x) {
// your polling logic which retrives status
if (status == x) {
return true;
}
else{
return false;
}
}
"""
In feature
* def statusFound = pollingFunc("Processed" )
* assert (statusFound == true)
If the expected status not obtained after polling the assert will fail the test

Related

Roblox - Call external GraphQL API

I would like to call an external graphql API (without authentication for the moment).
Here is my code :
local open_api = "https://graphqlzero.almansi.me/api"
local payload = '{"query": "query { post(id: 1) { id title body }}"}'
local headers = {
}
local function craftCall()
local response
local data
pcall(function ()
response = HttpService:PostAsync(open_api, payload, Enum.HttpContentType.ApplicationJson, false, headers)
data = HttpService:JSONDecode(response)
end)
if not data then return false end
print(data)
return false
end
if craftCall() then
print("Success")
else
print("Something went wrong")
end
I get always something went wrong. I need some help on what is going wrong... Specially I don't know if am I correctly formatting the Payload.
After your http call, you never return a success result. You've only outlined failure cases :
if not data then return false end
print(data)
return false
So your conditional, if craftCall() then always evaluates to false.
Why not make it return true or data after the print(data)? Then you'll know that it made it to the end of the call successfully.
local function craftCall()
local success, result = pcall(function()
local response = HttpService:PostAsync(open_api, payload, Enum.HttpContentType.ApplicationJson, false, headers)
return HttpService:JSONDecode(response)
end)
if not success then
warn("PostAsync failed with error : ", result)
return false
end
-- return the parsed data
return result
end

Karate SAXParseException when logPrettyResponse is true and response content type is 'text/turtle'

It looks like a bug but asking the question just in case I have missed something.
Karate version is 1.1.0
The post request is as below. Note that content type is text/turtle and I use logPrettyResponse because further requests in test are testing RDF/XML and other serialisations.
* configure logPrettyResponse = true
Given path '/graph'
* text payload =
"""
<http://example.com/a7460f22-561a-4dde-922b-665bd9cf3bd9> <http://schema.org/description> "Test"#en.
"""
And request payload
And header Accept = 'text/turtle'
And header Content-Type = 'text/turtle'
When method POST
Then status 200
And I get below error
ERROR com.intuit.karate - org.xml.sax.SAXParseException; lineNumber: 2; columnNumber: 8; Element type "http:" must be followed by either attribute specifications, ">" or "/>"., http call failed
Reason this seems to be happening is that fromString method in JsValue.java is trying to parse turtle as XML because condition case '<' is true when response is turtle.
public static Object fromString(String raw, boolean jsonStrict, ResourceType resourceType) {
String trimmed = raw.trim();
if (trimmed.isEmpty()) {
return raw;
}
if (resourceType != null && resourceType.isBinary()) {
return raw;
}
switch (trimmed.charAt(0)) {
case '{':
case '[':
return jsonStrict ? JsonUtils.fromJsonStrict(raw) : JsonUtils.fromJson(raw);
case '<':
if (resourceType == null || resourceType.isXml()) {
return XmlUtils.toXmlDoc(raw);
} else {
return raw;
}
default:
return raw;
}
}
To solve the problem I have set logPrettyResponse to false. I would love to know if anyone has any other thoughts or if someone can confirm that it is a bug?

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

GetOverlappedResult return true,but no data write

I check async write with following code.
BOOL bOk = ::GetOverlappedResult(hFile, pOverlapped, dwBytesTransferred, TRUE);
if ( FALSE == bOk )
{
TRACE_ERROR_NO_ASSERT(GetOverlappedResult);
}
bOk is TRUE, but dwBytesTransferred is 0, and pOverlapped->Internal is 258(timeout).
my questionn is : is my async operation timeout and will be finished later? or just failed? should I call CancelIo to cancel this timeout operation like this?
BOOL bOk = ::GetOverlappedResult(hFile, pOverlapped, dwBytesTransferred, TRUE);
if ( FALSE == bOk )
{
TRACE_ERROR_NO_ASSERT(GetOverlappedResult);
return FALSE;
}
if ( 0 == dwBytesTransferred )
{
CancelIoEx(hFile, pOverlapped); // is this neccessary?
}
I refer the MSDN document, but no description for this condition.
thanks in advance.
your operation is finished (failed) with STATUS_TIMEOUT - this is final status and operation complete. you not need and can not cancel it - it finished. that GetOverlappedResult return TRUE and not set error code - this is only bad (I be say error) design of this win32 api. it unconditionally return TRUE and not set last error if (0 <= status). as result it wrong process STATUS_TIMEOUT (I think you worked with serial (com) port).
so formal answer:
your operation finished.
you should not call CancelIo
however i think that use GetOverlappedResult for asynchronous i/o at all no sense. need use apc or iocp completion.

Can I override RESTClient default "HttpResponseException" response to >399 Return Codes?

I'm using the Groovy RESTClient class to do write some (spock) Acceptance tests for Java WebServices I've been authoring.
One frustration I've had is in testing the responses...
200 Status's are easy:
when: def result = callServiceWithValidParams()
then: result.status == 200
But with 400+ I'm forced to either wrap in a try-catch, or test for the HttpResponseException that RESTClient throws by default.
when:
callWithInvalidParams()
then:
def e = thrown(Exception)
e.message == 'Bad Request'
This is sort-of OK, if a little frustrating... but I want to do better.
Ideally, I want my tests to more resemble this
(might be confusing if you don't use groovy/spock)
#Unroll
def "should return #statusCode '#status' Response"()
{
when:
def result = restClient.get(path: PATH, query: [param: parameter])
then:
result.status == statusCode
where:
status | statusCode | parameter
'OK' | 200 | validParam
'Bad Request' | 400 | invalidParam
}
In the above example, the 'Bad Request' case fails. Instead of returning a value, restClient.get() throws HttpResponseException
#JonPeterson came up with what I think is a better solution, so I gave his answer the checkmark:
client.handler.failure = client.handler.success
More info here
The solution I (previously) landed on:
restClient.handler.failure = { it }
Which is shorthand for
restClient.handler.failure = { resp -> return resp }
#JimmyLuong noted in the comments that this approach drops the data from the response, and suggested the following enhancement:
restClient.handler.failure = { resp, data -> resp.setData(data); return resp }
As Tomasz already linked in a comment, here is my little one-liner answer from a similar question.
client.handler.failure = client.handler.success
One approach would be to make a Groovy convenience method that wraps your REST calls that catches exceptions and turns them into status codes