Каким образом описать класс с множеством однотипных элементов

webdriver
java
selenium
Теги: #<Tag:0x00007fedc41a0db0> #<Tag:0x00007fedc41a0c20> #<Tag:0x00007fedc41a0ae0>

(Sergey Pirogov) #23

Пока не понятно, чем этот фреймворк уникален и круче/хуже Yandex HTML elements + Selenide


(Рома Иовлев) #24

Ну это как если сравнивать сметану и огурец… что лучше? Лучше сделать отличный салатик )))
Они разные функции выполняют
Serenity - BDD фреймворка + репортинг
JDI - PageObject фреймворк для работы с UI элементами
BDD функции Serenity могут легко быть реализованы используя концепцию PageObjects в которой используются элементы JDI
:slight_smile:


(Рома Иовлев) #25

Не хочу доказывать что лучше. С Selenide или Serenity его сравнивать нельзя, они разные задачи решают и отлично дружат
С HtmlElements… Пусть тот кому интересно сам попробует сравнит и сделает выбор для себя.
Но сходу к примеру, у JDI больше элементов 30 против 11 и есть типы пейджобджектов (вроде форм, паджинации, dialog и прочее), встроенное логирование, много возможностей кастомизации, фреймворк не зависит от Selenium (есть реализация UI элементов для Appium и Sikuli) и много еще чего (можете посмотреть презентации)
Простой пример был в начале топика

@FindBy(xpath = "//div[*[@class='af_treeTable_icon-container']]")
public Tabs formularUNFASpan;
@FindBy(css = ".bpmenu_font_color")
public Tabs creditOrderMCLink;

HtmlElements так не умеют. Они вообще плохо работают с “не стандартными” элементами (если select это не < select> < option>… а дивы или форма не тег for или table не < table> а те же дивы, да даже если кнопка это не Input то это уже не кнопка, а к примеру Label)


(Roma Marinsky) #26

Я что-то не пойму. Зачем было делать ещё одну обёртку над селениумом
Если есть Селенид - который ещё проще чем ваш “джедай”
HTML Element не запрещает написать свой простой кастом элемент того же селекта суперособенного или лейбы

Как-то сомнительно это всё


(Рома Иовлев) #27

Не понимаю как вы сравниваете JDI с Selenide :smile:
В Selenide нет типизированных элементов, нет Таблиц и Селекторов, нет кнопок, есть только супер $(…), как и в Selenium WebElement


(asolntsev) #28

В Selenide нет типизированных элементов (типа Table, Select), потому что не надо.
Это принципиальное решение - я считаю, что они нужны, не несут пользы и только всё усложняют.

А всё, что надо - есть: удобная работа с таблицами, дополнительные селекторы и пр. И можно создавать свои классы-контейнеры, причём значительно проще.


(Рома Иовлев) #29

Такое мнение тоже имеет право на жизнь, мы не против. Мы предлагаем другой подход, дальше каждый выбирет, что ему по душе )


(Roma Marinsky) #30

Тут даже не то чтобы сказать, что типизированные элементы это избыточность или бесмыслица, они могут жить в целом
Но не в том виде чтобы ограничить или дать только определённый набор фунций над типом элемента для пользователя.

Мы можем дальше продолжать письками мерять решения ваше и селенида. Но достаточно просто сказать, что ваше решение использовать не столь удобно и не столь гибко для дополнения, ваше решение менее самодостаточно в том виде которое сейчас есть по сравнению с селенидом.
Вот честно, лучше бы уговорили Солнцева добавить типизированные элементы в селенид и сделать больше синонимов для Condition`ов, чем с нуля написать свой вариант селенида или вариант . Да что уж не то чтобы лучше уговорили, а проще было бы)))

Когда только начинал изучение java и написание тестового “крутого своего фреймворка” у меня были точно такие же решения (наименования методов, вид конструкций чтобы например кликнуть) даже некоторые лаконичнее, но без типизированных элементов, хотя попробовал и меня стошнило от типизированных элементов


(Рома Иовлев) #31

Интересно зачем уговаривать кого-то добавлять типизированные элементы в Selenide, если по вашему это в целом не удачная идея )))
Вы видимо не очень понимаете предназначение Selenide. Он не нуждается в типизированных элементах. Также как и Selenium, о чем не раз говорил Браанцев. Эти языки работают на своем уровне.
JDI, VIQA и HTML Elmenets на другом уровне абстракции. Их задача добавить наглядности в написанные тесты, логи и репорты и сэкономить время тестировщика на реализацию типичных для всех UI элементов функций, чего Selenide или Selenium НЕ должны делать в силу своей изначальной концепции.
В Selenide нельзя добавить типизированные элементы, потому что это будет уже не Selenide по своей сути)))


(asolntsev) #32

В целом согласен, кроме того, что добавление элементов добавляет наглядности.
Не добавляет.
Ровно наоборот, добавляет ненужной детализированности. Делает тестя слишком низкоуровневыми и зависящими от имплементации.

Грубо говоря, используете вы в тесте, скажем, какой-нибудь типизированный элемент Select. А в следующем релизе разработчики поменяли Select на radio button. А функционально (и может, даже визуально) для пользователя ничего не изменилось. А вам придётся тесты менять.

А в Selenide как было $(“input”).val(“xxx”), так и останется.


(Рома Иовлев) #33

Это было в Yandex HtmlElements. Я про это выше писал, что они очень привязаны к разметке страницы. Это один из поводов почему мы сделали JDI, чтобы таких проблем не было.
JDI построен на интерфейсах. т.е. это просто описание того, что умеет логически делать элемент.
Если по смыслу элемент не поменялся, а поменялась только разметка, то и тип элемента менять не надо, надо поменять только локатор/локаторы.
А для Selenide вам возможно придется написать метод вместо $(“input”).val(“xxx”) если вдруг у вас “не поддерживаемая Selenide разметка”
Selenide, тоже завязан на реализацию элемента в html коде.
https://github.com/codeborne/selenide/blob/master/src/main/java/com/codeborne/selenide/commands/SetValue.java
setValue можно сдлать только либо в < input> либо в < radio> либо в < select>
Допустим у вас в коде был < select>< option>… <>
вы везде писали свой
$(".selector").val("option1")
и вдруг он стал таким

<div class=selector>
<div> Option1 </div>
<div> Option2 </div>
<div>

что вы будете делать? вам придется везде поменять ваш

$(".selector").val("option1")

на метод

public WebElement setSelector(String text) {
  return $(By.xpath(//*[@class="selector")/div[.="+text+"]).click();
}
  • Поправьте меня если я не прав

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

В случае с JDI
У вас был бы элемент

@FindBy(css=".selector")
public Selector mySelector;

и в коде он где-то вызывался бы
mySelector.select("option1");
После изменений приложения
вы бы поменяли локатор на “.selector div” и все ) в тестах ничего менять не надо

@FindBy(css=".selector div")
public Selector mySelector;

Прежде чем ругать новый фреймворк, попробуйте его сначала )


(asolntsev) #34

А я вовсе не ругаю фреймворк, я говорю, почему типизированные элементы - это плохо.
Это новое объяснение немножко расходится с вашим изначальным примером. Так как раз использовались типизированные элементы (TextField, Checkbox, Button). Именно их я критиковал.

А в последнем комментарии вы уже описываете не типизированные элементы, а компоненты (что по большому счёту то же самое, что и пэдж обжекты). Они действительно не попадают под мою критику.

НО
компоненты можно было делать и в HtmlElements. И их можно делать в Selenide, причём опять же проще. :slight_smile:

Ну это совершенно несправедливо! В Selenide можно писать пэдж-обжекты (причём опять же, проще!).
Прежде чем ругать старый фреймворк, попробуйте его сначала :slight_smile:


(Рома Иовлев) #35

Я не спорю, что можно, просто Selenide немного “провоцирует” это не делать, в этом и его плюс, что можно легко не использовать педйжобджекты
писать в коде new Selector(".select").select(“Option1”) в JDI конечно тоже можно, но я бы сказал чт оэто будет плохой практикой.
Selenide хорош для простого быстрого использования простых элементов тегов.
JDI больше подходит для работы с PageObjects вот и все )
Как я могу ругать, если говорю, что они не сравнимы ))


(Рома Иовлев) #36

Кстати я смотрю вы сделали новую имплементацию команд через рефлекшн… Интересная идея, но честно говоря это мне вынесло мозг, ))) пока понял где же все-таки имплементируется метод setValue из интерфейса SelenideElement… по имени через Reflection… :slight_smile:


(asolntsev) #37

Ага, со временем система усложнилась больше, чем предполагал вначале.

Но вообще-то это классический command pattern.
Если уж на то пошло, любые вызовы методов, например, в Java работают точно так же.
Когда один раз его поймёшь, то потом очень легко искать. Как раз по имени-то крайне легко. Ctrl+N - и поехал.


(Рома Иовлев) #38

Я бы кстати добавил к SelenideElement метод select аналог val
И еще добавил бы select к $$(…).select()
который бы выбирал по имени один из списка веб элементов по getText


(Roma Marinsky) #39

Дайте ссылку где можно увидеть тесты, а лучше проектик маленький для осмотра возможностей, только не на gga-selenium-framework на гитхабе, потому что там я видел то что ооочень не красиво выглядит

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


(asolntsev) #40

Спасибо за предложения.

  1. аналог val - если я правильно понимаю, он уже есть:
  • $("select").selectOption("option text");
  • $("select").selectOptionByValue("option value");

Вы это имели в виду?

  1. $$(…).select() - кажется, и такой метод есть:
  • $$("tr").findBy(text("john"));

(Roma Marinsky) #41

а ещё натыкался на жутко неудобные инициализации страта тестов, пропертей, непонятные проверки, что такое new Check(…)?


(Рома Иовлев) #42

да но есть val и есть setValue и аналогично можно select просто другое имя, вполне логичное и короче, для удобства только )
ну и в $$ тоже для краткости
вместо $$(…).findBy(text("…")).click() просто $$(…).select("")