by.repeater() является локатором в Protractor,
предназначенным для работы с элементами, созданными с помощью директивы
ng-repeat в AngularJS. Эта директива позволяет
автоматически генерировать списки элементов на основе массивов или
коллекций объектов в модели Angular. Использование
by.repeater() обеспечивает точное и удобное взаимодействие
с повторяющимися элементами без необходимости вручную прописывать
сложные CSS или XPath-селекторы.
by.repeater() принимает строку, которая соответствует
синтаксису ng-repeat. Формат обычно следующий:
ng-repeat="item in items"
Для локатора в Protractor нужно передавать часть после
in или полное выражение. Например:
element.all(by.repeater('item in items'))
element.all() возвращает массив всех элементов,
соответствующих повторителю.Для работы с отдельным элементом из коллекции используется метод
get(index), где index — порядковый номер
элемента (нумерация с нуля):
let firstItem = element.all(by.repeater('item in items')).get(0);
let thirdItem = element.all(by.repeater('item in items')).get(2);
Это позволяет точно взаимодействовать с конкретным повторяющимся элементом, не затрагивая остальные.
Если повторитель создаёт таблицу или список с несколькими полями,
можно обращаться к отдельным колонкам с помощью метода
row().column():
let firstRowSecondColumn = element(by.repeater('item in items').row(0).column('name'));
row(index) возвращает строку с указанным индексом.column('fieldName') позволяет получить конкретное поле
внутри этой строки по имени из модели Angular
(item.name).Это особенно удобно для тестирования таблиц и списков, где важна структура данных.
Для проверки длины коллекции, сгенерированной ng-repeat,
используется свойство count():
let itemsCount = element.all(by.repeater('item in items')).count();
expect(itemsCount).toEqual(5);
count() возвращает Promise, поэтому в
современных версиях Protractor рекомендуется использовать
async/await:
const count = await element.all(by.repeater('item in items')).count();
if (count !== 5) {
throw new Error(`Ожидалось 5 элементов, найдено ${count}`);
}
Protractor позволяет применять фильтры к коллекции элементов, чтобы выбирать только те, которые соответствуют определённым условиям:
let filteredItems = element.all(by.repeater('item in items').row(0))
.filter(async (elem) => {
const text = await elem.getText();
return text.includes('Active');
});
filter() принимает функцию с проверкой каждого
элемента.Также возможен поиск текста конкретного повторителя:
const itemText = await element(by.repeater('item in items').row(1)).getText();
by.repeater() работает только с
AngularJS. В Angular 2+ и выше используется
*ngFor, для которого Protractor не предоставляет
встроенного локатора.ExpectedConditions) или методы
browser.wait(), чтобы элементы успели отобразиться перед
взаимодействием:const items = element.all(by.repeater('item in items'));
browser.wait(protractor.ExpectedConditions.visibilityOf(items.get(0)), 5000);
by.repeater() позволяет тестировать
динамические списки, где количество и содержимое
элементов может меняться во время работы приложения.Клик по определённому элементу:
await element.all(by.repeater('item in items'))
.get(2)
.click();
Проверка текста всех элементов повторителя:
const texts = await element.all(by.repeater('item in items')).getText();
expect(texts).toEqual(['Item 1', 'Item 2', 'Item 3']);
Работа с таблицей:
const secondRowFirstColumn = await element(by.repeater('user in users').row(1).column('username')).getText();
expect(secondRowFirstColumn).toBe('john_doe');
by.repeater() обеспечивает высокую точность и
удобство при тестировании динамических AngularJS-приложений. Он
минимизирует зависимость от сложных селекторов и делает код тестов более
читаемым и поддерживаемым. Особое внимание стоит уделять асинхронности,
фильтрации и работе с отдельными колонками таблиц для максимально
эффективного использования возможностей Protractor.