-
-
Notifications
You must be signed in to change notification settings - Fork 8.6k
Description
Description
Recent nullability changes made ExpectedConditions.* return a @Nullable WebElement:
| public static ExpectedCondition<@Nullable WebElement> presenceOfElementLocated(final By locator) { |
WebDriverWait extends FluentWait which declares until:
| public <V> V until(Function<? super T, V> isTrue) { |
When the two are combined, the until function now implicitly "declares" to return null and that breaks compilation of existing working Kotlin code:
> Task :test-integration:compileKotlin FAILED
e: .../wait.kt [ARGUMENT_TYPE_MISMATCH] Argument type mismatch: actual type is 'WebElement?', but 'WebElement' was expected.
For completeness:
| public interface ExpectedCondition<T extends @Nullable Object> | |
| extends Function<WebDriver, T>, java.util.function.Function<WebDriver, T> {} |
Solution?
until has the following structure (relevant parts only), where you can clearly see there's no code path which would return a V? instance.
public <V> V until(Function<? super T, V> isTrue) {
while (true) {
try {
V value = isTrue.apply(input);
if (value != null) {
return value;
}
} catch (Throwable e) {
}
if (...) {
throw;
}
try {
} catch (InterruptedException e) {
throw;
}
}
}Currently:
public <V> V until(Function<? super T, V> isTrue) {becomes
public <V = @Nullable WebElement> @Nullable WebElement until(Function<WebDriver, @Nullable WebElement> isTrue) {I hope it's possible to declare it like this:
public <V> @NonNull V until(Function<? super T, V> isTrue) {which hopefully becomes:
public <V = @Nullable WebElement> @NonNull WebElement until(Function<WebDriver, @Nullable WebElement> isTrue) {The Wait<?> interface might complicate things, hope that its design allows it to be non-null return type too (as it is documented!).
Reproducible Code
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.support.ui.ExpectedConditions
import org.openqa.selenium.support.ui.WebDriverWait
import kotlin.time.Duration.Companion.minutes
import kotlin.time.toJavaDuration
fun WebDriver.waitForExistenceAndVisibility(locator: By) {
val wait = WebDriverWait(this, 1.minutes.toJavaDuration())
val element = wait.until(ExpectedConditions.presenceOfElementLocated(locator))
wait.until(ExpectedConditions.visibilityOf(element))
}4.39.0: val element: WebElement!
4.40.0: val element: WebElement?
expected: val element: WebElement
ℹ️ Last known working version: 4.39.0