Я использую Selenium WebDriver (Java) и TestNG для проведения некоторых тестов на созданном мной веб-сайте. На этом веб-сайте у меня также есть JavaScript и в некоторых функциях он возвращает значения, а также выводит значения в консоль браузера через console.log().
Мне было интересно, есть ли простой способ для Selenium WebDriver получить доступ к некоторым из этих данных JavaScript, чтобы я мог выполнять утверждения с помощью TestNG.
Я очень новичок в Selenium, но понимаю, что вы можете сделать что-то вроде:
WebDriver driver = new ChromeDriver();
driver.findElement(By.id("btn")).click();
Итак, можно ли что-нибудь подобное сделать с помощью WebDriver, чтобы прочитать JavaScript на сайте?
Разъяснение
Похоже, что люди делают предположение, что я пытаюсь выполнить код JavaScript через Selenium.
Это не так. Вместо этого я пытаюсь сохранить уже определенную переменную JavaScript, используя Selenium.
В принципе, я хочу, чтобы Selenium мог захватить значение переменной JavaScript, сохранить его локально и затем выполнить на нем тест подтверждения.
Попытка 1
Скажем, у меня есть следующий JS-код для моего сайта:
$(document).ready(function() {
    var foo = $(#"input-field-val").val();
    function returnFoo() {
        return foo;
    }
});
Из того, что я читал и понимал, в моем отдельном тестовом файле Selenium (Selenium.java), я должен был бы сделать что-то вроде этого:
public class Selenium {
    WebDriver driver = new FirefoxDriver();
    JavascriptExecutor js = (JavascriptExecutor) driver;
    @Test
    public void testSample() {
        driver.get("www.mywebsite.com");
        js.executeScript("alert(returnFoo());");
    }
}
Я делаю что-то похожее на то, что выше, но окно предупреждения не появляется. Вместо этого появляется сообщение об ошибке:
Exception in thread "main" org.openqa.selenium.WebDriverException: ReferenceError: returnFoo is not defined
Я уверен, что не понимаю, что это значит, когда говорится, что переменная JS
не должен быть частью замыкания или локальной переменной
Я также попытался определить глобальную переменную выше $(document).ready(function()..., и настройка находится в пределах function returnFoo(), но все еще не работает.
Попытка 2
Я переместил как foo, так и returnFoo() за пределы $(document).ready(function().... У этого исправлено сообщение ReferenceError, которое я получал в Попытке 1 выше.
Я также дал значение foo, поэтому мой JS-код выглядит примерно так:
var foo = "Selenium test run";
$(document).ready(function() {
...
});
function returnFoo() {
    return foo;
}
Теперь мне трудно назначить возврат returnFoo() локальной переменной в мой тест Selenium. Вот что я пытался:
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);
    } 
Но консольный дисплей null вместо фактического значения  "Селеновый тестовый прогон" .
Попытка 2 - РЕШЕНИЕ
Похоже, если я делаю Object val = js.executeScript("alert(returnFoo());");, я получаю значение foo.
Решение
Итак, вот решение, которое я придумал с моей проблемой, благодаря решению Martin Foot ниже.
В моем файле JavaScript я создал функцию var и функцию setter/getter следующим образом:
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);
    }
}
Поэтому всякий раз, когда какой-либо код в моем JavaScript устанавливает мою переменную seleniumGlobal через метод setter, я могу вызвать ее через мой тест Selenium и сделать на нем утверждения.
Это, вероятно, не самый эффективный способ сделать, но если у кого-то есть лучшее решение, сообщите мне.