Как лучше организовать работу ожиданий в фреймворке

Если коротко - приложение с AJAX коллами, время загрузки каждого элемента постоянно меняется.
PageFactory и аннотации FindBy и т.д не использую и не планирую.
Использую Fluent ожидания, тесты работают с ними успешно. Но хочется советов бывалых, чтоб понять, как лучше и правильнее строить фреймворк с ожиданиями.

В данный момент есть отдельный класс с ожиданиями (Waiters.class). Использую ожидания из класса Waiters на уровне страницы, то есть внутри методов страницы, например:

public class DashboardPage extends BasePage {

//Locators:
String activitiesPage = “//a[@href=’/#/activities’]//span”;
String test = “//[@id=‘dashboard’]//[@class=‘row main-header hide-for-small left’ or @id=‘sideNav’]”;
String test2 = “//*@id=‘sideNav’]”;

public ActivitiesPage goToActivitiesPage(){
waiters.fluentWaitIgnoringNoSuchElementExceptionAndElementNotVisibleException(activitiesPage);
clickJs(activitiesPage);
return new ActivitiesPage();
}
}

то есть, жду пока элемент на странице появится, и после этого вызываю метод для клика.

Возможно, стоит зашить ожидания во внутрь методов взаимодействия с элементами (например, непосредственно в методо click, type и т.д?)

Вопрос в общем подходе. Любые советы, ссылки очень приветствуются. Заранее спасибо.

Взять готовые решения, например Selenide =)

4 лайка

Самое лучшее - использовать декораторы для драйвера.
смотрите тут (про декораторы с 26:30 на видео):
http://software-testing.ru/library/testing/testing-automation/2420-selenium-ecosystem

Сами библиотеки есть на гитхабе у Алексея:

Это слово уже скоро начнет раздражать )))

2 лайка

Еще можно свои костыли написать, например такой для jQuery, пример на питоне, но смысл думаю будет понятен:

def wait_for_ajax(_type, _locator, timeout=5):
        message = "Element '%s' was not visible in %s second(s)." % (_locator, str(timeout))
        driver = SeleniumWrapper().driver
        wait = WebDriverWait(driver, timeout)
        wait.until(lambda driver: driver.find_element(_type, _locator).is_displayed()
                   and driver.execute_script("return $.active") == 0, message=message)

Вам ответили на вопрос, но вы ответ не воспринимаете и упорно хотите написать свой велосипед. Selenide далеко не идеален, но если говорить о реализации механизма ожиданий - то как раз в Selenide (для Java) и Capybara (для Ruby) он реализован наилучшим образом.
Хотите написать свое - вперед, но гляньте в исходный код Selenide/Capybara для “вдохновления” (все ж open-source) и не надо изобретать ничего.

4 лайка

Два чаю этому господину.

Люди упорно пытаются строить свои велосипеды, но развивать их нет времени и желания.

Selenium WebDriver - низкоуровеневая библиотека для работы с браузером, это даже не библиотека для тестирования. Гораздо проще взять что-то готовое типа заявленых Selenide, Capybara, Protractor, ${FRAMEWORK_NAME}. Там и ожидания реализованы, и не нужно работать со всем этим балаганом одних и тех же проблем. Не бойтесь юзать готовое, лучше потратить свое время на более интересные задачи чем пилить свой 1001 фреймворк каждый раз для каждого проекта.

4 лайка

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

Кстати вход в мой фреймворк очень низок. практически только копипаст локатора и сказать что это за компонент + метод вызова.

В результате ребята пишут тесты очень быстро.
PS: надо на гитхаб как то положить будет

На велосипедах учатся) Вот сделает свой фреймворк, поучится чуток, затем бросит это дело и возьмет готовое, типа Selenide, Capybara, Protractor, ${FRAMEWORK_NAME}.
:slight_smile:

2 лайка

@kulasovvlad “Пара плюшек” - это всё не пара, а ощутимо больше.
Вопрос даже не в том, какие большие плюшки сами по себе, а в том, сколько времени они могут вам сэкономить. Селенидовские плюшки очень даже могут. В этом и есть кардинальное отличие.

Кстати, в Selenide можно (и очень легко!) описывать свои компоненты. Собственно, никакого отличия между “компонентом” и “page object” как бы и нет.

2 лайка

Что-то вы напутали… я вопрос не задавал).

Можно, но к знанию к селениуму нужно еще знание селинида(а зачем ?), а у него как бы еще свои проблемы, глюки и т. п. Любое добавление любой библиотеки ведет к добавлению проблем, а зачем они мне?
Вот я не уверен в экономии времени, где то сэкономил, где то потерял.

  • прибавляется а не бросит ли автор проект. Ну как например Тиллуриум. Тоже вроде был не плохо сделано… А забросили.
1 лайк

@kulasovvlad Совершенно оправданные сомнения.
Я лично тоже очень критически взвешиваю, а нужна ли мне та или иная библиотека, перед тем как взять её в проект. И от некоторых библиотек я даже со временем отказываюсь, когда понимаю, что глюков и багов она приносит больше, чем пользы.

Но в данном случае вот моё видение:

  1. Знание селенида как раз почти нулевое. По идее оно позволит потратить гораздо меньше времени на изучение селениума.
  2. “Любое добавление любой библиотеки ведет к добавлению проблем” - вот в случае с селенидом как раз он решает большинство типичных проблем.
  3. “Вот я не уверен в экономии времени, где то сэкономил, где то потерял.”
    Но это же не значит, что не надо вообще ничего использовать! Скорее это значит, что надо критически взвешивать, сколько сэкономил и сколько потерял. С этим я совершенно согласен. И моё видение - с селенидом ты экономишь гораздо больше, чем теряешь.
  4. “прибавляется а не бросит ли автор проект.” - да, такой риск есть у любого проекта. Но в случае с селенидом всё просто: проект активно развивается 5 лет, большой коммьюнити, и он реально используется серьёзными компаниями в серьёзных проектах. В частности, наша компания Codeborne использует его в нескольких реальных интернет-банках. То есть забросить его в принципе невозможно - весь бизнес на этом держится.

В этом главное отличие селенида от фукидида, теллуриума, FluentLenium и т.д.: его сделали не для продаж и не для хобби, а для решения реальных проблем. Для себя. Это т.н. dog food. Поэтому ничего с ним не случится.

4 лайка

Как минимум - стоит попробовать.
Selenide как раз один из тех инструментов которые легко понять и разобраться, а потом удивляешься - как я жил без этого все время с голым селениумом?

Кстати сам фреймворк написан очень качественно с точки зрения кода. Я даже специально открывал и читал код, реально приятно читать. Спасибо @asolntsev за проделанную работу!

2 лайка

Крутяк! Спасибо на добром слове. :slight_smile:

Поддержу. Хоть сам и новичок и считаю себя не автоматизатором, а тестировщиком, который использует программирование для упрощения своей работы и работы отдела. Я часто вижу “автоматизаторов”, которые считают ниже своего достоинства опускаться до предметной области или составить простой тест-план. По сути они сами ограничивают свои способности. Превращая себя в трансляторов тест-кейсов в язык программы.

У себя в команде мы пилим свой велосипед под несколько схожих проектов (не вэб-страницы). В этом велосипеде вынесен общий блок кода в отдельный гит-репозитарий, а проекто-зависимые части разнесены по своим отдельным хранилищам. Это позволяет не возиться с подключением библиотек и видеть/менять сразу общий код из любого проекта, но при этом не мешает вести параллельную разработку всех проектов, сохраняя их специфику. Уверен, что и у этого подхода найдется много как плюсов, так и минусов. Мы пока только в начале пути и плюсы для нас перевешивают, потому так и работаем. В Intellij IDEA, кстати, очень удобно работать с git + подмодули (вот тут есть упоминание про подобный подход - Организация GIT для небольшой команды разработчиков.. Если нужно шарить код библиотек между проектами, а не пилить по велосипеду на каждый проект или муторно переносить изменения между каждым, то получается весьма удобно. По крайней мере понравилось сильно больше, чем без него или подключением внешних jar и т.п.

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

Основной критерий при добавлении функциональности или библиотек - их необходимость и полезность для проекта (-ов), а также зрелость самой команды. К сожалению, этот фактор тоже нужно учитывать. Если при текущих потребностях и навыках команда идет с опережением графика, то мы двигаемся в верном направлении. Очень часто видел, как нахваливают тот или иной инструмент, модный/стильный/молодежный подход, но копнешь поглубже и там внутри ничего нет, кроме будущих проблем. Поэтому я за взвешенный подход и трезвую оценку как получаемой пользы, так и возможных рисков и степень готовности и нужности данных изменений для команды и компании в целом. Хотя очень часто бывает, что как раз наше мнение и не спрашивают… :confused:

P.S. к слову, я тут не про Selenide ни разу, инструмент наверно замечательный, но пока не довелось с ним тесно поработать. Просто, если человек уже сделал какой-то велосипед и успешно с ним работает месяцы-годы, эффективно решая поставленные задачи, то наверно ему видней, что использовать у себя на проекте. Необходимость должна созревать внутри. Хотя и тут спорный момент. Какие-то вещи действительно нужно прививать, а то так бы и сидели с перфокартами “-А что? Мне и так удобно!”. :grinning:

1 лайк