使用Selenium WebDriver读取JavaScript变量

时间:2022-06-02 22:46:17

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,在一些函数中,它通过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 WebDriver to 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

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()...上面定义一个全局变量,并且设置在函数returnFoo()中,但仍然不起作用。


Attempt 2

I've moved both foo and returnFoo() outside of the $(document).ready(function().... That has fixed ReferenceError message that I was getting in Attempt 1 above.

我已经将$ foo和returnFoo()移到了$(document).ready(function()....之外。它修复了我在上面的尝试1中获得的ReferenceError消息。

I hav also given foo a 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 null instead of the actual value of "Selenium test run".

但控制台显示null而不是“Selenium test run”的实际值。

Attempt 2 - SOLUTION

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 var and a setter/getter function like so:

在我的JavaScript文件中,我创建了一个var和一个setter / getter函数,如下所示:

index.js

index.js

var seleniumGlobal;

$(document).ready(function() {
...
)};

function setSG(toSet) {
    seleniumGlobal = toSet;
}

function getSG() {
    return seleniumGlobal;
}

SampleTest.java

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);
    }
}

So whenever some code in my JavaScript sets my seleniumGlobal variable through the setter method, I can call it through my Selenium test and do assertions on it.

因此,只要我的JavaScript中的某些代码通过setter方法设置我的seleniumGlobal变量,我就可以通过我的Selenium测试调用它并对其进行断言。

This is probably not the most efficient way to do but if someone else has a better solution, please let me know.

这可能不是最有效的方法,但如果其他人有更好的解决方案,请告诉我。

4 个解决方案

#1


10  

In Ruby you can use page.execute_script to 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中有类似的方法。

Edit: This might be a use case that is more suited to a JavaScript unit testing framework such as Jasmine.

编辑:这可能是一个更适合JavaScript单元测试框架(如Jasmine)的用例。

#2


41  

All you have to do is:

你所要做的就是:

Object val = js.executeScript("return returnFoo();");

That will give you what you are looking for.

那会给你你想要的东西。

#3


22  

No JavaScript functions need be defined. Nor is alert() needed.

不需要定义JavaScript函数。也不需要警报()。

Object result = js.executeScript("return globalVar");

For Python:

对于Python:

result = driver.execute_script("return globalVar")

#4


-2  

Try this:

尝试这个:

page.evaluate_script("script code")
page.execute_script("script code")
page.find("#id").click

#1


10  

In Ruby you can use page.execute_script to 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中有类似的方法。

Edit: This might be a use case that is more suited to a JavaScript unit testing framework such as Jasmine.

编辑:这可能是一个更适合JavaScript单元测试框架(如Jasmine)的用例。

#2


41  

All you have to do is:

你所要做的就是:

Object val = js.executeScript("return returnFoo();");

That will give you what you are looking for.

那会给你你想要的东西。

#3


22  

No JavaScript functions need be defined. Nor is alert() needed.

不需要定义JavaScript函数。也不需要警报()。

Object result = js.executeScript("return globalVar");

For Python:

对于Python:

result = driver.execute_script("return globalVar")

#4


-2  

Try this:

尝试这个:

page.evaluate_script("script code")
page.execute_script("script code")
page.find("#id").click