Protractor является инструментом для энд-ту-энд тестирования Angular-приложений и тесно интегрирован с особенностями Angular, такими как биндинги, директивы и зоны. Одним из ключевых аспектов является работа с Angular биндингами — механизмом, через который данные в модели приложения отображаются в интерфейсе.
В Angular биндинги бывают нескольких типов:
{{ }}) —
используется для вывода значений переменных в шаблоне.[property]="expression") — связывает свойства DOM
с переменной компонента.[(ngModel)]) —
обеспечивает синхронизацию данных между моделью и представлением.Protractor предоставляет специализированные селекторы и методы для работы с этими биндингами, что упрощает доступ к элементам и их проверку в тестах.
Protractor расширяет стандартные селекторы WebDriver следующими возможностями:
by.binding(bindingName) — ищет
элементы по интерполяционному биндингу.by.exactBinding(bindingName) — ищет
элемент, текст которого точно соответствует имени биндинга.Примеры использования:
// Поиск элемента с биндингом "username"
let usernameField = element(by.binding('username'));
// Проверка текста в элементе
expect(usernameField.getText()).toEqual('Иван');
Разница между by.binding и
by.exactBinding заключается в том, что первый
метод ищет частичное совпадение текста, а второй — только точное. Это
важно при тестировании динамически формируемого контента, когда в
элементе могут присутствовать дополнительные строки или пробелы.
Часто необходимо не просто проверять текст, но и значения свойств
DOM-элементов, привязанных к модели Angular. В Protractor это делается с
помощью метода getAttribute():
let inputField = element(by.model('user.email'));
expect(inputField.getAttribute('value')).toBe('user@example.com');
Здесь by.model('user.email') используется для поиска
элементов, связанных с двухсторонним биндингом ngModel. Это
позволяет проверять состояние полей формы, не взаимодействуя напрямую с
DOM-структурой.
Angular обновляет DOM асинхронно, поэтому Protractor автоматически
синхронизируется с Angular через
waitForAngular. Это означает, что тесты не
требуют явных задержек для ожидания обновления данных:
element(by.binding('username')).getText().then(function(text) {
expect(text).toEqual('Пётр');
});
Тем не менее, для сложных приложений с сторонними библиотеками или нестандартными зонами Angular может понадобиться ручная синхронизация:
browser.waitForAngularEnabled(false); // Отключение синхронизации
Angular часто использует динамические биндинги, например, в циклах
*ngFor или при условном рендеринге *ngIf. Для
их тестирования в Protractor применяются коллекции:
let items = element.all(by.binding('item.name'));
expect(items.count()).toBe(3);
expect(items.get(0).getText()).toBe('Элемент 1');
Метод element.all возвращает массив элементов,
удовлетворяющих биндингу, что позволяет проверять количество и значения
динамически создаваемых элементов.
Для элементов с вложенными биндингами или сложной структурой DOM возможно комбинирование локаторов:
let userInfo = element(by.css('.user-info')).element(by.binding('user.name'));
expect(userInfo.getText()).toBe('Анна');
Использование цепочек локаторов позволяет точно ориентироваться на нужный элемент в структуре, где несколько элементов могут иметь одинаковый биндинг.
by.binding или
by.exactBinding вместо универсальных CSS-селекторов для
Angular-приложений — это делает тесты более устойчивыми к изменению
разметки.by.model, чтобы проверять
значения и изменять их через .sendKeys().element.all и проверки .count() для надежной
валидации списка элементов.browser.waitForAngularEnabled(false) и явные ожидания для
синхронизации.Protractor обеспечивает мощный и удобный доступ к Angular биндингам, что позволяет создавать стабильные и читаемые тесты. Внимательное использование локаторов и понимание асинхронного поведения Angular — ключ к качественному автоматизированному тестированию.