How to pass ${__threadNum} value in selenium javascript? - jmeter

I used Webdriver sampler and write selenium -Javascript. Now in my script for achieving some result we need total number of users so I want to know how add ${__threadNum} value in my script?
or is there any way when multiple users run and some operations execute for only one user?

Either put the ${__threadNum} function to the "Parameters" section and refer it in the script as WDS.args[0] where required
var threadNum = WDS.args[0]
Or use WDS.ctx shorthand for JMeterContext class, there you will have access to getThreadNum() function. It will return zero-based number of thread so to get the same value you will need to increment it by 1
var threadNum = (WDS.ctx.getThreadNum() + 1)
Demo:
More information: The WebDriver Sampler: Your Top 10 Questions Answered article for more information if needed

Related

Parallel executions of dynamic URL's coming from for each controller

I have a requirement to load the dynamic assets(Images) parallelly which got extracted from the for each loop as there is only one sampler with variable passed. I cant use the parallel controller here, also I don't know the exact number of assets loaded to pass in parallel sampler.
As suggested by you in one of similar issues I have used that approach(add pre sampler) below script and try to execute it in, It is able to pick the values but the child element is always only one(Parallel requests are not happening) however I see the URL's passed main request has multiple passed.
Pre-Processor script used:
String var2 = vars.get("tokens");
String var3 = vars.get("Token");
vars.put("var3", "https://stagingassets.ovid.com"+"/"+var2+"/t/width-150-png?"+var3);
urlsList = vars.get("var3").tokenize(",")
for (int i = 0; i < urlsList.size(); i++) {
def row = new org.apache.jmeter.testelement.property.CollectionProperty()
row.addItem(urlsList[i])
sampler.data.addItem(row)
log.info("ROWS ${row}")
}
variables are coming from CSV where values are saved into a file from each loop using a Flexible File Writer.
please suggest , My requirement is to execute the images parallelly as it happens in the browser.
[JMeter script image][1]
Use Parallel Sampler, the URLs can be added dynamically via JSR223 PreProcessor using the following code snippet:
sampler.addURL('your-first-url')
sampler.addURL('your-second-url')
If you want to mimic browser-like behaviour you need to put the Parallel Sampler under the Loop Controller and set the number of loops to the number of your URLs / 6

Jmeter - Calling javascript using JSR223 Post processor

I capture 6 elements using a regular expression. say
Variable : UserDetails
Regular Expression : loadHeadWorkFlow\('(.+?)','(.+?)','(.+?)','(.+?)','(.+?)','(.+?)','/I
Template : $1$$2$$3$$4$$5$$6$
Now I could access these values via UserDetails_g1, UserDetails_g2.....UserDetails_g6
Next, these 6 values need to be encrypted using a javascript file. The file contains the logic.
How should my code be using JSR223 post processor?
The steps that I followed:
1.
load('Encryption.js');
var result = encrypt("${UserDetails_g1}","password");
log.info("encrypted value is "+result);
vars.put("LoginDataString",result);
var result1 = encrypt("${UserDetails_g2}","password1");
vars.put("UserId",result1);
var result2 = encrypt("${UserDetails_g3}","password2");
vars.put("RoleId",result2);
First value is encrypted correctly. But the other values aren't correct. If I add individual post processors for every variable. All the encrypted values show correctly.
Is there a way where I could use a single post processor to perform all the 6 encryptions. Thanks in advance
Regards,
Ajith
Use vars instead of ${} syntax
var result = encrypt(vars.get("UserDetails_g1"),"password");
log.info("encrypted value is "+result);
vars.put("LoginDataString",result);
var result1 = encrypt(vars.get("UserDetails_g2"),"password1");
vars.put("UserId",result1);
var result2 = encrypt(vars.get("UserDetails_g3"),"password2");
vars.put("RoleId",result2);
From JMeter perspective there is no problems, just check that your UserDetails_g2 variable has anticipated value using Debug Sampler and View Results Tree listener combination., the you might want to check this encrypt() function implementation.
Another possible reason is this JavaScript language selection itself, the Nashorn engine performance is a big question mark when it comes to the load, according to JMeter Best Practices it's recommended to use Groovy language for scripting so you might want to consider re-writing the function in Groovy

How to parametrize number of threads in JMeter 5.2.1

I have a JMeter 5.2.1 project where in the SetUp thread I generate properties with names like ThreadGroupName1-NumberOfThreads, ThreadGroupName2-NumberOfThreads, etc. with values representing integers.
Now, I wish to access these properties in thread groups named ThreadGroupName1, ThreadGroupName2, etc. to parametrize the number of threads. I tried something like ${__jexl3(props.get(threadName + "-NumberOfThreads"))} but it fails as threadName evaluates to standardjmeterengine.
Also, I tried to use ctx but ctx.getThread() and ctx.getThreadGroup() but they evaluate to null.
So far what 'works' for me is ${__jexl3(props.get("ThreadGroupName1-NumberOfThreads"))} but I want it be parametrized by the name of the thread group.
Is it possible to do this?
Is this threadName returning standardjmeterengine a bug?
Update: In fact, the easiest 'solution' that provides the parametrized number of threads there is ${__P(ThreadGroupName1-NumberOfThreads)} and what I want is to generate this key ThreadGroupName1-NumberOfThreads to be something like ${MyCurrentGroupName}-NumberOfThreads, effectively providing a way to have an abstract method like
int GetNumberOfThreads(string threadGroupName)
{
return properties.get(threadGroupName + "-NumberOfThreads";
}
Similarly, I wish to use this patter in Constant Throughput Timer as well with another prefix like -Rpm.
I don't think you can use any JMeter Function in the "Number of Threads" field of the Thread Group so this is not something you can do via UI. If you believe this is something everyone needs you can consider raising an enhancement request
As a workaround you can
Set the number of threads to 1
Add If Controller to the Thread Group and use the following __groovy() function as the condition:
${__groovy(ctx.getThreadNum() == 0 && vars.getIteration() == 1,)}
Add JSR223 Sampler as a child of the If Controller and put the following code into "Script" area:
SampleResult.setIgnore()
2.upto(props.get(ctx.getThreadGroup().getName() + '-NumberOfThreads') as int, { ctx.getThreadGroup().addNewThread(0, ctx.getEngine()) })
This way each thread Group will normally start with 1 thread, however this thread will read the property you defined earlier and add as many threads as needed.
You can use JMeterContext's getThreadNum to get thread number (increment, because it starts with 0)
${__jexl3(props.get("ThreadGroupName"))}${__jexl3((ctx.getThreadNum()+1) + "-NumberOfThreads" )}

How to create simple counter using Beanshell?

I'm trying to create a simple counter that will print the iteration number to the log.
the problem is that I didn't find a way to initialize the int value of i to 0.
if I'll do it inside the Beanshell script it will keep initializing, I need it to run only once at the beginning of the test.
My code:
int i=0;
log.info(string.valueOf(i));
i=i+1;
Add Once Only Controller, under it JSR223 Sampler with the initialization
vars.putObject("i", 0);
Then you can increment it after it (not under the Controller) with other JSR223 Sampler:
myI = vars.getObject("i")
log.info(String.valueOf(myI));
vars.putObject("i", ((Integer)myI+1));
It is recommended to avoid scripting where possible, and if you cannot live without scripting you should be using the most performing option which is JSR223 Test Elements and Groovy language.
Particularly your case can be implemented without any scripting, you can use the following JMeter Functions:
__log() - which prints an arbitrary message to jmeter.log file
__iterationNum() - which returns the number of current iteration
So if you use the statement like: ${__log(Current iteration is: ${__iterationNum},,,)} JMeter will return it where the function is called and additionally print the corresponding message to the log file.
Demo:
You can install __iterationNum() function as a part of Custom JMeter Functions bundle using JMeter Plugins Manager

Jmeter while controller doesn't seem to evaluate variables as numbers

I am writing a jmeter script that keeps loading data until a table reaches a specified size. I have a while loop, in which I have one HTTP Sampler to loads the data, then another HTTP Sampler with an XPath Post-processor to check the table size (they call two different APIs). The reference variable of the XPath Post Processor is currentSize and I have a user defined variable maxSize, but using ${currentSize} < ${maxSize} as the condition for the while loop creates an infinite loop.
Thinking maybe the problem is that the output of XPath is a string, I've tried doing various things in beanshell to coerce it to a number, but I'm a beanshell noob, so I haven't been successful with that either. Can anyone guide me about how to get jmeter to recognize a variable as a number? (Preferably a decimal, but if I have to round to an int, I can live with that.)
Thanks!
I think using __javascript(parseInt()) should suffice for you to check the condition.
e.g.
${__javaScript(parseInt(${time_elapsed_string}) < parseInt(${duration}))}
Assuming that you have following variables:
currentSize
maxSize
continue
where continue is set via User Defined Variables and has the value of true
You can use following Beanshell code to check if current size is equal or greater than maximum size:
import java.math.BigDecimal;
String currentSize = vars.get("currentSize");
String maxSize = vars.get("maxSize");
BigDecimal currentSizeNumber = new BigDecimal(currentSize);
BigDecimal maxSizeNumber = new BigDecimal(maxSize);
if (currentSizeNumber.compareTo(maxSizeNumber) > -1){
vars.put("continue", "false");
}
Make sure that following criteria are met:
Your While Controller has ${continue} as a condition
Beanshell Sampler, Pre / Post Processor or Assertion with the code above is added as a child of the While Controller
See How to use BeanShell guide for more details and kind of Beanshell cookbook.
Everything should work this way.
Hope this helps.

Resources