StaleElementReferenceException — одно из самых интригующих исключений, какое вы могли встретить, тестируя с помощью Selenium. Надеюсь, что этот пост поможет вам решить проблему с появлением данного исключения в ваших тестах.
Что такое StaleElementReferenceException?
Согласно документации Selenium Webdriver, слово “stale” означает то, что ссылка на элемент теперь “несвежая” — элемент больше не появляется в DOM страницы. Проще говоря, элемент, который вы обнаружили с помощью метода findElement, исчез, когда вы инициировали взаимодействие с ним.
Давайте разберем некоторые аспекты того, как Selenium WebDriver обрабатывает этот сценарий.
Когда вы пишете синтаксис для выполнения какого-либо действия с помощью Selenium WebDriver, он обращается внутренним вызовом к API WebDriver, связанному с этим методом.
Принцип работы Selenium WebDriverНапример, если вы ищете способ найти элемент в браузере, используя Selenium WebDriver и Java, синтаксис будет выглядеть следующим образом:
Поиск элемента с использованием Id в качестве селектораТеперь метод Java внутренне вызывает API WebDriver POST-запросом через передачу информации о локаторе в теле запроса, как показано ниже:
Запрос FindElement, отправленный через PostmanВ приведенном выше запросе localhost указывает на chromedriver, работающий в качестве локального сервера на порте 9515.
Примечание: при запуске тестов из IDE (такой как Eclipse), Selenium находит свободный порт во время выполнения, и это может быть не 9515, который является портом по умолчанию.
Ответ API от сервера chromedriver при успешном нахождении соответствия вернет WebElement и будет выглядеть следующим образом:
Ответ с информацией об элементеЗдесь вы найдете информацию об элементе с уникальным идентификатором для каждой сессии и запрошенного DOM. Примечание: информация об элементе изменится, когда страница будет перезагружена или если к ней будет совершен переход из других сессий.
Информация об элементе после перезагрузкиЭта информация об элементе принимается в качестве ответа от метода findElement в WebDriver и преобразуется к типу WebElement.
Ответ API преобразован в WebElementС учетом данной информации становится очевидным, что при попытке взаимодействовать с элементом, найденным несколькими миллисекундами раньше, он мог исчезнуть, потому что страница оказалась обновлена/перезагружена при взаимодействии с ней кликом, тапом или как-то иначе.
Из-за этого изменения информации об элементе в DOM между вызовами (locate и action) ChromeDriver (а не Selenium WebDriver), выбрасывает исключение о несвежей ссылке на элемент (Stale Element exception).
Stale Element Exception от Chrome DriverПодводя итог: исключение создается ChromeDriver (а не Selenium WebDriver), когда информация об элементе оказывается изменена при перезагрузке страницы между locate (findElement) и action (click/sendKeys).
Как мы можем справиться с этим исключением?
Существует несколько способов. Вам стоит подобрать самый простой и оптимальный вариант, основанный на характере возникающей у вас проблемы и вашем опыте.
Добавьте простое ожидание, используя Thread.sleep, на несколько секунд (или, может быть, немного больше, в зависимости от времени, за которое, по вашему мнению, ваше приложение сможет завершить компонент), прежде чем искать элемент с помощью findElement.
2. При появлении исключения возвратитесь к поиску элемента
Добавьте обработку исключений к своему действию, и если появится исключение Stale Element, то повторите попытку найти (locate) элемент после простого ожидания в течение 500 миллисекунд. Повторяйте эти действия до тех пор, пока действие не завершится успешно или не будет выполнено максимально допустимое количество итераций.
3. Используйте инструменты разработчика, чтобы знать состояние DOM
Используйте API dev-tools для того, чтобы узнавать, был ли DOM перезагружен между findElement и щелчком мыши. Если DOM оказался обновлен, то запросите у слушателя новую информацию об элементе для следующего действия.
По ссылке на GitHub вы найдете больше подробностей.
Исключения StaleElementReferenceException — одни из распространенных, и как только вы узнаете, почему они появляются и как с ними справляться, вы их одолеете. Каждое исключение научит вас чему-то уникальному, так что продолжайте учиться.
Перевод статьи Babu Manickam: The Untold Story — Stale Element Reference Exception in Selenium
Комментарии