Using XPATH in jmeter - based on parent - jmeter

I have a xml file having the following structure:
<subscriberDetailsItem>
<externalSubId>911</externalSubId>
<paymentIndicator>2</paymentIndicator>
<IMSI>302</IMSI>
<MSISDN>416</MSISDN>
<status>A</status>
<outSubscriptionDetails>
<subscriptionDetailsItem>
<socId>ABCDEF</socId>
<featureCode>GHIJKL</featureCode>
<startDate>20180720000000</startDate>
<featureSeq>47452111</featureSeq>
<subscriptionType>DATA</subscriptionType>
<shareGroupCd>SHARE</shareGroupCd>
<initialValueBytes>1073741824</initialValueBytes>
<priority>3000</priority>
<balanceType>BAL</balanceType>
</subscriptionDetailsItem>
</outSubscriptionDetails>
</subscriberDetailsItem>
I want to be able to extract the socID field based on the externalSubId field. Essentially, I want to be able to do this:
if externalSubId=911, then, extract SOCID. Anyone has tips?

You didn't specify where would you want to extract it, so I assume you can use XPath Extractor as a post-processor to some sampler that reads that file.
You configure post-processor like this:
XPath Query can be built like this:
Select subscriberDetailsItem that has externalSubId with the value you want:
//subscriberDetailsItem[externalSubId=911]
Select socId either by using absolute path:
//subscriberDetailsItem[externalSubId=911]/outSubscriptionDetails/subscriptionDetailsItem/socId
or you can omit entities in the middle if socId cannot be found elsewhere in the item:
//subscriberDetailsItem[externalSubId=911]//socId

Related

Jmeter - how to write specific variable to CSV file to specific row/column

My csv file looks like:
TC_name, username, password, excpecedCode
ad_test_master_successful_login,username,Test123!,200
What is the easiest way to so i can write to csv to specific row/column, and example to overwrite Test123! with variable fetched from user defined variables?
I know i can read value using JSR223 Pre/post processor with ex:
def line10 = new File('C:/Users/test/Desktop/testData/login.csv').readLines().get(1).split(",")[2]
log.warn("csv as-> " + line10);
There is no such concept as "cell" in CSV files, if you're looking for the code which will replace one string with another, you can do something like:
def file = new File('test.csv')
def text = file.text.replaceAll('Test123!', vars.get('foo'))
file.text = text
If you're looking for a better option you can consider using GroovyCSV library (you will need to download it and place in JMeter Classpath followed by JMeter restart) or consider switching to Excel file where you will have full control via Apache POI library like it's described in How to Implement Data Driven Testing in your JMeter Test article

camel:when on header value using blueprint

I have camel routes that make rest calls based on header values.
I had been using xpath to read values from xml and set them as the header and used xpath in a block as so:
<camel:setHeader headerName="clear">
<xpath>/TicketInfo/TicketData/Clear/text()</xpath>
</camel:setHeader>
<camel:choice>
<camel:when>
<camel:xpath>$clear='CLEARED'</camel:xpath>
<camel:doTry>
...
but now I am forced to use json so xpath will not work. I now have:
<camel:setHeader headerName="clear">
<camel:jsonpath>$.ticket.Type</camel:jsonpath>
</camel:setHeader>
<camel:choice>
<camel:when>
<camel:xpath>$clear='CLEARED'</camel:xpath>
<camel:doTry>
...
but obviously the <camel:xpath>$clear='CLEARED'</camel:xpath> part won't work anymore. Is there another way I can check the value of $clear header to restrict when the <camel:doTry> and following execute?
Try the simple language :
<camel:when>
<camel:simple>${in.header.clear} == 'CLEARED'</camel:simple>
<camel:doTry>
See this documentation

Extracting value from complex hash in Ruby

I am using an API (zillow) which returns a complex hash. A sample result is
{"xmlns:xsi"=>"http://www.w3.org/2001/XMLSchema-instance",
"xsi:schemaLocation"=>"http://www.zillow.com/static/xsd/SearchResults.xsd http://www.zillowstatic.com/vstatic/5985ee4/static/xsd/SearchResults.xsd",
"xmlns:SearchResults"=>"http://www.zillow.com/static/xsd/SearchResults.xsd", "request"=>[{"address"=>["305 Vinton St"], "citystatezip"=>["Melrose, MA 02176"]}],
"message"=>[{"text"=>["Request successfully processed"], "code"=>["0"]}],
"response"=>[{"results"=>[{"result"=>[{"zpid"=>["56291382"], "links"=>[{"homedetails"=>["http://www.zillow.com/homedetails/305-Vinton-St-Melrose-MA-02176/56291382_zpid/"],
"graphsanddata"=>["http://www.zillow.com/homedetails/305-Vinton-St-Melrose-MA-02176/56291382_zpid/#charts-and-data"], "mapthishome"=>["http://www.zillow.com/homes/56291382_zpid/"],
"comparables"=>["http://www.zillow.com/homes/comps/56291382_zpid/"]}], "address"=>[{"street"=>["305 Vinton St"], "zipcode"=>["02176"], "city"=>["Melrose"], "state"=>["MA"], "latitude"=>["42.466805"],
"longitude"=>["-71.072515"]}], "zestimate"=>[{"amount"=>[{"currency"=>"USD", "content"=>"562170"}], "last-updated"=>["06/01/2014"], "oneWeekChange"=>[{"deprecated"=>"true"}], "valueChange"=>[{"duration"=>"30", "currency"=>"USD", "content"=>"42749"}], "valuationRange"=>[{"low"=>[{"currency"=>"USD",
"content"=>"534062"}], "high"=>[{"currency"=>"USD", "content"=>"590278"}]}], "percentile"=>["0"]}], "localRealEstate"=>[{"region"=>[{"id"=>"23017", "type"=>"city",
"name"=>"Melrose", "links"=>[{"overview"=>["http://www.zillow.com/local-info/MA-Melrose/r_23017/"], "forSaleByOwner"=>["http://www.zillow.com/melrose-ma/fsbo/"],
"forSale"=>["http://www.zillow.com/melrose-ma/"]}]}]}]}]}]}]}
I can extract a specific value using the following:
result = result.to_hash
p result["response"][0]["results"][0]["result"][0]["zestimate"][0]["amount"][0]["content"]
It seems odd to have to specify the index of each element in this fashion. Is there a simpler way to obtain a named value?
It looks like this should be parsed into XML. According to the Zillow API Docs, it returns XML by default. Apparently, "to_hash" was able to turn this into a hash (albeit, a very ugly one), but you are really trying to swim upstream by using it this way. I would recommend using it as intended (xml) at the start, and then maybe parsing it into an easier to use format (like a JSON/Hash structure) later.
Nokogiri is GREAT at parsing XML! You can use the xpath syntax for grabbing elements from the dom, or even css selectors.
For example, to get an array of the "content" in every result:
response = #get xml response from zillow
results = Nokogiri::XML(response).remove_namespaces!
#using css
content_array = results.css("result content")
#same thing using xpath:
content_array = results.xpath("//result//content")
If you just want the content from the first result, you can do this as a shortcut:
content = results.at_css("result content").content
Since it is indeed XML dumped into a JSON, you could use JSONPath to query the JSON

XPath format required on namespace node

Can someone please show me the XPath format i should use to retrieve the 2nd txnDetail node's billAmount ?
I am expecting value 10.00 but i have issues with the namespace and "a:" and XPath fails to retrieve the correct value.
<TransactionRsp xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<avlBal>818.00</avlBal>
<blkAmt>0.00</blkAmt>
<cardID>2561683577196298</cardID>
<currBill>GBP</currBill>
<endBal>390.00</endBal>
<logDateTime>2013-04-30T12:17:20.4249292Z</logDateTime>
<msgID>121719721</msgID>
<rspCode>000</rspCode>
<startBal>400.00</startBal>
<txnDetail xmlns:a="http://schemas.datacontract.org/2004/07/CoreModels">
<a:txnDetail>
<a:billAmount>400.00</a:billAmount>
<a:billConvRate>0.00</a:billConvRate>
<a:blkAmount>0.00</a:blkAmount>
<a:debOrCred>1</a:debOrCred>
<a:itemID>2278</a:itemID>
<a:itemType>6</a:itemType>
<a:txnAmount>0.00</a:txnAmount>
<a:txnCurrency/>
<a:txnDateTime>2012-02-23T14:35:45</a:txnDateTime>
<a:txnDescription></a:txnDescription>
</a:txnDetail>
<a:txnDetail>
<a:billAmount>10.00</a:billAmount>
<a:billConvRate>0.00</a:billConvRate>
<a:blkAmount>0.00</a:blkAmount>
<a:debOrCred>0</a:debOrCred>
<a:itemID>3058</a:itemID>
<a:itemType>5</a:itemType>
<a:txnAmount>0.00</a:txnAmount>
<a:txnCurrency/>
<a:txnDateTime>2012-07-30T12:22:14</a:txnDateTime>
<a:txnDescription>Fee: Card Issue</a:txnDescription>
</a:txnDetail>
</txnDetail>
</TransactionRsp>
It's:
//TransactionRsp/txnDetail/a:txnDetail[2]
However, depending on your programming language you might have to register the a namespace. The document might have a default namespace as well. (Don't expect that the xml you've posted is the whole document)
I have managed to pull the relevant data using the following XPath:
/TransactionRsp/txnDetail/[local-name()='txnDetail'][2]/[local-name()='billAmount']
Now I need to know how to filter out only txnDetail with an itemType = 6 ??
Any thoughts ?

SoapUI XPath assertion with wildcards

Is there a way to use a wildcard inside an assertion in a XPath test with SoapUI?
I took a look at SoapUI's documentation and they say you can do something like this
<path1>
<path2>*</path2>
</path1>
I checked the 'Allow Wildcards' checkbox.
My question is : I want to assert my date starts with 2012-08-22 but i dont care about the minutes and seconds. I guess my the expression should be something like 2012-08-22* but it doesn't work.
What you are doing sounds like it should work. Here is a quick example i cooked up using a rest service from http://www.geonames.org/export/web-services.html#timezone. I'm using the demo they have supplied
http://api.geonames.org/timezone?lat=47.01&lng=10.2&username=demo
output is
<geonames>
<timezone tzversion="tzdata2012c">
<countryCode>AT</countryCode>
<countryName>Austria</countryName>
<lat>47.01</lat>
<lng>10.2</lng>
<timezoneId>Europe/Vienna</timezoneId>
<dstOffset>2.0</dstOffset>
<gmtOffset>1.0</gmtOffset>
<rawOffset>1.0</rawOffset>
<time>2012-07-25 04:39</time>
<sunrise>2012-07-25 05:50</sunrise>
<sunset>2012-07-25 21:00</sunset>
</timezone>
</geonames>
If you do an xpath match on the result and use the select from current button you get
//geonames/timezone/time
2012-07-25 04:39
If you update this to
//geonames/timezone/time
2012-07-25*
this will work fine and when updating the rest request with a new lat and lng the assertion will still pass since it is not checking the time. If this doesn't help, please supply your full assertion and maybe i could help more.
*note: for soap requests, make sure to declare the namespace and then use the proper format
//ns1:message
It will be sort of a pain, but here is what you can do:
1) Figure out an Xpath 'base' using the assertion tab (sounds like you are here already). I used this public site to test against: http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl
I used the CornerPoints method with 'hawaii' as the single param.
I created this 'base' xpath:
declare namespace ns1='http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl';
declare namespace SOAP-ENC='http://schemas.xmlsoap.org/soap/encoding/';
declare namespace SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/';
/SOAP-ENV:Envelope/SOAP-ENV:Body/ns1:CornerPointsResponse/listLatLonOut
(it will write the declare statements for you if you click declare)
(which you can test out in the assertions window)
2) Create a Properties step
3) Create a Property transfer step
4) Create a groovy script
5) add a property... i called mine misc
6) add a transfer step
* transfer from the CornerPoints - Request 1 --- Response
* paste the Xpath stuff in the box under the 'transfer from'
* Transfer to your property
(You can test with the little play button)
7) Add something like this to your groovy script:
def x = context.expand( '${Properties#misc}' )
def parts = x.tokenize(',')
for (def part in parts)
{
log.info(part)
if (part.startsWith("-153"))
log.info("good")
}
In the groovy step you can do anything you need to get at your (partial) data. The sample code I added gets lat/lons out of a long line wrapped in CDATA and then checks for just the starting part of some of the data.. just an example.
Remember that you can use groovy and java string methods:
http://groovy.codehaus.org/groovy-jdk/java/lang/String.html
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html
More groovy tips:
http://www.soapui.org/Scripting-Properties/tips-a-tricks.html

Resources