2 сложности:
- no such element exception - не найден.
- stale element reference exception. (stale - устаревший) - потерялся.
Поиск элемента выполняется с помощью команды findElement или findElements.
В качестве параметра эти команды принимают т.н. локатор, описание правил или стратегии поиска элемента(ов).
Например, эта команда найдет элемент, у которого есть атрибут name, имеющий заданное значение. Если на странице несколько таких элементов, значит будет найден первый из них. Когда нас интересует не только первый, а все элементы, надо использовать команду findElements, она возвращает список элементов.
Если по какой-то причине команда findElement не может найти то, о чем попросили, она выбрасывает исключение.
4 причины:
1. Невалидный локатор.
2. Нет такого элемента:
- страница поменялась, изменилась верстка.
- в локаторах использовались какие-то критерии, основанные на изменяющихся свойствах элементов. Например, часто бывает, что id элементов создаются динамически, либо каждый раз они вообще новые, либо заменяются при перекомпиляции целевого приложения. Выпустили разрабы новую версию, а там все локаторы другие.
3.
Сейчас нет такого элемента. Мы смотрим - он есть, но в тот момент, когда с.искал элемент, его не было. Скорей всего - надо использовать ожидание, т.е. искать элемент не сразу, а ждать, когда он появится.
4. Элемент может находиться в другом окне или другом фрейме.
findElement - выбрасывает исключение.
findElements - возвращает пустой список.
Посмотрим что возвращает метод findElement.
Поставим точку остановки, запустим сценарий в отладчике и проанализируем содержимое объекта типа WebElement.
Единственное, что хранится внутри этого объекта, это уникальный идентификатор. С. не загружает из браузера никакую инфу об элементах, кроме этого идентификатора. Если надо совершить с элементом какое-то действие или узнать какое-то свойство этого элемента, даже самое простое, например, тег, с. обращается к браузеру. Если мы два раза спросим тег элемента, он будет два раза обращаться к браузеру. Никакого кеширования на стороне клиентской библиотеки нет. Любое действие, любое получение свойства какого-то элемента - это всегда обращение к браузеру.
И при каждом таком обращении С. передает туда этот уникальный id элемента. Внутри браузера все элементы имеют такие уникальные id. Но когда страница меняется, элементы старые исчезают, появляются новые, у этих элементов будут новые идентификаторы. Даже если новые элементы находятся на том же самом месте, где находились старые элементы и даже если они абсолютно так же выглядят, имеют такой же набор свойств, такой же текст, у них все равно будут новые идентификаторы.
Когда С. обращается к браузеру и передает туда id исчезнувшего элемента, возникает исключение stale element reference exception. (stale - устаревший). Браузер сообщает, что элемента с таким id больше нет, он исчез.
Если искусственно создать такую ситуацию, например, вписать эту строчку:
Оно обновит страничку, айдишник у этого элемента будет другой. Локатор "q" будет тот же, а айдишник будет другим, это уже другой элемент.
Главное, что надо запомнить, это то, что, нужно искать элемент непосредственно перед использованием.
Если мы сохранили элемент в какую-то переменную, потом выполнили какие-то действия со страницей и после этого что-то пытаемся сделать с элементом, сохраенным в переменную, это исключение может возникнуть, ибо страница могла поменяться.
Надо выполнять поиск элемента непосредственно перед использованием.