使用Selenium WebDriver读取JavaScript变量

Fil*_*ero 53 javascript testng selenium selenium-webdriver

我正在使用Selenium WebDriver(Java)和TestNG在我创建的网站上进行一些测试.在这个网站上,我也有JavaScript,在一些函数中,它返回值并通过输出值输出到浏览器控制台console.log().

我想知道Selenium WebDriver是否有一种简单的方法可以访问这些JavaScript信息,因此我可以使用TestNG执行断言.

我对Selenium很新,但我知道你可以这样做:

WebDriver driver = new ChromeDriver();
driver.findElement(By.id("btn")).click();
Run Code Online (Sandbox Code Playgroud)

那么我可以用什么类似的东西WebDriver来阅读网站上的JavaScript?


澄清

看起来人们假设我正试图通过Selenium"执行"JavaScript代码.

不是这样的.相反,我正在尝试使用Selenium存储已定义的JavaScript变量.

基本上,我希望Selenium能够获取JavaScript变量的值,将其存储在本地,然后对其进行断言测试.


尝试1

说我的网站有以下JS代码:

$(document).ready(function() {
    var foo = $(#"input-field-val").val();

    function returnFoo() {
        return foo;
    }
});
Run Code Online (Sandbox Code Playgroud)

根据我的阅读和理解,在我单独的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());");
    }
}
Run Code Online (Sandbox Code Playgroud)

我做了类似于上面的事情,但没有弹出警报框.相反,我收到一条错误消息:

Exception in thread "main" org.openqa.selenium.WebDriverException: ReferenceError: returnFoo is not defined
Run Code Online (Sandbox Code Playgroud)

当我说JS变量时,我很确定我不明白它意味着什么

不应该是闭包或局部变量的一部分

我也尝试在上面定义一个全局变量,$(document).ready(function()...并且设置在function returnFoo()但仍然不起作用.


尝试2

我已经移动了两个fooreturnFoo()外面的$(document).ready(function()....这已经修复ReferenceError了我在上面的尝试1中得到的消息.

我也给foo了一个值,所以我的JS代码看起来像这样:

var foo = "Selenium test run";

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

function returnFoo() {
    return foo;
}
Run Code Online (Sandbox Code Playgroud)

现在,我很难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);
    } 
Run Code Online (Sandbox Code Playgroud)

但控制台显示null而不是"Selenium测试运行"的实际值.

尝试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;
}
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

小智 45

你所要做的就是:

Object val = js.executeScript("return returnFoo();");
Run Code Online (Sandbox Code Playgroud)

那会给你你想要的东西.


wTy*_*ers 26

不需要定义JavaScript函数.也不alert()需要.

Object result = js.executeScript("return globalVar");
Run Code Online (Sandbox Code Playgroud)

对于Python:

result = driver.execute_script("return globalVar")
Run Code Online (Sandbox Code Playgroud)


Mar*_*oot 13

在Ruby中,您可以使用它page.execute_script来评估JavaScript变量(如果它可以从Web浏览器的范围访问).它看起来像有在Java中类似的方法在这里.

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