Jmeter - find with regex and replace part of XML body using groovy - regex

I'm trying to replace part an XML response data with something else.
Here is an example:
?xml version="1.0" encoding="UTF-8"?>
<trustedDevices><trustedDevice><id>1942</id><name>BksQ9LKwWuNOHpn</name></trustedDevice><trustedDevice><id>1944</id><name>6f4srs4PkJk1j36</name></trustedDevice><trustedDevice><id>1943</id><name>7cGYVAlmQoXaVrf</name></trustedDevice></trustedDevices>
I'm trying to get all the <name>(.+?)<\/name> data and replace it with something else (timestamp or random string)
so far, my groovy post processor code looks like this:
String trustedDevices = prev.getResponseDataAsString()
log.info('Response: ' + trustedDevices)
def nameFind = "/<name>(.+?)<\/name>/"
def newTrustedDevices = trustedDevices.replaceAll(nameFind, "test")
log.info('New response: ' + newTrustedDevices)
Unfortunately it seems that replaceAll requires String or Long to work, and won't work with regex.

You regex just need a correct escaping:
def nameFind = "<name>(.+?)<\\/name>"

Replacing values in XML using regular expressions is not the best option as it will be fragile and very sensitive to any markup change.
I would suggest going for Groovy's XML parsing capabilities instead
Example code:
def trustedDevices = new XmlSlurper().parseText(prev.getResponseDataAsString())
trustedDevices.trustedDevice.findAll().each {
it.name = 'test'
}
def newTrustedDevices = new StreamingMarkupBuilder().bind { mkp.yield trustedDevices }.toString()
More information on Groovy scripting in JMeter: Apache Groovy - Why and How You Should Use It

Related

Parsing value from the Jmeter string response

I'm trying to get a value of post_data[‘postcode’] on Jmeter. I tried to parse with JSR223 PostProcessor with the below code but looks like my code is not able to find that variable name.
Response:
<script type="text/javascript">
parent.$("#dialog:ui-dialog").dialog("destroy");
parent.$("#dialog-message div").html("");
var url = '';
var post_data = {};
post_data[‘user’] = “value1”;
post_data[‘city’] = “value2”;
post_data[‘postcode’] = “value3”;
post_data[‘country’] = “value3”;
</script>
JSR223 PostProcessor groovy script:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
String stringToSearch=prev.getResponseDataAsString();
Pattern p = Pattern.compile("post_data[‘postcode’] = (\\w+)");
Matcher m = p.matcher(stringToSearch);
if (m.find()){
vars.put("postcode", m.group(1));
}
Any help is greatly appreciated.
You need to surround your match group with quotation marks
You need to escape meta characters
Groovy provides match operator out of box so you can simplify your code as:
vars.put('postcode', (prev.getResponseDataAsString() =~ /post_data\[‘postcode’\] = “(\w+)”/)[0][1])
Demo:
More information:
Groovy Regular Expressions - The Definitive Guide
Apache Groovy - Why and How You Should Use It

Unable to capture required string from text file using Groovy - Jmeter JSR223

I need to parse a text file testresults.txt and capture serial number and then write the captured serial number onto separate text file called serialno.txt using groovy Jmeter JSR223 post processor.
Below code is not working. It didn't get into the while loop itself. Kindly help.
import java.util.regex.Pattern
import java.util.regex.Matcher
String filecontent = new File("C:/device/resources/testresults.txt").text
def regex = "SerialNumber\" value=\"(.+)\""
java.util.regex.Pattern p = java.util.regex.Pattern.compile(regex)
java.util.regex.Matcher m = p.matcher(filecontent)
File SN = new File("C:/device/resources/serialno.txt")
while(m.find()) {
SN.write m.group(1)
}
If your code doesn't enter the loop it means that there are no matches so you need to amend your regular expression, you can use i.e. Regex101 website for experiments
Given the following content of the testresults.txt file:
SerialNumber" value="foo"
SerialNumber" value="bar"
SerialNumber" value="baz"
your code works fine.
For the time being I can only suggest using match operator to make your code more "groovy"
def source = new File('C:/device/resources/testresults.txt').text
def matches = (source =~ 'SerialNumber" value="(.+?)"')
matches.each { match ->
new File('C:/device/resources/serialno.txt') << match[1] << System.getProperty('line.separator')
}
Demo:
More information: Apache Groovy - Why and How You Should Use It

How to search and replace from a SafeHtml variable in Angular?

I've a very simple question.
I've a sanitized string and its type in Angular is SafeHtml.
How would be the best approach to search and replace some Html inside this SafeHtml variable?
...
const sanitzedHtml: SafeHtml = this.sanitizer.bypassSecurityTrustHtml(changes.pureHtml.currentValue);
...
My goal is to replace some string with some extra html code, so the best would be to be able to search only within the html nodes, not really everywhere in the code.
Are there faster way than reconverting the SafeHtml variable into a string and apply a basic replace with a RegExp?
Thanks
Change HTML code before sanitize
1 - Using regex
You can change your code by using Regex on your html string, then sanitize it.
let html = "<div>myHtml</div>"
const regex = /myRegexPattern/i;
html.replace(regex, 'Replacement html part'));
2 - Using DocumentFragment
You can also create a fragment of your html, modify what you want in it and string it before start your sanitize function
let str:string = "<div id='test'>myHtml</div>";
const sanitzedHtml:SafeHtml = this.sanitizer.bypassSecurityTrustHtml(changeMyHtml(str));
function changeMyHtml(htmlString:string):string{
let fragment= document.createRange().createContextualFragment(str);
//do what you need to do here like for exemple
fragment.getElementById('test').innerHtml = "myHtmlTest";
//then return a string of the modified html
const serializer = new XMLSerializer();
return serializer.serializeToString(element)
}

Regex to grab data from massive HTML string

I am grabbing a HTML source dump that includes some sort of JSON props created by react.
Trying to grab data in syntax like this: "siteName":"Example Site". I want to grab that "Example Site" text without the quotations.
I know I could be using an HTML parser but this is actually within some JS code in the source.
Any thoughts on how I could do this? Thanks
With this regex you get it but I would use something else like a Json parser
var regex = /"siteName":"(.+?)"/g;
var str = `{"siteName":"ABC Example Business","contactName":"Jeff","siteKey":"abcexample","tabKey":"service","entityKey":"1192289","siteId":152285976,"entityId":13123055221,"phone":"","mobile":"0100 000 000",}`;
var result = regex.exec(str);
console.log(result[1]);
How about that:
\"siteName\":\"(.+)\"

Regex JSON response Gatling stress tool

Wanting to capture a variable called scanNumber in the http response loking like this:
{"resultCode":"SUCCESS","errorCode":null,"errorMessage":null,"profile":{"fullName":"TestFirstName TestMiddleName TestLastName","memberships":[{"name":"UA Gold Partner","number":"123-456-123-123","scanNumber":"123-456-123-123"}]}}
How can I do this with a regular experssion?
The tool I am using is Gatling stress tool (with the Scala DSL)
I have tried to do it like this:
.check(jsonPath("""${scanNumber}""").saveAs("scanNr")))
But I get the error:
---- Errors --------------------------------------------------------------------
> Check extractor resolution crashed: No attribute named 'scanNu 5 (100,0%)
mber' is defined
You were close first time.
What you actually want is:
.check(jsonPath("""$..scanNumber""").saveAs("scanNr")))
or possibly:
.check(jsonPath("""$.profile.memberships[0].scanNumber""").saveAs("scanNr")))
Note that this uses jsonPath, not regular expressions. JsonPath should more reliable than regex for this.
Check out the JsonPath spec for more advanced usage.
use this regex to match this in anywhere in json:
/"scanNumber":"[^"]+"/
and if you want to match just happens in structure you said use:
/\{[^{[]+\{[^{[]+\[\{[^{[]*("scanNumber":"[^"]+")/
Since json fields may change its order you should make your regex more tolerant for those changes:
val j = """{"resultCode":"SUCCESS","errorCode":null,"errorMessage":null,"profile":{"fullName":"TestFirstName TestMiddleName TestLastName","memberships":[{"name":"UA Gold Partner","number":"123-456-123-123","scanNumber":"123-456-123-123"}]}}"""
val scanNumberRegx = """\{.*"memberships":\[\{.*"scanNumber":"([^"]*)".*""".r
val scanNumberRegx(scanNumber) = j
scanNumber //String = 123-456-123-123
This will work even if the json fields will be in different order (but of course keep the structure)