Selenium WebDriver:当使用WebDriver.findElement定位时,等待元素存在是不可能的

时间:2013-11-08 04:19:10

标签: java selenium selenium-webdriver

WebElementWebDriverWaitExpectedConditions同时显示WebElement.findElment会很方便。

问题是,如果WebDriverWait是找到元素的唯一可行方法,那会是什么呢?因为它没有id,没有名字,没有唯一的类?

WebDriver的构造函数仅接受WebElement作为参数,而不是implicitlyWait

我设置了try{} catch(NoSuchElementException e){}时间,因此使用input似乎不是一个好主意,因为我不想等待很长时间才能使用此元素。

以下是该方案:

有一个网页的表单包含许多input个标签。每个div标记都有格式要求。

当不满足格式要求时,此input标记后会显示动态input标记。

由于public WebElement txtBox(String name) { return driver.findElement(By.name(name)); } 标签太多,我创建了一个通用方法,如:

input

而不是为每个isValid代码创建数据成员。

然后我创建一个方法input来检查某些isValid中的用户输入是否有效。我应该在div中执行的操作是检查inputboxToCheck之后是否存在public boolean isValid(WebElement inputboxToCheck) { WebElementWait wait = new WebElementWait(inputboxToCheck, 1); try { wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("./following-sibling::div"))); return false; } catch (TimeOutException e) { return true; } } 标记,代码如下:

WebElementWait

WebDriverWait是一个虚构的(不存在)类,其工作方式与{{1}}相同。

4 个答案:

答案 0 :(得分:10)

上面提到的WebElementWait类:

package org.openqa.selenium.support.ui;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.NotFoundException;
import org.openqa.selenium.WebElement;

public class WebElementWait  extends FluentWait<WebElement>  {
    public final static long DEFAULT_SLEEP_TIMEOUT = 500;

      public WebElementWait(WebElement element, long timeOutInSeconds) {
            this(element, new SystemClock(), Sleeper.SYSTEM_SLEEPER, timeOutInSeconds, DEFAULT_SLEEP_TIMEOUT);
      }

      public WebElementWait(WebElement element, long timeOutInSeconds, long sleepInMillis) {
            this(element, new SystemClock(), Sleeper.SYSTEM_SLEEPER, timeOutInSeconds, sleepInMillis);
      }

      protected WebElementWait(WebElement element, Clock clock, Sleeper sleeper, long timeOutInSeconds,
              long sleepTimeOut) {
            super(element, clock, sleeper);
            withTimeout(timeOutInSeconds, TimeUnit.SECONDS);
            pollingEvery(sleepTimeOut, TimeUnit.MILLISECONDS);
            ignoring(NotFoundException.class);
      }

}

它与WebDriverWait相同,只是WebDriver参数被WebElement替换。

然后,isValid方法:

//import com.google.common.base.Function;
    //import org.openqa.selenium.TimeoutException;

public boolean isValid(WebElement e) {
    try {
        WebElementWait wait = new WebElementWait(e, 1);
        //@SuppressWarnings("unused")
        //WebElement icon = 
        wait.until(new Function<WebElement, WebElement>() {
                    public WebElement apply(WebElement d) {
                        return d.findElement(By
                                .xpath("./following-sibling::div[class='invalid-icon']"));
                    }
                });
        return false;
    } catch (TimeoutException exception) {
        return true;
    }
}

答案 1 :(得分:9)

我不知道这是否对你有所帮助,但它允许等待你想要多长时间。

public WebElement findDynamicElement(By by, int timeOut) {
    WebDriverWait wait = new WebDriverWait(driver, timeOut);
    WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(by));
    return element;
}

findDynamicElement(By.xpath("//body") , 30);

答案 2 :(得分:4)

用户2432405解决方案的一个更通用的变体是使用SearchContext类型而不是WebElement:

public class SearchContextWait  extends FluentWait<SearchContext>  {
    ...

这允许在WebDriver和WebElement上进行等待,因为SearchContext接口是WebDriver和WebElement的祖先。 isValid方法也需要调整:

...
        WebElement icon = wait
                .until(new Function<SearchContext, WebElement>() {
                    public WebElement apply(SearchContext d) {
...

不幸的是,您在内部使用WebDriver接口时失去了ExpectedConditions.xxxx()方法的所有便利。

答案 3 :(得分:1)

我找到了这个博客:检查一个元素 - 存在?,可见?,存在? - https://jkotests.wordpress.com/2012/11/02/checking-for-an-element-exists-visible-present/

它带来了存在,可见和现在之间的差异。

  
      
  • 存在? - 返回此元素是否确实存在。
  •   
  • 本? - 如果元素存在且在页面上可见,则返回true
  •   
  • 可见? - 如果任何父元素不可见,那么我们就不能写入元素。确定这一点的唯一可靠方法是迭代   DOM元素树检查每个元素以确保它是
      可见。
  •   

存在将告诉您,您正在搜索的内容是否在DOM中的任何位置;但是,WebDriver似乎没有内置的方法来检查元素是否存在,与普通driver.findElement(By.name(name))类似。

而且,正如博客中所解释的,存在目前不同。所以我不能使用ExpectedConditions.presenceOfAllElementLocatedBy(By.cssSelector(cssSelector)

我的解决方案:(在这里寻找反馈:)

public WebElement waitForElementExists(String selector, String timeout) {
    Wait<WebDriver> wait = new WebDriverWait(driver, timeout);

    WebElement element = wait.until(new Function<WebDriver, WebElement>() {
        public WebElement apply(WebDriver driver) {
            return driver.findElement(By.cssSelector(selector));
        }
    });

    return element;
 }