我正在使用Selenium WebDriver(Java)和TestNG在我创建的网站上进行一些测试。在这个网站上,我也有JavaScript,在某些功能中,它通过console.log()
返回值并输出值到浏览器控制台。
我想知道Selenium WebDriver是否有一种简单的方法可以访问某些JavaScript信息,因此我可以使用TestNG执行断言。
我对Selenium很新,但我知道你可以这样做:
WebDriver driver = new ChromeDriver();
driver.findElement(By.id("btn")).click();
那么我可以使用WebDriver
来阅读网站上的JavaScript吗?
看起来人们假设我正试图通过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()
之内,但仍然不起作用。
我已将foo
和returnFoo()
移到$(document).ready(function()...
之外。这已经修复了我在尝试1 上面的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”的实际值。
如果我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中的某些代码通过setter方法设置我的seleniumGlobal
变量,我就可以通过我的Selenium测试调用它并对其进行断言。
这可能不是最有效的方法,但如果其他人有更好的解决方案,请告诉我。
答案 0 :(得分:45)
您所要做的就是:
Object val = js.executeScript("return returnFoo();");
这会给你你想要的东西。
答案 1 :(得分:26)
无需定义JavaScript函数。也不需要alert()
。
Object result = js.executeScript("return globalVar");
对于Python:
result = driver.execute_script("return globalVar")
答案 2 :(得分:12)
在Ruby中,您可以使用page.execute_script
来评估JavaScript变量(如果可以从Web浏览器的范围访问它)。看起来在Java here中有类似的方法。
编辑:这可能是一个更适合JavaScript单元测试框架的用例,例如Jasmine。
答案 3 :(得分:-1)
下面的代码行对我来说很完美……
JavascriptExecutor js = (JavascriptExecutor ) getDriver();
String s=js.executeScript("return window.var.var_type").toString();
System.out.println(s);