Protractor является инструментом для автоматизированного тестирования веб-приложений на базе Angular. Одной из его ключевых особенностей является поддержка Angular-специфичных локаторов, которые позволяют взаимодействовать с элементами страницы, используя внутренние особенности фреймворка Angular. Это обеспечивает более надежное и точное определение элементов по сравнению с традиционными CSS или XPath локаторами.
1. by.model() Используется для поиска
элементов, связанных с ng-model. Такой локатор особенно
полезен при работе с формами, полями ввода и элементами, где данные
двусторонне связываются с моделью Angular.
Пример использования:
let usernameInput = element(by.model('user.name'));
usernameInput.sendKeys('admin');
Здесь user.name — это имя модели в Angular-контроллере.
Любое изменение значения в этом поле автоматически синхронизируется с
моделью.
2. by.binding() Позволяет находить
элементы, в которых отображаются данные через биндинг Angular
({{ }}). Это полезно для проверки текста на странице,
который динамически обновляется.
Пример:
let greeting = element(by.binding('user.greeting'));
expect(greeting.getText()).toEqual('Привет, админ!');
Если значение в модели user.greeting изменится, локатор
найдет обновленный текст без необходимости дополнительного поиска по
DOM.
3. by.repeater() Используется для
работы с повторяющимися элементами, определенными через директиву
ng-repeat. Позволяет получать как отдельные элементы
списка, так и все элементы целиком.
Примеры:
// Получение всех элементов списка
let items = element.all(by.repeater('item in items'));
// Получение первого элемента списка
let firstItem = element(by.repeater('item in items').row(0));
// Получение конкретной колонки в ряду
let price = element(by.repeater('item in items').row(1).column('item.price'));
Использование by.repeater() обеспечивает точное
взаимодействие с динамическими коллекциями данных Angular без сложных
CSS-селекторов.
4. by.options() Применяется для выбора
<option> внутри <select>
элементов, где значения генерируются через ng-options.
Пример:
let dropdown = element(by.model('user.role'));
dropdown.element(by.options('role.id as role.name for role in roles')).click();
Такой подход гарантирует, что будет выбран именно тот элемент, который соответствует модели Angular, даже если порядок элементов изменится.
5. by.cssContainingText() и
by.exactBinding()
by.cssContainingText() часто используется вместе с Angular
для поиска элементов по тексту, особенно когда биндинги сложные или
содержат HTML. by.exactBinding() применяется для точного
соответствия биндинга.
Примеры:
// Любой элемент с текстом "Привет"
let greeting = element(by.cssContainingText('.greeting', 'Привет'));
// Элемент с точным биндингом
let username = element(by.exactBinding('user.name'));
Одним из преимуществ Protractor является автоматическая синхронизация с Angular. Это означает, что перед взаимодействием с элементами Protractor ожидает завершения всех асинхронных операций Angular, включая HTTP-запросы и таймеры. Благодаря этому локаторы работают надежнее, и не возникает ошибок, связанных с тем, что элемент еще не отрендерился.
Пример:
element(by.model('user.name')).sendKeys('admin');
// Не требуется использовать sleep или explicit wait для ожидания загрузки Angular
by.model().by.binding() или by.exactBinding().by.repeater().<select> —
by.options().Использование Angular-локаторов повышает устойчивость тестов, делает их более читаемыми и уменьшает зависимость от структуры HTML, которая может изменяться при редизайне интерфейса.
by.css, by.id).by.repeater() вместе с .row() и
.column() для точного выбора.Angular-локаторы предоставляют мощный инструмент для создания надежных и стабильных автоматизированных тестов, позволяя работать напрямую с моделью и структурой данных приложения.