Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Webdriver не находит элемент - Element not found in the cache

java
selenium
webdriver
testng
Теги: #<Tag:0x00007f7b6488da60> #<Tag:0x00007f7b6488d718> #<Tag:0x00007f7b6488d538> #<Tag:0x00007f7b6488d1a0>

(Alexey Bes) #1

Добрый вечер. Суть вопроса заключается в том, что после того как залогинился на сайте загружается страница с кнопкой “Login” через некоторое время страница автоматически перезагружается и появляется вместо “Login” кнопка “Profile”, но Webdriver ее не находит, пишет ошибку - “Element not found in the cache - perhaps the page has changed since it was looked up” в интеренете не смог найти решение проблемы. Помогите пожалуйста.


(Sergey Korol) #2

Все экстрасенсы в отпуске. Показывайте код, будем смотреть. :wink:


(rmerkushin) #3

Вангую изменение элемента на странице во время загрузки, ajax там например или просто страница не до конца загрузилась и etc. Скорее всего вам нужен wait until.


(Евгений Бухгаммер) #4

Неужели сообщение вебдрайвера Вам не говорит прямым текстом проверить, что за время последнего lookup’a элемент в DOM структуре скорее всего уничтожился\изменился?

Если гуглить по сообщению ошибки, то находит следующий форум, наталкивающий на мысли:
http://software-testing.ru/forum/index.php?/topic/21727-element-not-found-in-the-cache/

и на SoF:

в общем, и там и там совет один: не хранить ссылки на элементы, а делать поиск непосредственно перед манипуляцией с элементом.


(Pavel Ordenko) #5

Перед повторным использованием элемента (клик, получение текста или значений атрибутов и т.д.) ищите его еще раз через 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. За кач-во кода не отвечаю, праздники, сами понимаете))


(asolntsev) #6

Предыдущий ответ в принципе правильный, но код можно написать гораздо короче.
Вот так:

$(byText("Profile")).click();

Selenide сама подождёт, пока элемент появится, и тогда кликнет на него.


(Alexey Bes) #7

Спасибо всем за ответы, попробую с явными ожиданиями. А Selenide - это отдельная библиотека как я понимаю, ее надо отдельно подключать? Я просто только начинаю вникать в автматизацию


(Roy Obenon) #8

http://selenide.org/quick-start.html


(Alexey Bes) #9

Спасибо