Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

PageObject Page с динамическими данными

oop
page-object
java
Теги: #<Tag:0x00007f7b6905f8e8> #<Tag:0x00007f7b6905f640> #<Tag:0x00007f7b6905f3e8>

(Андрей Бахтиозин) #1

Доброе время суток, есть проблема, не могу решить.
Есть некая BookingPage, у неё есть ряд общих локаторов и методов, но так же есть 3 различных её имплантации с дополнительными локаторами и методами, они зависят пока-что от 3х параметров(назовём их Х1,Х2,Х3). Мне не хотелось бы решать проблему банальным BookingХ1Page extend BookingPage и каждый раз в тестах писать BookingX1Page bookingX1Page = preBookingPage.order(); и далее работать уже с bookingX1Page, мне бы хотелось посредством какого-то патерна работать в самом тесте с BookingPage а на стороне Пейджей уже строить страницу из локаторов и давать нужные методы. Проблема ещё в том что у BookingX1Page и BookingX2Page есть одинаковый блок(он не один,это так для примера) ЖелаемыеУслуги(частично разные поля), когда как у BookingX3Page этого блока нет, есть совсем другой блок КонтактныеДанные, за-то у всех 3х страниц есть общий блок ОбщаяИнформация, только для каждой страницы там есть дополнительные спец.поля.

Я запилил по патерну builder preBookingPage там ситуация аналогичная, да я построил страницу наполняю блоки hashmaps нужными локаторами:
Базовые общие для всех страниц + уникальные для Х-параметра + Общие для комбинации Х1-Х2(использую интерфейсы для общих компбинаций) в зависимости от Х1,Х2,Х3, но вот у preBookingPage я вижу тьму левых методов Х1,Х2, которые мне не подходят так как я в данный момент использую в тесте Х3.

В общем начинаю подозревать что с добавлением новых параметров это будет просто не правильно, вдруг я приду пьяный на работу и хоть у меня страница собралась на основании Х1 я начну использовать методы для работы с Х3.
Если же просто использовать через BookingX1Page bookingX1Page = preBookingPage.order(); то это будет ужасная избыточность и куча повторений.
Подскажите, в какую сторону стоит смотреть паттерн/пример/шаблон, я бы действительно хотел работать только с BookingPage, имея доступ только к тем методам и локаторам которые доступны в зависимости от параметров.
ПС: извините за длинный пост и форматирование


(Taras) #2

Вам нужно правильно разбить UI на Page Object-и, или использовать Yandex Html Elements


(Sergey Korol) #3
  1. Много хаотичного текста, не подкрепленного кодом.
  2. имплантации / на стороне Пейджей уже строить страницу из локаторов и давать нужные методы - просто покажите, что сейчас имеете, поскольку подобные фразы звучат жутковато.
  3. Вы хотите отказаться от базовой концепции ООП (наследования) только потому, что вам сложно отличить методы родителя от наследника? К примеру, IntelliJ IDEA маркирует жирным шрифтом методы того класса, к которому вы обращаетесь напрямую.
  4. Если вы используете PageObject паттерн, то какая проблема переключаться между нужными имплиментациями страницы посредством возвращаемого значения метода? У вас ведь цепочечный вызов, так?
  5. Общие компоненты можно еще оформить в виде отдельных страниц и внедрять посредством композиции, если лень спускаться на уровень PageElement.
  6. Никакой избыточности / повторений не будет в случае правильно организованного наследования с элементами композиции (по желанию).

П.С. Кидайте ваш код, будем смотреть.


(Андрей Бахтиозин) #4

Кода много… вся суть моего текста что я хотел избежать такого в тестах:
для одного теста
BookingX1Page bookingX1Page = preBookingХ1Page.order();
для другого теста
BookingX1Page bookingX2Page = preBookingХ2Page.order();
для третего теста
BookingX1Page bookingX3Page = preBookingХ3Page.order();

Хотел избежать этого, использовать просто BookingPage bookingPage = preBookingPage.order(); и где-то на стороне посредством какого паттерна формировать эту страницу


(Sergey Korol) #5

Если у трех пейджей есть своя имплиментация метода order(), то полиморфизм вам в помощь.

public interface BookingPage {
    BookingPage order();
}

или

public abstract class BookingPage {
    abstract BookingPage order();
}

(Alsu Vadimovna) #6

можно начать с того, чтобы не делать этого :smile:

Если все три страницы отличаются только несколькими элементами, то почему бы и не сделать один BookingPage без всяких X1, иначе вы рискуете плодить одинаковый код на одни и те же элементы. Но если различия значительны, то лучше конечно разбивать.


(Андрей Бахтиозин) #7

Скинул скриншотов реализации, я вот как раз хочу как-то избавиться от всех доступных методов, скрыть то что не нужно и оставить только то что нужно в зависимости от того на основании какого билдера была построена страница BookFormPage.
В текущем примере я использую BookFormPage построеную на основании билдераХ1, и мне не хочется видеть левый метод который по сути использует только BookFormPage построенная на основании билдера Х3.
Я возможно я делаю что-то не правильно, я этого не исключаю.



(Taras) #8

у вас почему то на скринах метод которий фарбичний chooseByDesireTripOption а на втором скрине constructBookFromPage…напонятно как то