← Blog

"Selenium Series #10: JavaScriptExecutor — Scrolling, DOM Manipulation and Beyond WebDriver"

When WebDriver can't do it, JavaScript can. Learn to scroll pages, click overlapping elements, manipulate DOM values, extract computed styles, and interact with elements not reachable via standard APIs.

reading now
views
comments

Series Navigation

Part 9: Windows, Frames and Alerts

Part 11: Actions Class — Mouse, Keyboard and Drag-Drop


What Is JavaScriptExecutor?

JavaScriptExecutor is an interface that lets you run JavaScript code directly in the browser from your Selenium test. Cast any WebDriver to it:

JavascriptExecutor js = (JavascriptExecutor) driver;

// Execute script with no return value
js.executeScript("window.scrollTo(0, 500);");

// Execute script and get return value
String title = (String) js.executeScript("return document.title;");
Long count    = (Long)   js.executeScript("return document.querySelectorAll('a').length;");

// Execute script with WebElement argument (arguments[0] refers to the element)
WebElement element = driver.findElement(By.id("myBtn"));
js.executeScript("arguments[0].click();", element);
js.executeScript("arguments[0].scrollIntoView(true);", element);

// Execute with multiple arguments
js.executeScript("arguments[0].value = arguments[1];", element, "new value");

Scrolling

JavascriptExecutor js = (JavascriptExecutor) driver;

// Scroll to absolute position (x, y) in pixels
js.executeScript("window.scrollTo(0, 500);");

// Scroll to bottom of page
js.executeScript("window.scrollTo(0, document.body.scrollHeight);");

// Scroll to top
js.executeScript("window.scrollTo(0, 0);");

// Scroll by relative amount (right, down)
js.executeScript("window.scrollBy(0, 300);");

// Scroll specific element into view
WebElement footer = driver.findElement(By.tagName("footer"));
js.executeScript("arguments[0].scrollIntoView(true);", footer);

// Scroll into view with alignment options
// true  = align to top of viewport
// false = align to bottom of viewport
js.executeScript("arguments[0].scrollIntoView({behavior:'smooth', block:'center'});", footer);

// Scroll inside a scrollable div (not the whole page)
WebElement scrollableDiv = driver.findElement(By.id("scrollable-table"));
js.executeScript("arguments[0].scrollTop = arguments[0].scrollHeight;", scrollableDiv);

Clicking When WebDriver Can't

// When element.click() fails because something overlaps it
WebElement hiddenBtn = driver.findElement(By.id("overlappedButton"));
js.executeScript("arguments[0].click();", hiddenBtn);

// When element is hidden (display:none) but you need to click it
// (e.g. hidden file input)
WebElement fileInput = driver.findElement(By.id("fileInput"));
js.executeScript("arguments[0].style.display='block';", fileInput);
fileInput.sendKeys("/path/to/file.pdf");

// Remove disabled attribute
WebElement disabledBtn = driver.findElement(By.id("submitBtn"));
js.executeScript("arguments[0].removeAttribute('disabled');", disabledBtn);
disabledBtn.click();

Setting and Reading Values

// Set input value (bypasses sendKeys — useful for date pickers)
WebElement dateField = driver.findElement(By.id("startDate"));
js.executeScript("arguments[0].value = '2021-06-15';", dateField);

// Trigger change event after setting value (some React/Angular apps need this)
js.executeScript(
    "arguments[0].value = '2021-06-15'; " +
    "arguments[0].dispatchEvent(new Event('change'));",
    dateField
);

// Set localStorage
js.executeScript("localStorage.setItem('authToken', 'abc123');");

// Get localStorage value
String token = (String) js.executeScript("return localStorage.getItem('authToken');");

// Set cookie via JavaScript
js.executeScript("document.cookie = 'session=xyz123; path=/';");

// Read computed CSS property (what's actually rendered, after stylesheets)
String backgroundColor = (String) js.executeScript(
    "return window.getComputedStyle(arguments[0]).backgroundColor;",
    driver.findElement(By.id("header"))
);
System.out.println("BG color: " + backgroundColor); // rgb(25, 25, 112)

Page Information

// Page title
String title = (String) js.executeScript("return document.title;");

// Current URL
String url = (String) js.executeScript("return document.URL;");

// Page ready state
String readyState = (String) js.executeScript("return document.readyState;");
// Returns: "loading", "interactive", or "complete"

// Wait for page to fully load
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(d -> ((JavascriptExecutor) d)
    .executeScript("return document.readyState").equals("complete"));

// Count all links
Long linkCount = (Long) js.executeScript("return document.querySelectorAll('a').length;");

// Get all links hrefs as a list
List<String> hrefs = (List<String>) js.executeScript(
    "return Array.from(document.querySelectorAll('a')).map(a => a.href);"
);

Highlighting Elements (Useful for Debugging)

public void highlightElement(WebElement element) {
    JavascriptExecutor js = (JavascriptExecutor) driver;

    // Save original style
    String originalStyle = element.getAttribute("style");

    // Apply highlight
    js.executeScript(
        "arguments[0].setAttribute('style', arguments[1]);",
        element,
        "border: 3px solid red; background-color: yellow;"
    );

    // Pause so you can see it
    try { Thread.sleep(500); } catch (InterruptedException e) { }

    // Restore original style
    js.executeScript(
        "arguments[0].setAttribute('style', arguments[1]);",
        element,
        originalStyle
    );
}

JavaScriptExecutor Utility Class

public class JSUtils {

    private final JavascriptExecutor js;

    public JSUtils(WebDriver driver) {
        this.js = (JavascriptExecutor) driver;
    }

    public void scrollToBottom() {
        js.executeScript("window.scrollTo(0, document.body.scrollHeight);");
    }

    public void scrollToTop() {
        js.executeScript("window.scrollTo(0, 0);");
    }

    public void scrollIntoView(WebElement element) {
        js.executeScript("arguments[0].scrollIntoView({block:'center'});", element);
    }

    public void click(WebElement element) {
        js.executeScript("arguments[0].click();", element);
    }

    public void setValue(WebElement element, String value) {
        js.executeScript(
            "arguments[0].value = arguments[1]; " +
            "arguments[0].dispatchEvent(new Event('input')); " +
            "arguments[0].dispatchEvent(new Event('change'));",
            element, value
        );
    }

    public String getInnerText(WebElement element) {
        return (String) js.executeScript("return arguments[0].innerText;", element);
    }

    public boolean waitForPageLoad() {
        WebDriverWait wait = new WebDriverWait((WebDriver) js, 30);
        return wait.until(d ->
            ((JavascriptExecutor) d).executeScript("return document.readyState")
                .equals("complete")
        );
    }

    public void setLocalStorage(String key, String value) {
        js.executeScript("localStorage.setItem('" + key + "', '" + value + "');");
    }

    public String getLocalStorage(String key) {
        return (String) js.executeScript("return localStorage.getItem('" + key + "');");
    }

    public void clearLocalStorage() {
        js.executeScript("localStorage.clear();");
    }
}

What's Next

In Part 11 we use the Actions class for complex mouse interactions — hover menus, drag and drop, right-click, double-click, and keyboard shortcuts that require modifier keys.

Discussion

Loading...

Leave a Comment

All comments are reviewed before appearing. No links please.

0 / 1000