Tips for those who use Selenium – WebDriver Sampler with JMeter

Many people find it very challenging to convert their normal Selenium Tests scripts to adhere the WebDriver Samplers in JMeter. If you are very much used to the fact of writting Selenium scripts in a day to day basis, writing them on the WebDriver Sampler can not be very tedious. I faced a few challenges in the use of Selenium in JMeter when working on client projects. Following are 5 of those challenges and ways on how I over came them.

  1. Overcome unwanted crashes due to delay in page load
    The test scripts usually tend to fail when the Selenium Driver tries to search for a WebElement way before the page could completely load. For this we usually use the ExplicitWait() function in the normal selenium scripting world. In the WebDriver Sampler you could use the following.

    var pkg = JavaImporter(org.openqa.selenium)
    var support_ui = JavaImporter(org.openqa.selenium.support.ui.WebDriverWait)
    var ui = JavaImporter(org.openqa.selenium.support.ui)
    var wait = new support_ui.WebDriverWait(WDS.browser, 7000)
    //Here 7000 is the amount of milliseconds that code wait till it sees the specified username element
    
    wait.until(ui.ExpectedConditions.visibilityOfElementLocated(pkg.By.ByXPath("//input[@name='username']")))

     

  2. Can screenshots be taken for my JMeter Selenium Tests? Yes, with unique names by using parameters.
    You would like to take screenshots of your tests and verify them at the end of the test as the JMeter tests run so quickly and you can have it part of your test execution. This can be achieved in the following manner.

    var fileUtils = JavaImporter(org.apache.commons.io)
    var io = JavaImporter(java.io)
    var location = 'D:/Users/cthalayasingam/Documents/jmeterTest/'
    
    var screenshot = WDS.browser.getScreenshotAs(pkg.OutputType.FILE)
    fileUtils.FileUtils.copyFile(screenshot, new io.File(location+'messages1.png'))
  3. Can we use the JMeter User Defined Variables or JMeter Functions in the Selenium WebDriver Sampler Script? Yes, Can be achieved in the following ways (the first method is more preferred)
    If the JMeter variable is called cDate and you need to use it in send keys or some specific place in the code as shown below.

    fromDate.sendKeys(['${cDate1}'])

    The other is to mention the variable in the parameters field and then call it as shown in the following manner.

    Screen Shot 2017-08-31 at 12.40.52

  4. Checking if an element is present or displayed.
    WDS.browser.findElement(pkg.By.ByXPath("//div[contains(@class,'column2')]//div[contains(@class, 'dashlet')]//div[contains(.,'Resend Messages')][1]")).isDisplayed())
  5. Logging info messages.
    WDS.log.info('Messages all are deleted');
  6. How can we perform Drag And Drop function?
    var actions = new org.openqa.selenium.interactions.Actions(WDS.browser)
    
    wait.until(ui.ExpectedConditions.visibilityOfElementLocated(pkg.By.ByXPath("//ul[@class='availableList']//div[contains(@title,'Resend Messages')]")))
    
    var resendDashlet = WDS.browser.findElement(pkg.By.ByXPath("//ul[@class='availableList']//div[contains(@title,'Resend Messages')]"))
    var col2 = WDS.browser.findElement(pkg.By.ByXPath("//ul[@id='template_x002e_customise-dashlets_x002e_customise-user-dashboard_x0023_default-column-ul-2']"))
    
    //the element resendDashlet needs to be dragged and dropped into col2
    
    actions.clickAndHold(resendDashlet).moveToElement(col2).release(col2).build().perform()
    
    

     

There are many out there who had a few queries on how can the above be achieved. Hope the above tips were helpful. If there are more will keep updating this page or create more.

Advertisements

Running UI based performance tests for continuous integration using Selenium Grid + JMeter + Jenkins with reports.

Now you can run JMeter tests part of your continuous integration. More over you can run your browser related load tests  on remote machines using Selenium Grid and Jenkins Performance Plugin. The following pages will help you to achieve this.

Create JMeter tests which runs with Selenium Grid.

Configuring Jenkins to trigger and run JMeter test

Find more information in my talk at the Selenium Conference Austin 2017 found below.

Create JMeter tests which runs with Selenium Grid.

 

  • Create a new Test Plan in JMeter.
  • Add a Thread group.
  • Make sure the Selenium related plugins are install in the JMeter tool, else get them added with the help of the “Plugin Manager” (found under “Options”).

    Screen Shot 2017-02-15 at 10.33.52

  • Right Click on the Thread Group Goto Controller -> Add Simple Controller
  • Go to Config Element -> Add Remote WebDriver Config to the Simple Controller.

    Screen Shot 2017-02-15 at 10.34.28.png

  • Go to Sampler -> Add WebDriver Sampler to the Simple Controller under Remote WebDriver Config

    Screen Shot 2017-02-15 at 11.02.50.png

  • Once the the WebDriver Sampler is added write the Selenium code in the Sampler to run your automated tests. Add an assertion, and the Listeners like Summary Report and other Listeners.

    Screen Shot 2017-02-15 at 11.03.21.png

  • Make sure you set up the hub in your machine and connect them to the nodes, and add the node machine IP Address in the Selenium Grid URL space in Remote Webdriver Config, As shown below.

    Eg:- http://<IP_ADDRESS&gt;:<NODE PORT>/wd/hub

    Screen Shot 2017-02-15 at 14.45.30.png

  • Now you can run the tests on the node machines.

 

Configuring Jenkins to trigger and run JMeter test

 

  • Install Jenkins.
  • Download the Performance Plug-in (performance.hpi) for Jenkins from https://wiki.jenkins-ci.org/display/JENKINS/Performance+Plugin.
  • Unload Jenkins. Save the performance.hpi in the Plugins folder in the Jenkins. eg:- /Users/Shared/Jenkins/Home/plugins/
  • Load Jenkins. Login and goto Manage Jenkins -> Manage Plugins -> Installed (Tab) and check if the performance plugin is available.

    Screen Shot 2017-02-22 at 11.40.22

  • In the your Jmeter /bin/user.properties add the following line
        #jmeter.save.saveservice.output_format=xml
  • Now create a JMeter script and check it is working fine. This script can be the script created with the Remote WebDriver Config mentioned above.

     

  • Now try to run it with the following command on the terminal and check if the tests are running fine
         sh jmeter.sh -Jjmeter.save.saveservice.output_format=xml -n -t /<jmeter_script_location>/TestScript.jmx -l /<jmeter_test_result_location>/TestResult1.jtl
    
    
  • Go to Jenkins and Click on Create a new Job / New Item then select Freestyle project -> name it (eg:- JMeterSeleniumGridJenkins)

    Screen Shot 2017-02-21 at 12.36.17.png

  • Navigate to the project and Click on Configure.

    Screen Shot 2017-02-21 at 13.06.23.png

  • Scroll down to Build and click on Add a build step -> Execute shell.

    Screen Shot 2017-02-21 at 14.17.57.png

  • Add the following script in the command box.
          cd /<apache_jmeter_folder_location>/bin/
          sh jmeter.sh -Jjmeter.save.saveservice.output_format=xml -n -t /<jmeter_script_location>/TestScript.jmx -l /<jmeter_test_result_location>/TestResult1.jtl

    Screen Shot 2017-02-21 at 14.35.40.png

  • Scroll down to Post Build Actions and select Publish Performance test Result

    Screen Shot 2017-02-21 at 14.37.10

  • Select JMeter for for the Performance Report and give the path /<jmeter_test_result_location>/TestResult1.jtl

    Screen Shot 2017-02-21 at 14.37.33.png

  • You can change the threshold etc according to your need. Then click on save.

    Screen Shot 2017-02-21 at 14.38.10.png

  • Then click on Build now in the project. And click on the running build and check the Console Output.

    Screen Shot 2017-02-21 at 16.35.11.png

  • In case issues with the run please check the Read and Write option of the folders of accessing.
  • You should have the Performance reports displayed as well.

    Screen Shot 2017-02-21 at 16.35.20.png

 

Distributed Testing and Test Reporting with Selenium

As we are moving into the agile world, continuous integration has a major role to play.

So how do we cater for a complete test on every sprint or every release? We can use Selenium for Test Automation. When we use a continuous integration approach it would be helpful to use Selenium Grid. It allows you to run your tests on different machines against different browsers in parallel. Essentially, Selenium-Grid supports distributed test execution.

This helps you to run your automated tests on various different machines, operating systems and browsers at the same time. This saves time and would help  to run your testing in a nightly build.

Extent Reports will go hand in hand with Selenium Grid as it will help you retrieve all test results including Test Evidences into a comprehensive report. This webinar would give you a quick look of how to use both Selenium Grid and Extent Reports.

 

Comparing content value of a file with response JMeter

When working with data related systems, you will have to upload multiple documents as well as download documents and check if the downloaded documents is the same as you expected it to be.

When you call the API call for download and you have the same document in your system or your JMeter package then you can compared the content with the file that you have with you. As always you will have to use the response assertion to compare the file with the response you receive when you download the file from the application (you are testing).

The following call needed to be added in the response assertion of the Download API Call.

${__FileToString(/Users/testing-excellence/Perf/blog/json_file.txt,,)}

screen-shot-2017-02-02-at-3-26-48-pm

You can also a CSV Data config if you will have to compare the response with multiple downloads. Say you know that the download is going to be in order or you would like to make a specific call with a json value and you will need to make the call multiple times then you can use the above call for help.

You can have a CSV file with the names of the files(without extensions) with the respective json you need to to use the following call in the body

${__FileToString(/Users/testing-excellence/Perf/blog/${__eval(${json_file})}.txt,,)}
Where json_file as the CSV Data config variable.
screen-shot-2017-02-02-at-15-12-57

Uploading a document from same source document with jMeter.

This is another script that you can use to upload the same document to your system using jMeter. This is another way of doing as I have mentioned here.

import java.text.*;
import java.io.*;
import java.lang.*;
import org.apache.commons.io.FileUtils;

//Take the fileLocation from the user defined variable
//fileLocation = “/Users/cthalayasingam/Documents/jmeterTest/PerformanceTests/”;
fileLocation = vars.get(“fileCreatedPath”);
// The string portrays the current location of the document (Source file)
mainFile = “images.png”;
//The string portrays the location of the document which is renamed.
System.out.println(System.currentTimeMillis());
start = System.currentTimeMillis();
fileName = start + “images.png”;
//Save the name of the document with the time so that can be DELETED later
vars.put(“fileName1”, fileName);
//Get current document location
File file = new File( fileLocation + mainFile);
//Create location for renamed location
File file2 = new File( fileLocation + fileName);
System.out.println(fileName);
//Copy the file to the document to the new location
FileUtils.copyFile(file, file2);

After you have entered the above script in the Bean Shell pre processor. Then put the script in the delete script found below in a BeanShell Post Processor, that applies the delete for the document you have copied to the new destination.

import java.text.*;
import java.io.*;
import java.util.*;
import java.lang.*;

csvDir = vars.get(“fileCreatedPath”);
fileName2 = vars.get(“fileName1”);
File file1 = new File( csvDir + fileName2);
if (file1.exists()) {
file1.delete();
}