Protractor — это фреймворк для автоматизированного тестирования веб-приложений на Angular и не только. Его ядро строится на WebDriver, стандарте взаимодействия с браузерами, который обеспечивает управление веб-страницами на уровне пользователя. Понимание работы WebDriver является ключевым для эффективного использования Protractor и написания надёжных тестов.
WebDriver представляет собой протокол, позволяющий управлять браузером через HTTP-запросы. Архитектура включает несколько ключевых компонентов:
Клиентская библиотека (Client Library) В Protractor это JavaScript-обертка над WebDriver API. Она предоставляет удобные методы для поиска элементов, выполнения действий, ожидания состояний и проверки условий.
Сервер WebDriver (WebDriver Server / Selenium Server) При использовании Protractor напрямую или через Selenium Server запросы от клиентской библиотеки отправляются на сервер, который преобразует их в команды для конкретного браузера.
Браузерный драйвер (Browser Driver) Каждый
браузер имеет свой драйвер: chromedriver для Chrome,
geckodriver для Firefox и т.д. Драйвер принимает команды
сервера и управляет браузером на низком уровне, эмулируя действия
пользователя.
Важно: WebDriver абстрагирует различия между браузерами, предоставляя единый API, что делает тесты кросс-браузерными.
При запуске теста Protractor инициирует сессию WebDriver, которая представляет собой уникальное соединение с браузером. Каждая сессия имеет идентификатор и хранит состояние браузера (открытые страницы, куки, локальное хранилище).
Команды WebDriver делятся на несколько категорий:
Навигация: переход по URL, обновление страницы, возврат назад или вперёд в истории браузера.
browser.get('https://example.com');
browser.navigate().back();
browser.refresh();Манипуляции с элементами: ввод текста, клик, выбор опций, скроллинг.
element(by.css('#input')).sendKeys('тест');
element(by.buttonText('Отправить')).click();Состояние страницы и ожидания: проверка видимости, доступности элементов, ожидание загрузки Angular.
let button = element(by.id('submit'));
browser.wait(protractor.ExpectedConditions.elementToBeClickable(button), 5000);Работа с окнами и фреймами: переключение между вкладками, окнами, iframe.
Каждая команда отправляется через HTTP-запрос к драйверу, который
исполняет действие и возвращает результат. Этот процесс асинхронный,
поэтому в Protractor все операции поддерживают промисы и методы
async/await.
WebDriver работает на основе промисов, что отражает задержку между отправкой команды и получением результата из браузера. Protractor использует этот механизм для синхронизации действий, особенно при работе с Angular-приложениями, где страница может менять состояние динамически.
Пример правильной синхронизации:
it('должен открыть страницу и проверить заголовок', async () => {
await browser.get('https://example.com');
let title = await browser.getTitle();
expect(title).toEqual('Example Domain');
});
Важно понимать, что без await или then
результат команды может быть не получен к моменту проверки, что приведёт
к нестабильным тестам.
Protractor умеет автоматически ожидать завершения всех
асинхронных операций Angular, таких как HTTP-запросы или
таймеры. Для этого используется механизм
Angular Testability, который отслеживает состояние
приложения и блокирует выполнение тестов до завершения всех
процессов.
Если тестируется не-Angular приложение, нужно явно отключить эту синхронизацию:
browser.waitForAngularEnabled(false);
WebDriver позволяет отслеживать каждый шаг теста. В Protractor можно включить логирование HTTP-запросов и команд, что помогает отлаживать ошибки взаимодействия с браузером.
Также существует возможность делать скриншоты при падении теста:
browser.takeScreenshot().then((png) => {
require('fs').writeFileSync('screenshot.png', png, {encoding: 'base64'});
});
Selenium Grid.await, иначе тесты будут нестабильны.async/await или промисы.Эффективное использование WebDriver позволяет создавать надёжные, повторяемые и кросс-браузерные тесты, минимизируя влияние динамических изменений страниц и особенностей конкретного браузера.