Всем привет!
В западном мире начался период “Адвент”, или ожидание Рождества.
Дети распаковывают свои “рождественские календари”, в которых открывают каждый день по окошечку (и находят под ним шоколадку). В Java мире, например, ведут Java Advent Calendar, в котором разные авторы каждый день публикуют по статье. Я тоже в нём участвовал пару раз (2017 и 2018).
Я тоже решил не отставать и замутить Selenide Advent Calendar. Каждый день по статье. С 1 по 25 декабря. Начну я, а вы можете присоединиться - сообщите о себе любым способом.
Сегодняшняя тема будет такая:
Самый Главный Алгоритм
Главная фишка селенида, как многие считают - это автоматические ожидания.
Вам не нужно писать лишний код типа new WebDriverWait(driver, 30).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[contains(text(),'COMPOSE')]")))
, чтобы дождаться наступления какого-то события.
Вам не нужно тратить время и силы, чтобы вообще думать о том, а где нужны ожидания.
Вам не нужно раз за разом спотыкаться о моргнувший тест и думать, куда бы ещё добавить ожидание.
В селениде всё проще: любая строчка типа $(byText("COMPOSE")).shouldBe(visible)
автоматически ждёт, если надо.
А не замедлит ли это тест?
Нет.
Если элемент уже видимый, селенид сразу пойдёт дальше. Если нет - подождёт 100 мс и проверит снова. Если снова нет - подождёт ещё 100 мс и проверит ещё раз. И так до 4 секунд. А вот если по истечении 4 секунд элемент всё ещё невидим, тогда тест упадёт.
Естественно, эти 4с и 100 мс настраиваются. Вы можете задать любой таймаут под ваш проект.
Как это работает?
Вот мы и переходим к Самому Главному Алгоритму. На самом деле он очень прост.
Вот как работает, например, метод $(".btn").shouldBe(visible)
:
void shouldBeVisible() {
do {
try {
assert webdriver.findElement().isDisplayed() == true;
return ok;
}
catch (Exception e) {
sleep(100 мс)
}
} while (прошло меньше N секунд);
throw new ElementShouldBeVisible("Ожидали: то-то, на самом деле: то-то"); // тут ещё сделать скриншот.
}
В общем-то всё просто.
Этот же код в реальности выглядит чуть сложнее.
А всё потому, что он “универсальный” - не только для shouldBe(visible)
, но и для других операций и условий.
Как известно,
дьявол кроется в деталях
В приведённом выше коде есть масса вопросов:
- Какие именно ошибки ловить?
Exception
,Error
,Throwable
,AssertionError
,WebDriverException
?
- В случае каких ошибок надо вылететь сразу, не продолжая ожидание?
- например, если XPath невалидный, то он и через 4 секунды будет невалидный.
- Результат хороший или плохой?
- например, если элемент не найден - это может быть ок для условия
$.shouldNot(exist)
.
- например, если элемент не найден - это может быть ок для условия
- В какой момент делать скриншот?
- Можно ли всё это кастомизировать?
- Например, при использовании Аллюра, возможно, не стоит снимать скриншот, ведь Аллюр сам снимет скриншот.
- Или наоборот, стоит снять скриншот и как-то передать его Аллюру?
- (сейчас и Селенид, и Аллюр делают каждый по скриншоту, так что они дублируются)
- Что делать, если мы дошли до последней строки, а вот в ней-то как раз прилетел зло#учий
StaleElementException
?
Ответы на эти вопросы менялись с течением времени. И наверное, будут ещё меняться. Но суть остаётся.
Что теперь?
Теперь, я надеюсь, вы не будете относиться к селенидовским ожиданиям как магии, а будете понимать, как оно работает. Возможно, это поможет при изучении различных странных падений тестов и прочей мистики.
А может, и посоветуете, как улучшить или упростить ядро скайнета наш Главный Алгоритм.
ru.selenide.org
01.12.19