Вызов драйвера. Инициализация пейдж обджектов. Проблемы PageFactory

Поскольку я в своей работе использую Thucydides, я не обременял себя такими вопросами какое-то время, но интерес берет свое.

Хочу спросить у людей, которые пишут свой велосипед вокруг селениума о таких вещах:

Как вы реализовываете вызов драйвера. Этот вопрос подразумевает - что нужно иметь возможность написанные тесты запустить в любом браузере для которого существует драйвер.
Как осуществляется передача драйвера - для каждого теста, для сюита итд.
Как осуществляется перезапуск драйвера в случает падения браузера и прочих непредвиденных сутуациях.
Делитесь примерами кода своих фабрик.

Каким образом можна избежать в тестах вот такой штуки:
Page page = new Page(webdriver);
Каждый раз когда нам нужно проиниализировать наш пейдж обджект

Как обстоят дела с инициализацией динамических Ajax елементов в PageFactory

Любые идеи, реализации, и куски кода приветствуються

Посмотрите на библиотеку Selenide. Она решает все эти проблемы: и вебдрайвер прячет, и педж объекты инициализирует, и с аяксом справляется. Сама. Вам даже не надо об этом думать.

Элементарно

class BasePage{
  private WebDriver driver;
  public BasePage(){
    driver = BrowserManager().getDriver();
    PageFactory.initElements(driver, this);
  }
}

class Page1 extends BasePage{
}
...
Page1 page1 = new Page1();

Драйвер не нужен ни тестам, ни сьютам - прямое обращение к драйверу в них, имхо, не есть гуд.
Более того, в самих пейдж-обжектах - тоже: практически весь айпи драйвера можно делегировать базовому пейджу, это выглядит более логично.

PS: Или вопрос был не о “Page(webdriver)”, а о "Page page = new "?

ага о “Page page = new Page”

В testng.xml можно задать кастомные параметры, которые в свою очередь можно потом вытянуть в каком-нибудь BeforeMethod из ITestContext. Эти параметры парсятся и подсовываются в DesiredCapabilities, что позволяет задавать драйверу необходимую конфигурацию. Собственно сама инициализация проводится автоматически ввиду того, что соответствующий метод аннотирован каким-нибудь Before.

Тесты не должны ничего знать о драйвере, как уже писали выше. Он может появиться лишь на уровне пейджей. Посему:

Первый вариант - наследование, когда у вас есть common публичный геттер для драйвера, который можно передавать по цепочке пейджей, вплоть до родительской.

Второй вариант - статический геттер для драйвера, который можно дернуть напрямую из базовой пейджи. В данном случае придется дополнительно позаботиться о потокобезопасности драйвера в случае масштабирования.

Либо модифицируется нод (standalone jar), либо поднимается легковесный http сервер с каким-нибудь встроенным рычагом для убиения драйверов / браузеров / перезапуска хабов / нодов. Тут придется изобретать свою собственную логику мониторинга за системой, ибо в случае обращения к 1 ноду из различных источников нельзя убивать все связанные процессы когда нам того захочется.

Можно вынести геттеры с соотвтетствующими инициализаторами пейдж обджектов в отдельный базовый класс для всех тестов. При этом, нужно позаботиться о логике обращений к геттерам, ибо нам далеко не всегда нужно переинициализировать наши пейджи. Где-то на местном гит-хабе я уже выкладывал код с сырой имплементацией такого обработчика.

Вообще отказался от стандартной фабрики, ибо использую By класс + WebDriverWait.

1 лайк

Не вижу тут ничего критичного, если точно следовать “букве” паттерна PageObject - метод пейджобджекта который ведет на другую страницу приложения, он должен возвращать экземпляр этой страницы . Вам потребуется только один new в начале теста - new LoginPage().
А всякого рода фабрики страниц и вразнобой проинициализированные экземпляры не несут информации о связях между страницами и функционале приложения в целом. Хотя если это “сайт-визитка”, где связь между страницами отсутствует, такой подход имеет место быть.