Задался вопросом создания оптимальной системы вейтов, для асинхронных приложений.
Проблема вейтов стара как мир и чего бы не хотелось, так это велосипедировать
.
Хочется поделиться своими мыслями и услышать альтернативные варианты решений.
Основная идея - избавится от вейтов в коде и забыть об этой проблеме навсегда.
Хочется, чтобы система сама ждала столько сколько ей необходимо, конечно в рамках заданного таймаута.
Вкратце о структуре объектов фреймверка.
Использую фукедид. Струтура наследования страниц стандартная. PageObject -> BasePage -> Pages
Вебэлементы обернуты - есть разделение на Input, DataPicker, CheckBox …
До полноценного декоратора, правда, еще руки не дошли, так чтобы PageFactory
работала непосредственно c типами Input
и т.д. Пока что, PageFactory
, все также, работает с WebElement, а инициализация оберток проходит в конструкторах страниц. Все обертки имплементируют интерфейс HtmlElemtnt
, что позволяет гибко работать с разными типами контролов.
Теперь ближе к вейтам.
Идея в том, чтобы в обертках, перед тем как выполнить какое-то действие, элемент ждал рендеринга самого себя.
С этим все относительно ясно, кроме того момента, что ожидания приходится вызывать в начале каждого действия, каждого типа обертки. фактически это дублирование кода.
Решить эту проблему можно вводом Proxy класа между интерфейсом и реализацией.
IHtmlElement -> ProxyHtmlElement -> реализация ( e.g. CheckBox)
Контракт для страниц остается прежним, но прокси позволяет, в одном месте, для каждого контрактного метода интерфейса, вызвать ожидание, а дальше перенаправить исполнение к реализации.
Интересней вопрос с гридами, что есть самое наболевшее при работе с Ajax.
Элемент отбражается, а данные еще в пути.
Для того, чтобы все ждало нормально, необходимо ждать рендеринга данных таблиц.
Для работы с таблицами фукедид предоставляет класс HtmlTable
.
Его можно также, обернуть, перегрузить необходимые действия, например findFirstRowWhere
,
и перед вызовом super.findFirstRowWhere()
, вызывать некий метод waitForRendering()
,
который, в свою очередь будет, проверять наличие содержимого в ячейках таблицы и ждать, если такового нет.
Тем самым у нас будет, грубо говоря, 1 .setValue()
, 2 .getValue()
, 3 .click ()
в прокси классе. и 4 .findRow
, 5 .containsRow
в таблице. Вейты в 5 местах, в системе.