0

WebElement が有効になっているかどうかを確認する簡単なメソッドを作成し、このメソッドをテスト ケースのスーパー オブジェクトに入れました。

protected boolean isElementEnabled(By by) {
    // Temporarily set the implicit timeout to zero
    int originalTimeout = Integer.parseInt(System.getProperty(
            "com.brainshark.uitests.timeout", "120"));
    driver.manage().timeouts().implicitlyWait(0, TimeUnit.MILLISECONDS);
    // Check to see if there are any elements in the found list
    List<WebElement> elements = driver.findElements(by);
    boolean isEnabled = (elements.size() == 1)
            && elements.get(0).isEnabled();
    // Return to the original implicit timeout value
    driver.manage().timeouts()
            .implicitlyWait(originalTimeout, TimeUnit.SECONDS);
    return isEnabled;
}

問題なくかなり使用してきましたが、突然、このメソッドが InvalidElementStateException をスローする繰り返し可能なインスタンスに直面しました。

org.openqa.selenium.InvalidElementStateException: findElements の実行に失敗しました。SYNTAX_ERR: DOM 例外 12 (警告: サーバーはスタックトレース情報を提供しませんでした) コマンドの実行時間またはタイムアウト: 13 ミリ秒 ビルド情報: バージョン: '2.23.1'、リビジョン: '不明'、時刻: '2012-06-08 12 :33:29' システム情報: os.name: 'Windows 7'、os.arch: 'amd64'、os.version: '6.1'、java.version: '1.7.0_05' ドライバー情報: driver.version: RemoteWebDriverセッション ID: ed1a9cbb238fa4dfb616ad81e7f60141

失敗は、探しているロケーターに依存しているようです。このロケーターに本質的な問題はありますか?

final By AdministrationButton = By
            .cssSelector("div#top-nav a[href~=CorpAdmin/DisplayInformation]");

確認するために、上記のロケーターは、id=top-nav の div の子孫である「CorpAdmin/DisplayInformation」を含む href 属性を持つアンカー要素を見つけようとしています。私が使用しているような CSS ロケーターは ChromeDriver で動作するはずではありませんか? findElements のようなメソッドが InvalidElementStateExceptions をスローする理由を知っている人はいますか? 前もって感謝します!

補遺:さらに調査すると、別の方法であるページから別のページに移動した後にのみ、メソッドが失敗することが示されています。何かが古くなったり、存在しなくなった要素を参照しているように感じます。しかし、それが何であるかはわかりません。同じドライバー オブジェクトがテスト ケースとページ オブジェクトで使用可能になり、isElementEnabled が呼び出されるたびに使用されます。前のページの WebElements がキャッシュまたは参照されていません。ページが変更されたことを警告するために、ドライバーで何かする必要がありますか?

補遺 2:プロットが厚くなります。今、私はその前の補遺についてよくわかりません。新しいページに移動した後もまだ失敗しますが、そのロケーターに問題があるかどうかはわかりません。私は次のような呼び出しでコードをペッパーしようとしました:

debug("Attempt 3...");
things = getDriver().findElements(By.cssSelector("div a"));
debug("Attempt 3 found " + things.size() + " things!");

これらの呼び出しは、開始したページから移動するまで成功します。単純なロケーターに一致するページ上の 35 の要素を見つけます。ただし、新しいページに移動すると、新しい例外が発生します。

org.openqa.selenium.WebDriverException: findElements が無効な値を返しました: "[{\"ELEMENT\": \":wdc:1347370086846\"}, {\"ELEMENT\": \":wdc:1347370086847\"}, { \"ELEMENT\": \":wdc:1347370086848\"}, {\"ELEMENT\": \":wdc:1347370086849\"}, {\"ELEMENT\": \":wdc:1347370086850\"}, {\"ELEMENT\": \":wdc:1347370086851\"}, {\"ELEMENT\": \":wdc:1347370086852\"}, {\"ELEMENT\": \":wdc:1347370086853\"} , {\"ELEMENT\": \":wdc:1347370086854\"}, {\"ELEMENT\": \":wdc:1347370086855\"}, {\"ELEMENT\": \":wdc:1347370086856\" }, {\"ELEMENT\": \":wdc:1347370086857\"}, {\"ELEMENT\": \":wdc:1347370086858\"}, {\"ELEMENT\": \":wdc:1347370086859\"}, {\"ELEMENT\": \":wdc:1347370086860\"}, {\"ELEMENT\": \":wdc :1347370086861\"}, {\"ELEMENT\": \":wdc:1347370086862\"}, {\"ELEMENT\": \":wdc:1347370086863\"}, {\"ELEMENT\": \": wdc:1347370086864\"}, {\"ELEMENT\": \":wdc:1347370086865\"}, {\"ELEMENT\": \":wdc:1347370086866\"}, {\"ELEMENT\": \" :wdc:1347370086867\"}, {\"ELEMENT\": \":wdc:1347370086868\"}, {\"ELEMENT\": \":wdc:1347370086869\"}]" (警告: サーバーはコマンドの実行時間またはタイムアウト: 9 ミリ秒 ビルド情報: バージョン: '2.23.1'、リビジョン:'不明'、時間: '2012-06-08 12:33:29' システム情報: os.name: 'Windows 7'、os.arch: 'amd64'、os.version: '6.1'、java.version: '1.7.0_05' ドライバー情報: driver.version: RemoteWebDriver セッション ID: 174adf3205213984172556afa718f6a1

それがSeleniumがWebElementsを表す方法ですか? それらはオブジェクト自体への参照にすぎないと思います。以前に返された 35 個ではなく、26 個しかありません (別のページにいるため、これが正しい数である可能性があります)。なぜ何かが無効なのか、それとも何なのかわかりません。代わりに、上記の AdministrationButton のロケーターで isElementEnabled を呼び出すと、以前と同様に InvalidElementSateException が発生します。

4

2 に答える 2

2

1) 最初のポイント。率直に言って、あなたの方法isElementEnabledが整理されているのは好きではありません。セレンがローカライズされた要素で操作できるかどうかを知るには、これを試してください:

public boolean isElementPresent(By locatorKey) {
        try {
            driver.findElement(locatorKey);
            return true;
        } catch (org.openqa.selenium.NoSuchElementException e) {
            return false;
        }
    }

driver.findElement(By.cssSelector(....)).isEnabled();
driver.findElement(By.cssSelector(....)).isDisplayed()

ただし、この方法を使用する前に、流暢な待機を使用することをお勧めします。流暢な待機は、ロケーターによって見つかった Web 要素を返します (注: 流暢な待機で何かが失敗した場合は、必要な要素の xpath または cssselector に注意を払うことをお勧めします)。

 public WebElement fluentWait(final By locator){
        Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
                .withTimeout(30, TimeUnit.SECONDS)
                .pollingEvery(5, TimeUnit.SECONDS)
                .ignoring(NoSuchElementException.class);

        WebElement foo = wait.until(
new Function<WebDriver, WebElement>() {
            public WebElement apply(WebDriver driver) {
                        return driver.findElement(locator);
                }
                }
);
                           return  foo;              }     ;

流暢な待機については、ここを読むことをお勧めします

cssSelector を見つける方法については、率直に言って、私も好きではありません。"div#top-nav a[href~=CorpAdmin/DisplayInformation]" これを改善する 代わりに、div[id='top'] nav a[href~='CorpAdmin/DisplayInformation'] 常にローカライズされた要素を css または xPAth でチェックしてください (例: firepath、firefox アドオンから firebug)。下の図を参照してください。 ファイアパスのローカライズ

これが何らかの形で役立つことを願っています。

于 2012-09-11T16:36:14.613 に答える
1

ところで、私はそのような例外で同様の問題に遭遇しました。 Selenium webcrawling コンボ ボックス したがって、この種の問題は、selenium が対話できない要素 (つまり、非表示、無効化など) に遭遇したことを意味します。したがって、これらのケースでは、js が役立ちます (要素をクリックするか、要素のテキストを取得する際に)。目に見えない (無効になっている) 要素と js が対話する方法が気に入っています。そして、私見では、要素の可視性 (または有効化/無効化) の検証は、js チート アプローチを使用して必要ありません)。

public void jsClickOnElement(String cssSelector){
        JavascriptExecutor js = (JavascriptExecutor) driver;
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("var x = $(\'"+cssSelector+"\');");
        stringBuilder.append("x.click();");
        js.executeScript(stringBuilder.toString());

    }
于 2012-09-12T09:11:35.280 に答える