Accessing JavaScript variables through Selenium WebDriver

I've been using Selenium WebDriver with Java and TestNG to conduct testing on a website that I developed. This website includes JavaScript, which returns values and also outputs them to the browser console using console.log().

I'm curious if there's an effortless way for Selenium WebDriver to retrieve this JavaScript data for me to carry out assertions using TestNG.

Although I am new to Selenium, I understand that you can do something like:

WebDriver driver = new ChromeDriver();
driver.findElement(By.id("btn")).click();

So, is there a similar approach I can take using WebDriver to access the JavaScript on the site?


Clarification

It seems like some people assume that I want to "execute" JavaScript code through Selenium.

That's not my intention. Instead, I aim to store pre-defined JavaScript variables using Selenium.

In essence, I want Selenium to capture the value of the JavaScript variable, store it locally, and then run an assertion test on it.


Attempt 1

Let's say I have the following JavaScript code for my website:

$(document).ready(function() {
    var foo = $(#"input-field-val").val();

    function returnFoo() {
        return foo;
    }
});

Based on what I've read and understood so far, in my separate Selenium test file (Selenium.java), I should be able to do something like this?:

public class Selenium {
    WebDriver driver = new FirefoxDriver();
    JavascriptExecutor js = (JavascriptExecutor) driver;

    @Test
    public void testSample() {
        driver.get("www.mywebsite.com");
        js.executeScript("alert(returnFoo());");
    }
}

I've attempted something akin to the above but no alert box appears. Instead, I receive an error message:

Exception in thread "main" org.openqa.selenium.WebDriverException: ReferenceError: returnFoo is not defined

It's evident that I may be misunderstanding when it's mentioned that the JS variable

should not be part of a closure or local variable

I have even tried declaring a global variable above the $(document).ready(function()... and setting it within function returnFoo(), yet it still doesn't work.


Attempt 2

I have now moved both foo and returnFoo() outside of the $(document).ready(function().... This has resolved the ReferenceError message from Attempt 1.

I have also assigned a value to foo, so my JS code looks something like this:

var foo = "Selenium test run";

$(document).ready(function() {
...
});

function returnFoo() {
    return foo;
}

Currently, I'm facing difficulty assigning the return value of returnFoo() to a local variable within my Selenium test. Here's what I've tried:

public static void main(String[] args) {
        WebDriver driver = new FirefoxDriver();
        JavascriptExecutor js = (JavascriptExecutor) driver;

        driver.get("http://localhost:8080/HTML5TestApp/prod.html");
        Object val = js.executeScript("window.returnFoo();");
        System.out.println(val);
    } 

However, the console displays null instead of the actual value of "Selenium test run".

Attempt 2 - SOLUTION

It appears that if I use

Object val = js.executeScript("alert(returnFoo());");
, I obtain the value of foo.


SOLUTION

Therefore, here's how I've addressed my issue, thanks to Martin Foot's solution below.

In my JavaScript file, I created a var and setter/getter function like this:

index.js

var seleniumGlobal;

$(document).ready(function() {
...
)};

function setSG(toSet) {
    seleniumGlobal = toSet;
}

function getSG() {
    return seleniumGlobal;
}

SampleTest.java

// Do all the necessary imports

public class SampleTest {
    WebDriver driver = new FirefoxDriver();
    JavascriptExecutor js = (JavascriptExecutor) driver;

    @Test
    public void testPrintVal() {
        String sgVal = (String) js.executeScript("alert(getSG());");
        Assert.assertEquals("new value for seleniumGlobal", sgVal);
    }
}

If any segment of my JavaScript code sets my seleniumGlobal variable via the setter method, I can call it in my Selenium test and perform assertions on it.

This might not be the most efficient method, so if anyone has a better solution, please share it with me.

Answer №1

Simply follow these steps:

Retrieve the value using the javascript function "returnFoo()":

By executing the above code, you will obtain the desired result.

Answer №2

No need to define JavaScript functions. You also won't require the alert() function.

Object result = js.executeScript("return globalVar");

If you are using Python:

result = driver.execute_script("return globalVar")

Answer №3

When working in Ruby, you have the option to utilize the page.execute_script method to assess a JavaScript variable (as long as it is accessible within the web browser's scope). A similar approach can be found in Java referenced here.

Note: This scenario may be better suited for utilizing a JavaScript unit testing framework like Jasmine.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

unable to choose the element

Initially, I successfully selected an element using ng-repeat. However, the developers have now implemented virtual repeat, rendering the following code ineffective. expect(stores.listStores(0).getText()).toContain('Prahran'); expect(element.all ...

Is there a way to permanently attach a suffix to an HTML input field?

Is there a way to use jQuery to insert a fixed suffix of , Demos into an input field that cannot be deleted, while still being able to enter text before the suffix? For example: Default: ,Demos User Input: myText, Demos Any assistance on this matter wo ...

Uncovering the Image Orientation in Angular: Is it Possible to Determine the Direction Post-view or Upon Retrieval from Database?

I am currently working on creating centered and cropped thumbnails for images retrieved from a database. I came across some helpful information on how to achieve this: The resource I found is written for JavaScript, but I am using Angular 7. I am facing d ...

In JavaScript, the array is being passed as "undefined"

<html> <head> <script> function replaceLocation() { var locationArray= new Array(); locationArray[1,2,3,4]=document.getElementById("From").value.split(" "); document.getElementById("map").src="https://maps.google.com/maps?f=d& ...

OMDB API encountered a server error while processing the request

I have been attempting to fetch data from the OMDB API but keep encountering an 'internal server error' despite my data request: res.send(results["search"][0]) (I want to mention that I am using the goorm IDE) var express = require("express"); v ...

CSS Text ellipsis displays only the beginning of each paragraph

I want to add ellipsis to a text, but it keeps including the first line of all paragraphs. What I actually need is for only the first line of the content to have the ellipsis applied. Here is an example of the content: When using websocket to send message ...

Steps to retrieve the latest value of a specific cell within the Material UI Data Grid

After updating the cell within the data grid, I encountered an issue where I could retrieve the ID and field using the prop selectedCellParams, but retrieving the modified value was proving to be challenging. In order to successfully execute the PUT reque ...

What is the process for incorporating a third-party library into Angular 6?

Many developers face the challenge of using external libraries in Angular that are not officially supported, such as Clappr and HashWords. The desire is to integrate these libraries seamlessly into an Angular project, almost treating them like native Ang ...

Can you explain the functionality of `module.exports = mongoose model` in a NodeJs environment

Coming from a front-end React background, I am familiar with statements like import and exports. However, as I delve into learning Backend (NodeJs) with mongoDB, I find myself curious about the mechanics of import and export in this new environment. I hav ...

Displaying outcomes solely based on JSON upon choosing a filter

Goal I aim to only show results once their respective state is chosen. Currently, all results are displayed automatically upon page load. I prefer if nothing is shown initially. Only when a state is selected should the corresponding results appear. Bac ...

The Sendkeys() function within the Selenium WebDriver

The function sendKeys(CharSequence...) within the WebElement class cannot be used with a parameter of type (double) wd.findElement(By.id("----")).sendKeys(sheet.getRow(2).getCell(0).getNumericCellValue()); Is there a way to pass a numeric cell value from ...

Utilize Javascript to create a function that organizes numbers in ascending order

Is there a way to modify this code so that the flip clock digits appear in ascending order rather than randomly? $( '.count' ).flip( Math.floor( Math.random() * 10 ) ); setInterval(function(){ $( '.count' ).flip( Math.floor( Math.rand ...

Inserting items into arrays in Angular

I've encountered an issue with pushing an object into an array. The array contains objects, and this component is responsible for displaying them: <div class="row" *ngFor="let element of dietList"> {{element.name}} {{ element.weight }} </d ...

Deduce the generic types of conditional return based on object property

My goal is to determine the generic type of Model for each property. Currently, everything is displaying as unknown[] instead of the desired types outlined in the comments below. playground class Model<T> { x?: T } type ArgumentType<T> = T ...

Using Selenium to interact with a Modal Dialog window

When trying to navigate to a page in IE9 using Selenium, a certificate error message appears on the page. By using AutoIT, I am able to click within the browser, TAB twice, and hit enter without any issues. However, after this step, an error for a "Modal d ...

What is the best way to implement the <b-pagination-nav> component in Bootstrap Vue?

I'm eager to begin using the featured in this guide. However, I'm struggling to figure out how to incorporate the tag into my website. The tutorial's instructions are unclear and as a newcomer, I'm finding it difficult to make it func ...

Is there a successful combination of Fitnesse and WebDriver?

Has there been any collaboration between Fitnesse and Selenium WebDriver that is similar to Selenesse (https://github.com/marisaseal/selenesse), but specifically designed for WebDriver instead of the older version of Selenium? Appreciate your insight, Rac ...

Navigating with Angular and Express

Currently, my Angular project is configured with Express serving my index.html file. As the project progressed, I found the need for a landing page that requires some functionality from the index.html file, such as form input that triggers an API call. H ...

Unnecessary PHP code will run on its own in JavaScript

Attempting to initiate a session in PHP and assign a value to a session variable within a Javascript function on a PHP/HTML page is creating an issue. The problem arises when the PHP code inside the if statement runs automatically upon loading the page, ra ...

Integrate an Angular application within a div on a different domain without using an iframe

I am currently working on an angular application that has a lot of dependencies such as modules and styles. However, I also have multiple websites where I would like to incorporate this application along with all the dependencies (similar to how it is don ...