我正在使用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类型的 我也尝试定义这样的方法: 但是这个方法的调用都会抛出编译器错误。 我该怎么办?使用原始的ExpectedCondition参数并忽略警告? public static void waitFor(Function<? super WebDriver,Object> condition,int timeoutSeconds) throws Exception {
答案 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)
方法visibilityOfElementLocated
和invisibilityOfElementLocated
不会返回相同的类型:
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
或需要额外参数 这可以根据要求进行更改。