做自动化,隐式等待和显示等待是最常用的了,网上一搜也一大堆,但是答案几乎都是一样的,如下:
隐式等待:设置一个超时时间,在这个时间内会去不断寻找元素,超时找不到时就会报错;
driver.manage().timeouts().implicitlyWait(6, TimeUnit.SECONDS);
显示等待:设置一个超时时间和一个元素查找条件,在这个时间内不断寻找这个元素,超时找不到时就会报错;
WebDriverWait wait = new WebDriverWait(driver,10);
WebElement webElement = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
看起来似乎不一样又一样,打开wait.until的源码发现:
private static final Duration DEFAULT_WAIT_DURATION = Duration.ofMillis(500L);
private final T input;
private final Clock clock;
private final Sleeper sleeper;
private Duration timeout;
private Duration interval;
public <V> V until(Function<? super T, V> isTrue) {
Instant end = this.clock.instant().plus(this.timeout);
while(true) {
Throwable lastException;
try {
V value = isTrue.apply(this.input);
if (value != null && (Boolean.class != value.getClass() || Boolean.TRUE.equals(value))) {
return value;
}
lastException = null;
} catch (Throwable var7) {
lastException = this.propagateIfNotIgnored(var7);
}
if (end.isBefore(this.clock.instant())) {
String message = this.messageSupplier != null ? (String)this.messageSupplier.get() : null;
String timeoutMessage = String.format("Expected condition failed: %s (tried for %d second(s) with %d milliseconds interval)", message == null ? "waiting for " + isTrue : message, this.timeout.getSeconds(), this.interval.toMillis());
throw this.timeoutException(timeoutMessage, lastException);
}
try {
this.sleeper.sleep(this.interval);
} catch (InterruptedException var6) {
Thread.currentThread().interrupt();
throw new WebDriverException(var6);
}
}
}
- 这里大概的意思就是设置一个timeout和一个Millis(500L)的interval,然后每隔0.5秒就检查一次你传入的条件是否满足,满足就进行下面的操作,不满足就在超时后报错
总结:
其实隐式等待和显示等待在本质上是一致的,只是显示等待多了一个指定元素条件超时时间,在使用场景上,可以使用隐式等待来做一个全局的控制,例如设置全局隐式等待6秒;
如果某个控件比较特殊,需要更长的时间加载,比如十几秒或者更长,就可以使用显示等待对其进行单独处理;