WebDriverWait的包装器可以使用各种ExpectedConditon吗?

时间:2017-05-15 19:01:56

标签: java selenium parameters wait

我正在使用Selenium 3.4和Java。我正在测试一个不是很快的UI,并且使用隐式等待,这样每次加载时都不需要关心手动explcit。

但是,有时我还需要明确的等待。为此,我需要暂时禁用隐式等待。为了避免混乱代码,我在驱动程序管理器类中添加了以下方法:

public static void waitFor(ExpectedCondition<Boolean> condition,int timeoutSeconds) throws Exception {
    setImplicitWait(0);
    try {
        (new WebDriverWait(driver, timeoutSeconds)).until(condition);
    } finally {
        setImplicitWait(WAIT_REGULAR);
    }
}

setImplicitWait方法很简单:

public static void setImplicitWait(int TimeoutSeconds) {
    logger.debug("Setting implicit wait to {} seconds",TimeoutSeconds);
    driver.manage().timeouts().implicitlyWait(TimeoutSeconds, TimeUnit.SECONDS);
}

因此,此设置适用于某些等待,例如:

DriverManager.waitFor(ExpectedConditions.invisibilityOfElementLocated(By.className("gridxLoad")), DriverManager.WAIT_HUGE);

但是,如果我尝试这个:

DriverManager.waitFor(ExpectedConditions.visibilityOfElementLocated(By.className("gridxMain")), DriverManager.WAIT_HUGE);

我收到编译错误:

DriverManager类型中的waitFor(ExpectedCondition,int)方法不适用于参数(ExpectedCondition,int)

如果我将方法定义中的参数类型更改为ExpectedCondition<WebElement>,那么,当然,第二个等待会超过,第一个等待会抛出编译错误。如果我尝试为ExpectedCondition<WebElement>ExpectedCondition<Boolean>创建相同的方法,则会出现编译错误:

方法waitFor(ExpectedCondition,int)的擦除与DriverManager类型中的另一个方法相同

最后,如果我尝试将参数定义为ExpectedCondition,我会以相同的小方法获得大量编译警告:

ExpectedCondition是一种原始类型。对泛型类型ExpectedCondition的引用应该参数化

类型安全性:ExpectedCondition类型的表达式需要未经检查的转换以符合函数

类型安全:直到(ExpectedCondition)泛型方法的未经检查的调用,直到(FluentWait类型的

我也尝试定义这样的方法:

public static void waitFor(Function<? super WebDriver,Object> condition,int timeoutSeconds) throws Exception {

但是这个方法的调用都会抛出编译器错误。

我该怎么办?使用原始的ExpectedCondition参数并忽略警告?

5 个答案:

答案 0 :(得分:1)

我最终找到了我认为正确的解决方案:

public static void waitFor(ExpectedCondition<?> condition,int timeoutSeconds) throws Exception {
    setImplicitWait(0);
    try {
        (new WebDriverWait(driver, timeoutSeconds)).until(condition);
    } finally {
        setImplicitWait(WAIT_REGULAR);
    }
}

答案 1 :(得分:0)

方法visibilityOfElementLocatedinvisibilityOfElementLocated不会返回相同的类型:

public static ExpectedCondition<Boolean> invisibilityOfElementLocated(final By locator) { ... }

public static ExpectedCondition<WebElement> visibilityOfElementLocated(final By locator) { ... }

当条件应用时,第一个返回Boolean,而第二个返回WebElement

为了使其有效,您需要实现两者:

public static void waitFor(ExpectedCondition<Boolean> condition,int timeoutSeconds) throws Exception {
    setImplicitWait(0);
    try {
        (new WebDriverWait(driver, timeoutSeconds)).until(condition);
    } finally {
        setImplicitWait(WAIT_REGULAR);
    }
}

public static WebElement waitFor(ExpectedCondition<WebElement> condition,int timeoutSeconds) throws Exception {
    setImplicitWait(0);
    try {
        return (new WebDriverWait(driver, timeoutSeconds)).until(condition);
    } finally {
        setImplicitWait(WAIT_REGULAR);
    }
}

答案 2 :(得分:0)

我们的项目中有一个非常好的定制等待方法,可以很容易地适应您可能想要等待的任何条件

public static void waitForElementToBeVisible(WebDriver driver, int seconds, WebElement element) {
        WebDriverWait wait = (WebDriverWait) new WebDriverWait(driver, seconds)
                .ignoring(StaleElementReferenceException.class);
        wait.withMessage(ERROR_START + element + ERROR_MIDDLE + seconds + ERROR_END);
        wait.until((ExpectedCondition<Boolean>) webDriver -> element.isDisplayed());
}

只需将element.isDisplayed()替换为您想要的任何布尔条件。 int参数是最大值。超时你想等待条件成真。

将它与Selenium 3.4一起使用,就像魅力一样。

答案 3 :(得分:0)

我正在使用这些包装器方法来处理定位元素时的同步。试试这个:

public static void expWait_elementclick(WebDriver driver,By by){        
    try {
        (new WebDriverWait(driver, 10)).until(ExpectedConditions.elementToBeClickable(by));
        driver.findElement(by).click();
    } catch (StaleElementReferenceException  ser) {
        // TODO Auto-generated catch block
        driver.findElement(by).click();
    }
}


public static void expWait_elementlocated(WebDriver driver,By by){
    try {
        (new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(by));
        driver.findElement(by).click();
    } catch (StaleElementReferenceException  ser) {
        // TODO Auto-generated catch block
        driver.findElement(by).click();
    }
}

答案 4 :(得分:0)

您要问的一个例子如下:

2
  

同样,如果public WebElement waitFor(WebElement elem, String waitType, long waitInSeconds ) { Wait<WebDriver> wait = new FluentWait<WebDriver>(driver) .withTimeout(waitInSeconds, TimeUnit.SECONDS) .pollingEvery(500, TimeUnit.MILLISECONDS) .ignoring(NoSuchElementException.class); try{ switch(waitType) { case "elementToBeClickable": wait.until(ExpectedConditions.elementToBeClickable(elem)); break; case "visibilityOf": wait.until(ExpectedConditions.visibilityOf(elem)); break; case "elementToBeSelected": wait.until(ExpectedConditions.elementToBeSelected(elem)); break; default: wait.until(ExpectedConditions.visibilityOf(elem)); break; } } catch(TimeoutException e) { e.printStackTrace(); } return elem; } 作用于ExpectedCondition或需要额外参数   这可以根据要求进行更改。