I use Selenium WebDriver (Java) and TestNG to conduct some tests on the website I created. I also have JavaScript on this website and in some functions it returns values ββand also outputs the values ββto the browser console via console.log() .
I was wondering if there is an easy way for Selenium WebDriver to access some of this JavaScript data so that I can execute statements using TestNG.
I am very new to Selenium, but I understand that you can do something like:
WebDriver driver = new ChromeDriver(); driver.findElement(By.id("btn")).click();
So, is it possible to do something similar using WebDriver to read JavaScript on a site?
Explanation
It seems like people are speculating that I'm trying to execute JavaScript code through Selenium.
This is not true. Instead, I'm trying to save an already defined JavaScript variable using Selenium.
Basically, I want Selenium to be able to capture the value of a JavaScript variable, save it locally and then run a validation test on it.
Attempt 1
Let's say I have the following JS code for my site:
$(document).ready(function() { var foo = $(
From what I read and understood, in my separate Selenium test file (Selenium.java), I would have 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 am doing something similar to the one above, but the warning window does not appear. Instead, an error message appears:
Exception in thread "main" org.openqa.selenium.WebDriverException: ReferenceError: returnFoo is not defined
I'm sure I don't understand what this means when it is said that the JS variable
should not be part of a closure or local variable
I also tried defining a global variable above $(document).ready(function()... and the setting is within function returnFoo() but still not working.
Attempt 2
I moved both foo and returnFoo() outside of $(document).ready(function()... This fixed the ReferenceError message that I received in Attempt 1 above.
I also gave the value foo , so my JS code looks something like this:
var foo = "Selenium test run"; $(document).ready(function() { ... }); function returnFoo() { return foo; }
Now itβs hard for me to assign returnFoo() to return a local variable in my Selenium test. Here is what I 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); }
But the console display is null instead of the actual value of "Selenium Test Run . "
Attempt 2 - SOLUTION
It looks like if I do Object val = js.executeScript("alert(returnFoo());"); I get the value foo .
Decision
So, here is the solution I came up with my problem, thanks to Martin Foot's solution below.
In my JavaScript file, I created a var function and a setter / getter function as follows:
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); } }
Therefore, whenever any code in my JavaScript sets my seleniumGlobal variable through the setter method, I can call it through my Selenium test and make statements on it.
This is probably not the most efficient way to do it, but if anyone has a better solution, let me know.