Мне нужно проверить видимость элемента на странице.
Я использовал (psuedocode) wait.until (ExpectedCondition.visibilityOfElement (locator));
Однако стандартное ExpectedCondition проверяет только первый элемент в DOM, соответствующий локатору.
Мои локаторы не могут быть сделаны достаточно конкретными, чтобы соответствовать только одному элементу (это ограничение того, что меня попросили автоматизировать, и его нельзя изменить).Но из найденных элементов любой отображаемый является честной игрой.
Поэтому я использую пользовательское ExpectedCondition, перебираю найденные элементы, нахожу любые отображаемые элементы и возвращаю первый найденный элемент.
Код выглядит следующим образом:
public WebElement WaitForElementToBeVisible(WebDriver theDriver, By locator) {
return new WebDriverWait(theDriver, STANDARD_WAIT_TIME)
.pollingEvery(1, TimeUnit.SECONDS)
.withTimeout(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class)
.until((ExpectedCondition<WebElement>) driver -> {
List<WebElement> els = driver.findElements(locator);
for (WebElement el : els) {
try {
if (el.isDisplayed()) {
return el;
}
} catch (StaleElementReferenceException e) {
/* Ignore Exception */
} catch (NullPointerException e) {
System.out.println("NullPointerException thrown");
}
}
return null;
});
}
Однако в некоторых случаях вызов el.isDisplayed вызывает исключение NullPointerException.В других ответах я видел, что если элемента нет на странице, то это произойдет.Но в этом случае я знаю, что элемент присутствует.
Я добавил журналы, в которых говорилось, что:
- Элемент присутствует (вна самом деле их три)
- isDisplayed вызывается на всех трех элементах
- Все три элемента выдают исключение NullPointerException
Кроме того, поскольку он ожидает 5 секундчтобы отобразить элемент, у меня есть достаточно времени, чтобы посмотреть и увидеть, что да, кажется, элемент действительно отображается.
Если мы удалим блок catch, трассировка стека NullPointerException выглядит следующим образом(Только последняя строка, потому что все остальное зависит от компании, и мой босс не хочет, чтобы я делился этим):
java.lang.NullPointerException
at org.openqa.selenium.remote.RemoteWebElement.isDisplayed(RemoteWebElement.java:323)
И этот след приводит к:
public boolean isDisplayed() {
Object value = execute(DriverCommand.IS_ELEMENT_DISPLAYED, ImmutableMap.of("id", id))
.getValue();
try {
return (Boolean) value;
} catch (ClassCastException ex) {
throw new WebDriverException("Returned value cannot be converted to Boolean: " + value, ex);
}
}
Ошибка вызывается оператором return, поэтому по любой причине команда execute возвращает ноль.
Я полагаю, что это соответствующие разделы файла pom:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.10.0</version>
</dependency>
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>3.6.2</version>
</dependency>
Любая помощь вотладка этого вопросамы будем благодарны.