Вышла Selenide 6.9.0

Вышла Selenide 6.9.0

Подменяем результаты
07.10.22


Привет!

Позвольте прервать ваш думскроллинг хорошей новостью.

Вы выпустили Selenide 6.9.0! В основном прокачали прокси и обновили селениум.

Научили прокси подменять ответ сервера

Как вы знаете, селенид умеет запускать свой встроенный прокси между браузером и тестируемым приложением. До сих пор мы использовали его в основном для отслеживания запросов (логирования, скачивания файлов), но теперь ещё и добавили возможность подменить ответ сервера. Это удобно, например, чтобы замокать ответ какого-то сервиса.

Давайте рассмотрим на каком-нибудь простеньком абстрактном примере.

Пример

Допустим, вы тестируете сайт, показывающий результаты референдума. Это html-страница по адресу, скажем, https://referendum.ru, которая обращается к сервису https://cik.ru и тянет с него json с результатами голосования.

Поскольку результаты заранее неизвестны, а сайт протестировать нужно здесь и сейчас, мы хотим проверить, как он будет выглядеть в разных пограничных случаях (corner cases).

Тест

open();
getSelenideProxy().responseMocker().mockText("cik-mock",
    urlStartsWith(GET, "https://cik.ru/api/gov/no/referendum"), 
    () -> "{votes: 2133326, for: 99.23, against: 0.77}");

open("https://referendum.ru");
$("#votesFor").shouldHave(text("99.23%"));
$("#h3").shouldHave(text("Не только порадовали, но и удивили"));

Детали

Остановимся подробнее на первом параметре cik-mock. Это имя мока. Нужно оно для того, чтобы после теста его отменить (чтобы случайно не повлиять на следующие тесты):

@AfterEach
void tearDown() {
  getSelenideProxy().responseMocker().reset("cik-mock");
}

Ну или для надёжности можно отменить все моки:

@AfterEach
void tearDown() {
  getSelenideProxy().responseMocker().resetAll();
}

Ограничения

Если страница и сервис работают на одном домене, ограничений нет. А вот если страница обращается к сервису на другом домене, то мок сработает только при выполнении условий:

  • страница и сервис бегают на https (не http)
  • сервис работает и физически доступен из прокси

В общем

Использование моков - мощная техника, позволяющая вам проверять разные пограничные условия, которые иначе повторить сложно или невозможно (“146% голосов за”, “никто не явился на выборы”, “сервис недоступен” и т.д.)

Не стесняйтесь своего желания что-то подправлять, подчищать, добавлять. Будет так, как вы захотите.

См. issue 1254 и PR 1978.


Посылаем заголовок авторизации только нужному домену

Некоторые сайты, которые вам приходится тестировать, закрыты от внешнего мира с помощью BasicAuth. Селенид позволяет их открыть с помощью метода open с доп. параметрами:

open("https://referendum.ru/admin", BASIC, 
             new BasicAuthCredentials("vlastelin", "gojda!!!"));

Этот метод умеет обходить BasicAuth:

  • если прокси выключен - добавлением логина-пароля в URL,
  • а если прокси включен - добавлением заголовка Authorization в запросы от браузера к серверу.

Но вот незадача. Недавно мы обнаружили, что селенид слал заголовок Authorization не только тестируемому приложению, но и всем сторонним сервисам, к которым оно могло обращаться (например, S3 или Google authentication).

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

open("https://referendum.ru/admin", BASIC, 
             new BasicAuthCredentials("referendum.ru", "vlastelin", "gojda!!!"));

См. issue 1974 и PR 1975.


Подкрутили имя прокси хоста

Когда вы включаете прокси в селениде (например, через Configuration.proxyEnabled = true), селенид запускает встроенный прокси-сервер на случайном порту. И открывает браузер с указанием использовать прокси-сервер HOST:PORT. Вопрос, какой HOST тут использовать?

До сих пор по умолчанию использовался результат команды ClientUtil.getConnectableAddress() (это поведение по умолчанию в BrowserUpProxy). Но с этого релиза будет использоваться new NetworkUtils().getNonLoopbackAddressOfThisMachine() (это метод из Selenium). Мне лень разбираться, в чём там их специфика, но на моём компе они иногда выдают разный результат:

  • new NetworkUtils().getNonLoopbackAddressOfThisMachine() -> 192.168.0.18
  • ClientUtil.getConnectableAddress() -> 127.0.0.1

И первый однозначно лучше, когда браузер бежит на другой машине или в контейнере. Под адресом 127.0.0.1 прокси просто не будет виден с другой машины.

Кстати, если этот механизм почему-то вам не помог, вы всегда можете явно задать имя хоста для прокси через настройку Configuration.proxyHost = "my.comp.eu";

См. PR 1970.


Обновились на Selenium 4.5.0

Из заметных изменений:

  • удалили поддержку браузера Opera
  • добавили альтернативную реализацию вебдрайвера на JDK 11 HTTP client вместо Netty client
  • Добавили проверки на disabled в класс Select (больше не получится выбрать задизейбленный option в выпадающем списке)
  • Убрали имя хоста из селениумовских эксепшенов

    цуко, я просил об этом ещё в 2015 году!!!

См. ченджлог и PR 1967.


Выкинули поддержку Opera

Следствие предыдущего пункта. Селениум выкинул - и мы выкинули. Тестировать в опере не имеет особого смысла, т.к. это по сути тот же Chrome. Если очень хочется - можно, просто используйте chromedriver.

См. PR 1967.


Убрали getAlias из отчётов

Спасибо Reserved Word за PR 1971.


Вернули настройку “connection timeout”

Это мало кому нужно, так что смело пропускайте.

Когда-то у нас было две настройки для http клиента вебдрайвера: “connection timeout” и “read timeout”. Первую пришлось убрать при обновлении на Selenium 4, потому что её там выпилили. Теперь её реанимировали в Selenium 4.5.0, ну и мы реанимировали.

См. PR 1977.


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

  • LittleProxy from 2.0.12 to 2.0.13
  • slf4j from 2.0.2 to 2.0.3


Новости


Айтишники, учите английский по ирландским комикам!


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

ru.selenide.org

07.10.22