-
Notifications
You must be signed in to change notification settings - Fork 14
Overview (Russian)
Aquality Selenium является надстройкой над инструментом работы с браузером посредством Selenium WebDriver. Работа с Selenium WebDriver требует определенных навыков и опыта. Aquality Selenium предлагает упрощенный, а главное, более безопасный и стабильный способ работы с Selenium WebDriver.
- 1. PLATFORM SUPPORT
- 2. CONFIGURATIONS
- 3. AQUALITY SERVICES
- 4. BROWSER
- 5. ELEMENTS
- 6. FORMS
- 7. JAVASCRIPT EXECUTION
- 8. CONDITIONAL WAIT
В настоящее время Aquality Selenium позволяет автоматизировать веб тесты для Chrome, Firefox, Safari, IExplorer и Edge. Также присутствуют возможности самостоятельно реализовать поддержку новых браузеров, которые поддерживаются Selenium (подробнее здесь). При этом запуск тестов может выполняться на любой операционной системе с установленным на ней .NET Core SDK 2.1 и выше.
Aquality Selenium предоставляет пользователю гибкие возможности по конфигурации запусков путём редактирования конфигурационного файла settings.json Большинство настроек понятны без дополнительных объяснений, но основные моменты обозначены ниже в данном разделе. Также существует возможность использования Aquality Selenium реализовав собственные классы конфигурации.
Работа с решением подразумевает использование settings.json или его измененных копий для запуска тестов. По умолчанию используется файл settings.json хранящийся в dll библиотеки как Embedded Resource. Если вам необходимо изменить какие-либо настройки в данном файле, вам необходимо создать такой же файл в директории Resources
вашего проекта, к которому подключена данная библиотека, и уже в нем изменять необходимые параметры. Также можно создать несколько копий settings
файла для единовременного хранения нескольких конфигураций, отличающихся какими-либо параметрами. При этом имя должно соответствовать шаблону settings.{profile}.json
. Создавать данные файлы необходимо в той же директории Resources
. Как правило это удобно, когда есть необходимость выполнять запуск тестов на различных операционных системах, машинах, браузерах и т.п. Например, в настоящее время команда разработчиков Aquality Selenium использует две конфигурации settings.json и settings.local.json для выполнения запусков в локальном docker Circle CI и на персональной инфраструктуре.
Для того, чтобы удобно управлять тем, какой конфигурационный файл необходимо использовать можно установить переменную окружения с именем profile
и присвоить ей желаемое значение (например, local). По умолчанию во время запусков используется файл с именем settings.json
.
Любой параметр settings.json может быть также переопределен через переменную окружения. Для этого необходимо указать jsonPath
к параметру в JSON и его значение. Например: driverSettings.chrome.webDriverVersion: 77.0.3865.10
.
Settings файл содержит несколько секций, назначение которых описывается ниже.
browserName
параметр определяет на каком браузере будет выполняться запуск. Например browser=chrome - означает, что запуск осуществиться в Google Chrome.
isRemote
параметр определят будет ли запуск выполняться на той же машине, где выполняется .NET процесс или использовать удалённый сервер, указанный в параметре remoteConnectionUrl
.
driverSettings
секция файла settings.json предоставляет возможность устанавливать необходимые capabilities, options или start arguments для web driver.
Для получения допустимых аргументов и опций обратитесь к официальным источникам от разработчиков браузеров. Например, для chrome: run-chromium-with-flags
Мы постарались здесь описать особенности работы с IExplorer самостоятельно ввиду разрозненности информации на этот счёт в интернете.
settings.json содержит секцию timeouts
, которая включает в себя набор параметров, связанных с различного рода таймаутами, используемыми в решении.
Все параметры данной конфигурации используются для инициализации объекта класса TimeoutConfiguration, доступного впоследствии путем обращения AqualityServices.Get<ITimeoutConfiguration>()
.
Ниже приводится описание параметров из секции timeouts
c их назначением:
-
timeoutImplicit
= 0 секунд - значение неявного ожидания web driver'а Selenium Implicit Wait -
timeoutCondition
= 15 секунд - время ожидания событий в решении. К событиям относятся ожидание элементов или их состояния -
timeoutScript
= 10 секунд - данное значение служит лимитом выполнения скриптов с использованием метода WebDriver ExecuteAsyncScript -
timeoutPageLoad
= 30 секунд - время ожидания загрузки страницы -
timeoutPollingInterval
= 300 миллисекунд - интервал опроса в при явных ожиданиях -
timeoutCommand
= 60 секунд - максимальное время ожидания выполнения каждой команды, отправляемой web driver'у
В рамках решения все ожидания элементов выполняются при помощи Explicit Wait. Перед ожиданием элемента значение implicit wait будет установлено в ноль принудительно, независимо от того, что находится в конфигурации. Использование двух типов ожиданий не рекомендовано, так как может приводить к некорректному поведению.
Секция retry
файла settings.json отвечает за конфигурацию количества попыток выполнения операций над элементом. Все операции над элементами (нажатия, ввод текста и т.п.) могут быть выполнены повторно в случае неудачи. Данная логика заложена в классе ElementActionRetrier посредством которого выполняются любые операции.
Параметр number
означает количество предпринимаемых попыток выполнить операцию прежде чем выбросить исключение.
Параметр pollingInterval
означает интервал между попытками в миллисекундах.
ElementActionRetrier автоматически отлавливает исключения StaleElementReferenceException
и InvalidElementStateException
и повторяет попытку снова.
Решение поддерживает логирование выполняемых операций (взаимодействие с браузером, элементами страницы). Пример логирования:
2019-07-18 10:14:08 INFO - Label 'First product' :: Moving mouse to element
Логирование поддерживается на языках:
Значение языка логирования устанавливается в параметре logger.language.
Для того, чтобы настроить запуск на удалённом сервере Selenium Grid (Selenoid, Zalenium) или на платформах вроде BrowserStack, Saucelabs и т.д., необходимо в конфигурационном файле settings.json установить корректное значение URL для подключения к сервису в параметр remoteConnectionUrl
, а также убедиться, что параметр isRemote
равен true.
Например, для BrowserStack параметр может иметь вид https://USERNAME:[email protected]/wd/hub.
isElementHighlightEnabled
параметр отвечает за необходимость подсветки элементов веб страницы с которыми производится работа. Включение опции позволяет более явно наблюдать за действиями теста.
Доступ к данным из конфигурационного файла обеспечивается посредством обращения к методам экземпляра класса Configuration. Например:
var browserName = AqualityServices.Get<IBrowserProfile>().BrowserName;
Данная конструкция вернёт значение параметра browserName
из settings.json
файла.
Решение основано на технологии dependency injection где класс AqualityServices предоставляет нам доступ ко всем зарегистрированным зависимостям. Для примера, если Вам необходимо получить экземпляр браузера:
var browser = AqualityServices.Browser;
Чтобы получить доступ к любым другим зависимостям aquality можно воспользоваться методом public static T Get<T>()
, к примеру:
var browserProfile = AqualityServices.Get<IBrowserProfile>();
Все зарегистрированные в aquality зависимости можно увидеть в классе BrowserStartup.
Класс Browser, являющийся своего рода фасадом для Selenium WebDriver и содержит методы работы с окном браузера и непосредственно с WebDriver (например, navigate, maximize window и т.д.). Написание скрипта начинается с создания экземпляра Browser
- подробнее об этом ниже.
Решение предполагает наличие единственного экземпляра класса Browser
(содержит поле типа RemoteWebDriver
) в рамках одного потока исполнения. Как правило тесты работают с одним экземпляром браузера и данный подход оптимален.
Если вы решаете задачу использования в рамках одного теста несколько браузеров, каждый браузер необходимо создавать в отдельном потоке. С примерами работы в многопоточном режиме можно ознакомиться здесь BrowserConcurrencyTests.cs
Если вы используете стандартные средства параллелизации, предоставляемые такими инструментами как NUnit, MSTest и т.п., для каждого потока будет автоматически создан свой экземпляр Browser
.
Существует несколько вариантов инициализации Browser
. Основной способ базируется на использовании класса AqualityServices
и его статического свойства Browser
. Ниже рассматриваются варианты работы с AqualityServices
.
Если нам необходимо получить браузер с данными из конфигурационного settings файла то достаточно просто произвести вызов:
var browser = AqualityServices.Browser;
Первый вызов Browser
создаст необходимый экземпляр с WebDriver (откроется окно браузера, если только не задан headless режим). Все последующие обращения в рамках одного потока будут работать с созданным экземпляром.
Неявно для пользователя AqualityServices
предоставляет Browser
посредством обращения к фабрике браузеров. В решение существуют следующие реализации фабрик:
-
LocalBrowserFactory - для создания браузера в случае использования параметра
isRemote=false
-
RemoteBrowserFactory - для создания браузера в случае использования параметра
isRemote=true
Каждая реализация фабрики реализует интерфейс IBrowserFactory
с единственным свойством Browser
. Это предоставляет возможность реализовать свою фабрику.
Чтобы Browser
возвращала Browser
, созданный вашей реализацией фабрики, необходимо до первого вызова Browser
установить в AqualityServices
свою реализацию фабрики,
используя метод SetFactory(IBrowserFactory browserFactory)
.
Примеры использования собственной фабрики можно рассмотреть здесь CustomBrowserFactoryTests
Если по каким либо причинам вы решите отказаться от использования фабрик, у вас остается возможность создать экземпляр Browser
самостоятельно и в дальнейшем установить его в AqualityServices.Browser
.
Класс Browser
содержит публичный конструктор со следующей сигнатурой public Browser(RemoteWebDriver webDriver, IConfiguration configuration)
.
При этом, для создания собственной реализации IConfiguration
, вам по-прежнему доступно использование уже имеющихся реализаций IDriverSettings
, ITimeoutConfiguration
и т.д.
В процессе создания Browser
и в частности WebDriver используются реализации интерфейса IDriverSettings
. Реализация включает свойство DriverOptions
, которые впоследствии устанавливаются в WebDriver при его инициализации.
Если вы пользуетесь BrowserFactory
по умолчанию, список options будет сформирован на основании информации в settings.json файле.
Пример с использованием пользовательских options представлен здесь: Should_BePossibleToUse_CustomFactory.
Не редким случаем является необходимость скачивать файлы в браузере и впоследствии производить с ними работу. Чтобы получить текущую директорию для загрузки можно воспользоваться свойством DownloadDirectory
экземпляра Browser
.
Для поддержания этой функциональности интерфейс IDriverSettings
обязывает реализовать свойство string DownloadDir { get; }
. Если вы используете одну из уже реализованных BrowserFactory
, то директорию для загрузки файлов необходимо указать в файле settings.json.
Например:
{
"download.default_directory": "//home//selenium//downloads"
}
Обратите внимание, что ключ download.default_directory
отличается для разных браузеров. Изучить какие ключи актуальны для каких браузеров можно в соответствующих классах:
В настоящее время решение поддерживает загрузку файлов только в браузерах Chrome, Firefox, Safari.
Класс Browser
предоставляет методы работы с Alerts:
AqualityServices.Browser.HandleAlert(AlertAction.Accept);
Больше примеров использования можно найти здесь AlertTests.
Для получения снимков экрана класс Browser
предоставляет метод
var screenshot = AqualityServices.Browser.GetScreenshot();
Более подробный пример использования смотрите в тесте Should_BePossibleTo_TakeScreenshot.
Класс Browser
предоставляет методы для работы с вкладками:
AqualityServices.Browser.Tabs().SwitchToLastTab();
Больше примеров использования можно найти здесь BrowserTabsTests.
Когда Browser
инициализирован и осуществлен переход на требуемую страницу можно начинать работу с элементами этой страницы.
Решение включает класс ElementFactory, который отвечает за создание элемента необходимого типа. Ниже приводится пример получения ITextBox
:
var elementFactory = AqualityServices.Get<IElementFactory>();
var usernameTextBox = elementFactory.GetTextBox(By.Id("username"), "Username");
ElementFactory
способна создавать объекты любых классов, реализующих интерфейс IElement
.
ElementFactory
содержит ряд методов, которые возвращают реализации IElement
, имеющиеся по умолчанию в решении (IButton
, ITextBox
, ICheckBox
и т.д.). Обратите внимание, что работа с элементами ведется через интерфейсы, чтобы пользователь обращал внимание только на функциональность, но не на реализацию.
Пользователь имеет возможность создать свой элемент или расширить имеющийся по умолчанию. Для этих целей ElementFactory
предоставляет метод T GetCustomElement<T>
. Достаточно лишь реализовать IElement
интерфейс или расширить имеющийся класс элемента. С примером расширения и последующего использования можно ознакомиться в классе CustomElementTests.
Для получения списка элементов ElementFactory
предоставляет метод FindElements
, использование которого демонстрируется ниже:
var checkBoxes = elementFactory.FindElements<ICheckBox>(By.XPath("//*[@class='checkbox']"));
С другими примерами работы с ElementFactory
и элементами можно ознакомиться здесь Element Tests.
При работе с элементами страницы в зависимости от задачи как правило ожидается либо только нахождение элемента который виден на странице (Displayed), либо который хотя бы присутствует в верстке (Exists in any state).
Для получения и последующей работы с данными типами элементов методы ElementFactory
имеют не обязательный параметр state
. Например,
var link = elementFactory.GetLink(By.Id("redirect"), "Link", state: ElementState.Displayed);
При работе с элементами частой является ситуация проверки состояния элемента или ожидание желаемого состояния.
Данная функциональность реализуется посредством класса ElementStateProvider. Доступ к экземпляру этого класса можно получить посредством свойства State
у элемента:
UserNameTextBox.State.WaitForEnabled();
var isDisplayed = UserNameTextBox.State.IsDisplayed;
Больше примеров можно увидеть в классе ElementStateTests.
Основное назначение решения - помощь в автоматизации тестирования Web приложений. Существует практика автоматизации с использованием подхода Page Objects. Для поддержания и расширения данного подхода решение предлагает к использованию класс Form, который может служить родительским классом для всех описываемых страниц и форм приложения. Пример использования:
public class SliderForm : Form
{
public SliderForm() : base(By.Id("slider_row"), "Slider")
{
}
}
Здесь Id = "slider_row"
устанавливает локатор, который будет использован при проверке открытия страницы/формы, используя свойство IsDisplayed
класса Form.
Пример теста с использованием Page Objects здесь ShoppingCartTests.
При необходимости выполнить какой либо JavaScript на открытой странице можно воспользоваться одним из методов ExecuteScript
класса Browser
.
Решение содержит достаточное количество наиболее используемых скриптов при выполнении автоматизации тестирования. Список скриптов представлен перечислением JavaScript. Сами скрипты расположены в директории ресурсов JavaScripts.
Примеры использования метода имеются в классе BrowserTests.
Также существует перегрузка для передачи файла с JavaScript или непосредственно строки со скриптом.
В случае необходимости ожидания выполнения какого-либо условия можно использовать IConditionalWait, который по умолчанию реализован тут. Пример ниже показывает как можно получить доступ к реализации этого интерфейса:
AqualityServices.ConditionalWait
Все методы класса ждут выполнения условия, но по разному возвращают значения и обрабатывают ошибки:
-
public void WaitForTrue
- выкидывает ошибку в случае, если условие не выполнилось, ничего не возвращает. Не использует ожидание WebDriver'a. -
bool WaitFor
- возвращает true если условие выполнилось или false если не выполнилось, ошибок не выбрасывает. -
public T WaitFor<T>
- использует ожидание WebDriver'a, возвращает объект T или ошибку, в случае если условие не выполнилось.