6

次のコードで存在しない要素をチェックすると:

// ...
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
try {
    driver.findElement(By.cssSelector("td.name"));
} catch (NoSuchElementException e) {

    // here you go, element not found

}

findElement正しい結果が得られますが、暗黙的な待機でメソッドがブロックされているため、実行時間は常に 30 秒です。

暗黙の待機を維持しながら、この動作を回避する方法はありますか?

<EDIT>テストは、非開発者によって Selenium IDE を介して生成されるため、彼らの仕事をできるだけシンプルに保つソリューションが必要です (つまり、待機を暗黙的に保ちます!)。</EDIT>

ありがとう、

マルコ

4

6 に答える 6

3

上記のメソッドは、要素が存在しなくなった場合でも、指定された時間だけ待機します。要素が表示され、存在しないまで待機するための独自のメソッドを作成しました。彼らは私のために働いています。どうぞ:

public void waitUntilElementExists(By by, int waitSeconds,
        int noOfRetries) {
    getDriver().manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
    boolean foundElement = false;
    for (int i = 0; i < noOfRetries; i++)
        try {
            getDriver().findElement(by);
            foundElement = true;
            break;
        } catch (Exception e) {
        }
    assertTrue("The searched element was not found after " + noOfRetries * waitSeconds + " seconds!", foundElement);
}

public void waitUntilElementDoesntExist(By by, int waitSeconds,
        int noOfRetries) {
    getDriver().manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
    boolean elementDisappeared = false;
    for (int i = 0; i < noOfRetries; i++)
        try {
            getDriver().findElement(by);
            waitABit(1000 * waitSeconds);
        } catch (Exception e) {
            elementDisappeared = true;
            break;
        }
    assertTrue("The searched element did not disappear after " + noOfRetries * waitSeconds + " seconds!", elementDisappeared);
}
于 2013-03-18T10:17:12.130 に答える
2

タイムアウトを設定する代わりに、2.25 で導入された fluentWait を使用します。

public void waitForElement(WebDriver driver, final String xpath)
{
 //Set up fluentWait to wait for 35 seconds polling every 1
 Wait<WebDriver> fluentWait = new FluentWait<WebDriver>(driver)
     .withTimeout(35, TimeUnit.SECONDS)
     .pollingEvery(1, TimeUnit.SECONDS)
     .ignoring(NoSuchElementException.class);

 WebElement element;

 //Look for element, if not found start fluentWait
 try
 {
     element = driver.findElement(By.xpath(xpath));
 }
 catch (WebDriverException e)
 {
     logger.info("[getElementByXpath] Element not initially found. Starting fluentWait ["+xpath+"]");

     try
     {
         element = fluentWait.until(new Function<WebDriver, WebElement>() {
             public WebElement apply(WebDriver d) {

                 return d.findElement(By.xpath(xpath));
             }
         });
     }
     catch (WebDriverException f)
     {
         logger.info("[getElementByXpath] FluentWait findElement threw exception:\n\n" + f +"\n\n");

         throw new WebDriverException("Unable to find element ["+xpath+"]");
     }
 }

 //Once we've found the element wait for element to become visible
 fluentWait.until(ExpectedConditions.visibilityOf(element));
}

driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);メソッドをこのようなものに変換する場合は、要素をすぐに見つけられないように削除することができます。

お役に立てれば!

于 2012-10-06T03:59:29.443 に答える
2

xpathセレクターでそれを行うことができるかもしれません。その直前に存在するはずの要素を見つけ、「following-sibling」を使用して次の要素を取得します。何かのようなもの:

//td.previous/following-sibling::td

次に、「名前」が返されていないことを確認します。もちろん、それは別の「td」要素がある場合にのみ機能します。

個人的には、暗黙の待機をやめて、必要なときに待機を使用したくなるでしょう。

private WebElement cssWait( final String css )
{
    return new WebDriverWait( driver, 30 ).until( new ExpectedCondition< WebElement >()
    {
        @Override
        public WebElement apply( WebDriver d )
        {
            return d.findElement( By.cssSelector( css ) );
        }
    } );
}
于 2012-10-05T14:30:06.223 に答える
0

いいえ、あなたがすることはできません。 implicit待機時間は、明示的な待機よりも優先されます。時間が 30 秒の場合、implicit実行するすべての検索は、要素が存在しない場合に少なくとも 30 秒かかります。あなたができることはimplicit、フレームワークの待機時間を操作することですが、それが IDE でどのように機能するかはわかりません。私はそれを使用したことがありません。

結果とともにを返すカスタム メソッドを作成しましたboolean。入力は、 WebDriver (CSS、xpath など) でサポートされている任意のBy ロケーターです。または、必要に応じて変更することもできます。

私のコードをよりクリーンで高速にするのに役立ちました。他の人にも役立つことを願っています。

デフォルトpoolingは 500 ミリですが、オブジェクトで変更できwaitます。

public boolean isElementNotPresent(final By locator) {
        boolean result = false;
        // use your custom timeout here
        long timeout = ConfigurationProvider.getWebDriverWaitTimeout();

        // log4j used
        msg = "isElementNotPresent: " + locator;
        LOG.info(msg);

        Wait<WebDriver> wait = new FluentWait<WebDriver>(
                getDriver()).withTimeout(timeout, TimeUnit.SECONDS);

        try {
            result = wait.until(new Function<WebDriver, Boolean>() {
                @Override
                public Boolean apply(WebDriver driver) {
                    return driver.findElements(locator).size() == 0;
                }
            });
        } catch (TimeoutException e) {
            msg = String.format("Element remained visible after %.2f seconds",
            ((float) timeout / 1000));
            LOG.debug(msg);
        } catch (Exception e) {
            msg = "Exception at isElementNotPresent()\n" + e.getMessage();
            // I use jUnit to fail my test
            Assert.fail(msg);
        }

        return result;
    };
于 2015-04-06T20:40:11.280 に答える
0

findElementsではなくを使用する、次のような関数が必要ですfindElement

public static ExpectedCondition<Boolean> elementCountIs(final By sel, final int count) {
    return new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver driver) {
            return driver.findElements(sel).size() == count;
        }
    };
}

FluentWait次に、Falkenfighter で説明されているようにオブジェクトをセットアップし、次のことができます。

fluentWait.until(elementCountIs(By.cssSelector("td.name"), 0);
于 2014-04-30T09:45:47.280 に答える