jQuery injection for Selenium Automation tests

Introduction

Guillermo Jose Aiquel
Virtualmind
Published in
4 min readOct 2, 2018

--

Selenium WebDriver provides methods to manipulate the browser, find elements and interact with them, but sometimes they are not enough and you need other ways to take the actions you need. As you know, Selenium can run javascript code on the browser, so… why not run the jQuery functions that you need to hack your testing?

Problems to solve

The Selenium built in methods to get elements use css or xpath locators, but you can’t distinguish between dynamics statuses of the elements like ‘hover’, ‘focus’, ‘enabled’, ‘visible’, etc. It’s really common on web applications that a modal or dialog exists on the DOM but it is hidden, and is a good case to use the “visible” suffix on the selector to get it only when it is visible.

Enhanced features

The known javascript library, called jQuery, provides a bunch of methods that can be performed over any web element and, of course, since Selenium is able to run javascript code, you can run jQuery methods on them using WebDriver.

This library also allows you to use all CSS enhanced selectors, like “:has”, “:not”, “:contains” to find in a better way the element you need.

How to inject jQuery library

There is no weird trick to inject the jQuery library into the page, it is the same way you can do it by using the browser console manually. By the way, every time the page is refreshed you should inject it if necessary.

The javascript code to inject the library is the following:

// Javascript code

var headID = document.getElementsByTagName(“head”)[0];

var newScript = document.createElement(‘script’);

newScript.type = ‘text/javascript’;

newScript.src = ‘https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js';

headID.appendChild(newScript);

Basically you are creating a new HTML ‘script’ element whose source is the link to the jQuery library (in the example above it is injecting version 3.3.1, but you can use the one you need).

To execute javascript with WebDriver, you should use JavascriptExecutor, so let me show you how to do it, and how to perform the injection.

// Java code

JavascriptExecutor js = (JavascriptExecutor) driver;

js.executeScript(

“var headID = document.getElementsByTagName(“head”)[0];” +

“var newScript = document.createElement(‘script’);” +

“newScript.type = ‘text/javascript’;” +

“newScript.src = ‘https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js';” +

“headID.appendChild(newScript);”);

After the injection is executed we need to wait until jQuery is fully loaded, so we need to create an Explicit wait to do it and be sure we succeed:

// Java code

WebDriverWait wait = new WebDriverWait(driver, 30);

Function<WebDriver, Boolean> jQueryAvailable = WebDriver -> (

(Boolean) js.executeScript(“return (typeof jQuery != \”undefined\”)”)

);

wait.until(jQueryAvailable);

What the code above does is to wait for 30 seconds for jQuery to be available. We can know that it is loaded by running javascript code asking if the type of jQuery is not undefined. When the condition is true, the method stops waiting.

Well, after all this you can run jQuery code or use its selector enhancements to find elements, but we can still improve something in order to avoid future issues with some other third party libraries. Injecting jQuery replaces the dollar sign ‘$’ value from javascript global variables, it is the shortener used to access jQuery methods, so we need to restore the value it had before we inject the library, no matter if it was in use or not, but it is a good practice to avoid future issues. Run the following code to avoid conflicts:

// Java code

js.executeScript(“$.noConflict();”);

How to use jQuery selectors and methods

Once jQuery is injected and available for us on the webpage, we can use any of its methods or enhanced selectors. Remember that after running noConflict() method, we are not able to use the shortcut symbol (dollar sign) to access jQuery, so we need to call it with the jQuery keyword.

Again the JavascriptExecutor will be needed, because we are going to run javascript code. For example, for getting Web Elements you should run code as the one below:

// Java code

JavascriptExecutor js = (JavascriptExecutor) driver;

List<WebElement> elements = (List<WebElement>) js.executeScript(“return jQuery.find(‘div.className:visible’)”);

You can find all jQuery selectors here.

There is not much difference for executing jQuery methods, you can do it the following way:

// Java code

JavascriptExecutor js = (JavascriptExecutor) driver;

Long w = (Long) js.executeScript(“return jQuery.find(‘div.className:visible’).width()”);

So now you have no constraints on managing jQuery and JavascriptExecutor. You are able to run any javascript and jQuery code you need. Think big and rock your code using the wide features of the jQuery you love.

--

--