I need to pass a parameter (part of URL) in a request for example:
"S;4;163;1;O;rAghjgjU="
But this value is extracted as a regular expression like that:
"S%3B4%3B163%3B1%3BO%3BrAghjgjU%3D"
I want to use BeanShell to decode the URL.
JMeter provides __urldecode() function so if you use it like:
${__urldecode(S%3B4%3B163%3B1%3BO%3BrAghjgjU%3D)}
you'll get the required value.
If you still want to go for Beanshell, you can invoke URLDecoder.decode(); method like:
String decoded = URLDecoder.decode("S%3B4%3B163%3B1%3BO%3BrAghjgjU%3D", "UTF-8");
There is also __Beanshell() function which allows executing arbitrary Beanshell script, invoke it like:
${__BeanShell(URLDecoder.decode("S%3B4%3B163%3B1%3BO%3BrAghjgjU%3D"\, "UTF-8"),)}
See How to Use BeanShell: JMeter's Favorite Built-in Component for more information on Beanshell scripting in JMeter, in particular pay attention to how Java and JMeter API classes are invoked from within Beanshell scripts.
Related
How can I pass values from Karate API to Java class?
As mentioned in the documentation, I used the following code snippet to get the response from Java API. But its returning the response with un-formatted JSON content.
Map<String, Object> result = CucumberRunner.runClasspathFeature("demo/java/from-java.feature", args, true);
And then, I used the following script to print the response.
for(Map.Entry<String , Object> entry: getMbrWksMembershipDetailsResponse.entrySet())
{
if (entry.getKey().equalsIgnoreCase("response"))
{
System.out.println(entry.getValue());
}
}
It shows like,
{soap:Envelope={_={soap:Body={ns1:getMbrWksMembershipDetailsResponse={_={ns4:WksMembershipSummaryResponse={_={ns2:customerSummary={ns2:address={ns2:city=SOUTH CHESTERFIELD, ns2:country=USA, ns2:isoCountryCode=US, ns2:line1=9998, N. MICHIGAN ROAD., ns2:postalCode=23834, ns2:state=VA}, ns2:allowPasswordChange=true, ns2:arpMember=false, ns2:brandCode=RCI, ns2:brandId=1, ns2:companyCode=RCI, ns2:eliteMemberRewardStatus=false, ns2:eliteRewardStatus=true, ns2:europePointsClubMember=false, ns2:firstName=FRANK, ns2:homePhone=804/733-3004, ns2:isoCurrencyCode=USD, ns2:isoLanguageCode=EN, ns2:language=EN, ns2:lastName=BROWNING B, ns2:locale=en_US, ns2:memberDeveloperRenewed=false, ns2:memberEnrolledDate=2009-10-26T00:00:00-04:00, ns2:memberEnrolledForDirectDebit=false, ns2:memberEnrolledForPltDirectDebit=false, ns2:memberStatus=A, ns2:middleName=B, ns2:msgTranslationLanguageCode=EN, ns2:officePhone=0/-0, ns2:pointsCurrencyCode=0......
So it's little difficult to split the data based on the fields / tags from Map.
Please suggest what is the best option to get the values field wize / tag wise from Java API.
Thanks.
Yes, XML is internally held as a strange Map structure, refer to the section on type-conversion to understand more.
You have a simple way to do this. Just define a new variable that is the response converted to a string.
* xmlstring responseXml = response
After this you just need to get the responseXml out of the Map returned by the Java API which will be a string.
Note: don't use the Java API unless you are really trying to mix Karate with something else. The whole point of Karate is to avoid using Java for testing JSON and XML web-services.
Jmeter passes default value when trying to fetch a part of response in my case is a unique name which I want to pass in next request but it takes default value:
{"status":"success","body":{"uniqueName":"jpr1444130495897","voucherType":"sales","transactions":[{"creditAccount":{"uniqueName":"acctomerge","name":"Mayank"},"debitAccount":{"uniqueName":"dacc","name":"dummyaccount"},"amount":2228}],"voucherNo":1912,"date":"01-09-2015","tag":"dummydata","description":"Q3goK8QrUo"}}
In above response I have to capture uniquename & pass it in my next request. But by default it take default value.
Bean shell assertion contains:
${__setProperty(uniqueName,${uniqueName})}
Next request is this.
Still fetching default value. Somebody please help.
As Biffen said it is better to use JSON Path Extractor that comes with jmeter plugins (http://jmeter-plugins.org/wiki/JSONPathExtractor/). It's a lot easier for JSON - just put JSON path (probably in your case just uniqueName will be enough, but you can put there $.body.uniqueName) add a variable name as uniqueName as well, so there will be no problem to use it later as ${uniqueName} in the next request. And that's it.
Oh, and your post suggests that you try to extract it with Beanshell assertion instead of Regular Expression Extractor by the way - that also can be a case.
What exact uniqueName you need to extract? There are 3 of them in your JSON data:
jpr1444130495897
acctomerge
dacc
It isn't necessary to convert variable to property to use in next request. If both requests live in the same thread group - it's enough to use reference name like ${uniqueName}
For JSON data it's more handy to use JSON Path Extractor (available via JMeter Plugins project). See Using the XPath Extractor in JMeter guide (scroll down to "Parsing JSON") for plugin installation and usage instructions.
My end goal here is to get a string from a list that is created dynamically from a JSON response. I am having troubles calling a value from the list that is created in an external BeanShell script. The external script reads the JSON response and creates the list from the filtered response.
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Filter;
try{
String json = new String(prev.getResponseDataAsString());
List allPositiveAffects = JsonPath.read(json, "$.affectTags[?(#.value > 0.0)].key", new Filter[]{});
vars.putObject("allPositiveAffects",allPositiveAffects);
log.info("allPositiveAffects: " + allPositiveAffects);
int positiveAffectCount = allPositiveAffects.size();
vars.put("positiveAffectCount",Integer.toString(positiveAffectCount));
} catch (Throwable ex){
log.error("Error:\n", ex);
}
allPositiveAffects returns the expected values, so now I want to get one of those values into a subsequent JSON POST.
My Jmeter test setup:
- Thread Group
+ JSON GET request
- BeanShell PostProcessor
+ JSON POST request
Attempting to get a value from allPositiveAffects has proven to be not as easy as calling allPositiveAffects.get(n) like I can within my BeanShell script.
I haven't figured out an easy way to get the contents of the Lists. Am I missing something? I have tried several different things in my JSON POST request. The latest being:
//json POST data
{
"entries":[
"id": -1,
"key": "${__BeanShell(${allPositiveAffects}.get(1))}"]
}
Which returns the following error:
java.lang.ClassCastException: net.minidev.json.JSONArray cannot be cast to java.lang.String
Any help on a solution or workaround for this would be greatly appreciated. It would be a lot easier for me to be able to call a List instead of creating various variables.
I believe that you could just add .toString() to your expression like:
`${__BeanShell(${allPositiveAffects}.get(1).toString())}`
By the way, Beanshell has some performance overhead so I would rather suggest going for JSON Path Extractor which is available via Extras with Libs Set of JMeter Plugins package, it should be more convenient and less resource consuming.
See Using the XPath Extractor in JMeter (scroll down to "Parsing JSON") for installation instructions and some JSON Path language reference examples.
I am creating a web service with play framework and scala. The service get a url and a language, and use this information, but i can't put a url into the service.
I have this in routes
GET /trans/$url<(http%3A%2F%2Fa)>/:lang controllers.Application.getTranslation(url:String, lang:String)
and in Application:
def getTranslation(iri: String,lang:String) = Action { implicit request =>
etc.
and i want to receive something like
'/trans/htp://a/es' (its http instead of htp but i can't write it here)
is it posible? Because i've tried everything and i'm not able. is ther ane way to pass a url as parameter?
You have to url escape and unescape on both sides. It is called URL Encoding or Percent Encoding (because escaped character are rewritten using a combination that start with %)
https://en.wikipedia.org/wiki/Percent-encoding
Here is a question that give you information if your client side is in js:
Encode URL in JavaScript?
And here is nice scala library that can be used to encode and decode URL persent encoding.
https://github.com/theon/scala-uri
I have started scala myself (most of my prod work on playframework is still in Java), so I do not know if there is a better scala uri library out there.
EDIT :
You got me curious so I searched a bit:
http://www.motobit.com/util/url-encoder.asp
you should be carefull about the encoding on both sides.
I would like to fetch a source of file and wrap it within JSONP.
For example, I want to retrieve pets.txt as text from a host I don't own. I want to do that by using nothing but client-side JavaScript.
I'm looking for online service which can convert anything to JSONP.
YQL
Yahoo Query Language is one of them.
http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D"http://elv1s.ru/x/pets.txt"&format=json&callback=grab
This works if URL is not blocked by robots.txt. YQL have respect to robots.txt. I can't fetch http://userscripts.org/scripts/source/62706.user.js because it blocked via robots.txt.
http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D"http://userscripts.org/scripts/source/62706.user.js"&format=json&callback=grab
"forbidden":"robots.txt for the domain disallows crawling for url: http://userscripts.org/scripts/source/62706.user.js"
So I'm looking for another solutions.
I built jsonpwrapper.com.
It's unstable and slower than YQL, but it doesn't care about robots.txt.
Here's another one, much faster, built on DigitalOcean & CloudFlare, utilizing caching et al: http://json2jsonp.com
Nononono. No. Just please; no. That is not JSONP, it is javascript that executes a function with an object as its parameter that contains more javascript. Aaah!
This is JSON because it's just one object:
{
'one': 1,
'two': 2,
'three':3
}
This is JSONP because it's just one object passed through a function; if you go to http://somesite/get_some_object?jsonp=grab, the server will return:
grab({
'one': 1,
'two': 2,
'three':3
});
This is not JSON at all. It's just Javascript:
alert("hello");
And this? Javascript code stored inside a string (ouch!) inside an object passed to a function that should evaluate the string (but it might or might not):
grab({"body": "alert(\"Hello!\");\n"});
Look at all those semicolons and backslashes! I get nightmares from this kind of stuff. It's like a badly written Lisp macro because it's much more complicated than it needs to (and should!) be. Instead, define a function called grab in your code:
function grab(message) {
alert(message.body);
}
and then use JSONP to have the server return:
grab({body: "Hello!"});
Don't let the server decide how to run your web page Instead, let your web page decide how to run the web page and just have the server fill in the blanks.
As for an online service that does this? I don't know of any, sorry
I'm not sure what you're trying to do here, but nobody will use something like this. Nobody is going to trust your service to always execute as it should and output expected JavaScript code. You see Yahoo doing it because people trust Yahoo, but they will not trust you.