繁体   English   中英

Selenium 2 - 如何在隐式等待时检查元素是否不存在?

[英]Selenium 2 - How to check if element not present while implicitly waiting?

如果使用以下代码检查缺少的元素:

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

    // here you go, element not found

}

你得到了正确的结果,但是运行时间总是30秒,因为隐式等待上的findElement方法阻塞。

有没有办法避免这种行为,同时保持隐含的等待?

<EDIT>测试将由非开发人员通过Selenium IDE生成,因此我需要一种解决方案,使他们的工作尽可能简单(保持等待隐含!)。 </EDIT>

谢谢,

马尔科

即使元素不再存在,上述方法也会等待所提供的时间量。 我编写了自己的方法,等待元素可见而不存在。 他们为我工作。 他们来了:

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

您可以使用xpath选择器来完成它。 找到你知道应该在那之前的元素,然后使用“follow-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 ) );
        }
    } );
}

我没有设置超时,而是使用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); 允许你'不'立即找到一个元素。

希望这可以帮助!

你需要一个像这样的函数,它使用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描述设置一个FluentWait对象:

fluentWait.until(elementCountIs(By.cssSelector("td.name"), 0);

您必须暂时更新ImplicitWait,并在完成后重置它。

这是我们处理这种情况的方式 - 保存当前默认值,暂时更新ImplicitWait,然后再更改回默认值。
这是基于Mozilla的建议,这是他们如何处理你期望某些东西存在的情况: https//blog.mozilla.org/webqa/2012/07/12/webdrivers-implicit-wait-and-删除元素/

public bool ElementExists(By by, int waitMilliseconds)
{
        var defaultWebDriverTimeout = 30000;// Get default timeout that you're using
        WebDriver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromMilliseconds(waitMilliseconds));

        try
        {
            WebDriver.FindElement(by); //Note could be FindElements instead, but this is quicker
            return true;
        }
        catch (NoSuchElementException)
        {
            return false;
        }
        finally
        {
            WebDriver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromMilliseconds(defaultWebDriverTimeout));
        }
}

你不能。 implicit等待时间优先于显式等待。 如果您的implicit时间是30秒,则在元素不存在的情况下,您运行的任何查找将至少为30秒。 你可以做的是操纵你的框架上的implicit等待时间,但不知道如何与IDE,我从来没有使用它。

我创建了一个自定义方法,返回带有结果的boolean 输入是WebDriver支持的任何By定位器 (CSS,xpath等) 或者,您可以根据需要进行修改。

它有助于使我的代码更清洁,更快。 我希望它也可以帮助其他人。

默认pooling为500 Millis,但可以在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;
    };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM