Вышла Selenide 5.16.0

Вышла Selenide 5.16.0

Плагины и сообщения об ошибках
20.11.20

Всем привет!

Мы выпустили релиз Selenide 5.16.0.

Плагины

В начале 2020 года на конференции SeleniumCamp я рассказывал про roadmap селенида. Одна из ключевых идей на этот год была создать в селениде возможность подключать сторонние плагины.

И вот этот день настал!

На данный момент доступно два плагина:

Расскажем о них в отдельных постах.

Вероятно, дальше стоит оформить в виде плагинов поддержку Allure, JUnit, TestNG, AShot.
Накидывайте ещё идеи!

См. issue #1051 и PR #1264, PR 1317 и PR 1321.

Сообщения об ошибках

Одна из основных обязанностей селенида - составлять подробные сообщения об ошибках в случае падения тестов.
Иногда в эти сообщения тоже закрадываются неточности в каких-то сложных случаях.
В этом релизе мы запилили целую пачку улучшений сообщений об ошибках:

Улучшили описание проверок AND и NOT

Нормальный способ устроить негативную проверку в селениде - метод shouldNotHave. А проверить несколько условий подряд - просто через запятую:

  $("#username").shouldNotHave(text("admin"));
  $("#username").shouldHave(text("____"), attribute("data-masked"));

Но есть ещё методы Condition.not и Condition.and для особых случаев: например, с их помощью можно определять составные условия, таким образом составляя целый DSL для ваших тестов.

  public class MyConditions {
    private static final Condition NONADMIN = not(text("admin"));
    private static final Condition MASKED = and("MASKED", text("___"), attribute("data-masked"));
  }

  public class MyTest {
    $("#username").shouldBe(MASKED);
    $("#username").shouldBe(NONADMIN);
  }

Оказалось, что оба эти методы выводили в отчёте неполную информацию:

  | #username |should be(MASKED)                  |PASS |
  | #username |should have(not text)              |PASS |

Проблема в том, что в нём не виден ожидаемый текст (“admin”) и другие условия.

Теперь мы эту проблему исправили, и при падении проверки вы увидите сообщение с текстом:

  | #username |should be(MASKED: text '___' and attribute data-masked)      |PASS |
  | #username |should have(not text 'admin')                                |PASS |

Спасибо Pavel Fokin за PR 1306 и PR 1306.


Добавили информацию о предках

Селенид позволяет искать элементы внутри других элементов. Например, так:

  $("#user-table").$("thead").$("trrrr-chah-chah").shouldHave(text("Age"));

Но если такая проверка падает, в сообщении был виден только локатор дочернего элемента:

  Element not found {trrrr-chah-chah}

А теперь мы также добавили информацию и о родителях:

  Element not found {#user-table/thead/trrrr-chah-chah}

Спасибо Petro Ovcharenko за PR 1312.



Добавили актуальные текст для проверок ownText и exactOwnText

Как вы помните, в Selenide 5.15.0 мы добавили проверки ownText и exactOwnText:

  $("#child_div1").shouldHave(ownText("Sonar"));

Но и тут оказалось, что при падении такой проверки в сообщении не выводился, а какой же “свой текст” был на самом деле. Выводился только текст элемента с детьми:

  Element should have own text 'Sonar' {#child_div1}
  Element: '<div id="child_div1">Son</div>'

Теперь мы добавили строчку “Actual value” с собственным текстом элемента:

  Element should have own text 'Sonar' {#child_div1}
  Element: '<div id="child_div1">Son</div>'
  Actual value: Son

См. issue 1261 и PR 1294.



Кидаем правильную ошибку при загрузке несуществующего файла

Если вы пытались загрузить несуществующий файл:

  $("input[type='file']").uploadFile(new File("/foo/bar/xyz.pdf"));

То получали некорректную ошибку:

  Element not found {input[type='file']}
  ...
  Caused by: InvalidArgumentException: invalid argument: File not found : /foo/bar/xyz.pdf

Казалось бы, мелочь, но иногда это сбивало с толку.

Теперь мы это исправили, и вы получите сразу

  InvalidArgumentException: invalid argument: File not found : /foo/bar/xyz.pdf

См. issue 987 и PR 1301.


Корень проблемы в том, что в селенум не хватает отдельных классов ошибок для всех возможных нестандартных ситуаций, и простой WebDriverException может говорить как о ненайденном элементе, так и неверной кодировке в вводимой строке. См., например, issues 1293.

Плюс некоторые реализации вебдрайвера могут кидать какие-то нелогичные ошибки - например, IEDriver когда-то кидал Throwable вместо ElementNotFound.

Поэтому в своё время в селениде была принята консервативная стратегия: если не удалось определить тип ошибки точнее, по умолчанию считаем, что элемент не найден. А в “caused by” будут видны подробности.



Адекватно показываем ClickOptions в отчёте

Как вы помните, в Selenide 5.15.0 мы добавили удобные методы для клика со всевозможными опциями:

  $("#page").click(usingJavaScript().offset(123, 222));

И снова оказалось, что в отчёте такая строка выглядит некрасиво:

  | #page               |click(com.codeborne.selenide.ClickOptions@33617539)         |PASS |

Мы и это исправили, теперь строчка стала окейнее:

  | #page               |click(method: JS, offsetX: 123, offsetY: 222)               |PASS |

См. issue 1302 и PR 1303.


Другое

Добавили проверку $$.shouldHave(exactTextsCaseSensitiveInAnyOrder(...))

В селениде уже давно есть проверки для коллекций:

  $$(".employee").shouldHave(texts("вася", "петя", "катя"));            // case-insensitive, substring
  $$(".employee").shouldHave(textsInAnyOrder("вася", "катя", "петя"));  // case-insensitive, substring, any order
  $$(".employee").shouldHave(exactTexts("вася", "петя", "катя"));       // case-insensitive, full string match

И теперь к ним добавилась ещё одна - менее толерантная:

  // case-sensitive, full string match, any order
  $$(".employee").shouldHave(exactTextsCaseSensitiveInAnyOrder("Вася", "Петя", "Катя"));

Спасибо Vitali Plagov за PR 1286.


Исправили проверку href со спец.символами

Как вы помните, в Selenide 5.15.0 мы добавили проверку href.
Оказалось, что она неправильно работала, если в href затесались экранированные символы, как во второй строке:

  $("a").shouldHave(href("/foo/bar/details.html"));    // works
  $("a").shouldHave(href("/files/some%20file.pdf"));   // fails

Проблема исправлена.

См. issue 1298.
Спасибо rerednaw за PR 1299.


Разрешаем хрому скачивать несколько файлов

Бывают такие хитрые ссылки, по клику на которые браузер начинает скачивать не один, а сразу два или больше файлов.
Оказалось, что в этом случае браузер Chrome показывает диалог “Уверены, что хотите скачать все файлы?” - и этот диалог не даёт ничего дальше сделать, пока пользователь не нажмёт кнопку. И ваш тест падает.

Самое противное в этой проблеме то, что её очень сложно повторить руками: браузер показывает диалог только в первый раз, так что при локальном запуске скорее всего вы его не увидите, и тест будет зелёным.

Чтобы вылечить эту проблему, мы добавили при запуске хрома специальный ключик profile.default_content_setting_values.automatic_downloads=1, который сразу разрешает хрому качать сколько угодно файлов без всяких диалогов.

См. issue 1307.
Спасибо Alexei Vinogradov за PR 1308.


Разрешили скачивать файлы со слэшем в названии

Метод download не разрешает скачивать файл, если в его названии есть неразрешённые символы, в числе которых был и слэш:

  File report = $("#report").download();
  
  --> IllegalArgumentException("File name cannot contain slash: 11/08/2020_-_day_transactions.pdf")

Нам казалось это логичным, ведь такие файлы тупо не разрешает создавать файловая система.
Но оказалось, что иногда слэш вполне логичен - например, как разделитель в датах. И хром вполне скачивает такие файлы, просто заменяя слэш на подчёркивание.

Теперь и селенид так делает.

См. issue 1322 и PR 1323.


Зафиксировали версию Guava 30.0-jre

Ох уж эта гуава!

В коде самого селенида Guava не используется, нам она не нужна.
Но с ней вечные проблемы: от неё зависят многие другие библиотеки (Selenium, LittleProxy, BrowserUpProxy, Checkstyle), и все от разных версий. А ещё ведь у неё есть специальная версия для android…

В общем, слишком часто так случалось, что Maven или Gradle подтягивал не ту версию Guava, и селенид в итоге не работал.
Нам это надоело, и теперь в селениде явно прописана свежая версия Guava 30.0-jre. Надеемся, это поможет избежать всех этих бесконечных конфликтов завиимостей.


Перешли на Github Actions

Как в любом приличном проекте, в Selenide есть свой набор автотестов (юнит- и интеграционных), и они запускаются автоматически для всех веток на CI сервере. Раньше мы использовали Travis CI, который предоставляет бесплатный сервис для опен-сорс проектов. Спасибо им большое за годы совместной работы. :)

Но в этом году гитхаб выкатил свой CI сервис под названием “Github actions”.

Смотри обзор от Артём Ерошенко и Севы Брекелова в выпуске №3 Шоу “Ошибка выжившего”.

И казалось логичным использовать его.

Ура, этот день настал! Теперь все билды селенида видны прямо на гитхабе.

Спасибо Boris Osipov за PR 1319.


Уффф.

Многабукаф, но вы осилили. Все молодцы!

Как обычно - обновляйтесь, пробуйте, смело сообщайте о проблемах и делитесь идеями.


Андрей Солнцев

ru.selenide.org

20.11.20