Добрый вечер. Суть вопроса заключается в том, что после того как залогинился на сайте загружается страница с кнопкой “Login” через некоторое время страница автоматически перезагружается и появляется вместо “Login” кнопка “Profile”, но Webdriver ее не находит, пишет ошибку - “Element not found in the cache - perhaps the page has changed since it was looked up” в интеренете не смог найти решение проблемы. Помогите пожалуйста.
Все экстрасенсы в отпуске. Показывайте код, будем смотреть.
Вангую изменение элемента на странице во время загрузки, ajax там например или просто страница не до конца загрузилась и etc. Скорее всего вам нужен wait until.
Неужели сообщение вебдрайвера Вам не говорит прямым текстом проверить, что за время последнего lookup’a элемент в DOM структуре скорее всего уничтожился\изменился?
Если гуглить по сообщению ошибки, то находит следующий форум, наталкивающий на мысли:
http://software-testing.ru/forum/index.php?/topic/21727-element-not-found-in-the-cache/
и на SoF:
в общем, и там и там совет один: не хранить ссылки на элементы, а делать поиск непосредственно перед манипуляцией с элементом.
Перед повторным использованием элемента (клик, получение текста или значений атрибутов и т.д.) ищите его еще раз через driver.findElement(By). Ну и да, как упоминалось выше, лучше через явные ожидания WebDiverWait.until(Function<T,V>) / WebDiverWait.until(ExpectedCondition) или как его. Например, на жаве будет как-то так
...
// Допустим, это поле с драйвером, который инициализировали перед запуском теста
private WebDriver driver;
// А это - локатор элемент
private final By locator = By.xpath("//button");
...
public WebElement getElement(By locator) {
Wait<WebDriver> wait = new WebDriverWait<>(driver, 30);
ExpectedContidion<WebElement> condition = new ExpectedCondition<>() {
@Override
public WebElement apply(WebDriver driver) {
try {
return driver.findElement(locator);
} catch (NoSuchElementException) {
return null;
}
}
}
WebElement element = wait.until(condition);
if (element == null) {
throw new NoSuchElementException("Element not found: " + locator);
} else {
return element;
}
}
p.s. За кач-во кода не отвечаю, праздники, сами понимаете))
Предыдущий ответ в принципе правильный, но код можно написать гораздо короче.
Вот так:
$(byText("Profile")).click();
Selenide сама подождёт, пока элемент появится, и тогда кликнет на него.
Спасибо всем за ответы, попробую с явными ожиданиями. А Selenide - это отдельная библиотека как я понимаю, ее надо отдельно подключать? Я просто только начинаю вникать в автматизацию
Спасибо