Задался вопросом создания оптимальной системы вейтов, для асинхронных приложений.
Проблема вейтов стара как мир и чего бы не хотелось, так это велосипедировать
.
Хочется поделиться своими мыслями и услышать альтернативные варианты решений.
Основная идея - избавится от вейтов в коде и забыть об этой проблеме навсегда.
Хочется, чтобы система сама ждала столько сколько ей необходимо, конечно в рамках заданного таймаута.
Вкратце о структуре объектов фреймверка.
Использую фукедид. Струтура наследования страниц стандартная. 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 местах, в системе.