Вышла Selenide 5.4.1

Вышла Selenide 5.4.1

Статики победили
16.10.19

Всем привет!

Нет ничего унылее октября. Давайте же скрашивать его хорошими новостями!

Сегодня мы выпустили Selenide 5.4.0 с парочкой существенных изменений, о которых многие из вас давно просили.

UPD В 5.4.0 была ошибка, так что обновляйтесь сразу на 5.4.1

UPD 2 В 5.4.1 тоже нашлась малюсенькая ошибочка: опция Configuration.holdBrowserOpen не работает. Исправим в следующей версии. Надеюсь, вы не используете её часто.


1. Исправили ошибку “IllegalStateException WebDriver has been closed”

Начиная с Selenide 5.0.0 (т.е. примерно год назад), многие пользователи стали жаловаться на ошибку IIlegalStateException WebDriver has been closed....

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

Но жалоб было слишком много, поэтому с тяжёлым сердцем я всё-таки решил убрать эту ошибку.

В конце концов, каждый имеет право набивать свои шишки.

Если вкратце, ошибка эта случается, когда SelenideElement переиспользуют с разными инстансами SelenideDriver. Обычно так бывает, когда SelenideElement объявляют как статическое поле (в пэдж обжекте или в тесте, неважно). И инициализируют его раньше, чем открывается браузер. Либо перезапускают браузер между тестами. Ещё это бывает, когда используют Cucumber, который пытается инициализировать степы и пэдж обжекты до открытия браузеров. Или зачем-то пихают в тесты Guice или Spring. В тесты, Карл!

Так вот, всё это переусложнение и в тестах не нужно. Статические поля - зло. Подробнее об этом я рассказывал в докладе Антистатик.

Но раз уж людям так впёрлось - ладно. Ловите Selenide 5.4.0

Теперь вот такой код будет работать:

public class SomeClass {
  private static SelenideElement body = $("body");

  public static void main(String[] args) {
    open("https://mail.ru");
    body.should(exist);

    Selenide.close();

    open("https://mail.ru");
    body.should(exist);   // А раньше отсюда летел "IllegalStateException WebDriver has been closed"
  }
}

Больше примеров и жалоб можно найти в issue 862, 902, 954, 922, 873.

Как мы позволили статикам победить, можно отследить в PR 989.


2. Теперь SelenideDriver.close() всегда закрывает браузер

Опять же, начиная с Selenide 5.0.0, люди стали жаловаться на то, что метод close() не закрывает браузер. Конечно, не всегда, а только в одном специфическом случае - когда пользователь сам же браузер и открыл.

SelenideDriver browser=new SelenideDriver(new FirefoxDriver());
browser.close(); // вот так браузер НЕ закрывался
browser.getWebDriver().close(); // а так закрывался

Это тоже не совсем бага, потому что изначально в Селениде была такая философия: браузер, открытый пользователем, селенид не закрывает. Потому что поди знай, вдруг его ещё где-нибудь используют помимо Селенида.

Как говорят в Сбертехе,

где браузер открывали - там его и закрывайте. :)

Но опять же, жалобы были. У людей вызывало непонимание, как так: метод close() есть, отрабатывает без ошибок - но не закрывает.

Теперь мы это тоже исправили. Метод close() закрывает браузер.

P.S. Если у вас вдруг браузер начнёт закрываться в ненужный момент - обращайтесь, будем изучать.

См. issue 896 и PR 989


3. Вернули короткие сообщения об ошибках

Как мы могли заметить, в Selenide 5.3.1 прилетела одна некритичная регрессия. Сообщения об ошибках стали слишком длинными:

com.codeborne.selenide.ex.ElementNotFound: Element not found {#customerDashboardButton}

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

Element not found {#customerDashboardButton}

P.S. У бедных пользователей maven-surefire-plugin 2.22.2 всё ещё будут длинные сообщения, подробности тут. Сочувствую.

См. PR 993


4. Добавили метод using для лёгкого переключения несколькими вебдрайверами

Повторюсь, использование нескольких браузеров в одном тесте в подавляющем большинстве случаев я считаю плохой практикой.

Но теперь набивать шишки таким образом стало чуть удобнее.

Если раньше приходилось постоянно дёргать метод setWebDriver() и не забывать, какой браузер активный в данный момент:

var browser1 = new FirefoxDriver();
var browser2 = new FirefoxDriver();

setWebDriver(browser1);
open("http://google.com");
$("h1").shouldHave(text("Released Selenide 5.4.0"));

setWebDriver(browser2);
open("http://yandex.ru");
$("h1").shouldHave(text("Вышла Selenide 5.4.0"));

то теперь можно завернуть блоки кода для разных браузеров в разные блоки using:

var browser1 = new FirefoxDriver();
var browser2 = new FirefoxDriver();

using(browser1, () -> {
  open("http://google.com");
  $("h1").shouldHave(text("Released Selenide 5.4.0"));
});

using(browser2, () -> {
  open("http://yandex.ru");
  $("h1").shouldHave(text("Вышла Selenide 5.4.0"));
});

См. PR 976 и примеры кода в CustomWebdriverTest.java.


5. Добавили защиту от одной типичной ошибки с xpath

Типичная ошибка:

$(".parent").find(By.xpath("/child")).shouldBe(visible);

Дело в том, что XPath, начинающийся на слэш (“/”), ищет элемент от корня проекта (а не от элемента .parent, как, очевидно, хотел автор этого кода).

Слишком многие наступали на эти грабли. Поэтому мы добавили защиту от этой типичной ошибки.

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

IllegalArgumentException: XPath starting from / searches from root

Исправить этот код можно по-разному (смотря что вам требуется):

$(".parent").find(By.xpath("./child")).shouldBe(visible);
$(".parent").find(By.xpath(".//child")).shouldBe(visible);
$(".parent").find(By.xpath("child")).shouldBe(visible);

См. PR 963 и PR 975


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

  • upgrade to webdrivermanager:3.7.1
  • exclude old Guava dependency coming from net.lightbody.bmp:browsermob-core:2.1.5

Внимание, в WDM обнаружена ошибка: когда вы хотите скачать chromedriver версии 77, он иногда может скачать “75.0.3770.90”. Да-да, потому, что эта версия содержит подстроку “77”. Смешно, да? :)


Новости


Конференции

Друзья, в унылый пасмурный октябрьский денёк очень советую пойти на конференцию Joker. Круче этой программы ничего не может быть!


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

ru.selenide.org

16.10.19