Он может быть как на главной странице и на самой форме и на Popup окне. Все они одинаковы, различаются только локатором и значениями в нем, но функционал на всех листах похож. Также один и тот же List2List может встретиться на разных страницах, но его также может и не быть (кстати аналогичная ситуация с другими полями).
Посмотрев видео про PageObject pattern понял, что нужно описывать каждую страницу отдельно. А если на странице есть функционал более сложный выносить его в отдельный класс. Также если происходит дублирование кода, то нужно тоже задуматься о том стоит ли его вынести.
Я решил сделать так: есть класс Karaoke, в нем присутствует метод editList, который просто возвращает экземпляр класса List2List, в нем содержатся все значения элементов этих листов, которые могут встретиться в админке. Каждый из методов передает элемент в следующий класс EditList2List и уже в нем описана функциональность (удалить и добавить значение, добавить все и удалить все):
public class Karaoke extends Page{
...
public List2List editList(){
return new List2List(driver)
}
...
}
public class List2List{
@FindBy(css = "section[name='row.__states.Genres']")
public WebElement states_Genres;
...
public Genres(){
return new EditList2List(states_Genres);
}
...
}
public class EditList2List{
...
WebElement element;
public List2List(WebElement element) {
this.element = element;
}
public void addAll(){
element.findElement(By.cssSelector("[ng-click='addAll()']")).click();
}
public void deleteAll(){
element.findElement(By.cssSelector("[ng-click='deleteAll()']")).click();
}
public void addValue(){
}
public void deleteValue(){
}
...
}
По сути это поможет мне писать в тесте:
karaoke.editList2List().genres().addAll();
Такой способ верный? Также интересует в общем что делать с более сложным функционалом на странице, который может повторятся, а может нет.
Более-менее нормально. Мне лично только не нравится класс EditList2List. Классы - это обычно существительные, а глаголы - это методы классов. Я бы все методы работы со списком делал просто в классе List2List, класс EditList2List тут лишний на мой взгляд
А если например представить, что (элементов стало много) есть в общей сложности 50 видов кнопок и 1000. И они могут быть на странице, а могут не быть, ну и различные комбинации бывают. В этом случае я думал что нужно делать некую видимость элементов для конкретной страницы (karaoke.footer().save(); // после футера видно будет только 15 методов) или все же нужно в один класс все 50 кнопок поместить и по мере необходимости унаследовать этот класс?
P.S. вопрос практически похожий но я хотел это посмотреть с более глобальной точки зрения.
Любой повторяющийся элемент интерфейса - это отдельный класс, реализующий паттерн PageObject
Сложность возникает тогда, когда один и тот же элемент интерфейса, например, список объектов, который с виду выглядит одинаково на разных страницах и так и просится выделить его в отдельный класс и переиспользовать, в реальности оказывается реализован на разных страницах по-разному: имеет разную верстку, разные id элементов и т.д.
Придерживайся правила в п.1 и не забывай по поводу п.2 требовать с разработчиков одинаковой реализации одинаковых элементов на разных страницах
Хорошо, но если я вынес элементы в отдельный класс (Button.class) и тут встречается страница где 3 кнопки отсутствуют. Я наследую класс с элементами кнопок для Karaoke.class, но в этом случае будет видимость нескольких кнопок которые не доступны по сути у Karaoke.class такое поведение правильно?
karaoke.footer().save(); // кнопка save - доступна для формы караок
karaoke.footer().print(); // кнопка print - не доступен для формы караок
Хорошо, а допустим есть Footer с кнопками, который есть на главных страницах меню(караоке, видеофильмы итд) если мы откроем форму одной из этих страниц, то там есть тоже Footer со своими кнопками, а внутри формы есть Popup в котором тоже есть Footer и тоже со своими отличными кнопками. То есть 3 разные страницы со своим Footer. Как быть в такой ситуации?
Если на разных страницах разные футеры, значит они должны быть представлены разными PageObject-классами фреймворка. Причём, если этот футер уникален для этой конкретной страницы (на других страницах не используется), то его вообще нет необходимости выносить в отдельный класс, а реализовывать в классе самой страницы
Решил вынести в отдельный класс Footer для форм, так как кнопки там одинаковые. И опять сразу возникла проблема (по видео с Михаилом по PageObject) говорится что мы в каждом методе должны возвращать объект страницы с которой продолжаем работать. В следующем случае я должен возвращать, что-то после метода public void save() ?
public class Footer{
public void save(){
}
}
public class Karaoke extends Page{
public Footer button(){
return new Footer(driver);
}
}
public class Movie extends Page{
public Footer button(){
return new Footer(driver);
}
}