How to obtain response to be used on hooks - karate

I am trying to make a simplified version of test report where I am generating a single HTML file report containing only assertion and error response message when there is any (attempting to not publish all the logs and steps).
I understand that we have hooks in karate. However I have looked for karate objects in the github but unable to found any objects where I can extract the response from (to be passed to the js function called on hook)
What I am doing right now is this:
Config:
//karate-config.js
karate.configure('afterScenario', karate.call('classpath:hooks.js'));
Hook:
//hooks.js
//Looking on how to extract the response and log it here
function(){
var info = karate.tags;
karate.log('Tags', info);
}
Am I missing anything on the karate objects? Or this should be achieved in another way?
Thanks a lot!

Try this:
var response = karate.get('response');
EDIT better example:
Background:
* configure afterScenario = function(){ karate.log('***', karate.get("response.headers['X-Karate']")) }
Scenario:
Given url 'http://httpbin.org'
And path 'headers'
And header X-Karate = 'test'
When method get
# this will fail
Then status 400
I have tried with both karate.get('response') and response directly, and both work. If you use karate.call() pass the response as a parameter.

Related

Unable to convert rest assured test to karate test

I am trying to migrate one of api test to karate framework. However I am unable to write the corrent step defined in karate documentation. Maybe I am missing some basic syntax..but could anyone have any idea how we write following steps in karate feature
requestPostDoc.header("x-api-key","FG6dcYHN9N7PYKfWCUlGo5QGTwZhv2Re1MrDSOTV");//New chnages
requestPostDoc.contentType("multipart/form-data").multiPart("part2-file",file).formParam("part1-json",objDocumentWrite.toJSONString());
requestPostDoc.queryParam("loadProperties",true); //New changes
responseForNewCaseDocFile=requestPostDoc.post("https://vrh0oox3hl.execute-api.eu-central-1.amazonaws.com/default/");//New changes
filterableRequestSpecification = (FilterableRequestSpecification) requestPostDoc;
filterableRequestSpecification.removeQueryParam("loadProperties");
I have written following feature file in karate:
Given url 'https://vrh0oox3hl.execute-api.eu-central-1.amazonaws.com/default/'
And header x-api-key = 'FG6dcYHN9N7PYKfWCUlGo5QGTwZhv2Re1MrDSOTV'
And header Authorization = 'Bearer ' + jwt
And param loadProperties = true
And multipart file info = { read: 'classpath:testData/documentWrite.json', filename: 'documentWrite.json' }
And multipart file Uploading = { read: 'classpath:testData/TextFile.txt', filename: 'TextFile.txt' }
When method post
Then print response
Then status 200
When I execute this test i am getting 400 response code
status code was: 400, expected: 200, response time in milliseconds: 252, url: https://vrh0oox3hl.execute-api.eu-central-1.amazonaws.com/default/?loadProperties=true, response:
Based on the cURL command in the comments, this is my best guess. The rest is up to your research. Read the docs and tweak the Content-Type and other sub-headers if needed. You need to figure this out depending on what your server wants: https://github.com/karatelabs/karate#multipart-file
* multipart file part1-json = { read: 'documentWrite.json' }
* multipart file part2-file = { read: 'TextFile.txt' }
For anyone coming across this question in the future and if you are stuck, get a friend if needed and go through this exercise together: https://github.com/karatelabs/karate/issues/1645#issuecomment-862502881
This stuff can be hard and needs time. There are no short cuts.

SoapUI correlation (property transfer)

I have a REST request that respond with the following:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IlQwWE8xNnAtMmZzMWxremV5",
"expires_in": 2592000,
"token_type": "Bearer"
}
I want to take the value of access_token, store it in a property and reuse it for two subsequent requests.
Following some tutorial here, when running the request that obtains the access_token I get a:
error parsing target property: error unexpected element CDATA
But why?
There is no CDATA in my raw response.
If you've problems using transfer properties step to get the JSON value from your response, you can use a groovy test step to achieve your goal.
So create a groovy test step to parse your response, get your value and set it as a property (for example at testCase level) with the follow code:
import groovy.json.JsonSlurper
// get response using the name of your test step
def response = context.expand('${REST Test Request#Response}')
// parse response
def jsonResp = new JsonSlurper().parseText(response)
// get the token an set as a property in the testCase
testRunner.testCase.setPropertyValue('access_token',jsonResp.access_token)
Then in the other testSteps (REST or SOAP...) you can use the follow code to get the access_token value you set in the testCase:
${#TestCase#access_token}
Hope this helps,

What's the easiest way to display content depending on the URL parameter value in DocPad

I'd like to check for an URL parameter and then display the confirmation message depending on it.
E.g. if I a GET request is made to /form?c=thankyou docpad shows the form with thank you message
I think there is two basic ways to do this.
look at the url on the server side (routing) and display differing content according to URL parameters
Look at the parameter on the client side using JavaScript and either inject or show a dom element (eg div) that acts as a message box.
To do this on the server side you would need to intercept incoming requests in the docpad.coffee file in the serverExtend event. Something like this:
events:
# Server Extend
# Used to add our own custom routes to the server before the docpad routes are added
serverExtend: (opts) ->
# Extract the server from the options
{server} = opts
docpad = #docpad
# As we are now running in an event,
# ensure we are using the latest copy of the docpad configuraiton
# and fetch our urls from it
latestConfig = docpad.getConfig()
oldUrls = latestConfig.templateData.site.oldUrls or []
newUrl = latestConfig.templateData.site.url
server.get "/form?c=thankyou", (req,res,next) ->
document = docpad.getCollection('documents').findOne({relativeOutPath: 'index.html'});
docpad.serveDocument({
document: document,
req: req,
res: res,
next: next,
statusCode: 200
});
Similar to an answer I gave at how to handle routes in Docpad
But I think what you are suggesting is more commonly done on the client side, so not really specific to Docpad (assumes jQuery).
if (location.search == "?c=thankyou") {
$('#message-sent').show();//show hidden div
setTimeout(function () {
$('#message-sent').fadeOut(1000);//fade it out after a period of time
}, 1000);
}
This is a similar answer I gave in the following Docpad : show error/success message on contact form
Edit
A third possibility I've just realised is setting the document to be dynamically generated on each request by setting the metadata property dynamic = true. This will also add the request object (req) to the template data passed to the page. See Docpad documentation on this http://docpad.org/docs/meta-data.
One gotcha that gets everyone with setting the page to dynamic is that you must have the docpad-plugin-cleanurls installed - or nothing will happen. Your metadata might look something like this:
---
layout: 'default'
title: 'My title'
dynamic: true
---
And perhaps on the page (html.eco):
<%if #req.url == '/?c=thankyou':%>
<h1>Got It!!!</h1>
<%end%>

Using Node JS to proxy http and modify response

I'm trying to write a front end to an API service with Node JS.
I'd like to be able to have a user point their browser at my node server and make a request. The node script would modify the input to the request, call the api service, then modify the output and pass back to the user.
I like the solution here (with Express JS and node-http-proxy) as it passes the cookies and headers directly from the user through my site to the api server.
proxy request in node.js / express
I see how to modify the input to the request, but i can't figure out how to modify the response. Any suggestions?
transformer-proxy could be useful here. I'm the author of this plugin and I'm answering here because I found this page when looking for the same question and wasn't satisfied with harmon as I don't want to manipulate HTML.
Maybe someone else is looking for this and finds it useful.
Harmon is designed to plug into node-http-proxy https://github.com/No9/harmon
It uses trumpet and so is stream based to work around any buffering problems.
It uses an element and attribute selector to enable manipulation of a response.
This can be used to modify output response.
See here: https://github.com/nodejitsu/node-http-proxy/issues/382#issuecomment-14895039
http-proxy-interceptor is a middleware I wrote for this very purpose. It allows you to modify the http response using one or more transform streams. There are tons of stream-based packages available (like trumpet, which harmon uses), and by using streams you can avoid buffering the entire response.
var httpProxy = require('http-proxy');
var modifyResponse = require('http-proxy-response-rewrite');
var proxy = httpProxy.createServer({
target:'target server IP here',
});
proxy.listen(8001);
proxy.on('error', function (err, req, res) {
res.writeHead(500, {
'Content-Type': 'text/plain'
});
res.end('Something went wrong. And we are reporting a custom error message.');
});
proxy.on('proxyRes', function (proxyRes, req, res) {
modifyResponse(res, proxyRes.headers['content-encoding'], function (body) {
if (body && (body.indexOf("<process-order-response>")!= -1)) {
var beforeTag = "</receipt-text>"; //tag after which u can add data to
// response
var beforeTagBody = body.substring(0,(body.indexOf(beforeTag) + beforeTag.length));
var requiredXml = " <ga-loyalty-rewards>\n"+
"<previousBalance>0</previousBalance>\n"+
"<availableBalance>0</availableBalance>\n"+
"<accuruedAmount>0</accuruedAmount>\n"+
"<redeemedAmount>0</redeemedAmount>\n"+
"</ga-loyalty-rewards>";
var afterTagBody = body.substring(body.indexOf(beforeTag)+ beforeTag.length)+
var res = [];
res.push(beforeTagBody, requiredXml, afterTagBody);
console.log(res.join(""));
return res.join("");
}
return body;
});
});

unable to get the cross domain json response using script tag proxy

I am using a script tag proxy like this:
Ext.regModel('login',{fields:['status']});
var loginstore = new Ext.data.Store({ model:'login', proxy:{type:'scripttag',url:'myurl',reader:{type:'json',root:'data'}},autoLoad : true,});
loginstore.load();
In that, the url will return the response format below:
{"data":{"status":"error"}}
I am getting the error:
unexpected token :
Why am I getting this error? What are all the other ways to get the json response from cross domain without callback key and yql.
You cannot use scripttagproxy like that. Please have a look at this thread.
After you configure your server and callback function. You might want to try simpler method to call your cross-domain request as follows.
Ext.util.JSONP.request({
url: some_cross_domain_url,
params: {param1: "something", param2: ...}
callback:function(response){
//response here will be JSON object.
}
});
Please also have a look at this simple tutorial about how to configure your JSONP request.