Почему я получаю NoSuchElementException в моем PageObject c selenide?

locators
page-object
java
webdriver
selenide
Теги: #<Tag:0x00007fedc4695028> #<Tag:0x00007fedc4694ee8> #<Tag:0x00007fedc4694da8> #<Tag:0x00007fedc4694c68> #<Tag:0x00007fedc4694b28>

(Eugene Moskalenko) #21

нет, у меня по тесту страница перегружается, чиститься кука, добавляется в урл параметр и происходит релоад страницы и потом происходит поиск элемента


(Roma Marinsky) #22

У селенида такого нет :slight_smile:


(asolntsev) #23

@evgmoskalenko Привет!
Жаль, что я так поздно дошёл до этой темы.

Когда вы инициализируете пэдж-объект с помощью метода page:
PayPalFirstStepPage firstStep = page(PayPalFirstStepPage.class).

Selenide

  1. создаёт экземпляр объекта (и полю fieldFirstName присваивается значение $("#product:fname")), но после этого
  2. Вызывает селениумовскую фабрику PageFactory.initElements(), которая пытается найти у всех элементов @FindBy и по ним найти элементы в браузере. Если у какого-то элемента нет аннотации @FindBy (как в вашем случае), он ищет элемент по имени поля, т.е. fieldFirstName.

В общем, проще всего объявлять поля с типом By:

private By fieldFirstName = By.id(“product:fname”);


(Eugene Moskalenko) #24

Спасибо, только начал позновать селенид, сталкиваюсь с нюансами :slight_smile:

то есть по сути, такой вот метод page() делает принудительную инициализацию селениумовской фабрики PageFactory.initElements()? Чтобы не передавать во всяких там конструкторах? Заюзал метод page и пиши @FinBy?

И такой еще вопросик, зачем искать по имени поля - “fieldFirstName”? :slight_smile:

@asolntsev, а вот такой подход нормальный?

private SelenideElement fieldFirstName = $(By.id("product:fname"));


(Roma Marinsky) #25

ничоси


(asolntsev) #26

Да, нормальный. И тогда метод page() вообще не нужен. Вообще круто!


(Eugene Moskalenko) #27

Спасибо, теперь стало все прозрачней.

Мне просто больше нравится совмещать подходы - объявление веб-элементов в объекте страницы и использовать поиск веб-элементов в методах $("#foobar").click();

идея очень хорошая писать в методах поиск элемента и работу с ним, но с другой стороны когда используется больше одного раза веб-элемент, то лучше вынести в переменную, а писать эти постоянные @FinBy - со временем напрягает. Да и разработчиков сложно потом заставить переверстать страницу так, чтобы я мог не использовать длинный xpath локатор, а айдишник. А в методе такой xpath-локатор не оч хорошо смотрится :slight_smile:

Еще я вот какую штуку заметил, если писать в классе вот так (обьявлять веб-эелементы):

private SelenideElement fieldFirstName = $("#product:fname");

то выходит, что поиск элемента происходит не в момент его использования, а в момент инициализации объекта. То есть если такую строку написать в самом верху, затем инициализировать объект страницы, но не дернуть метод, который работает с этим элементом “fieldFirstName”, то поиск элемента этого будет выполняться, дебажил… :slight_smile:


(asolntsev) #28

Неа, не будет.
В вашем случае поиск выполнился именно из-за дебага. Как только вы остановились на брейкпойнте, IDE вызвала у объекта SelenideElement метод toString(), и он уже полез искать элемент. :slight_smile:

А без дебага поиск не выполнится. Проще всего проверить так: объявите несуществующий элемент. Если бы поиск осуществлялся, вы бы сразу получили ошибку.


(Eugene Moskalenko) #29

ага попробую, спасибо, но дело в том, что у меня этот элемент не присутствует на странице пока вкладку не нажму, а сам элемент вверху класса. И выходит так, что страница загрузилась, вкладка не нажималась и метод, который с элементом работает - не дергался, но логи показывают, что этот элемент не найден (без дебага). Если же такой элемент убрать из переменной и подставить в сам метод, тогда все работает на ура. Тесты его не пытаются искать на странице, пока не дернит его метод, в котором этот веб-элемент используется…


(asolntsev) #30

А можешь приложить точные логи?
С полным стектрейсом ошибки, что элемент не найден.


(Eugene Moskalenko) #31

да, постараюсь сделать на днях… Вернуть надо код в прежнее состояние, а то из-за той штуки переделал многое :slight_smile: Выложу сюда…


(Oleksandr Khotemskyi) #32

Так и есть, двоеточия вообще не очень правильно юзать для айдишников.
http://www.w3schools.com/cssref/css_selectors.asp
Вот тут есть примеры локаторов с :

Как вариант если поменять айдишник нельзя, но очень хочется css selector:
$("[id='product:fname']")


(Eugene Moskalenko) #33

дак айдишник такой же поставил не я :slight_smile: Он уже стоит такой…


(asolntsev) #34

Кстатий, Сергей Пирогов как раз нарвался на ту же проблему и описал в своём блоге:


(Eugene Moskalenko) #35

Таки да :slight_smile: Видать мы с Сергеем пришли к этому, как-то :slight_smile:


(Roma Marinsky) #36

Но я к этому раньше пришел. Когда не очень разбирался в page object у селениума