Angular — это фронтенд-фреймворк для построения динамических веб-приложений, основанный на компонентной архитектуре и двухстороннем связывании данных (two-way data binding). Его ключевая особенность — реактивность: изменение данных модели автоматически отражается в пользовательском интерфейсе, а действия пользователя могут мгновенно обновлять состояние приложения. Angular использует Zone.js для отслеживания асинхронных операций, таких как HTTP-запросы, таймеры и события пользовательского интерфейса, что позволяет фреймворку управлять жизненным циклом изменений без вмешательства разработчика.
Для автоматизированного тестирования Angular-приложений важна способность тестового фреймворка понимать внутренние механизмы приложения. Здесь на помощь приходит Protractor.
Protractor — это энд-ту-энд тестовый фреймворк для приложений на Angular, построенный поверх WebDriverJS. Его основная задача — позволить тестам работать синхронно с асинхронной природой Angular. Это достигается с помощью нескольких ключевых механизмов:
Protractor использует встроенный механизм Angular-specific wait, который позволяет тесту ждать завершения всех асинхронных операций в Angular перед выполнением действий.
Ключевые моменты:
browser.sleep() или длинных таймаутов для
синхронизации.Protractor расширяет стандартные селекторы WebDriver, добавляя Angular-специфичные локаторы:
by.model('modelName') — поиск по привязке модели
(ng-model).by.binding('expression') — поиск элементов по
Angular-выражениям, отображающим данные
({{expression}}).by.repeater('item in items') — работа с повторяющимися
элементами (ng-repeat).by.cssContainingText('css', 'text') — поиск по CSS с
фильтрацией по тексту внутри Angular-элемента.Использование этих локаторов делает тесты более устойчивыми к изменениям разметки и позволяет напрямую работать с данными приложения, а не только с DOM.
Angular использует зоны (Zones) для отслеживания асинхронной
активности. Protractor интегрируется с этим механизмом через
browser.waitForAngular(), что позволяет:
Чтобы Protractor корректно видел Angular, требуется правильная конфигурация:
Включение Angular-синхронизации По умолчанию Protractor ожидает Angular-приложение. Для не-Angular страниц нужно отключить ожидание:
browser.waitForAngularEnabled(false);Использование Testability API Angular 2+
предоставляет getTestability для проверки готовности
приложения. Protractor автоматически использует этот API, если
приложение корректно интегрировано с Angular.
Конфигурация селекторов Для старых
AngularJS-приложений можно использовать by.model,
by.binding и by.repeater. Для современных
Angular (2+) рекомендуется использовать data-testid
атрибуты или стандартные CSS-селекторы вместе с Angular-aware
синхронизацией.
// Ожидание, пока приложение станет стабильным
browser.waitForAngular();
// Поиск инпута по модели и ввод данных
let username = element(by.model('user.name'));
username.sendKeys('test_user');
// Проверка данных, привязанных к выражению
let greeting = element(by.binding('user.greeting'));
expect(greeting.getText()).toEqual('Hello, test_user!');
// Работа с повторяющимся списком
let items = element.all(by.repeater('item in items'));
expect(items.count()).toBe(5);
В этом примере видно, как Protractor напрямую взаимодействует с Angular-логикой, а не только с HTML-структурой.
by.model, by.binding) не работают в Angular
2+.browser.wait или browser.sleep), если
Testability API недоступен.Protractor обеспечивает глубокую интеграцию с Angular, делая тестирование реактивных приложений простым и предсказуемым. Понимание того, как фреймворк видит Angular, позволяет писать стабильные и надежные тесты без постоянных проблем с асинхронностью.