web-dev-qa-db-ja.com

Selenium WebDriverを使用してJavaScript変数を読み取る

Selenium WebDriver(Java)とTestNGを使用して、作成したWebサイトでテストを実行しています。このWebサイトにはJavaScriptもあり、一部の関数では値を返し、console.log()を介して値をブラウザーコンソールに出力します。

TestNGを使用してアサーションを実行できるように、Selenium WebDriverがこのJavaScript情報の一部にアクセスする簡単な方法があるかどうか疑問に思っていました。

私はSeleniumを初めて使用しますが、次のようなことができることを理解しています。

_WebDriver driver = new ChromeDriver();
driver.findElement(By.id("btn")).click();
_

WebDriverを使用してサイトのJavaScriptを読み取ることができる類似の方法はありますか?


明確化

私は、Seleniumを介してJavaScriptコードを「実行」しようとしていると想定しているようです。

そうではありません。代わりに、Seleniumを使用して定義済みのJavaScript変数を保存しようとしています。

基本的に、SeleniumでJavaScript変数の値を取得し、ローカルに保存してから、アサーションテストを実行できるようにします。


試行1

私のウェブサイトに次の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()内ですが、それでも動作しません。


試行2

fooreturnFoo()の両方を$(document).ready(function()...の外側に移動しました。これにより、上記の試行1で取得していたReferenceErrorメッセージが修正されました。

fooの値も指定しているため、JSコードは次のようになります。

_var foo = "Selenium test run";

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

function returnFoo() {
    return foo;
}
_

現在、Seleniumテスト内でreturnFoo()の戻り値をローカル変数に割り当てるのは大変です。私が試みたものは次のとおりです。

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

しかし、コンソールは"Selenium test run"の実際の値の代わりにnullを表示します。

試行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;
}
_

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テストを介して呼び出してアサーションを実行できます。

これはおそらく最も効率的な方法ではありませんが、他の誰かがより良い解決策を持っているなら、私に知らせてください。

53
FilmiHero

In Rubyを使用できますpage.execute_scriptは、JavaScript変数を評価します(Webブラウザーのスコープからアクセスできる場合)。 Java here に同様のメソッドがあるようです。

編集:これは、 Jasmine などのJavaScript単体テストフレームワークにより適したユースケースである可能性があります。

13
Martin Foot

あなたがしなければならないのは:

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

それはあなたが探しているものを提供します。

45
Jose Sutilo

JavaScript関数を定義する必要はありません。alert()も必要ありません。

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

Pythonの場合:

result = driver.execute_script("return globalVar")
26
wTyeRogers