Protractor является инструментом для End-to-End (E2E) тестирования веб-приложений на базе Angular и AngularJS, но также поддерживает тестирование любых веб-приложений, взаимодействующих с браузером через WebDriver. Его главная цель — проверять работу приложения в условиях, максимально приближенных к реальным сценариям использования.
Protractor построен поверх Selenium WebDriver, обеспечивая управление браузерами и взаимодействие с DOM. Отличительной особенностью является встроенная поддержка Angular, что позволяет:
$http и $timeout.by.model,
by.binding, by.repeater) для более удобного
поиска элементов.Компоненты архитектуры:
protractor.conf.js) — задаёт параметры
тестирования: браузеры, пути к тестам, фреймворк (Jasmine, Mocha или
Cucumber), таймауты.Установка выполняется через npm:
npm install -g protractor
После установки необходимо обновить WebDriver:
webdriver-manager update
Запуск локального сервера Selenium:
webdriver-manager start
Конфигурационный файл может выглядеть следующим образом:
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['tests/**/*.spec.js'],
capabilities: {
browserName: 'chrome'
},
framework: 'jasmine',
jasmineNodeOpts: {
defaultTimeoutInterval: 30000
},
onPrepare: function() {
browser.waitForAngularEnabled(true);
}
};
Ключевые моменты конфигурации:
seleniumAddress — адрес работающего Selenium
сервера.specs — путь к файлам тестов.capabilities — параметры браузера.framework — используемый фреймворк тестирования.onPrepare — функция, выполняющаяся перед запуском
тестов, например, включение ожиданий Angular.Protractor обычно используют с Jasmine или Mocha. Типичный тест выглядит так:
describe('Тестирование формы входа', function() {
it('Должен открыть страницу и проверить заголовок', async function() {
await browser.get('https://example.com/login');
const title = await browser.getTitle();
expect(title).toEqual('Login Page');
});
it('Должен ввести данные и отправить форму', async function() {
const username = element(by.id('username'));
const password = element(by.id('password'));
const submitBtn = element(by.buttonText('Войти'));
await username.sendKeys('testuser');
await password.sendKeys('password123');
await submitBtn.click();
const successMessage = element(by.css('.success'));
expect(await successMessage.getText()).toContain('Успешный вход');
});
});
Особенности синтаксиса:
element(by.selector) — поиск одного элемента.element.all(by.selector) — поиск коллекции
элементов.await используется для асинхронных операций (в
Protractor версии 6+ рекомендуется явное ожидание).expect() — проверки состояния.Protractor обеспечивает автоматическую синхронизацию с Angular, но для элементов вне Angular или динамически загружаемых данных необходимо использовать Explicit Wait:
const EC = protractor.ExpectedConditions;
const button = element(by.id('loadButton'));
await browser.wait(EC.elementToBeClickable(button), 5000);
await button.click();
Типичные ожидания:
elementToBeClickable — элемент кликабелен.visibilityOf — элемент видим.presenceOf — элемент присутствует в DOM.Для не-Angular приложений требуется отключить ожидание Angular:
browser.waitForAngularEnabled(false);
Это необходимо, чтобы Protractor не ждал Angular событий, которых нет.
Для поддержки масштабируемости тестов рекомендуется использовать Page Object Pattern. Пример:
// loginPage.js
class LoginPage {
constructor() {
this.username = element(by.id('username'));
this.password = element(by.id('password'));
this.submitBtn = element(by.buttonText('Войти'));
}
async login(user, pass) {
await this.username.sendKeys(user);
await this.password.sendKeys(pass);
await this.submitBtn.click();
}
}
module.exports = new LoginPage();
// login.spec.js
const loginPage = require('./loginPage');
describe('Тест формы входа', function() {
it('Успешный вход', async function() {
await browser.get('https://example.com/login');
await loginPage.login('testuser', 'password123');
const successMessage = element(by.css('.success'));
expect(await successMessage.getText()).toContain('Успешный вход');
});
});
Преимущества Page Object Pattern:
Protractor поддерживает:
browser.sleep(ms) — временная пауза (не рекомендуется
использовать часто).browser.takeScreenshot() — создание скриншотов для
отчётности.console.log() внутри тестов для проверки данных.Для сложных сценариев полезно комбинировать с внешними библиотеками отчётности, например, Allure, Protractor Reporter.
Protractor поддерживает параллельное выполнение
через параметры multiCapabilities:
multiCapabilities: [
{ browserName: 'chrome' },
{ browserName: 'firefox' }
]
Это позволяет ускорять прогон тестов и проверять совместимость с разными браузерами.
element(...).click() без проверки видимости может привести
к флейку.Protractor легко интегрируется с системами CI/CD, такими как Jenkins, GitLab CI, GitHub Actions. Важно:
chromeOptions: { args: ['--headless'] }) для экономии
ресурсов.Такой подход позволяет строить надежное, масштабируемое и поддерживаемое E2E тестирование веб-приложений, обеспечивая высокое качество и стабильность функционала.