Вышла Selenide 6.18.0

Вышла Selenide 6.18.0

Актуальные тексты
06.09.23

Все уже перевернули календарь?
Тогда при свете костров рябин можете обновиться на Selenide 6.18.0.


Показываем актуальные тексты в коллекциях

В релизе 6.16.0 мы ускорили проверки коллекций.

$$(".troubles").shouldHave(texts(
  "Всё не то", "всё не так", 
  "ты мой друг", "я твой враг"));

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

List size mismatch: expected: = 4, actual: 3

Но люди стали жаловаться, что хотелось бы увидеть, какие же там всё-таки были тексты. Похоже, это тот случай, когда удобство важнее скорости. А падают ваши тесты не так уж часто, ведь правда? ;)

Поэтому с этого релиза будем показывать и размер, и тексты:

List size mismatch (expected: 4, actual: 3)
Actual (3): [Журавлей белый клин, твоя дочь, и мой сын]
Expected (4): [Всё не то, всё не так, ты мой друг, я твой враг]

См. issue 2434 и PR 2456.


Обновили Selenium с 4.11.0 на 4.12.1

Ченджлог здесь. Среди прочего, там исправили злополучный дедлок в devtools, из-за которого нам пришлось выпустить предыдущий релиз.

См. PR 2452.


Вернули BasicAuth через DevTools

В релизе 6.16.0 мы запилили авторизацию BasicAuth через механизм HasAuthentication в браузерах семейства Chromium.

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

См. issue 2336, PR 2358 и PR 2452.


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

В селениде уже был метод $$.getSelectedOptions() - он возвращает выбранные опции элемента <select>. А теперь мы добавили похожий метод $$.getOptions(), чтобы можно было проверить все его опции.

$("select").getOptions()
  .shouldHave(texts("день прощанья", "костры рябин", "обещания"));

$("select").selectOption("день прощанья");

$("select").getSelectedOptions()
  .shouldHave(texts("день прощанья"));

См. issue 2445 и PR 2446.


Метод getFocusedElement() обленился

Теперь метод getFocusedElement() возвращает SelenideElement, а не WebElement.

Что автоматически означает ленивую загрузку и прочие плюшки.
А ещё вы можете использовать для него стандартные should-проверки:

Selenide.getFocusedElement()
  .shouldHave(tagName("input"), id("otpCode"));

См. PR 2454.


Добавили поддержку полей SelenideAppiumElement в пэдж обжектах

Если вы пишете тесты для мобилок с нашим плагином selenide-appium, то теперь вы можете объявлять поля пэдж обжекта с типом SelenideAppiumElement, вместо SelenideElement.

Это даёт дополнительные методы для мобилок: hideKeyboard(), swipe() и т.п.

class LoginPage {
  @AndroidFindBy(accessibility = "Username input field")
  SelenideAppiumElement login;

  @AndroidFindBy(accessibility = "Password input field")
  SelenideElement password;
  
  public void login() {
    password.swipeTo();
  }
}

См. issue 2437 и PR 2438.


Точечный скроллинг в мобилках

Продолжая тему мобилок. В плагине selenide-appium есть метод scroll:

import static com.codeborne.selenide.appium.AppiumScrollOptions.with;

$.scroll(with(UP, 20)); // свайпать вверх, не больше 20 раз

А теперь ему в параметрах можно более точно указать начальную и конечную точку свайпа (в процентах от высоты экрана):

import static com.codeborne.selenide.appium.AppiumScrollOptions.up;

$.scroll(up(10, 80)); // свайпать от точки 10% до точки 80%

Спасибо qwez за PR 2449.


Нельзя наследовать пэдж обжект от ElementsContainer

Некоторые пользователи жаловались на такой вот странный ворнинг от селенида:

WARN com.codeborne.selenide.impl.SelenidePageFactory - Cannot initialize field private com.codeborne.selenide.SelenideElement com.codeborne.selenide.ElementsContainer.self

Мы начали исследовать тему и поняли, что это происходит, если вы наследуете пэдж обжект от ElementsContainer:

class LoginPage extends ElementsContainer {
}

Что на самом деле не нужно. Собственно, теперь и не получится. :)

Изначально ElementsContainer был задуман для того, чтобы объявлять компоненты внутри пэдж обжекта:

class LoginPage {
  @FindBy(id="weather")
  WeatherWidget weatherWidget;
}

class WeatherWidget extends ElementsContainer {
  @FindBy(id="temperature")
  SelenideElement temperature;
}

Просто уберите extends ElementsContainer из своего пэдж обжекта, и всё будет прекрасно работать.

P.S. Дело в том, что это разные объекты с разной судьбой.

  1. Пэдж обжекты вы можете создавать методом LoginPage page = Selenide.page();. И для этого им не требуется наследоваться от ElementsContainer.
  2. А вот поля этих пэдж обжектов надо наследовать от ElementsContainer, чтобы селенид знал, что в них надо тоже искать аннотации @FindBy.

См. issue 2439 и PR 2455.


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

  • bump LittleProxy from 2.0.19 to 2.0.20 (fixes a memory leak in Selenide proxy)
  • update vulnerable jackson dependency - см. PR 2442


Статистика

Количество ежемесячных скачиваний Селенида перевалило за 670 тыщ!


Такими темпами у нас будет всё всерьёз. Следующего второго сентября.


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

ru.selenide.org

06.09.23