Count redirects in jmeter - redirect

At the moment im usig HTTP request sampler with 'Follow Redirects' enabled and want to keep it that way. As a secondary check besides assertion i want to count the number of redirects as well, but i dont want to implement this solution.
Is there a way when i can use only 1 HTTP sampler and a postprocessor (beanshell for now) and fetch this information? Im checking SamplerResult documentation , but cant find any method which would give back this information for me.

I heard Groovy is new black moreover users are encouraged to use JSR223 Test Elements and __groovy() function since JMeter 3.1 as Beanshell performs not that well so you can count the redirects as follows:
Add JSR223 PostProcessor as a child of your HTTP Request sampler
Put the following code into "Script" area:
int redirects = 0;
def range = new IntRange(false, 299, 400)
prev.getSubResults().each {
if (range.contains(it.getResponseCode() as int)) {
redirects++;
}
}
log.info('Redirects: ' + redirects)
Once you run your test you will be able to see the number of occurred redirects in jmeter.log file:

Add the following Regular Expression Extractor as a child of your sampler:
Apply to: Main sample and sub-samples
Field to check: Response code
Regular Expression: (\d+)
Template: $1$
Match No.: -1
Then add a BeanShell Post Processor also as a child of the sampler and add the following to the script area:
int matchNr = Integer.parseInt(vars.get("MyVar_matchNr"));// MyVar is the name of the variable of the above regular expression extractor
int counter = 0;
for(i=1; i <= matchNr; i++){
String x = vars.get("MyVar_"+i);
if(x.equals("302")){
counter = counter + 1;
}}
log.info(Label + ": Number of redirects = " + String.valueOf(counter));// The output will be printed in the log like this(BeanShell PostProcessor: Number of redirects = 3 ) so you might want to change the name of the beanshell post processor to the same name of your sampler.
Then you can see the number of redirects for the sampler in the log.

Related

I need to add multiple contains assertion in my REST API test Steps using Groovy Script

I have to check ever parameter of my response using Contains Assertion, there are approx 20 parameter. I added few using setToken(), but it's difficult to write this for 20 times. Is there any other method using which I can add all parameter in few lines of code?
I have written below code for adding few assertions
def addassert = testSteps.addassertion("Contains")
addassert.setToken("totalCases")
addassert.setName("Total Cases")
addassert = testSteps.addassertion("Contains")
addassert.setToken("numberofChains")
addassert.setName("No Of Chains")
addassert = testSteps.addassertion("Contains")
addassert.setToken("numberofOutlets")
addassert.setName("No Of Outlets")
addassert = testSteps.addassertion("Contains")
addassert.setToken("expiringToday")
addassert.setName("Exp Today")

How can I can list of alerts associated with scan rules in OWASP ZAP?

I want to get the list of alerts in a tabular form like below. I copy the URL's in the alerts and manually prepare such a tabular table myself. However, I need to do this automatically or semi-automatically (at least)
Alert Name URL Scan Type Scan_Name WASCID CWEID
---------- --------------- --------- --------- ----- ------
You can export the report in XML and apply any kind of XSL transform to it that you might like.
You could pull the XML report into Excel (or whatever spreadsheet program) and manipulate it.
You could pull alerts from the web API and have them in XML or json and process them however you like programmatically.
You could write a standalone script (within ZAP) to traverse the Alerts tree and output the details tab delimited in the script console pane. For example:
extAlert = org.parosproxy.paros.control.Control.getSingleton().
getExtensionLoader().getExtension(
org.zaproxy.zap.extension.alert.ExtensionAlert.NAME)
extPscan = org.parosproxy.paros.control.Control.getSingleton().
getExtensionLoader().getExtension(
org.zaproxy.zap.extension.pscan.ExtensionPassiveScan.NAME);
var pf = Java.type("org.parosproxy.paros.core.scanner.PluginFactory");
printHeaders();
if (extAlert != null) {
var Alert = org.parosproxy.paros.core.scanner.Alert;
var alerts = extAlert.getAllAlerts();
for (var i = 0; i < alerts.length; i++) {
var alert = alerts[i]
printAlert(alert);
}
}
function printHeaders() {
print('AlertName\tSource:PluginName\tWASC\tCWE');
}
function printAlert(alert) {
var scanner = '';
// If the session is loaded in ZAP and one of the extensions that provided a plugin for the
// existing alerts is missing (ex. uninstalled) then plugin (below) will be null, and hence scanner will end-up being empty
if (alert.getSource() == Alert.Source.ACTIVE) {
plugin = pf.getLoadedPlugin(alert.getPluginId());
if (plugin != null) {
scanner = plugin.getName();
}
}
if (alert.getSource() == Alert.Source.PASSIVE && extPscan != null) {
plugin = extPscan.getPluginPassiveScanner(alert.getPluginId());
if (plugin != null) {
scanner = plugin.getName();
}
}
print(alert.getName() + '\t' + alert.getSource() + ':' + scanner + '\t' + alert.getWascId() + '\t' + alert.getCweId());
// For more alert properties see https://static.javadoc.io/org.zaproxy/zap/2.7.0/org/parosproxy/paros/core/scanner/Alert.html
}
Produces script console output like (note the 2nd, 6th, and 7th rows the specific alert name differs from the general scanner name):
Alert_Name Source:PluginName WASC CWE
Cross Site Scripting (DOM Based) ACTIVE:Cross Site Scripting (DOM Based) 8 79
Non-Storable Content PASSIVE:Content Cacheability 13 524
Content Security Policy (CSP) Header Not Set PASSIVE:Content Security Policy (CSP) Header Not Set 15 16
Server Leaks Version Information via "Server" HTTP Response Header Field PASSIVE:HTTP Server Response Header Scanner 13 200
Server Leaks Information via "X-Powered-By" HTTP Response Header Field(s) PASSIVE:Server Leaks Information via "X-Powered-By" HTTP Response Header Field(s) 13 200
Non-Storable Content PASSIVE:Content Cacheability 13 524
Timestamp Disclosure - Unix PASSIVE:Timestamp Disclosure 13 200
Which pastes well in Excel:
Detailed steps:
(This assumes ZAP is running, and the session you want information for is open/loaded).
1. Goto the scripts tree (behind the Sites Tree) [if you can't see it
click the plus sign near the Sites Tree tab and add "Scripts"].
2. In the Scripts tree right click "Standalone" and select "New Script":
give it a name and select the JavaScript Script Engine ("EcmaScript
: Oracle Nashorn") [no Template is necessary]. Click "Save" on the New
Script dialog.
3. In the new script window (in the request/response area) paste the script
from the answer.
4. Run it (the blue triangle play button above the script
entry pane).
5. The results will display in the output pane below the
script.
6. Copy/paste the output into Excel.

How do i pass ## separated values in Scala?

Consider the following scenario:
["123##456","789##101112","131415##161718","192021##222324"]
first-id: 123, second-id: 456...
I get the above as two different sets of ids in the JSON payload of my response.
Saving the values via
.check(jsonPath("$.data[*].Id").findAll.saveAs("Id"))
works perfectly fine for me.
But now I need to pass the above-mentioned ids in the next request of post method, which comes as
["123##456","789##101112","131415##161718","192021##222324"]
So how to achieve that? If you could explain with an example please?
You could use split, something like:
var data = Array("123##456","789##101112","131415##161718","192021##222324");
for(i <- 0 until data.length){
var ids = data(i).split("##");
println("first id is: " + ids(0));
println("second id is: " + ids(1));
}

Groovy script for count value matches with offset

<... count="6" offset="3,2,7,1,4,5"/>
from the above snippet, i want to verify number of offset values should get match with count value. Please help to get SOAPUI REST services groovy script for this one.
Thanks!
Your question it's not clear so supposing that you've something like:
<myTag count="6" offset="3,2,7,1,4,5"/>
You can use XmlSlurper in groovy script to validate your requirement as follows:
def xmlStr = '<myTag count="6" offset="3,2,7,1,4,5"/>'
def xml = new XmlSlurper().parseText(xmlStr)
// use # notation to acces attributes
def count = xml.#count
def offset = xml.#offset.toString().split(',')
// assert that count matches the length of the array
assert count == offset.length
Anyways consider to provide more details and what you tried as #Opal suggest in it's comment.
Hope it helps,

Selenium IDE - always fail on any 500 error

Is there an easy way to tell Selenium IDE that any action that results in a http 500 response means the test failed?
I have tests that are 75 page requests long. Sometimes, I get a crash and burn somewhere in the middle, but the tests come back green.
Taking a look at selenium-api.js, I saw that there is a parameter ignoreResponseCode in the signature of the doOpen method in selenium-api.js :
Selenium.prototype.doOpen = function(url, ignoreResponseCode) {
This parameter is used by the browserbot object :
if (!((self.xhrResponseCode >= 200 && self.xhrResponseCode <= 399) || self.xhrResponseCode == 0)) {
// TODO: for IE status like: 12002, 12007, ... provide corresponding statusText messages also.
LOG.error("XHR failed with message " + self.xhrStatusText);
e = "XHR ERROR: URL = " + self.xhrOpenLocation + " Response_Code = " + self.xhrResponseCode + " Error_Message = " + self.xhrStatusText;
self.abortXhr = false;
self.isXhrSent = false;
self.isXhrDone = false;
self.xhrResponseCode = null;
self.xhrStatusText = null;
throw new SeleniumError(e);
}
I've tried calling the open function from selenium IDE with value = false and this results in an error (test failed).
My PHP test page was :
<?php
header('HTTP/1.1 500 Simulated 500 error');
?>
And this results in :
For me, this solves the problem of checking HTTP response status.
Make a JavaScript file called "user-extensions.js" and add it to the Selenium-IDE under Options > Options. If you are running Selenium RC, pass it into the parameter when starting up your server in the jar command. There should be a user extensions javascript file attribute.
Then close and restart Selenium-IDE. The User-Extensions file is cached when the IDE starts up.
Add this code to your Selenium user-extensions.js file to make a custom command called "AssertLocationPart". As you know "assertLocation" and "storeLocation" are standard commands. I tried to reduce the extra line of code to storeLocation just by getting the href in the custom function. I wasn't able to get the doAssertValue command to work. I'll have to post my own question for that. That's why it's commented out. For now, just use "this.doStore" instead. And add an extra line to your script after your custom AssertLocationPart command. Since we're not actually doing an assertion in the custom function/command, we should call it "storeLocationPart" (function would be named "doStoreLocationPart"), not "assertLocationPart" (function would be named "doAssertLocationPart"), and just pass in the first parameter. But if you can get the doAssert* to work, please let me know. I'll mess with it another day since I need to do this same thing for work.
Selenium.prototype.doAssertLocationPart = function(partName,assertTo) {
var uri = selenium.browserbot.getCurrentWindow().document.location.href;
//alert("URI = " + uri);
var partValue = parseUri(uri,partName);
//alert("Part '" + partName + "' = " + partValue);
//this.doAssertValue(partValue,assertTo);
this.doStore(partValue,"var_"+partName);
};
// Slightly modified function based on author's original:
// http://badassery.blogspot.com/2007/02/parseuri-split-urls-in-javascript.html
//
// parseUri JS v0.1, by Steven Levithan (http://badassery.blogspot.com)
// Splits any well-formed URI into the following parts (all are optional):
//
// - source (since the exec() method returns backreference 0 [i.e., the entire match] as key 0, we might as well use it)
// - protocol (scheme)
// - authority (includes both the domain and port)
// - domain (part of the authority; can be an IP address)
// - port (part of the authority)
// - path (includes both the directory path and filename)
// - directoryPath (part of the path; supports directories with periods, and without a trailing backslash)
// - fileName (part of the path)
// - query (does not include the leading question mark)
// - anchor (fragment)
//
function parseUri(sourceUri,partName){
var uriPartNames = ["source","protocol","authority","domain","port","path","directoryPath","fileName","query","anchor"];
var uriParts = new RegExp("^(?:([^:/?#.]+):)?(?://)?(([^:/?#]*)(?::(\\d*))?)?((/(?:[^?#](?![^?#/]*\\.[^?#/.]+(?:[\\?#]|$)))*/?)?([^?#/]*))?(?:\\?([^#]*))?(?:#(.*))?").exec(sourceUri);
var uri = {};
for(var i = 0; i < 10; i++){
uri[uriPartNames[i]] = (uriParts[i] ? uriParts[i] : "");
if (uriPartNames[i] == partName) {
return uri[uriPartNames[i]]; // line added by MacGyver
}
}
// Always end directoryPath with a trailing backslash if a path was present in the source URI
// Note that a trailing backslash is NOT automatically inserted within or appended to the "path" key
if(uri.directoryPath.length > 0){
uri.directoryPath = uri.directoryPath.replace(/\/?$/, "/");
if (partName == "directoryPath") {
return uri.directoryPath; // line added by MacGyver
}
}
return uri;
}
Then add this to your web.config file and make sure customErrors is turned off. Since you have a 500 error, it will redirect the user to the default page. Feel free to add a custom page for a 500 HTTP status code if you want to be specific in your Selenium scripts.
<customErrors mode="On" defaultRedirect="/ErrorHandler.aspx">
<error statusCode="401" redirect="/AccessDenied.aspx" />
<error statusCode="403" redirect="/AccessDenied.aspx" />
<error statusCode="404" redirect="/PageNotFound.aspx" />
</customErrors>
This is what your commands will look like in the IDE:
Make sure you're on this page (or something similar) before running the script:
https://localhost/ErrorHandler.aspx?aspxerrorpath=/path/pathyouweretryingtoviewinwebapp.aspx
Log shows that it passed!
[info] Executing: |storeLocation | var_URI | |
[info] Executing: |echo | ${var_URI} | |
[info] echo: https://localhost/ErrorHandler.aspx?aspxerrorpath=//path/pathyouweretryingtoviewinwebapp.aspx
[info] Executing: |assertLocationPart | fileName | ErrorHandler.aspx |
[info] Executing: |assertExpression | ${var_fileName} | ErrorHandler.aspx |
Using the error handler from my previous answer:
Command: assertLocation
Target: regexp:^(https://localhost/ErrorHandler.aspx).*$
Or (per your comment) it's inverse if you don't have error handling turned on, use AssertNotLocation. This may require more work on the person writing the scripts. You'd have to keep track of all pages.
More on pattern matching:
http://seleniumhq.org/docs/02_selenium_ide.html#matching-text-patterns
http://www.codediesel.com/testing/selenium-ide-pattern-matching/