Selenium Webdriver с Java: элемент не найден в кеше - возможно, страница изменилась с момента ее поиска

Я инициализирую переменную в начале моего класса:

public WebElement logout;

Позже в коде, в каком-то методе, в первый раз, когда я сталкиваюсь с кнопкой выхода, я назначаю значение этой переменной (в скобках оператора if/else):

logout = driver.findElement(By.linkText("Logout"));
logout.click();

Затем я снова использую "logout", успешно, на другом этапе моего теста:

logout.click();

И в конце теста в месте, где элемент тот же (By.linkText( "Выход" ), я получаю эту ошибку:

Element not found in the cache - perhaps the page has changed since it was looked up

Почему?

EDIT: На самом деле, я не успешно использую logout.click(); commant на другом этапе моего испытания. Похоже, я не могу использовать его снова. Мне нужно создать web-элемент logout1 и использовать его...

Ответ 1

Если произошли какие-либо изменения на странице после того, как вы изначально нашли element, ссылка webdriver теперь будет содержать ссылку stale. Когда страница изменилась, element больше не будет там, где webdriver ожидает, что она будет.

Чтобы решить вашу проблему, попробуйте find использовать элемент каждый раз, когда вам нужно его использовать, - написание небольшого метода, который вы можете назвать как и когда это хорошая идея.

import org.openqa.selenium.support.ui.WebDriverWait

public void clickAnElementByLinkText(String linkText) {
    wait.until(ExpectedConditions.presenceOfElementLocated(By.linkText(linkText)));
    driver.findElement(By.linkText(linkText)).click();
}

Затем в вашем коде вам нужно будет:

clickAnElementByLinkText("Logout");

Таким образом, каждый раз, когда он найдет элемент и щелкнет по нему, как таковой, даже если страница изменится, так как она "обновляет" ссылку на этот элемент, все это успешно нажмите.

Ответ 2

Браузер восстанавливает структуру DOM динамических страниц, поэтому элементам не нужно держать их перед тем, как их использовать.

Использование XPath, например. Этот подход неверен (может вызвать исключение org.openqa.selenium.StaleElementReferenceException в будущем):

WebElement element = driver.findElement(By.xpath("//ul[@class=\"pagination\"]/li[3]/a"));
...// Some Ajax interaction here
element.click(); //<-- Element might not be exists

Этот подход правильный:

driver.findElement(By.xpath("//ul[@class=\"pagination\"]/li[3]/a")).click();

Ответ 3

Это потому, что вы не уделяете должное время для загрузки страницы. Поэтому вам нужно предоставить код Thread.sleep(); для данной страницы.
Я также получаю ту же проблему для своего проекта, но после использования Thread.sleep(); его работая отлично для меня, дайте веб-странице столько, сколько возможно в течение 30-50 секунд.