Sep. 16th, 2014

The WebDriver Sampler: Your Top 10 Questions Answered

The Webdriver Sampler is a great tool - but not everyone knows how to use it! In the past, we’ve covered how to use Selenium with JMeter's WebDriver Sampler. So today I’m going to answer the top ten questions that I get asked about using the WebDriver Sampler - with some extra tips and techniques to help you with Selenium scripting in JMeter.

 

Q. How do I Allocate the WebDriver Sampler?

 

A. First of all, don’t use the WebDriver Sampler to create the load! You’ll need around 1 CPU core per virtual user to keep the JMeter resource consumption within an acceptable range. The WebDriver Sampler should be used in addition to HTTP Request Samplers. Here’s an example of how it should be used:

 

  • 1,000 of users are simulated by HTTP Request Samplers
  • 1 user is the WebDriver Sampler

 

You should use the WebDriver Sampler to evaluate a real-life user experience. It’s most commonly used to measure the load times of pages when the system is experiencing high loads. The HTTP Request doesn’t really “render” the page and it can’t execute JavaScript. That’s why the WebDriver Sampler is so valuable - JMeter isn’t a browser and it overcomes limitations posed by this fact.  

 

Q. Implementing the WebDriver Sampler

 

A. The language for test development in the current version (1.1.3) of the WebDriver Sampler is JavaScript. The Java Specification Request (JSR) 223 defines APIs allowed to access Java objects from scripts (and vice versa), so it’s possible to use any Java framework from your WebDriver Sampler script. If you want to find out more, you can check out the JSR 223 Specification on the Java Community Process page: https://jcp.org/en/jsr/detail?id=223.

 

 

Q. How do I Know Which Browsers are Supported?

 

A. The WebDriver Sampler relies on underlying Selenium and HTMLUnit libraries. Therefore, browser support is dependent on 3rd-party libraries providing Selenium integration.

 

You can see which underlying version of Selenium is being used in your WebDriver Sampler. Here’s how:

 

  1. Go to the /lib folder of your JMeter installation

  2. Look for .jar files which the word “selenium” at the start

  3. Take note of the version number (just before the “.jar” extension)

 

For example, if you get the following output:

 

~/Applications/jmeter/lib> ls -l selenium*

selenium-android-driver-2.39.0.jar

selenium-api-2.39.0.jar

selenium-chrome-driver-2.39.0.jar

selenium-firefox-driver-2.39.0.jar                                                                                                              

selenium-htmlunit-driver-2.39.0.jar                                                                                                             

selenium-remote-driver-2.39.0.jar                                                                                                               

selenium-support-2.39.0.jar

 

It means that Selenium version 2.39.0 is being used in your WebDriver Sampler.

 

To see which browser versions are supported, go to Selenium Changelog. This contains the release notes so you can look for the desired version. As JMeter is a Java-based application, we need to look into the “java” folder.  So, for version 2.39.0, we have:


 

v2.39.0

 
 

=======

 

WebDriver:

 

* Update to support native events for Firefox 26.

 

So it makes sense to use Firefox 26 with this WebDriver Sampler release. It doesn’t necessarily mean that later versions won’t work, but it’s better to use a browser version which has passed tests than waste time trying to find a solution which hasn’t been implemented yet.


 

Q. How do I Pass Parameter Data to the WebDriver Sampler?

 

A. There are two approaches that you can take here. You can either take them separately or combine them:

 

  1. Pass the JMeter Variables to the WebDriver Sampler

 

The WebDriver Sampler naturally supports JMeter Variables...when provided in this form: ${variableName}. The Sampler evaluates the variable and uses its value. So, if we have the “foo” variable with the value of “bar”, we can access it as ${foo} in the WebDriver Sampler JavaScript code.

 

wds_define_variable.png

 

wds_access_variable.png

 

2. Use the “Parameters” Section to Pass Data to the WebDriver Sampler

 

Above the ‘Script’ section in the Web Driver Sampler, you’ll see the ‘Parameters’ field. You can access the values entered here in the WebDriver Sampler by using the following pre-defined variables:

 

  • WDS.parameters - for the value, provided in “Parameters” field.

  • WDS.args - if multiple values are entered, they can be accessed as WDS.args[0], WDS.args[1], etc. Multiple values must be separated by spaces.



 

wds_parameters.png


 

Q. How do I Get Data from the WebDriver Sampler?

 

A. The WebDriver Sampler shows the WDS.sampleResult entity (which stands for org.apache.jmeter.samplers.SampleResult) However, for some reason the methods which should set the response code, message and body are being overwritten -  so you won’t be able to set custom response messages, code or body. That being said, it’s possible to set up custom response headers via WDS.sampleResult.setResponseHeaders().

 

wds_set_header.png

If you need to extract multiple values and more headers, you can use the “\n” delimiter. Here’s an example of how this is used correctly:

 

WDS.sampleResult.setResponseHeaders('Header_1_Name: Header_1_Value' + '\n' + 'Header_2_Name: Header_2_Value')

 

Header values can be extracted from the response via the Regular Expression Extractor and the JMeter Variables you get from this can be used in further test actions.

 

Q. How do I Access Java SDK classes from the WebDriver Sampler Code?

 

A. There’s not really anything here that I can add to the guide:  Using Java From Scripts. If you’re using the WebDriver Sampler, it’s well worth familiarizing yourself with it will be very helpful in the implementation of advanced WebDriver Sampler use cases.

 

Q. Why can’t I locate the element/NoSuchElementException work around?

 

A. There could be a number of reasons why you get this exception during the WebDriver Sampler execution:

 

  1. The element’s locator is invalid

  2. The element belongs to another frame

  3. The element is not available in DOM yet

 

Each problem has a different solution:

If your problem is caused by point one, you need to double-check the element locator definition (id, tag, style, xpath, etc.)

 

If it’s point two, you should check the parent frame ID or index (or find it as a regular WebElement by any other means) and switch to it using the switchTo() method.

 

WDS.browser.switchTo().frame("myFrame"); // switch to target frame
// do what required
WDS.browser.switchTo().defaultContent(); // return to original scope

 

If it’s point three, the element might not be available in DOM right after the click(), get(), submit() or other WDS.browser method of execution. In addition, the DOM may automatically act on its own accord due to AJAX-driven changes or other dynamic variations. For example: if you change the value of a combobox, you won’t be able to access it through the instance reference because it’s now a different element. So, I recommend the following:

 

  • Explicitly use the call find() method before you try to interact with the element

  • If your previous method of execution (get(), click(), submit(), etc) is finished, it doesn’t necessarily mean the page load is completed. So it’s better to “wait” until the required element is visible/clickable/changeable etc. Take a look at the code snippet below as an example:


 

var pkg = JavaImporter(org.openqa.selenium)
var support_ui = JavaImporter(org.openqa.selenium.support.ui.WebDriverWait)
var conditions = org.openqa.selenium.support.ui.ExpectedConditions
var wait=new support_ui.WebDriverWait(WDS.browser, 10)

WDS.sampleResult.sampleStart()
WDS.browser.get('http://example.com')
wait.until(conditions.presenceOfElementLocated(pkg.By.linkText('More information...')))
var element=WDS.browser.findElement(pkg.By.linkText("More information..."))
element.click()
WDS.sampleResult.sampleEnd()

 

Q. How do I Take a Screenshot When I Hit Errors?

 

A. Taking screenshots when you hit failures is a good way to simplify the analysis process and get a visual confirmation of the error. Here’s how you do it:

 

  • Perform an action

  • When you hit an error, take a screenshot and fail the sampler

 

You’d normally take the following approach: try -> catch -> finally.

 

  • In the “try” block, we place our test code

  • In the “catch” block, we identify any errors and take a screenshot.

  • In the “finally” block, we perform any clean-up needed to ensure the application is left in exactly the same state as it was in before the test - to avoid impact on other areas. We also re-throw the error here to trigger the current WebDriver Sampler failure.

 

The code below opens the “example.com” site and waits for 5 seconds for the link. As the link doesn’t exist, it produces a TimeoutException, takes a screenshot of JMeter’s current working directory and re-throws the same exception to generate a sampler failure.

 

var pkg = JavaImporter(org.openqa.selenium)
var support_ui = JavaImporter(org.openqa.selenium.support.ui.WebDriverWait)
var conditions = org.openqa.selenium.support.ui.ExpectedConditions
var wait=new support_ui.WebDriverWait(WDS.browser, 5)
var exception = null

WDS.sampleResult.sampleStart()

try
{
   WDS.browser.get('http://example.com')
   wait.until(conditions.presenceOfElementLocated(pkg.By.linkText('Not existing link')))
}
catch (err)
{
   WDS.log.error(err.message)
   var screenshot = WDS.browser.getScreenshotAs(pkg.OutputType.FILE)
   screenshot.renameTo(new java.io.File('screenshot.png'))
   exception = err
}
finally
{
   throw (exception)
}

WDS.sampleResult.sampleEnd()

 

The path “screenshot.png” is relative to JMeter’s current working directory. This is usually the /bin folder of a JMeter installation but if, for example, you’re running JMeter via desktop shortcut - it could be the desktop or user home folder.  So, as always, I recommend you use full paths where required.


 

Q. How do I Set a Page Load Timeout?

 

A. It’s easy! The code below demonstrates how to set a timeout of 10 seconds for the page to load.

 

var timeunit = java.util.concurrent.TimeUnit
   
WDS.sampleResult.sampleStart()
WDS.browser.manage().timeouts().pageLoadTimeout(10, timeunit.SECONDS);
WDS.browser.get('http://example.com')
WDS.sampleResult.sampleEnd()

 

Q. How do I Switch Between Windows in the WebDriver Sampler?

 

A. To show you how to do this, I’ll start with “example.com”, then open a new window with BlazeMeter’s URL and print page titles to the jmeter.log.

 

WDS.sampleResult.sampleStart()
WDS.browser.get('http://example.com')
WDS.browser.executeScript('window.open("http://blazemeter.com");')
var handles = WDS.browser.getWindowHandles()
var iterator = handles.iterator()
var counter = 1;
while (iterator.hasNext())
{
   var handle = iterator.next()
   WDS.browser.switchTo().window(handle)
   WDS.log.info('Window ' + counter + ' title = ' + WDS.browser.getTitle())
   counter++;
}
WDS.sampleResult.sampleEnd()

 

wds_switch_windows.png

 

That’s it! I’ve covered the most frequently asked questions that I receive on WebDriver. I’ve also offered solutions to JavaScript specific to the WebDriver Sampler.

 

I truly hope that you’ve found this information valuable and that it will save you time and frustrations! If you think I missed anything or would like to know more about one of the topics, please add your comments and questions in the form below.

 

Want to learn more? Check out these free online training materials on performance testing.

 

Read more about Continuous Testing in our White Paper "Continuous Testing in Practice".

Interested in writing for our Blog? Send us a pitch!