Всем привет!
Мы выпустили релиз Selenide 5.16.0.
В начале 2020 года на конференции SeleniumCamp я рассказывал про roadmap селенида. Одна из ключевых идей на этот год была создать в селениде возможность подключать сторонние плагины.
И вот этот день настал!
На данный момент доступно два плагина:
Расскажем о них в отдельных постах.
Вероятно, дальше стоит оформить в виде плагинов поддержку Allure, JUnit, TestNG, AShot.
Накидывайте ещё идеи!
См. issue #1051 и PR #1264, PR 1317 и PR 1321.
Одна из основных обязанностей селенида - составлять подробные сообщения об ошибках в случае падения тестов.
Иногда в эти сообщения тоже закрадываются неточности в каких-то сложных случаях.
В этом релизе мы запилили целую пачку улучшений сообщений об ошибках:
Нормальный способ устроить негативную проверку в селениде - метод 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
Корень проблемы в том, что в селенум не хватает отдельных классов ошибок для всех возможных нестандартных ситуаций, и простой
WebDriverExceptionможет говорить как о ненайденном элементе, так и неверной кодировке в вводимой строке. См., например, issues 1293.Плюс некоторые реализации вебдрайвера могут кидать какие-то нелогичные ошибки - например, IEDriver когда-то кидал
ThrowableвместоElementNotFound.Поэтому в своё время в селениде была принята консервативная стратегия: если не удалось определить тип ошибки точнее, по умолчанию считаем, что элемент не найден. А в “caused by” будут видны подробности.
Как вы помните, в 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 не используется, нам она не нужна.
Но с ней вечные проблемы: от неё зависят многие другие библиотеки (Selenium, LittleProxy, BrowserUpProxy, Checkstyle), и все от разных версий. А ещё ведь у неё есть специальная версия для android…
В общем, слишком часто так случалось, что Maven или Gradle подтягивал не ту версию Guava, и селенид в итоге не работал.
Нам это надоело, и теперь в селениде явно прописана свежая версия Guava 30.0-jre. Надеемся, это поможет избежать всех этих бесконечных конфликтов завиимостей.
Как в любом приличном проекте, в Selenide есть свой набор автотестов (юнит- и интеграционных), и они запускаются автоматически для всех веток на CI сервере. Раньше мы использовали Travis CI, который предоставляет бесплатный сервис для опен-сорс проектов. Спасибо им большое за годы совместной работы. :)
Но в этом году гитхаб выкатил свой CI сервис под названием “Github actions”.
Смотри обзор от Артём Ерошенко и Севы Брекелова в выпуске №3 Шоу “Ошибка выжившего”.
И казалось логичным использовать его.
Ура, этот день настал! Теперь все билды селенида видны прямо на гитхабе.
Спасибо Boris Osipov за PR 1319.
Многабукаф, но вы осилили. Все молодцы!
Как обычно - обновляйтесь, пробуйте, смело сообщайте о проблемах и делитесь идеями.