This is the final post, part 2 of a series:
- Part 1: Website automation with Selenium and JMeter
- Part 2: Selenium scripting, Installation
In this post I show how to script Selenium for handling asynchronous browser behaviour, and how to install the tools.
WebDriver Sampler
There are many online resources that show how to write boilerplate WebDriver Sampler code (see references at the end). Below are some code snippets (we chose JavaScript) that demonstrate the more interesting techniques we used.
Waiting for State
Create an instance of WebDriverWait, a helper for waiting until a page element has the required state e.g. element is present/visible. Our script code uses the helper extensively.
var support_ui = JavaImporter(org.openqa.selenium.support.ui) var wait = new support_ui.WebDriverWait(WDS.browser, 5) // wait up to 5 seconds, then timeout
Use an HTTP GET command to load the OpenShift default web page:
WDS.browser.get('https://192.168.3.134:8443/console/')
The above HTTP GET generates a sequence of URL redirects before eventually loading the login page that expects a username and password. The script needs to wait through these redirects until one of the required form input elements becomes present. The snippet below performs the wait, and finds HTML elements by ID and CSS selector:
var element // Wait for the username text box to be present, then enter text. element = wait.until(conditions.presenceOfElementLocated(selenium.By.id('inputUsername'))) element.sendKeys('developer') // No need to wait again; find the password element on the same page, enter text. element = WDS.browser.findElement(selenium.By.id('inputPassword')) element.sendKeys('developer') // same as username // Find the login button on the same page, click it. var selector = 'button.btn.btn-primary.btn-lg' element = WDS.browser.findElement(selenium.By.cssSelector(selector)) element.click()
The login click above generates another sequence of URL redirects that eventually load the home page. The script needs to wait until the my-project link is present, then click the link to view the project page. The snippet below finds an HTML link element:
element = wait.until(conditions.presenceOfElementLocated(selenium.By.linkText("my-project"))) element.click()
I omitted similar code that loads the Builds view. Having requested this view, the script needs to wait for the “last build” link to become visible, then click to view that build. The snippet below uses an XPath locator to find the element:
selector = '/html/body/div[1]/div/div/div[2]/div/div/div/table/tbody/tr/td[2]/span/a' element = wait.until(conditions.visibilityOfElementLocated(selenium.By.xpath(selector))) element.click()
Logging
The WebDriver Sampler provides access to JMeter logging. The script engine doesn’t provide a debugger, and script commands can fail for various reasons, so it’s useful to log script commands, as in the snippet below:
WDS.log.info(logPrefix + '> GET ' + url) WDS.browser.get(url) WDS.log.info(logPrefix + '< GET ' + url + ', Title: ' + WDS.browser.getTitle())
Below is a simplified extract from the log:
13:35:56,275 INFO > GET https://192.168.3.134:8443 13:35:57,735 INFO < GET https://192.168.3.134:8443, Title: OpenShift Web Console 13:35:57,737 INFO > User name: wait.until presenceOfElementLocated by ID inputUsername 13:35:58,442 INFO < User name: wait.until presenceOfElementLocated by ID inputUsername 13:35:58,444 INFO > sendKeys(developer) 13:35:58,629 INFO < sendKeys(developer)
If a server error caused the browser to load an error page, we can write that page to the JMeter log. This can be convenient for accessing error information without having to switch context to the server. Also, a faulty WebDriver script can load an unexpected page then fail because a page element is missing. The code below writes the page source code to the log (limited to 8 Kb in case of very large page content, e.g. not an error page).
try { element = WDS.browser.findElement(selenium.By.id('inputUsername')) } catch (err) { WDS.log.error(logPrefix + WDS.browser.getPageSource().substring(0, 8192)) throw (err) }
Browser Timeouts
If the server takes a long time to serve a given request, this can cause a script to fail for the wrong reason: browser timeout. The snippet below increases the browser’s default time limit.
// Change the browser's default page load timeout (300 seconds for Chrome) to test // pages that are slow to load. var timeUnit = JavaImporter(java.util.concurrent.TimeUnit) var timeouts = WDS.browser.manage().timeouts() timeouts.pageLoadTimeout(600, timeUnit.TimeUnit.SECONDS) // 10 minutes
Installing the Tools
JMeter
To install JMeter and required plugins, see the directions below:
- Install Java 8 or 9.
- Install JMeter: choose a download package, then extract the compressed file to a suitable local directory.
- Download the JMeter Plugins Manager and copy this file to the JMeter lib\ext sub-directory.
- Start the JMeter IDE: in the JMeter bin sub-directory, run either jmeter.bat (Windows) or jmeter.sh (Linux).
- On the main menu, go to Options > Plugins Manager. Check the box at Selenium/WebDriver Support to auto-download the Selenium WebDriver plugins to the lib\ext sub-directory.
ChromeDriver
To install ChromeDriver, see the directions below:
- Download ChromeDriver from the main download page (screenshot below).
- Click the link at Latest Release:
- Choose a build for the target platform:
- Extract the downloaded file (an executable) to a suitable directory. A ChromeDriver Config element in a JMeter script should specify this path.
Credits
Featured image:
https://westergaard.eu/wp-content/uploads/2017/07/edorasware-illustration-memory-leak-horizontal.jpg
References
- https://www.seleniumhq.org/
- WebDriver API Java Packages
- https://jmeter-plugins.org/wiki/WebDriverSampler/
- https://jmeter-plugins.org/wiki/ChromeDriverConfig/
- Mixing Selenium Into Your Load Scenario
- Selenium vs. JMeter – Which One Should You Choose, and When?
- The WebDriver Sampler: Your Top 10 Questions Answered