使用 Selenium WebDriver 读取 JavaScript 变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13994393/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reading JavaScript variables using Selenium WebDriver
提问by FilmiHero
I'm using Selenium WebDriver (Java) and TestNG to do some testing on a website I created. In this website, I also have JavaScript and in some of the functions, it returns values and also outputs values to the browser console through console.log().
我正在使用 Selenium WebDriver (Java) 和 TestNG 在我创建的网站上进行一些测试。在这个网站中,我也有 JavaScript,在一些函数中,它返回值并通过 .js 将值输出到浏览器控制台console.log()。
I was wondering if there is an easy way for Selenium WebDriver to access some of this JavaScript information so I can perform assertions using TestNG.
我想知道是否有一种简单的方法可以让 Selenium WebDriver 访问一些 JavaScript 信息,以便我可以使用 TestNG 执行断言。
I'm quite new to Selenium but I understand that you can do something like:
我对 Selenium 很陌生,但我知道您可以执行以下操作:
WebDriver driver = new ChromeDriver();
driver.findElement(By.id("btn")).click();
So is there anything similar I can do using WebDriverto read the JavaScript on the site?
那么有什么类似的东西我可以WebDriver用来阅读网站上的 JavaScript 吗?
Clarification
澄清
It looks like people are making the assumption that I'm trying to "execute" JavaScript code through Selenium.
看起来人们假设我正在尝试通过 Selenium“执行”JavaScript 代码。
Thats not the case. Instead, I'm trying to store already-defined JavaScript variable using Selenium.
事实并非如此。相反,我正在尝试使用 Selenium 存储已定义的 JavaScript 变量。
Basically, I want Selenium to be able to grab the JavaScript variable's value, store it locally, and then do an assertion test on it.
基本上,我希望 Selenium 能够获取 JavaScript 变量的值,将其存储在本地,然后对其进行断言测试。
Attempt 1
尝试 1
Say I have the following JS code for my website:
假设我的网站有以下 JS 代码:
$(document).ready(function() {
var foo = $(#"input-field-val").val();
function returnFoo() {
return foo;
}
});
From what I've reading and understanding, in my seperate Selenium test file (Selenium.java), I should be able to do something like this?:
根据我的阅读和理解,在我单独的 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());");
}
}
I do something similar to what's above but no alert box pops up. Instead, I get an error message:
我做了类似于上面的事情,但没有弹出警告框。相反,我收到一条错误消息:
Exception in thread "main" org.openqa.selenium.WebDriverException: ReferenceError: returnFoo is not defined
I'm pretty sure I'm not understanding what it means when its said that the JS variable
我很确定当它说 JS 变量时我不理解它的含义
should not be part of a closure or local variable
不应该是闭包或局部变量的一部分
I have also tried defining a global variable above the $(document).ready(function()...and setting is within function returnFoo()but still doesn't work.
我也试过在上面定义一个全局变量,$(document).ready(function()...并且设置在里面,function returnFoo()但仍然不起作用。
Attempt 2
尝试 2
I've moved both fooand returnFoo()outside of the $(document).ready(function().... That has fixed ReferenceErrormessage that I was getting in Attempt 1above.
我既感动foo和returnFoo()外面的$(document).ready(function()...。这已经修复ReferenceError了我在上面的尝试 1中得到的消息。
I hav also given fooa value so my JS code looks something like this:
我还给出foo了一个值,所以我的 JS 代码看起来像这样:
var foo = "Selenium test run";
$(document).ready(function() {
...
});
function returnFoo() {
return foo;
}
Now, I'm having a tough time assigning the return of returnFoo()to a local variable within my Selenium test. Here's what I've attempted:
现在,我很难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);
}
But the console display nullinstead of the actual value of "Selenium test run".
但是控制台显示的null不是"Selenium test run"的实际值。
Attempt 2 - SOLUTION
尝试 2 - 解决方案
It looks like if I do Object val = js.executeScript("alert(returnFoo());");I get the value of foo.
看起来如果我这样做,Object val = js.executeScript("alert(returnFoo());");我会得到foo.
SOLUTION
解决方案
So here's the solution I've come up w/ to my problem thanks to the solution by Martin Foot below.
多亏了下面 Martin Foot 的解决方案,这就是我针对我的问题提出的解决方案。
In my JavaScript file, I created a varand a setter/getter function like so:
在我的 JavaScript 文件中,我创建了var一个 setter/getter 函数,如下所示:
index.js
索引.js
var seleniumGlobal;
$(document).ready(function() {
...
)};
function setSG(toSet) {
seleniumGlobal = toSet;
}
function getSG() {
return seleniumGlobal;
}
SampleTest.java
示例测试.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);
}
}
So whenever some code in my JavaScript sets my seleniumGlobalvariable through the setter method, I can call it through my Selenium test and do assertions on it.
因此,每当我的 JavaScript 中的某些代码seleniumGlobal通过 setter 方法设置我的变量时,我都可以通过 Selenium 测试调用它并对其进行断言。
This is probably not the most efficient way to do but if someone else has a better solution, please let me know.
这可能不是最有效的方法,但如果其他人有更好的解决方案,请告诉我。
采纳答案by Martin Foot
In Ruby you can use page.execute_scriptto evaluate a JavaScript variable (if it is accessable from the scope of the web browser). It looks like there is a similar method in Java here.
在 Ruby 中,您可以page.execute_script用来评估 JavaScript 变量(如果它可以从 Web 浏览器的范围内访问)。看起来Java here 中也有类似的方法。
Edit: This might be a use case that is more suited to a JavaScript unit testing framework such as Jasmine.
编辑:这可能是一个更适合 JavaScript 单元测试框架(例如Jasmine )的用例。
回答by Jose Sutilo
All you have to do is:
您所要做的就是:
Object val = js.executeScript("return returnFoo();");
That will give you what you are looking for.
这会给你你正在寻找的东西。
回答by wTyeRogers
No JavaScript functions need be defined.Nor is alert()needed.
不需要定义 JavaScript 函数。也不alert()需要。
Object result = js.executeScript("return globalVar");
For Python:
对于 Python:
result = driver.execute_script("return globalVar")

