我正在使用Selenium WebDriver(Java)和TestNG在我创建的网站上进行一些测试。在这个网站上,我也有JavaScript,并且在某些功能中,它返回值,并通过将值输出到浏览器控制台console.log()。
console.log()
我想知道Selenium WebDriver是否有一种简单的方法来访问某些JavaScript信息,以便可以使用TestNG执行断言。
我对Selenium还是很陌生,但我知道您可以执行以下操作:
WebDriver driver = new ChromeDriver(); driver.findElement(By.id("btn")).click();
那么,可以使用类似的方法WebDriver读取网站上的JavaScript吗?
WebDriver
似乎人们在假设我正在尝试通过Selenium“执行” JavaScript代码。
事实并非如此。相反,我试图使用Selenium存储已经定义的JavaScript变量。
基本上,我希望Selenium能够获取JavaScript变量的值,将其存储在本地,然后对其进行断言测试。
假设我的网站有以下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()但仍然不起作用。
$(document).ready(function()...
function returnFoo()
我既感动foo和returnFoo()外面的$(document).ready(function()...。那已经修复ReferenceError了我在上面的 尝试1 中遇到的消息。
foo
returnFoo()
ReferenceError
我也给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而不是 “ Selenium test run” 的实际值。
null
好像Object val = js.executeScript("alert(returnFoo());");我知道了的值foo。
Object val = js.executeScript("alert(returnFoo());");
因此,这是我要解决我的问题的解决方案,这要归功于下面的Martin Foot解决方案。
在我的JavaScript文件中,我创建了var和设置器/获取器函数,如下所示:
var
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测试对其进行调用并对其进行断言。
seleniumGlobal
这可能不是最有效的方法,但是如果其他人有更好的解决方案,请告诉我。
在Ruby中,您可以page.execute_script用来评估JavaScript变量(如果可以从Web浏览器的范围访问它)。它看起来像有在Java中类似的方法在这里。
page.execute_script
编辑:这可能是一个更适合JavaScript单元测试框架(如Jasmine)的用例。