Вышла Selenide 5.0.0

Вышла Selenide 5.0.0

Нам 7 лет!
10.10.18

Ура! Наконец-то это случилось. Мы выпустили мажорную версию Selenide 5.0.0

Самое большое изменение в Selenide 5.0.0 - это большой рефакторинг. То есть внутренние изменения. Вас это почти не должно задеть. Кому интересно - детали рефакторинга будут в отдельном посте.

Какие же изменения ждут вас в Selenide 5.0.0?

Возможность открывать два браузера в одном тесте

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

Обычно такое желание возникает для того, чтобы, скажем, одним браузером в админке поменять какую-то настройку и другим браузером проверить, что на страничке пользователя эта настройка отобразилась. Но правильное решение в таком случае - тестировать админку отдельно и пользовательскую страничку отдельно. А подготавливать окружение (в т.ч. менять настройки) можно как угодно (rest запрос, прямой запрос в базу и т.п.), но только не через UI. Вы ведь тестируете UI, а значит, априори не должны ему доверять.

Если вы всё-таки решите идти грешным путём, это делается примерно так:

SelenideDriver browser1 = new SelenideDriver();
SelenideDriver browser2 = new SelenideDriver();

browser1.open("https://google.com");
browser2.open("http://yandex.ru");

browser1.$(h1).shouldHave(text("Google"));
browser2.$(h1).shouldHave(text("Yandeks"));

См. актуальный пример в тестах Селенида

См. issue 354 и PR 801

Хочу выразить благодарность людям, которые сыграли важную роль в этом рефакторинге:

  • Iakiv Kramarenko за изначальную идею,
  • Alexei Barantsev за конструктивные споры и убедительные аргументы,
  • Aliaksandr Rasolka за моральную поддержку и генерацию идей

NB! Старые добрые open, $, $$ работают по-прежнему, и я по-прежнему рекомендую их использовать. Внутри они тоже создают new SelenideDriver(), но правильно его хранят и уничтожают. Вам незачем городить свои велосипеды и решать те же задачи снова и снова.

Ещё раз: два браузера в тесте - это наверняка ПЛОХАЯ ПРАКТИКА!


Теперь Селенид по умолчанию использует Chrome

Когда-то давно мы выбрали Firefox по умолчанию, потому что это был единственный браузер, для запуска которого не требовалось установки отдельного вебдрайвера. Этот аргумент давно неактуален, т.к. 1) Firefox теперь тоже требует установки geckodriver, и 2) Селенид умеет устанавливать их автоматически.

Зато Chrome, по нашему опыту, быстрее и надёжнее. Поэтому наступила эпоха Хрома.

См. issue 811 – спасибо Aliaksandr Rasolka за PR 812


Селенид больше не максимизирует браузер по умолчанию

Когда-то казалось хорошей идеей запускать браузер на весь экран. Казалось, что это должно сделать тесты стабильнее: ведь больше элементов поместится на экран. Это поверье очень популярно и по сей день.

На самом деле это делает тесты нестабильными: ведь их результат зависит от размера экрана, а это величина случайная и нам неподконтрольная. Наша новая рекомендация - выставлять окну браузера фиксированный размер. Минимальный, который ваше приложение должно поддерживать. Селенид по умолчанию устанавливает 1366x768 как самое популярное в мире на данный момент. Как обычно, вы можете его переопределить как любую другую настройку.

См. issue 810 – спасибо Aliaksandr Rasolka за PR 812


Селенид больше не открывает браузер автоматически

Действия и проверки (например, $("#name").click() и $$("#list").shouldHave(size(1))) теперь кидают ошибку, если браузер не открыт (или уже закрыт). Т.е. сначала нужно открыть браузер (вызвать open(url)), а лишь потом работать с элементами.

Раньше подобные действия открывали браузер сами, если он ещё не был открыт. И это поведение было иногда неожиданным. Например, у людей иногда выскакивал Firefox там, где они ожидали Chrome. Или открывалось два браузера вместо одного. Понятно, что это ошибка в их тестах, но теперь Селенид поможет легче её найти.

Уже известны случаи, когда тесты начали падать после перехода на Selenide 5.0.0 по двум причинам:

  1. Поля пэдж обжекта были объявлены статическими, а браузер закрывался после каждого теста. Статические поля инициализировались только один раз. Каждый следующий тест не переинициализировал их, а получал SelenideElement от предыдущего теста с устаревшей ссылкой на вебдрайвер (уже закрытый). Решение: сделать поля нестатическими. Статики - зло.
  2. Поля тест-класса (в случае TestNG) инициализировались не в setUp методе, а прямо в объявлении полей. За это я и люблю JUnit. Счастливые пользователи JUnit могут позволить себе такую роскошь:
    public class MyTest {
      SelenideElement header = $("h1");
    }
    

    А бедные пользователи TestNG вынуждены выносить инициализацию во всякие @Before методы:

    public class MyTest {
      SelenideElement header;
      @BeforeEach
      public void setUp() {
        header = $("h1");
      }
    }
    

    Ужасно, правда? Мой вам совет: забудьте TestNG как страшный сон. JUnit рулит.

См. issue 809


Подчистили старые настройки и фичи

См. issue 806 – спасибо Aliaksandr Rasolka за PR 812

В том числе убрали поддержку следующих настроек:

  • browser (используйте selenide.browser)
  • remote (используйте selenide.remote)
  • selenide.browser-size (используйте selenide.browserSize)
  • selenide.browser.version (используйте selenide.browserVersion)
  • browser.version (используйте selenide.browserVersion)
  • selenide.start-maximized (используйте selenide.startMaximized)
  • selenide.chrome.switches (используйте selenide.chromeSwitches)
  • chrome.switches (используйте selenide.chromeSwitches)
  • selenide.page-load-strategy (используйте selenide.pageLoadStrategy)
  • selenide.click-via-js (используйте selenide.clickViaJs)
  • selenide.reports (используйте selenide.reportsFolder)


Убрали зависимость от junit5-api

Раньше Селенид транзитивно тянул за собой junit5-api, даже если вы не используете JUnit5. Очевидно, вам это не надо. Теперь больше не тянет.

Если вы всё же используете JUnit5 и у вас из classpath пропали нужные классы, придётся в своём проекте явно объявить зависимость "org.junit.jupiter:junit-jupiter-api:5.3.1".


Ну и по мелочам:

  • Классы AssertionMode, SelectorMode, FileDownloadMode перенесены из класса Configuration в пакет com.codeborne.selenide
  • Теперь Селенид кидает ElementIsNotClickableException вместо ElementNotFoundException (если элемент закрыт другим элементом и поэтому не удалось его кликнуть)
  • Селенид кидает ошибку, если Configuration.fileDownload == PROXY, но Configuration.proxyEnabled == false. Вам придётся проставить Configuration.proxyEnabled=true, если хотите скачивать файлы через прокси.
  • 817 fix “FirefoxDriverFactory overwrites Firefox profile provided by Configuration” – спасибо Boris Osipov за PR 821
  • bugfix: method Selenide.download() should not fail if there is no opened browser yet
  • 825 Обновили WebDriverManager до версии 3.0.0 (снова)
  • 825 Придумали костыль для WebDriverManager, чтобы он не обращался слишком часто к github (получая при этом ошибку 403)
  • 832 Added support for screenshots outside of “user.dir” in CI server – спасибо Alex Yu


И технические изменения (которые вас, скорее всего, не затронут)

  • Обновились до htmlunitdriver 2.33.0
  • Перенесли константы IE, FIREFOX и т.д. из класса WebDriverRunner в его родительский класс Browsers
  • Перенесли класс Selenide, WebDriverRunner, Configuration в подпапку statics.
  • Перенесли логику инициализации дефалтовых настроек из Configuration в SelenideConfig.
  • when waiting for a condition, catch explicitly only needed exceptions instead of Throwable which is too generic. It does not make sense to wait for 4 seconds in case of IllegalStateException, FileNotFoundException etc.


Новости

Нам 7 лет!

Время летит незаметно. Не успели оглянуться, а 25 октября селениду исполняется целых 7 лет. Сейчас, конечно, смешно смотреть, какими были первые коммиты.


А как у вас прошло обновление?

Делитесь своим опытом, смело заводите тикеты на гитхабе, обсуждайте проблемы в слаке или гиттере.


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

ru.selenide.org

10.10.18