Как подождать, пока элемент не появится в Selenium?
Я пытаюсь заставить Selenium ждать элемент, который динамически добавляется в DOM после загрузки страницы. Пробовал это:
fluentWait.until(ExpectedConditions.presenceOfElement(By.id("elementId"));
В случае, если это помогает, вот fluentWait
:
FluentWait fluentWait = new FluentWait<>(webDriver) {
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(200, TimeUnit.MILLISECONDS);
}
Но он выбрасывает NoSuchElementException
- выглядит как presenceOfElement
ожидает, что элемент будет таким, чтобы это было некорректно. Это, должно быть, хлеб и масло для Селена и не хотят изобретать колесо... может ли кто-нибудь предложить альтернативу, в идеале без катания моего собственного Predicate
?
Ответы
Ответ 1
Вам нужно вызвать ignoring
с исключением, чтобы игнорировать, пока WebDriver
будет ждать.
FluentWait<WebDriver> fluentWait = new FluentWait<>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(200, TimeUnit.MILLISECONDS)
.ignoring(NoSuchElementException.class);
Для получения дополнительной информации см. документацию FluentWait. Но будьте осторожны, что это условие уже реализовано в ExpectedConditions, поэтому вы должны использовать
WebElement element = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
Базовый учебник для ожидания можно найти здесь.
Ответ 2
Рекомендуем вам использовать библиотеку Selenide.
Это позволяет писать гораздо более сжатые и читаемые тесты. Он может ждать появления элементов с гораздо более коротким синтаксисом:
$("#elementId").shouldBe(visible);
Вот пример проекта для проверки поиска Google:
https://github.com/selenide-examples/google
Ответ 3
public WebElement fluientWaitforElement(WebElement element, int timoutSec, int pollingSec) {
FluentWait<WebDriver> fWait = new FluentWait<WebDriver>(driver).withTimeout(timoutSec, TimeUnit.SECONDS)
.pollingEvery(pollingSec, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class, TimeoutException.class).ignoring(StaleElementReferenceException.class);
for (int i = 0; i < 2; i++) {
try {
//fWait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//*[@id='reportmanager-wrapper']/div[1]/div[2]/ul/li/span[3]/i[@data-original--title='We are processing through trillions of data events, this insight may take more than 15 minutes to complete.']")));
fWait.until(ExpectedConditions.visibilityOf(element));
fWait.until(ExpectedConditions.elementToBeClickable(element));
} catch (Exception e) {
System.out.println("Element Not found trying again - " + element.toString().substring(70));
e.printStackTrace();
}
}
return element;
}
Ответ 4
FluentWait вызывает исключение NoSuchElementException - это случай путаницы
org.openqa.selenium.NoSuchElementException;
с
java.util.NoSuchElementException
в
.ignoring(NoSuchElementException.class)