Extend default @FindBy waits, java, selenium 3.3.1

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Спасибо!

1 лайк

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

посмотрите GitHub - henrrich/jpagefactory: JPageFactory is a set of Selenium Java FindBy annotations that eases the usage of Selenium page factory pattern for automating Angular based web application. It is based on JProtractor project which is a Java wrapper of Protractor framework. - в 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));
    }

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