Scenario: I send an image_URL at my Request Body to an endpoint, and I would like to confirm image URL is loaded by asserting from the response (Easy peasy)
Background: Get ready
#Get random image via Java class
* def dataGenerator = Java.type('Com.helpers.DataGenerator')
* def randomImage = dataGenerator.getImage()
Scenario: Pass Image_URL, assert image URL is in the response
Given url myUrl
And request
"""
{
"image": { "upload_url": #(randomImage) },
}
"""
When method POST
* print "=========image URL============== " + response.metadata.image_url
* print "=========random Image============== " + (randomImage)
Then status 201
Then match response.metadata[*].image_url == (randomImage)
The response is something like this:
{
"metadata": {
....,
"image_url": "https://link/image.jpeg",
....}
}
My issue:
`"response.metadata.image_url"` from response is different than `(randomImage)`, hence assertion is failing.
When I manually run from the postman, Response "image_url" is matching with request body "upload url"
From my understanding,
* def randomImage should be called once before Every Scenario, so it should be the exact same entire Scenario during runtime.
Not sure if I am missing some obvious concept. Curious to see any guidance on this one
Versions:
<java.version>1.8</java.version>
<maven.compiler.version>3.8.1</maven.compiler.version>
<maven.surefire.version>2.22.2</maven.surefire.version>
<artifactId>karate-junit5</artifactId>
<karate.version>1.1.0</karate.version>
Also, my Java Helper class is working fine, but I can add it if needed.
Related
i have one feature file as
Feature: Getting the Token
Background:
header Content-Type 'application/json'
def CookieGenerator = Java.type('com.ade.Helpers.CookiesGenerator');
def endpoints read('classpath: src/test/java/com/ade/resources/endpoints.json')
Given url endpoints.token
Scenario: To check the Schema of the response
Given cookies (new CookieGenerator().getCookieValue())
When method GET
Then status 200
def txnToken = response
#print token
from above code i am getting Token's value as something like this "gdjsgjshjhsjfhsg646"
now i have another feature file where i have to use above Token's value in my query parameter value as
Feature: Testing datent Name and Client
Background:
header Content-Type 'application/json""
def endpoints read('classpath:src/test/java/com/ade/resources/endpoints.json") def CookieGenerator Java.type('com.ade.Helpers.CookiesGenerator");
call read('Token.feature')
Given url baseUrl+endpoints.dit.Client.path
Scenario: To check the Schema of the response
Given def head read('classpath:src/test/java/com/ade/resources/reqpay.json") =
def req head.data[1]
And cookies (new CookieGenerator().getCookieValue())
And request req
And param {txntoken = txnToken}
When method post
Then status 200
from above my endpoint should be like https://something.com/clients?txntoken='gdjsgjshjhsjfhsg646'
but i am getting as https://something.com/clients?txntoken=txnToken
https://something.com/clients?txntoken='gdjsgjshjhsjfhsg646'
Your post is hard to read, as #peter-thomas said, please try formatting it better in the future, or edit the post if I haven't answered your question.
I believe what you're looking for is described in the documentation here
* def signIn = call read('classpath:my-signin.feature') { username: 'john', password: 'secret' }
* def authToken = signIn.authToken
you can see how information can be passed
I also asked a similar question fairly recently here
relevant bit here:
* def key = karate.call('ReadRoundUpSubscription.feature');
* def keyvalue = key.acckey
i prefer to call features like this, and not defining things in the reusable feature.
HI there I am making post call using karate And for that I am passing json Payload but before i pass it i want to validate is there any null or empty string present and if yes then Abort the post call and print message empty string or null values cant be accepted.
Thanks in advance!
peter thomas Thank you in advance
This doesn't make sense to me, because if you are preparing this payload yourself, you never need to validate it.
That said, you can run a match anytime.
* def body = { myKey: 'myValue' }
* match body == { myKey: '#string' }
* url 'https://httpbin.org/anything'
* request body
* method post
* status 200
* match response contains deep { json: { myKey: 'myValue' } }
See how the second line does a validation.
Also refer this answer to see how you can programmatically run karate.match() for advanced use-cases: https://stackoverflow.com/a/50350442/143475
Whenever I try to call the feature file(one.feature) from another feature file(starter.feature), I am not able to access the info(caller) in specific scenario
But It is working fine and I am able to access info(caller),
when I run one.feature file standalone.
when I run one.feature file through Junit test case.
CODE WORK-FLOW :
In one.feature :
In the scenario(Scenario: matching two Strings) we are trying to match two Strings and configuring afterScenario JS function to get the info of the scenario and If the info contains any errors, The function will call the other scenario(Scenario: getting caller details) with info details assigned in the variable caller
starter.feature :
Feature: call another feature
Scenario: calling feature file
* def callFeat = call read('one.feature')
one.feature :
Feature: get details
Background:
* configure afterScenario =
"""
function() {
var info = karate.info;
if(info.errorMessage){
karate.call('one.feature#CallCaller', { caller : info });
}
}
"""
#CreateErrorMsg
Scenario: matching two Strings
* def Text1 = 'Hey'
* def Text2 = 'Hello'
* match Text1 == Text2
#CallCaller #ignore
Scenario: getting caller details
* print caller
Can't you use karate.log from the JS function rather than calling another scenario to just print the info? Also, note that karate.info has been deprecated from 1.0 version of Karate and replaced by karate.scenario - https://github.com/karatelabs/karate/wiki/1.0-upgrade-guide#karateinfo-deprecated
* configure afterScenario =
"""
function() {
var info = karate.info;
if(info.errorMessage){
karate.log(info.scenarioName);
}
}
"""
I want to assert responseTime of all scenarios. But i do not want to repeat the assertion code in every scenario. Below is my feature file:
Feature: Reqres api test cases
Background: base url
Given url base_url
Scenario: list single user get request
Given path single_user_path
When method get
Then status 200
And assert responseTime < 4000
Scenario: create user using post and inline json payload
* def path = '/users'
Given path path
And request {"name": "morpheus","job": "leader"}
When method post
Then status 201
And assert responseTime < 4000
In the above code block, I want to avoid responseTime assertion duplication. How to achieve this in karate?. Please help.
No this is not supported and not planned either. It is unlikely every API call will have the exact same SLA. Also this is what the Gatling integration is for: https://stackoverflow.com/a/55146463/143475
EDIT as an example of how you can do "reuse" of response assertions:
Feature:
Background:
* def validateResponse =
"""
function() {
var contentType = karate.get("responseHeaders['Content-Type'][0]");
if (contentType !== 'application/json') {
karate.fail('content type is not json');
}
var responseType = karate.get('responseType');
if (responseType !== 'json') {
karate.fail('response type is not json');
}
}
"""
Scenario:
* url 'https://httpbin.org/post'
* request { foo: 'bar' }
* method post
* validateResponse()
Please note that I absolutely don't recommend the above approach because of reasons best explained here: https://stackoverflow.com/a/54126724/143475
I'm trying to scrap a range of webpages but I got holes, sometimes it looks like the website fails to send the html response correctly. This results in the csv output file to have empty lines. How would one do to retry n times the request and the parse when the xpath selector on the response is empty ? Note that I don't have any HTTP errors.
you could do this with a Custom Retry Middleware, you just need to override the process_response method of the current Retry Middleware:
from scrapy.downloadermiddlewares.retry import RetryMiddleware
from scrapy.utils.response import response_status_message
class CustomRetryMiddleware(RetryMiddleware):
def process_response(self, request, response, spider):
if request.meta.get('dont_retry', False):
return response
if response.status in self.retry_http_codes:
reason = response_status_message(response.status)
return self._retry(request, reason, spider) or response
# this is your check
if response.status == 200 and response.xpath(spider.retry_xpath):
return self._retry(request, 'response got xpath "{}"'.format(spider.retry_xpath), spider) or response
return response
Then enable it instead of the default RetryMiddleware in settings.py:
DOWNLOADER_MIDDLEWARES = {
'scrapy.downloadermiddlewares.retry.RetryMiddleware': None,
'myproject.middlewarefilepath.CustomRetryMiddleware': 550,
}
Now you have a middleware where you can configure the xpath to retry inside your spider with the attribute retry_xpath:
class MySpider(Spider):
name = "myspidername"
retry_xpath = '//h2[#class="tadasdop-cat"]'
...
This won't necessarily retry when your Item's field is empty, but you can specify the same path of that field in this retry_xpath attribute to make it work.
You can set RETRY_TIMES setting in settings.py to the amount of times you wish the pages are retried. It defaults to 2 times.
See more on RetryMiddleware