Как стать автором
Обновить

Stale Element Reference в Selenide

Время на прочтение2 мин
Количество просмотров3.9K

Всем привет! Данная ошибка является очень популярной при использовании Selenide автотестах в Java. На поиск решения у меня ушло довольно много времени, поэтому в этой статье я хочу подробно рассказать про эту ошибку и как с ней работать.

Что такое Stale Element Reference и как ее избежать

Stale Element Reference (дальше буду писать SER) является исключением, при котором элемент на странице меняет свой айди при изменении DOM дерева. Чаще всего эту ошибку можно поймать при переборе коллекции элементов в Selenide.

Что я понял про ошибку SER?

В Selenide при итерации списка выполняется метод .snapshot() который замораживает эту коллекцию и элементы стают неизменны, а путь элемента на странице остается прежним. Соответственно мы не сможем обратиться к обновленному элементу, если изменится DOM дерево страницы.

Есть сайт специально для отлова ошибок и тренировки поиска элементов через Xpath. Как раз на этом сайте можно можно поймать SER

Сайт - http://the-internet.herokuapp.com/challenging_dom

Давайте определим коллекцию элементов (3 разноцветные кнопки, которые находятся слева).

ElementsCollection buttons = $$x(".//a[contains(@class,'button')]");

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

Например вот так, мы словим SER перед нажатием на вторую кнопку.

for (SelenideElement button : buttons){
            button.click();
        }

Коллекцию элементов можно обновить только через получение какого то элемента из нее, вызвав метод .get(index), соответственно коллекция обновляется и пути к элементам тоже обновляются, а ошибка SER не вылазит.

Можно перебирать элементы таким способом:

for(int i = 0; i<buttons.size(); i++){
            buttons.get(i).click();
        }

Как вариант можно использовать цикл forEach, добавив в него внешний индекс. Также ошибки SER не будет.

int index = 0;
        for (SelenideElement button : buttons){
            buttons.get(index).click();
            index++;
        }

Также можно написать метод, который ловит SER ошибку и код программы продолжает выполняться.

public boolean isVisible(SelenideElement element) {
        try {
            return element.isDisplayed();
        }
        catch (StaleElementReferenceException e) {
            return false;
        }
    }

Также можно использовать этот простой цикл, чтобы перебрать коллекцию и добавить какое то условие максимально безопасно. То есть, если элемент будет SER, то будет переопределение элемента на странице и дальнейшее взаимодействие

int index = 0;
for (SelenideElement element : buttons) {
            if(isVisible(element)){
                element.click();
            } else {
                buttons.get(index).click();
            }
            index++;

После прочтения данной статьи многие автотестеры смогут решить свою проблему.

Теги:
Хабы:
Всего голосов 3: ↑3 и ↓0+3
Комментарии2

Публикации