67

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()...これにより、上記の試み 1ReferenceErrorで得られたメッセージが修正されました。

値も指定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);
    } 

ただし、 「Selenium test run」nullの実際の値の代わりにコンソールが表示されます。

試行 2 - 解決策

Object val = js.executeScript("alert(returnFoo());");もしそうなら、の値を取得するように見えますfoo


解決

以下のMartin Footによる解決策のおかげで、私の問題に対して私が思いついた解決策は次のとおりです。

私の JavaScript ファイルでは、次のvarようなセッター/ゲッター関数を作成しました。

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 のコードがseleniumGlobalsetter メソッドを介して変数を設定するときはいつでも、Selenium テストを介して変数を呼び出し、それに対してアサーションを実行できます。

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

4

3 に答える 3

49

あなたがしなければならないことは次のとおりです。

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

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

于 2013-02-15T16:25:23.807 に答える
29

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

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

Python の場合:

result = driver.execute_script("return globalVar")
于 2013-10-04T00:37:38.740 に答える
14

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

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

于 2012-12-21T17:20:55.227 に答える