Как стать автором
Обновить

Автоматизация тестирования с использованием Selenide через Selenoid в Docker контейнере

Время на прочтение16 мин
Количество просмотров50K

Данная статья будет полезна начинающим QA специалистам, а также тем, кто интересуется особенностями и возможностями таких популярных фреймворков тестирования, как Selenide и Selenoid.

Здесь мы рассмотрим некий базовый проект на Selenium. Увидим, как подключить Selenium и TestNG к проекту, пример Page Object с описанием элементов страницы и используемых методов.

Далее, знакомство с Selenide: рассмотрим сам фреймворк, его основные возможности и преимущества, добавление Selenide в тестовый проект. Рассмотрим работу с элементами, проверки и ожидания, доступные в Selenide.

И наконец, подключим к своему проекту фреймворк Selenoid для запуска тестов в Docker контейнере и вне его.




* Статья подготовлена на основе доклада Никиты Калиниченко — Senior QA специалиста компании IntexSoft.
В статье присутствуют ссылки на внешние материалы.


1. Selenium + TestNG


Мы рассматриваем проект на сборщике Maven, поэтому описание структуры проекта мы можем найти в файле pom.xml. Для того, чтобы использовать Selenium и TestNG, в наш файл pom.xml должны быть добавлены соответствующие зависимости. Их вы можете наблюдать между тегами dependencies ниже:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>

   <groupId>test</groupId>
   <artifactId>test</artifactId>
   <version>1.0-SNAPSHOT</version>
   <dependencies>
            <dependency>
                    <groupId>org.seleniumhq.selenium</groupId>
                    <artifactId>selenium-java</artifactId>
                    <version>3.141.59</version>
          </dependency>
          <dependency>
                    <groupId>org.testng</groupId>
                    <artifactId>testng</artifactId>
                    <version>6.14.3</version>
                    <scope>test</scope>
          </dependency>
  </dependencies>
</project>

Далее мы рассмотрим пример Page Object’а:


import...

public class SignUpPage {
   private WebDriver driver;

   public SignUpPage(WebDriver driver) { this.driver = driver; }

   private By emailField = cssSelector("#register-email");
   private By confirmEmailField = cssSelector("#register-confirm-email");
   private By passwordField = cssSelector("#register-password");
   private By displayNameField = cssSelector("#register-displayname");
   private By monthDropDown = cssSelector("#register-dob-month");
   private By dayField = cssSelector("#register-dob-day");
   private By yearField = cssSelector("#register-dob-year");
   private By shareCheckbox = cssSelector("#register-thirdparty");
   private By registerButton = cssSelector("#register-button-email-submit");

   //Метод для заполнения поля email
   public SignUpPage typeEmail(String email) {
      //Находим поле и вводим в него текст
      driver.findElement(emailField).sendKeys(email);
      return this;
  }
  
  //Метод для заполнения поля Confirm email
  public SignUpPage typeConfirmEmailField(String email) {...}

  //Метод для заполнения поля password
  public SignUpPage typePassword(String password) {...}

  //Метод для заполнения поля ввода имени
  public SignUpPage typeName(String name) {...}

  //Метод выбора месяца
  public SignUpPage setMonth(String month) {...}
 
 //Метод для заполнения поля Day
  public SignUpPage typeDay(String day) {...}

 //Метод для заполнения поля Year
  public SignUpPage typeYear(String year) {...}

Как мы видим, в верхней части java-файла находится описание переменных с локаторами для элементов страницы регистрации. Ниже секции переменных расположены методы непосредственно для взаимодействия с элементами нашей страницы.

Откроем сами тесты:


//Добавляем переменную страницы регистрации
private WebDriver driver;
//Добавляем переменные драйвера
private SignUpPage page;

@BeforeMethod
public void setUp() {
       //Указываем путь где хранится geckodriver
       System.setProperty("webdriver.gecko.driver", "C:\\Users\\Nikita\\IdeaProjects\\autotests_examples\\drivers\\geckodriver.exe");
       //Создаем новый драйвер
       driver = new FirefoxDriver();
       //Добавляем неявное ожидание, используемое при поиске любого из элементов
       driver.manage().timeouts().impicitlyWait(10, TimeUnit.SECONDS);
       //Открываем url в браузере с помощью метода webdrivera get
       driver.get("https://www.spotify.com/us/signup/");
}

Как видим, в аннотации BeforeMethod мы описываем то, что у нас будет происходить перед каждым методом.


@Test
public void typeInvalidYear() {
     //Создаём объект класса страницы регистрации и передаём в конструктор класса driver
     page = new SignUpPage(driver);
     //Устанавливаем месяц
     page.setMonth("December");
                 //Указываем день
                 .typeDay("20")
                 //Указываем год
                 .typeYear("85")
                 //Жмём чекбокс
                 .setShare(true);
       //Проверяем видимость ошибки, ошибка должна быть видна;
      Assert.assertTrue(page.isErrorVisible("Please enter a valid year."));

В аннотации Test приведён код тестовых методов.


   @AfterMethod
    //Метод, закрывающий браузер
    public void tearDown() {
        driver.quit();
    }

А в аннотации AfterMethod содержится код, который должен выполниться после каждого метода.

При запуске тестов с использованием Selenium будет происходить следующее:

  1. Открытие отдельного окна браузера
  2. Переход по url
  3. Выполнение кода тестов
  4. Закрытие сессии и окна браузера после каждого теста

При выполнении следующего теста будет происходить то же самое. Следует упомянуть, что выполнение тестов на Selenium – довольно ресурсозатратный процесс.

2. Selenide: что, где, и как


Что же такое сам Selenide, каковы его основные возможности и преимущества?

Если кратко, Selenide – это обёртка вокруг Selenium WebDriver, позволяющая быстро и просто его использовать при написании тестов. По своей сути, Selenide – это инструмент для автоматизации действия пользователя в браузере, ориентированный на удобство и легкость реализации бизнес-логики в автотестах на языке пользователя, не отвлекаясь на технические детали работы с «драйвером браузера». Для примера, нам не нужно акцентировать внимание на работе с ожиданиями элементов в процессе автоматизации тестирования динамических веб-приложений, а также на реализации высокоуровневых действий над элементами.

Ключевые и главные преимущества Selenide:

  • Лаконичный синтаксис в духе jQuery
  • Автоматическое решение большинства проблем с Ajax, ожиданиями и таймаутами
  • Управление жизнедеятельностью браузера
  • Автоматическое создание скриншотов

Цель Selenide – сосредоточиться на бизнес-логике тестов и не “растрачивать” ментальную энергию на технические детали.

Перевод проекта на Selenide


Для того, чтобы подключить Selenide и начать работу с ним, в файле pom.xml между тегами dependencies мы указываем зависимость от Selenide. Так как зависимость Selenium нам больше не нужна, мы попросту ее удаляем.


         <dependency>
                    <groupId>com.codeborne</groupId>
                    <artifactId>selenide</artifactId>
                    <version>5.2.8</version>
         </dependency>

Далее, для того, чтобы подключить и начать использовать Selenide в своем проекте, нам необходимо сделать несколько импортов. Примеры импортов:

import static com.codeborne.selenide.Selenide.*;
import static com.codeborne.selenide.Selectors.*;
import static com.codeborne.selenide.Condition.*;
import static com.codeborne.selenide.CollectionCondition.*;

Подробнее о том, как подключить Selenide, используя остальные сборщики проектов, можно прочесть в разделе Quick Start документации Selenide.

Работа с элементами, проверки и ожидания


Перейдем к рассмотрению работы Selenide с элементами и познакомимся с некоторыми проверками и ожиданиями, доступными нам в Selenide.


import...

public class SignUpTest {
    //Добавляем переменную страницы регистрации
   private SignUpPage page;

   @BeforeClass
   public static void setUp() {
       //Property baseurl, которое хранится в классе Configuration и будет являться базовым url
       baseurl = "https://www.spotify.com";
       //Property browser, которое находится в классе Configuration и указывает на каком браузере будет выполнен запуск тестов
       browser = "chrome";
       
   }

В файле с тестами мы заменяем аннотацию BeforeMethod на аннотацию BeforeClass, так как она нам больше не нужна, Selenide нас избавляет от нужды писать Before и After методы – функцию AfterMethod на себя берет сам Selenide. У нас остаётся только аннотация BeforeClass чтобы прописать пару properties.

В аннотации BeforeClass мы прописали property baseurl, которое находится в классе configuration и будет являться базовым url. Поэтому, driver.get, который мы использовали в тестах на Selenium, больше не нужен. В property browser мы прописываем браузер, на котором мы будем осуществлять запуск наших тестов.

В своём тестовом проекте мы можем полностью отказаться от драйвера Selenium, всю работу с ним Selenide возьмёт на себя, инкапсулируя её в своих классах. Нам останется сосредоточиться на логике самих тестов.

Перейдем к использованию Selenide на нашей странице:


    //Метод для открытия страницы с помощью метода Selenide open
    public SignUpPage open() {
         //Указываем обратный путь
         Selenide.open (relativeOrAbsoluteUrl: "/us/signup/");
         return this;
    }
    //Метод для заполнения поля email
    public SignUpPage typeEmail(String email) {
         //Находим поле и вводим в него текст
         $(emailField).sendKeys(email);
         return this;
       
   }

При вызове метода open, Selenide сам запускает браузер и открывает страницу. Также он заботится о том, чтобы в конце браузер закрылся. В Selenide.open мы можем прописать либо полный путь c http, либо передать какой-либо относительный к baseurl – relative url. В качестве baseurl мы указали абсолютный путь, поэтому в методе Selenide.open нам достаточно будет указать “/”.


//Метод для заполнения поля email
public SignUpPage typeEmail(String email) {
    //Находим поле и вводим в него текст
    $(emailField).sendKeys(email);
    return this;
}

//Метод для заполнения поля Confirm email
public SignUpPage typeConfirmEmailField(String email) {
    //Находим поле и вводим в него текст
    $(confirmEmailField).setValue(email);
    return this;
}

Для того, чтобы с использованием Selenide найти элемент, нам необходимо указать $ вместо driver.findElement, который используется в Selenium. То есть, при помощи метода длиной в один символ, мы можем найти непосредственно сам элемент. По умолчанию, метод поиска принимается в виде строки, аналогично библиотеке JavaScript jQuery.

Для того, чтобы с использованием Selenide найти список элементов, нужно указать два символа $$. Вместо List<WebElement, мы прописываем ElementsCollection, которая уже расширена дополнительными методами.


Для работы с элементами мы можем использовать как стандартные методы Selenium (sendKeys()), так и setValue() или более короткую версию vаl().


Исходя из наименования, как мы видим, методы Selenide более понятны. Метод click() таким и остается. Хотя у Selenide есть несколько методов click(): contextClick() (имитация нажатия правой кнопки мыши), doubleClick() (имитация двойного нажатия по элементу) и т.д. Имея уже найденный элемент мы можем продолжать поиск при помощи других локаторов.


От метода Selenium driver.findElement(By), метод Selenide find() отличается тем, что сразу умеет получать CSS селекторы и оперирует c Selenide-элементами, а не с Web-элементами. В принципе, Selenide-элементы – это более умная и со своими методами альтернатива Web-элементам Selenium.


Selenide уже содержит в себе методы, которые пришлось бы делать посредством какого-либо action класса или ещё каким-то образом. Он позволяет писать краткие и “красивые” методы, написанные понятным всем языком. Также, Selenide обладает большой долей гибкости, благодаря которой мы можем использовать стандартные возможности Selenium.


С остальными методами Selenide также можно ознакомится в официальной документации.


Рассмотрим широкие и понятные примеры проверок, которые нам предоставляет Selenide:



//Проверяем видимость ошибки, ошибка должна быть видна
page.getError("Please enter a valid year.").shouldBe(Condition.visible);
//Проверяем видимость ошибки, ошибка должна быть не видна
page.getError("When were you born?").shouldNotBe(Condition.visible);
//Проверяем количество ошибок сравнивая с размером списка
page.getErrors().shouldHave(CollectionCondition.size(6));
//Проверяем текст ошибки по её номеру
page.getErrorByNumber(3).shouldHave(Condition.text("Please enter your birth month."));

Схема проверки Selenide позволяет нам взять некий элемент, найти его и использовать к нему следующие формулировки: should, shouldBe, shouldHave, shouldNot, shouldNotBe и shouldNotHave. Схема проверки сводится к нахождению элемента и вызовом у него этих формулировок. Далее в скобках мы указываем, либо состояние, которому он должен соответствовать или не соответствовать, либо какой-либо атрибут.


В зависимости от логики и наших потребностей, мы используем определенные методы. Если мы хотим проверить, что элемент существует, мы используем метод should(exist), если мы хотим проверить видимость элемента, мы используем shouldBe(visible) и т.д. По сути мы используем только три формулировки: либо should, shouldBe, shouldHave, либо обратные им shouldNot, shouldNotBe, shouldNotHave.


Проверки над элементами или коллекциями элементов совершаются на Selenide с помощью описанных выше методов, которым передается условие для проверки. Они играют роль ожидания момента, когда элемент будет удовлетворять какому-то условию, а не только совершают проверку по условию.


Формулировки в Selenide довольно логичны и понятны. Мы можем написать наши проверки, либо используя подсказки среды разработки, либо логические предположения. И само собой, мы всегда можем взглянуть на код реализации нужных методов в документации или заглянуть в реализацию самого метода.


Автоматические скриншоты в тесте


Для JUnit:

Чтобы автоматически делать скриншот после каждого упавшего теста, можно сделать импорт и указать Rule



import com.codeborne.selenide.junit.ScreenShooter;

@Rule
public ScreenShooter makeScreenshotOnFailure = ScreenShooter.failedTests();

Но по сути, это рудимент, так как Selenide уже давно автоматически делает скриншоты при падении тестов. Это очень удобно для анализа наших ошибок. По умолчанию Selenide складывает скриншоты в папку build/reports/tests.

Для того, чтобы автоматически делать скриншот после каждого теста (в т.ч. зелёного), можно использовать следующую команду:


@Rule 
public ScreenShooter makeScreenshotOnFailure = ScreenShooter.failedTests().succeededTests();

Для TestNG мы также делаем импорт:



import com.codeborne.selenide.testng.ScreenShooter;

@Listeners({ ScreenShooter.class})

Чтобы делать скриншоты после зелёных тестов, нужно вызвать следующую команду перед запуском тестов:



ScreenShooter.captureSuccessfulTests = true;

Также можно сделать скриншот в любом месте теста одной строкой:



import static com.codeborne.selenide.Selenide.screenshot;

screenshot("my_file_name");

При этом Selenide создаст два файла: my_file_name.png и my_file_name.html

3. Docker: особенности и преимущества использования


Перейдем непосредственно к Docker и рассмотрим его преимущества:


  • Ускоренный процесс разработки. Нет необходимости устанавливать вспомогательные инструменты их можно запускать в контейнерах
  • Удобная инкапсуляция приложений
  • Понятный мониторинг
  • Простое масштабирование

Когда мы говорим о Docker’е, следует прояснить следующие моменты:


Контейнер – это исполняемый экземпляр, который инкапсулирует требуемое программное обеспечение. Он состоит из образов. Его можно легко удалить и снова создать за короткий промежуток времени.


Образ – базовый элемент каждого контейнера.


Docker Hub – публичный репозиторий с интерфейсом, предоставляемый Docker Inc. Он хранит множество образов. Ресурс является источником «официальных» образов, сделанных командой Docker или созданных в сотрудничестве с разработчиком ПО.


Установка Docker


Чтобы получить Docker на Windows, мы идём на https://hub.docker.com и скачиваем приложение Docker Desktop для Windows или MacOS с последующей установкой.


Для Ubuntu Linux устанавливаем Docker командой sudo apt install docker.io


Далее необходимо запустить Docker и настроить его автоматический запуск при загрузке системы выполнив следующие команды:


  • sudo systemctl start docker
  • sudo systemctl enable docker


4. Selenoid: возможности и преимущества


Selenoid – это сервер, запускающий изолированные браузеры в Docker контейнерах.


Преимущества использования Selenoid:


  • Единая среда для параллельного запуска автотестов
  • Изолированное окружение: каждый браузер запускается в отдельном контейнере, что позволяет полностью изолировать окружение нашего браузера
  • Масштабируемость: окружение никак не влияет на качественное и непрерывное проведение тестов
  • Потребление и утилизация ресурсов: Selenoid позволяет поддерживать высокую нагрузку без дополнительных ресурсозатрат; кроме того, он утилизирует все неактивные контейнеры после завершения самой его сессии, тем самым постоянно поддерживая нужно количество свободной памяти
  • Установка: не занимает много времени и осуществляется, по сути, при помощи одной команды
  • Одновременная поддержка нескольких версий одного браузера: данная опция доступна только у Selenoid, для этого необходимо создать несколько контейнеров с необходимыми браузерами
  • Фокус: операционная система работает таким образом, что в фокусе может быть только одно окно. При запуске нескольких браузеров на одной машине, окна могут начать конкурировать за фокус. У Selenoid такой проблемы нет, поскольку каждый тест запускается в отдельном контейнере
  • Пользовательский интерфейс и логи: Selenoid позволяет быстро получить доступ к имеющимся журналам. Помимо этого есть возможность интеграции с ELK стэком для более быстрого сбора и анализа текущих файлов.

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


Установка Selenoid


Подготовительные действия для установки Selenoid:


  • Необходим установленный и запущенный Docker, так как далее рассматривается использование Selenoid вместе с Docker
  • Простейший способ установки Selenoid – загрузить Configuration Manager, который используется для автоматизации установки продуктов Aerokube, коим и является Selenoid
  • Переименовать загруженный файл в cm.exe (для удобства взаимодействия)
  • Запустить Selenoid командой:

    ./cm.exe selenoid start --vnc
    ./cm.exe selenoid-ui start

В результате выполнения команды ./cm.exe selenoid start--vnc произойдёт загрузка образов с VNC-сервером, то есть образов, в которых доступна возможность видеть экран браузера в реальном времени. Также, в процессе выполнения этой команды будет скачана свежая версия Selenoid вместе с контейнерами, исполняемые файлы веб-драйверов, будут созданы файлы конфигурации и последним этапом будет сразу же запущен сам Selenoid.

Следующей командой ./cm.exe selenoid-ui start мы скачиваем и запускаем Selenoid UI – графическую оболочку, через которую мы можем посмотреть ход выполнения наших тестов в реальном времени, видеозаписи выполнения сценариев, примеры конфигурационных файлов, собрать какую-то статистику и т.д.

Selenoid по умолчанию работает на стандартном порту Selenium 4444. Порт можно переопределить, использовав ключ --port.

Selenoid был создан для работы в больших кластерах Selenium и поэтому не имеет встроенного пользовательского интерфейса. Поэтому попытка открыть
Endpoint для тестов localhost:4444/wd/hub вернет ошибку 404.

Статистика и сессии Selenoid UI


Selenoid UI доступен по адресу http://localhost:8080/


Здесь мы можем ознакомиться со статистикой и сессиями. Посмотреть текущее использование квоты, ожидающие браузеры и саму очередь. Selenoid UI получает обновления через SSE, поэтому не нужно обновлять страницу в браузере, чтобы увидеть, что происходит. После любых временных сбоев содержимое страницы автоматически обновиться.


Если мы говорим об одновременном тестировании на различных устройствах: например у нас есть кроссплатформенное веб-приложение с функциональностью чата в реальном времени, то мы одновременно можем тестировать взаимодействие между ними, что, безусловно, удобно.


Возможности Selenoid UI


Также в Selenoid UI имеются следующие возможности:



Мы можем выбрать браузер из списка доступных браузеров и пользовательский интерфейс предоставит нам пример настройки с правильными capabilities. На скриншоте видно, что примеры доступны для нескольких языков.



При выборе браузера, мы можем его запустить вручную прямо в интерфейсе. Во время исполнения тестов существует возможность подключится к порту vnc в режиме реального времени и получить доступ к экрану нужного браузера, и даже вмешаться в процесс исполнения автотестов.

Логи и VNC


Если вы используете capability enabaleVnc=true, вы можете увидеть на странице список доступной статистики. VNC позволяет нам видеть браузер и взаимодействовать с ним. В то время, как наш журнал будет отображать все действия браузера.


VNC сессия:


Полноэкранный режим VNC выглядит следующим образом:


Также вы можете видеть журналы контейнера докер для каждого сеанса даже без VNC. То есть, если, к примеру, вы не использовали флаг --vnc при установке самого Selenoid, то вы будете видеть только логи.


Также есть возможность просмотра видео наших тестов. К видео файлам можно попасть, открыв http://localhost:4444/video/, либо перейдя во вкладку “Videos” в Selenoid UI.

Подключение к Selenide проекту Selenoid для запуска своих тестов в Docker контейнере


Для того, чтобы подключить Selenoid, в аннотацию BeforeClass нам необходимо добавить следующую конфигурацию:

Configuration.remote = "http://localhost:4444/wd/hub";
Configuration.browser = "chrome";
Configuration.browserSize = "1920x1080";
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(capabilityName: "enableVNC", value: true);
capabilities.setCapability(capabilityName: "enableVideo", value: true);
Configuration.browserCapabilities = capabilities;

Удаляем Property baseurl, которое указывало на каком браузере выполнялся запуск тестов, так как теперь у нас используется свойство
Configuration.browser = «chrome»;

В проекте это выглядит следующим образом:


@BeforeClass
public static void setUp() {
      //Url удалённого веб драйвера
     Configuration.remote = "http://10.0.75.1:4444/wd/hub";
     //Определяем какой браузер будем использовать
     Configuration.browser = "chrome";
     //Размер окна браузера
     Configuration.browserSize = "1920x1080";
     //Создаём объект класса DesiredCapabilities, используется как настройка  вашей конфигурации с помощью пары ключ-значение
     DesiredCapabilities capabilities = new DesiredCapabilities();
     //Включить поддержку отображения экрана браузера во время выполнения теста
     capabilities.setCapability(capabilityName: "enableVNC", value: true);
     //Включение записи видео в процессе выполнения тестов
     capabilities.setCapability(capabilityName: "enableVideo", value: true);
     //Переопределяем Browser capabilities
     Configuration.browserCapabilities = capabilities;

Дополнительные возможности Selenoid


  • Хранение данных в оперативной памяти: в Selenoid все временные памяти хранятся в Tmpfs – временном файловом хранилище, которое позволяет хранить файлы в оперативной памяти. Доступ к ОЗУ, как известно, осуществляется намного быстрее, чем к файловой системе жесткого диска.
  • Selenoid позволяет использовать различное разрешение экрана: мы самостоятельно можем настраивать подходящее разрешение экрана для запущенного контейнера. Сделать это можно посредством выставления необходимых параметров в настройках компонента Browser Capabilities.
  • Видеозапись тестов: активация записи в Selenoid на примере браузера Google Chrome происходит за счет выставления параметра true в соответствующую настройку компонента Browser Capabilities:

    ChromeOptions options = new ChromeOptions();
    options.setCapability(“enableVideo”,true);

Использование Selenoid без Docker


Selenoid использует контейнеры для запуска браузеров, однако существуют случаи, когда запуск браузера в контейнере невозможен. Например, в Windows у нас есть Internet Explorer, который нельзя запустить внутри контейнера. Selenoid может использоваться в качестве “легкой” замены сервера Selenium для запуска Internet Explorer, Firefox или Chrome в Windows, например, чтобы использовать Selenoid с Internet Explorer.

Для этого нам потребуется:

1. Загрузить последний архив IEDriverServer и распаковать его в какой-либо каталог (в нашем примере C: \)

2. Загрузить последний бинарный файл Selenoid

3. Создать файл конфигурации browsers.json

Пример фрагмента browsers.json:

{ 
   "internet explorer": {
     "default": "11",
     "versions": {
        "11": {
           "image": ["C:\\IEDriverServer.exe", "--log-level=DEBUG"]
         }
      }
   }
}


4. Запустить Selenoid:
./selenoid_win_amd64.exe -conf ./browsers.json -disable-docker

5. Запустить тесты, используя endpoint http://localhost:4444/wd/hub со следующими capabilities:
browserName = internet explorer
version = 11

6. Для того, чтобы запустить Chrome, необходимо загрузить бинарный файл Chromedriver и, соответственно, изменить browsers.json

7. По умолчанию Selenoid не обрабатывает логи запущенного драйвера, поэтому нужно запустить Selenoid с флагом -capture-driver-logs, чтобы добавить логирование драйверов для каждой сессии в основной лог.

Подводя итог


Решение на основе Selenide + Selenoid в Docker контейнере демонстрирует высокий уровень гибкости в настройке среды исполнения. Стабильность данного решения, значительная экономия времени при его использовании и ряд дополнительных возможностей позволяет оптимизировать процесс и в сжатые сроки обеспечивать высокое качество программных продуктов, в результате легко отдать предпочтение вышеупомянутым решениям, поскольку они позволяют быстро и качественно выполнять задачи по автоматизации тестирования.
Теги:
Хабы:
+8
Комментарии4

Публикации

Истории

Работа

Ближайшие события