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

Extend default @FindBy waits, java, selenium 3.3.1

java
selenium
webdriver
Теги: #<Tag:0x00007f7b64c21938> #<Tag:0x00007f7b64c217a8> #<Tag:0x00007f7b64c215c8>

(Vladyslav Lopatynskyi) #1

Доброго времени суток!
Подскажите, пожалуйста, есть ли возможность расширить политику вейтов в @FindBy дабы расширить дефолтные кондишены и не тянуть их каждый раз перед поиском элемента?
(По идее надо как то переопределить page load condition, но адекватного ответа пока было не найдено)
Заренее благодарен!


(Taras) #2

@FindBy вейт ето тот самий implicit wait - если ви хотите переписать implicit wait только при визове @FindBy Вам нужно переписать PageFactory initElements метод и внутри него декоратор. page load condition - ето уже какая то кастумная имплементация Ваш-а, - по дефолту в WebDriver API-ке @FindBy такого по ходу нету


(Vladyslav Lopatynskyi) #3

Спасибо! Попробую копнуть в эту область.

А есть ли, может, способ глобально implicitlyWait заоверрайдить?


(Taras) #4

driver.manage().timeouts ви не используете?


(Vladyslav Lopatynskyi) #5

Есть такое, но я так понимаю implicitlyWait по дефолту ждет readystate=true. Хотелось бы туда добавить еще пару angular вейтов и jquery. Такое вообще реально заекстендить?


(Taras) #6

Не не, readyState оно не ждет… что то Ви перепутали) да реально , нужно свой initElements написать просто, extend-нуться от PageFactory


(Oleksii Ihnatiuk) #7

Вам нужно Explicity Waits. По типу: stackoverflow . Также взгляните на source код любого Expected condition. Это поможет вам понять, что написать свой condition не сложно или просто используйте существующие.


(Vladyslav Lopatynskyi) #8

Свой кондишн написать не проблема.
Проблема в данный момент как раз его навесить чтобы он исполнялся при каждой инициализации @FindBy по дефолту.


(Oleksii Ihnatiuk) #9

хм, прочитал ваш ответ еще раз и понял что написал не то :slight_smile:


(Vladyslav Lopatynskyi) #10

Дело в том что там проблема решена explicit вейтом для конкретного элемента, в данном же случае проблема заключается в том чтобы добавить кастомный implicit вейт глобально для любого элемента который получит @FindBy. Делается это для того чтобы не тянуть этот вейт для каждого элемента в проекте.

Самый простой способ пока что просто обернуть findElement со своим вейтом но тогда придется отказаться от FindBy аннотации.
Пробую переопределить initElements в PageFactory, но похоже надо копать глубже в PageLoadCondition так как элементы то будут “искаться” уже после инициализации класса.


(Oleksii Ihnatiuk) #11

Я новенький в автоматизации поэтому не обладаю экспертным мнением. Но в докладе на SeConf 2017 (Austin) Simon Stewart (создатель WebDriver) говорил о том, что следующие вещи это не самые лучшие решения:

  • Desire Capabilities;
  • Page Factory and @FindBy;
  • Headless Browsers;
  • Implicit Waits.

Можете посмотреть сами.


(Vladyslav Lopatynskyi) #12

Да, так как потенциально из Selenium либы они буду выпиливаться, чтобы в конечном итоге Selenium позиционировался как сервис для взаимодействия с браузером и не больше.


(Taras) #13

Вам нужно написать свою анотацию @WaitForFindBy и в ней будет парам вейта. Вопрос где обработать ето значение которое там будет и как его менят когда каждий раз FindBy колаеться…- Вам нужно переписать цепочку класов которие тянуться от PageFactory - клас в котором обрабативаеться ета анотация DefaultFieldDecorator - там и нужно заинджектить вейти


(Vladyslav Lopatynskyi) #14

Вроде нашел способ.
Необходимо написать свою factory наподобие AjaxElementLocatorFactory
и инициализировать PageFactory с ней. Примерно вот такое получается в тесте PageFactory.initElements(new AngularElementFactory(driver, Configuration.TIMEOUT), this);

вместе с фактори надо еще прописать стратегию поиска элементов в в AngularElementLocator опять таки на подобии AjaxElementlocator
вроде работает:)

Спасибо!


(Oleksii Ihnatiuk) #15

А у вас есть возможность выложить этот код на гитхаб? Я бы посмотрел :slight_smile:


(Сергей Кузьмин) #16

посмотрите https://github.com/henrrich/jpagefactory - в protracor
например

 @Override
    public NgWebElement findElement(By by) {
        if (by instanceof JavaScriptBy) {
            ((JavaScriptBy) by).root = this.element;
        }
        this.driver.waitForAngular();
        return new NgWebElement(this.driver, this.element.findElement(by));
    }

то есть есть по умолчанию ожидание