Вышла Selenide 6.13.0

Вышла Selenide 6.13.0

В жопу баннеры!
04.04.23

Привет!

Сегодня у нас большой мажорный релиз Selenide 6.13.0.

Добавили метод $.cached()

Иногда приходится воротить довольно сложный код для поиска элемента. И он может работать медленно, особенно если элемент ищется из какой-то большой коллекции с применением сложной фильтрации. Что-то вроде такого:

ElementsCollection subscriptions = $$("div.subs-expands")
  .filter(childExactText(
     By.xpath(".//div[contains(@class,'data')]//div[contains(@class,'heading')]"),
     orderNumber)
  );

SelenideElement target = subscriptions
  .filter(childAttributeValue(...))
  .find(childExactText(....));

Каждое обращение к target заметно притормаживает.

Теперь такие тесты можно ускорить, закэшировав значение target:

SelenideElement target = subscriptions
  .filter(..)
  .find(..)
  .cached();

Естественно, это можно сделать только в том случае, если вы уверены, что этот элемент не меняется, не перегружается и т.д.
Если он всё-таки перегрузится, то вы словите тот самый легендарный StaleElementReferenceException.

См. issue 2171, issue 1927 и PR 2189.


Добавили http статус при моке ответа сервера

В селениде есть методы, чтобы замокать ответ сервера:

getSelenideProxy().responseMocker().mockText("login-mock", 
          urlContains(POST, "/login"), () -> "{role: admin}");

Раньше можно было мокать только тело ответа, но статус всегда оставался 200 (“OK”).
Теперь можно задать и другой статус:

getSelenideProxy().responseMocker().mockText("login-mock", 
          urlContains(POST, "/login"), 403, () -> "{role: looser}");

См. issue 2227 и PR 2234.


Новый метод inNewBrowser для запуска куска кода в новом браузере

Иногда вам хочется посреди теста запустить кусок кода в новом браузере.

Если что, я это осуждаю: такие вспомогательные действия надо делать не через UI (который мы тестируем, а потому не доверяем), а каким-то контролируем способом: через API, прямой запрос в базу и т.п.

Уже давно для этого есть метод using. Но он требует, чтобы вы открыли новый браузер с какими-то своими настройками. А что, если вам подходят обычные селенидовские настройки? То есть вам нужен точно такой же браузер, только новый?

Теперь для этого есть метод inNewBrowser:

open("https://site.com/login/as/user/bob");

inNewBrowser(() -> {
  open("https://site.com/login/as/admin");
  $(by("value", "bob")).find("[name=is_admin]").setEnabled();
});

$("h1").shouldHave(text("Hello, chat admin!"));

См. issue 2213 и PR 2236.


Добавили метод $.doubleClick(options)

Раньше был просто метод $.doubleClick(), который мог кликать только по центру элемента. Теперь же у него появился продвинутый тёзка с параметром options. Опции такие же, как и у обычного клика:

$(".btn").doubleClick(usingDefaultMethod());
$(".btn").doubleClick(usingJavaScript());
$(".btn").doubleClick(usingDefaultMethod().offset(66, 33));
$(".btn").doubleClick(usingJavaScript().offset(66, 33).withTimeout(ofSeconds(9)));

См. issue 2133. Спасибо aakachurin за PR 2135.


Добавили условие $.shouldHave(innerText())

Оно позволит проверять текст невидимых элементов.

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

Но если всё-таки очень хочется, то можно:

$("#theHiddenElement")
  .shouldHave(innerText("Видишь суслика? И я не вижу. А он есть!"));
  // Обычный $("#theHiddenElement").text() выдаёт здесь пустую строку "";

См. issue 2220 и PR 2223.


Добавили условие для коллекций $$.shouldHave(attributes(...))

$$("#numbers option").shouldHave(attributes("value", 
                  "one", "two", "three", "four", "five"));

См. issue 2091. Спасибо Alexey Lakovych за PR 2091. Также см. PR 2230.


Ясное сообщение об ошибки в методах $.select*()

В селениде есть методы для работы с выпадающими списками:

$("select#gender").selectOptionContainingText("Female");

Недавно мы переделали их реализацию на JavaScript - так быстрее и надёжнее.

Но оказалось, что если по ошибке вызвать такой метода для не-селекта, вылетала очень непонятная ошибка:

$("ul").selectOptionContainingText("Kelly Snyder");
--> JavascriptException: 
      javascript error: 
        undefined is not iterable (cannot read property Symbol(Symbol.iterator))

Теперь сообщение будет понятное:

IllegalArgumentException: Cannot select option from a non-select element

См. issue 2231 и PR 2233.

Исправили ошибку в методе $$.subList()

Как вы знаете, в селениде есть удобные методы для проверки разом целой коллекции элементов:

  $$("#numbers").shouldHave(texts("One", "Two", "Three", "Four", "Five"));

Но метод $$ возвращает объект ElementsCollection, который, к сожалению, наследуется от AbstractList<SelenideElement>. А потому случайно (так не задумывалось!) наследует от него некоторые методы, на которые мы не рассчитывали.

Один из таких методов - subList:

  $$(".user").subList(1, 4).iterator();

Приведённый выше итератор возвращает не три, а всего два элемента. Обрезает последний. Ошибочка. ¯\_(ツ)_/¯

Теперь она оперативно исправлена.

См. issue 2239 и PR 2240.


Обновили зависимости

  • bump Selenium from 4.8.1 to 4.8.3 – см. CHANGELOG
  • bump LittleProxy from 2.0.16 to 2.0.17
  • bump BrowserUpProxy from 2.2.8 to 2.2.9
  • bump nettyVersion from 4.1.90.Final to 4.1.91.Final


Новости

Сегодня у нас подборка видосов про Селенид


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

ru.selenide.org

04.04.23