Regex in BrowserMob Scripts

If you’re using an RBU or VU you may need to extract content from the previous response. For example, enumerate a link to a PDF file for subsequent download.

The BrowserMob interface has a handy findRegexMatches method you can call as follows:

var link = browserMob.findRegexMatches(selenium.getHtmlSource(), 'href="(.+?pdf)"');
browserMob.beginStep("16_download_content");
  browser.get(link[0], 200);
browserMob.endStep();

It takes a string input and regex pattern parameters. For the string input I am simply passing in the HTML source from the previous request based on a browser object:
var browser = browserMob.getActiveHttpClient();

The regex pattern is self explanatory. The link object will be an array of matches; in this case I’m issuing a get request for the first link in the match array. You might want to add some more code to make this more robust e.g. if no links are found etc.

Pretty simple hey!

Read More

Emulating Think Time and Pacing with BrowserMob

If you come from the commercial toolset mindset, you might be interested in how we achieve think time and pacing when using alternatives such as BrowserMob.

Think Time
Think time, is normally defined as the amount of time a virtual user ‘thinks’ between individual steps within a transaction. This time is usually excluded from response time measurements and is an important inclusion in terms of script behaviour. Having no think time means the virtual user will race through transactions more quickly than a normal user would which potentially creates unrealistic load. So how do we emulate think time behaviour in a BrowserMob script?

The BrowserMob replay engine drives Selenium scripts, so you will need to play in the JavaScript sandbox so to speak, in order to emulate think time. There’s some well documented ways to implement this on the BrowserMob blog here.

The BrowserMob interface (API documentation here) has a pause method as follows:
browserMob.pause(15000);

This effectively pauses the user for a period of 15 seconds in the previous example.

The Selenium interface (API documentation here) also has a similar setSpeed method which will set the number of milliseconds to pause after each step elminating the need to specify individual pause statements between each step as follows:
selenium.setSpeed(2000);

If you would like to emulate some common think time settings as you might see in a LoadRunner script you can implement the following at the top of your RBU or VU scripts:

// Multiply think time by:
var think_time_multiple = 1;
 
// Use random percentage for think time e.g. 50 - 100:
var think_time_percentage = 50 + (Math.random() * 100);
 
// Limit think time to:
var think_time_limit = 0;
 
// Set think time to:
var think_time = 3; //seconds
 
if(think_time_limit > 0) {
  selenium.setSpeed(think_time_limit * 1000);
} else {
  selenium.setSpeed(think_time * think_time_multiple * (think_time_percentage/100) * 1000);
}

If you need additional think time after steps then you can add the following statement where required:
browserMob.pause(3000 * think_time_multiple * (think_time_percentage/100));

Pacing
Some people like to control transaction volume/throughput by messing about with think time. I don’t favour this approach because you need to first be cognisant of how long each iteration will take including think time then adjust think time accordingly. Once it’s set (or hardcoded into your script) then the vusers are stuck with that setting. I much prefer the pacing concept, which determines how long a vuser should ‘wait’ before starting the next iteration. This wait time is determined by elapsed time including any server side processing, not just user think time. So how do we emulate pacing in a BrowserMob script?

First I like to set some targets such as the transaction rate (per hour per user) and then calculate the pacing from this target. I also set a variable iterate to true, which comes into play in the main body of the script.

// Run logic
var transaction_rate = 10;  // Target transaction rate per hour per user
var pacing  = 60*60*1000 / transaction_rate;
var iterate = true;

Now we’ve got the target and pacing set, we can get into the main logic. Let’s start an iteration.

while (iterate) {
  var start = new Date();
  browserMob.beginTransaction();
  ...

Notice I’ve used a while loop which checks for the iterate boolean and creates a start date time stamp. I also initiate a BrowserMob transaction.

After we complete the iteration (which is essentially a bunch of BrowserMob steps) we can close the while loop with some pacing logic.

  ...
  // Calculate Pacing
  var finish  = new Date();
  var elapsed = finish.getTime() - start.getTime();
 
  if (browserMob.isValidation()) {
    browserMob.log("Adjusted pacing would be "+ (pacing - elapsed) + " msecs");
    browserMob.log("or " + Math.round(3600000 / (pacing - elapsed) ) + " trans/hour");
    iterate = false;
  } else {
    if(pacing > elapsed)
      browserMob.pause(pacing - elapsed);
  }
 
  browserMob.endTransaction();
}

This will calculate the finish date time stamp and then determine the difference between the previously calculated target pacing and the actual time elapsed. If there is a difference then the user will pause, otherwise it will just continue on to the next iteration. This basically allows you to target a set number of transactions per hour. When validating the script it will output these calculations to the log file.

Read More