12

等待 和出现WebElement很方便。WebDriverWaitExpectedConditions

问题是,如果WebElement.findElment是唯一可能的定位元素的方法,因为它没有 id、没有名称、没有唯一的类?

WebDriverWait的构造函数只接受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.

4

4 回答 4

12

上面提到的 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;
    }
}
于 2013-11-09T07:00:23.443 回答
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);
于 2013-11-08T08:48:10.447 回答
5

user2432405 解决方案的一个更通用的变体是使用 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) {
...

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

于 2015-04-07T21:36:22.150 回答
2

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

它提出了存在、可见和现在之间的差异。

  • 存在吗?– 返回此元素是否实际存在。
  • 当下?– 如果元素存在并且在页面上可见,则返回 true
  • 可见的?– 如果任何父元素不可见,则我们无法写入该元素。确定这一点的唯一可靠方法是迭代 DOM 元素树,检查每个元素以确保其
    可见。

Exists 会告诉您您要搜索的内容是否在 DOM 中的任何位置;但是,WebDriver似乎没有内置方法来检查是否存在类似于 plain 的元素driver.findElement(By.name(name))

而且,正如博客中所解释的,ExistsPresent不同。所以我不能使用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;
 }
于 2014-12-15T22:17:34.203 回答