Я использую 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 и сделать на нем утверждения.
Это, вероятно, не самый эффективный способ сделать, но если у кого-то есть лучшее решение, сообщите мне.