9

JavascriptをオフにしてWebDriverでテストを実行すると、要素を見つけてクリックしようとすると、ElementNotFoundエラーが原因でWebDriverがクラッシュすることがあります。

しかし、要素は明らかにそこにあります!

これを読んだ後: http://code.google.com/p/selenium/wiki/FrequentlyAskedQuestions#Q:_My_XPath_finds_elements_in_one_browser、 _but_not_in_others._Wh

私は、Webページのロードが完了するまでWebドライバーが待機してはならないという結論に達しました。Webdriver Waitクラスを使用するにはどうすればよいですか?誰かが例を提供できますか?

4

3 に答える 3

18

この例は Google グループ に投稿されました。Google 開発者によると:

1 暗黙の待機を使用します。ここで、ドライバーは、要素が見つかるまで、指定されたタイムアウトまで待機します。警告については、javadoc を必ずお読みください。使用法:

driver.get("http://www.google.com"); 
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); 
WebElement element = driver.findElement(By.name("q")); 
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); 
// continue with test... 

2org.openqa.selenium.support.ui.WebDriverWaitクラスを使用します。これは、期待される条件が真になるまでポーリングし、その条件の結果を返します (要素を探している場合)。これは、任意のカスタム動作を定義できるため、暗黙的な待機よりもはるかに柔軟です。使用法:

Function<WebDriver, WebElement> presenceOfElementLocated(final By locator) { 
  return new Function<WebDriver, WebElement>() { 
    public WebElement apply(WebDriver driver) { 
      return driver.findElement(locator); 
    }
  };
}

// ... 
driver.get("http://www.google.com"); 
WebDriverWait wait = new WebDriverWait(driver, /*seconds=*/3); 
WebElement element = wait.until(presenceOfElementLocated(By.name("q"));
于 2010-11-10T22:07:13.147 に答える
3

nilesh の回答をさらに一歩進めると、SearchContext インターフェイスを使用して、より細かく調整された検索 (たとえば、WebElement のコンテキスト内) を許可することもできます。

Function<SearchContext, WebElement> elementLocated(final By by) {
    return new Function<SearchContext, WebElement>() {
        public WebElement apply(SearchContext context) {
            return context.findElement(by);
        }
    };
}

実行は、(WebDriverWait ではなく) FluentWait<SearchContext> インスタンスによって実行されます。その実行と必要な例外処理をユーティリティ メソッドでラップすることにより、適切なプログラミング インターフェイスを作成します ( PageObject型階層のルートは適切な場所です)。

/**
 * @return The element if found before timeout, otherwise null
 */
protected WebElement findElement(SearchContext context, By by,
        long timeoutSeconds, long sleepMilliseconds) {
    @SuppressWarnings("unchecked")
    FluentWait<SearchContext> wait = new FluentWait<SearchContext>(context)
            .withTimeout(timeoutSeconds, TimeUnit.SECONDS)
            .pollingEvery(sleepMilliseconds, TimeUnit.MILLISECONDS)
            .ignoring(NotFoundException.class);
    WebElement element = null;
    try {
        element = wait.until(elementLocated(by));
    }
    catch (TimeoutException te) {
        element = null;
    }
    return element;
}

/**
 * overloaded with defaults for convenience
 */
protected WebElement findElement(SearchContext context, By by) {
    return findElement(context, by, DEFAULT_TIMEOUT, DEFAULT_POLL_SLEEP);
}

static long DEFAULT_TIMEOUT = 3;       // seconds
static long DEFAULT_POLL_SLEEP = 500;  // milliseconds

使用例:

WebElement div = this.findElement(driver, By.id("resultsContainer"));
if (div != null) {
    asyncSubmit.click();
    WebElement results = this.findElement(div, By.id("results"), 30, 500);
    if (results == null) {
        // handle timeout
    }
}
于 2011-06-30T00:58:31.157 に答える
0

Fluent Wait - 最も柔軟で、その場で構成できるため、最良のアプローチです (例外を無視するオプション、ポーリングごと、タイムアウトがあります)。

public Wait<WebDriver> getFluentWait() {
    return new FluentWait<>(this.driver)
            .withTimeout(driverTimeoutSeconds, TimeUnit.SECONDS)
            .pollingEvery(500, TimeUnit.MILLISECONDS)
            .ignoring(StaleElementReferenceException.class)
            .ignoring(NoSuchElementException.class)
            .ignoring(ElementNotVisibleException.class)
}

次のように使用します。

WebElement webElement = getFluentWait().until(x -> { return driver.findElement(elementBy); } );

明示的な待機- と同じFluentWaitですが、事前に構成さpollingEveryれ、待機のタイプがあります。例FluentWait<WebDriver>(使用する方が速い):

WebDriverWait wait = new WebDriverWait(driver, 30000);
WebElement item = wait.until(ExpectedConditions.visibilityOfElementLocated(yourBy));

ImplicitWait - すべてのセッションで 1 回設定されるため、お勧めしません。これはすべての検索要素にも使用され、存在のみを待機します (なしExpectedConditionsなど):

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
于 2016-11-20T15:40:07.867 に答える