Javascript Executor in Selenium

A Javascript is a small chunks of a program that makes a website interactive. For example, a javascript could create a pop-up alert box, or provide a dynamic dropdown menu.

JavaScript code can listen to even on the web page, like reacting to a click on a button, reacting to when checking a checkbox, or when we enter any value into the text bar.

Javascript can change the content of the HTML page dynamically; it can also change the attributes of a web element like changing a button from the disabled state to enabled state.

JavascriptExecutor vs. Javascript Webdriver : There is a chance that sometimes people get confused with this topic; this tutorial totally deals with JavascriptExecutor. JavascriptExecutor is something that is present in every selenium tool, and in all the languages, we can execute it on the browser.

Javascript Webdriver is another version of the webdriver tool and known as Webdriverjs or Protractor, where we use javascript or Typescript (a superset of javascript) as a programming language, in Protractor also we have JavascriptExecutor.

Note : Typescript has a good scope in the future as it handles with angularjs applications.

Javascript Executor : Javascript executor allows you to run pure Javascript code irrespective of the Selenium language binding(Java, C#, Python, etc.) you are using.

We should go for Javascript Executor only when we are not able to perform a particular task with our selenium; like some, we may not be able to click an element, such cases we can go for Javascript Executor.

To use Javascript Executor, we may require little or no knowledge of javascript. We can get the commands from google (I do so), so do not worry much about it, I will try to cover Javascript Executor as much as possible in this tutorial.

JavascriptExecutor Interface

JavascriptExecutor is an interface present under org.openqa.selenium package in Selenium Webdriver. JavascriptExecutor Interface has two abstract methods which are :

1. executeScript()
2. executeAsyncScript()


How to use Javascript Executor in Selenium Webdriver :
We have to cast driver object into JavascriptExecutor type to use the methods present in the JavascriptExecutor interface

// cast the driver object to JavascriptExecutor
JavascriptExecutor js = (JavascriptExecutor) driver;

// access the methods
js.executeScript("javascript command");
js.executeAsyncScript("javascript command");

In a shorter way but not a preferred way

// cast the driver object to JavascriptExecutor
((JavascriptExecutor) driver).executeScript("javascript command");

Now let's see how to perform all the remaining operations in using the JavascriptExecutor interface.

Methods present in JavascriptExecutor



executeScript()
The executeScript method executes given JavaScript in the current frame if the control is inside the frame; if the control is on page level(window level, i.e. outside frames), javascript will be executed in the current frame.

All the local variables created inside the javascript block will be destroyed once the block execution is over, but if the variable is created globally, it will be present for other javascript code.

JavascriptExecutor just runs the javascript in the browser, but it will not return any value by default, if we want to return any value from the javascript block, then we must use return statement along with our javascript.

We can manipulate the returned value based on our need like asserting or to check whether it contains something so on..

The code we write in javascript is either called a query or javascript command.

Example: Below code returns the title of the page.

((JavascriptExecutor) driver).executeScript("return document.title");

If Javascript code has a return statement, then it could return one of the following:

1. This method returns a WebElement if the javascript command results in an HTML element.
2. A Double value is returned if the javascript command results in Decimal value.
3. A Long value will be returned if the javascript command results in a non-decimal number value.
4. A Boolean is returned if the query results in a boolean value.
5. For all other primary values, String will be returned.
6. List<Object> will be returned if the query results in an array. It also supports nested lists. Lists must fall under above one of the category (WebElement, Decimal value, Long, Boolean, String).
7. Map<String, Object> will be returned if the query results in Map and values in the map must fall under the above category(WebElement, Decimal value, Long, Boolean, String).

The actual syntax of the executeScript method:

executeScript(String script, Object... args)


String Script : 'Script' is the javascript to be executed; it must be the type of String.
Object... args 'args' can be a number, a boolean, a String, WebElement, or a List of any combination previously mentioned types. If the given argument does not fall under these categories, then selenium webdriver will throw an Exception.

executeAsyncScript : I am still researching on this topic, so I will update this section very soon.

Find an Element with JavascriptExecutor

We can find the element with JavascriptExecutor, and we can perform all the operations using selenium webdriver

Steps to Find Element :
1. Create an object for Browser and navigate to URL

2. Cast the driver object to JavascriptExecutor

3. Call the executeScript("Command") method from the object; we have to use a return statement to return a value from the browser.

4. We have to cast the object returned from JavascriptExecutor to webelement to access all the web element related methods.

import java.util.concurrent.TimeUnit;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class FindElementJS {
	public static void main(String[] args) {
		// set the geckodriver.exe property
		System.setProperty("webdriver.gecko.driver", "C:/Users/user/Pictures/geckodriver.exe");
		// open firefox
		WebDriver driver = new FirefoxDriver();
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

		// open webpage
		driver.get("https://google.com");

		// find the search textbar in JavascriptExecutor
		JavascriptExecutor js = (JavascriptExecutor) driver;

		Object searchTextbar = js.executeScript("return document.getElementById('lst-ib')");
		// we have to cast the returned object into webelement to access
		// all the webelement related methods
		((WebElement) searchTextbar).sendKeys("abc");

		/* (same as above) find the search textbar in selenium
		driver.findElement(By.id("lst-ib")).sendKeys("abc");*/
	}
}

How to handle browser windows using selenium webdriver

Click an element with JavascriptExecutor

We can click an element present in the webpage using JavascriptExecutor

In this tutorial I have used getElementsByName which is DOM locator, this method tries to find all the elements that have name attribute 'btnI' on the web page,

Steps to perform a click with JavascriptExecutor :
1. Create an object for Browser and navigate to URL

2. Cast the driver object to JavascriptExecutor

3. Call the executeScript("document.getElementsByName('btnI')[0].click()") method from the object, this methods performs the click.

4. document.getElementsByName('btnI')[0].click() is the javascript command for click operation

public class ClickJSE {
	public static void main(String[] args) {
		// set the geckodriver.exe property
		System.setProperty("webdriver.gecko.driver", "C:/Users/user/Pictures/geckodriver.exe");
		// open firefox
		WebDriver driver = new FirefoxDriver();
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

		// open webpage
		driver.get("https://google.com");

		JavascriptExecutor js = (JavascriptExecutor) driver;

		// click i am lucky in JavascriptExecutor
		js.executeScript("document.getElementsByName('btnI')[0].click()");

		/* (same as above) click i am lucky button in selenium
		driver.findElement(By.name("btnI")).click();*/
	}
}

Sendkeys with JavascriptExecutor

JavascriptExecutor has provisions for setting the value to text bars / textarea basically for all the input elements; we can perform sendkeys operation using JavascriptExecutor in selenium webdriver

Steps to perform Sendkeys in JavascriptExecutor :
1. Create an object for Browser and navigate to URL

2. Cast the driver object to JavascriptExecutor

3. Call the executeScript("document.getElementById('lst-ib').value='ppp'") method from the object, this methods sets a value to input element.

4. document.getElementById('lst-ib').value='ppp' is the javascript command for setting a value

public class SendkeysJSE {
	public static void main(String[] args) {
		// set the geckodriver.exe property
		System.setProperty("webdriver.gecko.driver", "C:/Users/user/Pictures/geckodriver.exe");
		// open firefox
		WebDriver driver = new FirefoxDriver();
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

		// open webpage
		driver.get("https://google.com");

		JavascriptExecutor js = (JavascriptExecutor) driver;

		// set google search bar value
		js.executeScript("document.getElementById('lst-ib').value='chercher tech'");

		/* (same as above) send keys to search bar in selenium
		driver.findElement(By.id("lst-ib")).sendKeys("chercher tech");*/
	}
}

Custom Locators in Selenium

Scroll webpage in JavascriptExecutor

Sometimes we may need to scroll a webpage to a particular position; we cannot perform the scroll operation using selenium webdriver, During such scenarios, we have to use JavascriptExecutor to scroll the webpage

Steps to scroll webpage in JavascriptExecutor :
1. Create an object for Browser and navigate to URL

2. Cast the driver object to JavascriptExecutor

3. Call the executeScript("window.scrollBy(0,300)") method from the object, this methods scrolls the webpage to particular distance

4. window.scrollBy(0,300) is the javascript command for scrolling a page, scrollBy(horizontalDistance, verticalDistance) accepts two parameter

1. horizontalDistance - distance to be scrolled horizontally
2. verticalDistance - distance to be scrolled vertically
We have to set 'hozontalDistance=0' for scrolling vertically, vice-versa

public class FindElementJS {
	public static void main(String[] args) {
		// set the geckodriver.exe property
		System.setProperty("webdriver.gecko.driver", "C:/Users/user/Pictures/geckodriver.exe");
		// open firefox
		WebDriver driver = new FirefoxDriver();
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

		// open webpage
		driver.get("https://google.com");

		JavascriptExecutor js = (JavascriptExecutor) driver;

		// scroll vertically by 300 px
		js.executeScript("window.scrollBy(0,300)");
	}
}

Handle dropdowns in selenium

Scroll Into View in JavascriptExecutor

Sometimes we may need to scroll a webpage to a particular location/element, those cases we can use scrollIntoView method in javascript to scroll


Insight :
Selenium 2 tries to scroll to the element and then click on it. This is because Selenium 2 will not interact with an element unless it thinks that it is visible.

Scrolling to the element happens implicitly, so you just need to find the item and then work with it.

Use below way only when required or when selenium fails to scroll to the element implicitly.

Steps :
1. Cast the driver object to JavascriptExecutor
2. Find the element using the DOM locator and call the scrollIntoView method.

public class ScrollToView {
	public static void main(String[] args) {
		// set the geckodriver.exe property
		System.setProperty("webdriver.gecko.driver", "C:/Users/user/Pictures/geckodriver.exe");
		// open firefox
		WebDriver driver = new FirefoxDriver();
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

		// open webpage
		driver.get("https://chercher.tech/java/javascript-executor-selenium-webdriver");

		JavascriptExecutor js = (JavascriptExecutor) driver;

		// scroll to particular element
		js.executeScript("document.getElementById('default').scrollIntoView(true)");
	}
}

Take Page & Element Screenshot, Compare Screenshots in selenium

Web page Operations with JavascriptExecutor

We can use JavascriptExecutor to perform or to retrieve details about the current page in selenium webdriver.

Title of the page with JavascriptExecutor :
We can get the title of the webpage using JavascriptExecutor, using the document.title command in javascript, which returns title as a string

document point to the current webpage if the control is in the webpage, if control is inside a frame then it points to URL of the frame

JavascriptExecutor js = (JavascriptExecutor) driver;

// return the title of the page
js.executeScript("return document.title");

/* //(same as above) get title
driver.getTitle();*/


URL with JavascriptExecutor :
We can retrieve the URL of the current page with JavascriptExecutor using the document.URL javascript command

JavascriptExecutor js = (JavascriptExecutor) driver;

// return the url of the page
js.executeScript("return document.title");

/* //(same as above) get url
driver.getCurrentUrl();*/


Webpage loaded or not using JavascriptExecutor :
With JavascriptExecutor, we can check the state of the webpage loaded or not. document.readyStatejavascript command gives detail about page load. If the page is loaded completely, it returns a Complete as a value if the page is still loading it returns 'interactive' as a result

JavascriptExecutor js = (JavascriptExecutor) driver;

// return the state of the page load
js.executeScript("return document.readyState");


Domain Name with JavascriptExecutor :
We can retrieve the domain name alone from the webpage rather than the full URL using JavascriptExecutor using the return document.domain javascript command
"https://chercher.tech/java/index" is the URL, "https://chercher.tech" is the domain

JavascriptExecutor js = (JavascriptExecutor) driver;

// return the state of the page load
js.executeScript("return document.domain");


Zoom Levels with JavascriptExecutor :
JavascriptExecutor allows the user to set the zoom level while running the code, document.body.style.zoomhelps to set the zoom level on the webpage.
The below code sets the zoom level to 90%.

JavascriptExecutor js = (JavascriptExecutor) driver;

// set zoom level to 90%
js.executeScript("document.body.style.zoom='90");


Highlight an Element in JavascriptExecutor :
We can highlight the element using JavascriptExecutor; to highlight an element first, we have to find the element uniquely. style.backgroundColor changes the background of the element to 'custom color'.

JavascriptExecutor js = (JavascriptExecutor) driver;

// highlight the search bar on google.
js.executeScript("document.getElementById('lst-ib').style.backgroundColor='red'");

Browser Properties with JavascriptExecutor

We can retrieve browser properties using JavascriptExecutor

Inner - Webpage
Outer - Browser

inner-outer-height-javascript-executor

Size of Webpage in JavascriptExecutor : We can get the height of the webpage using window.innerHeight command in javascript, similarly we can fetch the width of the webpage as well using window.innerWidth.

These commands will not return the total height and width of the webpage, but they will return the height and width, which is visible to the user.

JavascriptExecutor js = (JavascriptExecutor) driver;

// height of the webpage
js.executeScript("window.innerHeight");

// width of the webpage
js.executeScript("window.innerWidth");


Size of the browser in JavascriptExecutor : JavascriptExecutor helps the user to fetch the height and width of the browser; the height of the browser not only contains the webpage it also contains the address bar (URL bar), menubar, bookmarks bar.

We can fetch the height of the browser using the window.outerHeight. Similarly, we can also retrieve the width of the browser using window.outerWidth

JavascriptExecutor js = (JavascriptExecutor) driver;

// height of the webpage
js.executeScript("window.outerHeight");

// width of the webpage
js.executeScript("window.outerWidth");


Scroll By Pages in JavascriptExecutor :
We can scroll the webpage based on the number of pages in selenium webdriver using JavascriptExecutor; one page is nothing but whatever you can see on the screen for that moment. It is basically nothing but simulating 'PageDown or PgDn' key on the keyboard.

Below code scrolls the webpage by three page-downs.

JavascriptExecutor js = (JavascriptExecutor) driver;

// scrolls the page by three page downs
js.executeScript("window.scrollByPages(3)");


Similarly, we can perform page up as well in the above command; we have pass a negative number to simulate the pageup. Below code scrolls the webpage by 5 page ups

// scrolls the page by 5 page up
js.executeScript("window.scrollByPages(-5)");


Navigate to Url in JavascriptExecutor :
We normally use a driver.get() and driver.navigate().to() methods present in selenium webdriver to open a webpage, but we can use the window.location method present in the JavascriptExecutor to Open a webpage.

This method navigates the user to the given URL, below code, navigates the user to the google page.

JavascriptExecutor js = (JavascriptExecutor) driver;

// Opens the Google page
js.executeScript("window.location="https://google.com";");


Maximum Scroll distance in JavascriptExecutor :
With JavascriptExecutor in selenium, we can calculate the maximum scrollable distance using the window.scrollMaxY and window.scrollMaxX.

window.scrollMaxY gives detail about how much distance we can scroll Vertically, window.scrollMaxXgives maximum scroll detail about how much distance we can scroll Horizontally

JavascriptExecutor js = (JavascriptExecutor) driver;

// maximum scroll distance vertically
js.executeScript("return window.scrollMaxY

// maximum scroll distance Horizontally
js.executeScript("return window.scrollMaxX");

When we read something, we must analyze that before accepting, because everything is linked. For example, try to derive what else you can do with the above result.

Yes, Your guess is right, 1. We can verify whether the scrollbar is present or not; when Maximum scrolls are zero, then there are no scroll bars.

Note for very beginners : I have used ' ! ' which changes the true to false, and false to true (most of us know it, but this note is for very beginners)

public class PresenceOfScrollBar {
	public static void main(String[] args) {
		// set the geckodriver.exe property
		System.setProperty("webdriver.gecko.driver", "C:/Users/user/Pictures/geckodriver.exe");
		// open firefox
		WebDriver driver = new FirefoxDriver();
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

		// open webpage
		driver.get("https://chercher.tech/java/javascript-executor-selenium-webdriver");

		JavascriptExecutor js = (JavascriptExecutor) driver;

		// get the maximum scroll distance Horizontally
		Object horizontalScrollBar = js.executeScript("return window.scrollMaxX");

		// get the maximum scroll distance Vertically
		Object verticalScrollBar = js.executeScript("return window.scrollMaxY");

		if(! horizontalScrollBar.equals("0")){
			System.out.println("Horizontal Scroll bar is Present");
		}else{
			System.out.println("Horizontal Scroll bar is Not Present");
		}

		if(! verticalScrollBar.equals("0")){
			System.out.println("Vertical Scroll bar is Present");
		}else{
			System.out.println("Vertical Scroll bar is Not Present");
		}
	}
}

Why we should not use JavascriptExecutor

Why is it a bad solution ?

The Selenium Webdriver works a similar way to a user; selenium webdriver will perform the operation only if a user(physical person) can perform the operation on the element.

We can rely on selenium webdriver if Selenium says that it cannot interact with an element, then the physical person also cannot interact with the element.

So, It is better to fail the test case when selenium methods fail instead of trying with JavascriptExecutor.

For example, you may have a transparent element that is covering the element that you want to click on and blocking the click action so that you can't reach it. Visually, it will be visible to you, but Selenium will correctly see it as not visible.

With the above case, if you try with the JavaScript executor to click on that element, your test will pass, but users will not be able to access that element when they try to use your website.

Before going to try with JavascriptExecutor, you must try to execute your selenium code with a different browser, if it works well with other browsers, then only you should go for the JavascriptExecutor, but if the test is failing in all browser, then you should fail the test case.

So the user should give the least priority to JavascriptExecutor. Sometimes slightly increasing or decreasing the selenium version or driver server version may work for you. So, do not be hasty to use JavascriptExecutor.

Learn about Inheritance in Java & Selenium

Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions