StaleElementReferenceException — одно из самых интригующих исключений, какое вы могли встретить, тестируя с помощью Selenium. Надеюсь, что этот пост поможет вам решить проблему с появлением данного исключения в ваших тестах.
Что такое StaleElementReferenceException?
Согласно документации Selenium Webdriver, слово “stale” означает то, что ссылка на элемент теперь “несвежая” — элемент больше не появляется в DOM страницы. Проще говоря, элемент, который вы обнаружили с помощью метода findElement, исчез, когда вы инициировали взаимодействие с ним.
Давайте разберем некоторые аспекты того, как Selenium WebDriver обрабатывает этот сценарий.
Внутреннее устройство WebDriver
Когда вы пишете синтаксис для выполнения какого-либо действия с помощью Selenium WebDriver, он обращается внутренним вызовом к API WebDriver, связанному с этим методом.
Метод WebDriver
Например, если вы ищете способ найти элемент в браузере, используя Selenium WebDriver и Java, синтаксис будет выглядеть следующим образом:
Запрос к API
Теперь метод Java внутренне вызывает API WebDriver POST-запросом через передачу информации о локаторе в теле запроса, как показано ниже:
В приведенном выше запросе localhost указывает на chromedriver, работающий в качестве локального сервера на порте 9515.
Примечание: при запуске тестов из IDE (такой как Eclipse), Selenium находит свободный порт во время выполнения, и это может быть не 9515, который является портом по умолчанию.
Ответ API
Ответ API от сервера chromedriver при успешном нахождении соответствия вернет WebElement и будет выглядеть следующим образом:
Здесь вы найдете информацию об элементе с уникальным идентификатором для каждой сессии и запрошенного DOM. Примечание: информация об элементе изменится, когда страница будет перезагружена или если к ней будет совершен переход из других сессий.
Ответ WebDriver
Эта информация об элементе принимается в качестве ответа от метода findElement в WebDriver и преобразуется к типу WebElement.
Browser Driver выбрасывает исключение о несвежей ссылке на элемент
С учетом данной информации становится очевидным, что при попытке взаимодействовать с элементом, найденным несколькими миллисекундами раньше, он мог исчезнуть, потому что страница оказалась обновлена/перезагружена при взаимодействии с ней кликом, тапом или как-то иначе.
Из-за этого изменения информации об элементе в DOM между вызовами (locate и action) ChromeDriver (а не Selenium WebDriver), выбрасывает исключение о несвежей ссылке на элемент (Stale Element exception).
Подводя итог: исключение создается 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 — одни из распространенных, и как только вы узнаете, почему они появляются и как с ними справляться, вы их одолеете. Каждое исключение научит вас чему-то уникальному, так что продолжайте учиться.
Читайте также:
- Proxy - сокровище JavaScript
- Как сжимать коммиты в Git с помощью git squash
- Чего я не знал о CSS, а стоило бы
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи Babu Manickam: The Untold Story — Stale Element Reference Exception in Selenium