В Protractor массивы элементов представлены типом
ElementArrayFinder. Он используется при работе с
несколькими DOM-элементами, найденными с помощью
element.all().
const items = element.all(by.css('.list-item'));
ElementArrayFinder не является обычным массивом
JavaScript. Это ленивый объект, который выполняет поиск элементов только
в момент обращения к данным. Большинство операций над ним возвращают
Promise, что необходимо учитывать при проверках.
Основные способы получения данных из массива элементов:
getText()getAttribute()count()map()filter()Самая базовая проверка — соответствие ожидаемому количеству элементов.
expect(items.count()).toEqual(5);
Метод count() возвращает
Promise<number>, однако Protractor автоматически
разрешает его в матчере expect. Эта особенность основана на
использовании Control Flow (актуально для старых версий) или async/await
в современных конфигурациях.
Проверка количества часто используется:
Для проверки текста всех элементов используется метод
getText(), возвращающий массив строк.
expect(items.getText()).toEqual([
'Apple',
'Banana',
'Orange'
]);
Проверка чувствительна к:
При необходимости допускается частичное сравнение.
expect(items.getText()).toContain('Apple');
Когда важен сам факт присутствия значения, а не полный список,
используется toContain.
expect(items.getText()).toContain('Admin');
Такой подход применяется при:
Проверка отрицательных сценариев так же важна, как и позитивных.
expect(items.getText()).not.toContain('Guest');
Это позволяет удостовериться, что элемент не отображается:
Иногда порядок элементов не имеет значения. В этом случае сравнение выполняется после сортировки.
items.getText().then(texts => {
expect(texts.sort()).toEqual(['A', 'B', 'C']);
});
Такой подход особенно актуален:
Метод map() позволяет извлекать конкретные данные из
каждого элемента.
const prices = items.map(el => el.getAttribute('data-price'));
Проверка значений:
prices.then(values => {
expect(values).toEqual(['10', '20', '30']);
});
Используется при:
Метод filter() возвращает новый
ElementArrayFinder, содержащий только элементы,
удовлетворяющие условию.
const activeItems = items.filter(el =>
el.getAttribute('class').then(cls => cls.includes('active'))
);
Проверка количества отфильтрованных элементов:
expect(activeItems.count()).toBe(2);
Фильтрация позволяет:
Для последовательной проверки всех элементов используется
each().
items.each(el => {
expect(el.isDisplayed()).toBe(true);
});
Такой подход полезен при:
isEnabled);Современный стиль написания тестов предполагает отказ от Control Flow.
const texts = await items.getText();
expect(texts.length).toBeGreaterThan(0);
expect(texts).toContain('Dashboard');
Преимущества:
Иногда требуется проверить только часть массива.
items.getText().then(texts => {
const firstThree = texts.slice(0, 3);
expect(firstThree).toEqual(['One', 'Two', 'Three']);
});
Применяется при:
При работе с асинхронными обновлениями необходимо использовать ожидания.
const EC = protractor.ExpectedConditions;
browser.wait(
EC.visibilityOf(items.first()),
5000
);
После ожидания выполняется проверка массива.
expect(items.count()).toBeGreaterThan(0);
Это предотвращает:
Неправильное ожидание массива вместо Promise
const texts = items.getText();
expect(texts.length).toBe(3); // ошибка
Игнорирование асинхронности
items.getText();
expect(true).toBe(true); // проверка выполняется раньше
Сравнение ElementArrayFinder с обычным массивом
expect(items).toEqual(['a', 'b']); // некорректно
Корректная работа с массивами в Protractor всегда предполагает явное получение данных и учет асинхронной модели выполнения.
Проверки массивов используются в большинстве UI-тестов:
Грамотное использование ElementArrayFinder, асинхронных
проверок и матчеров Jasmine позволяет создавать стабильные и
предсказуемые тесты даже для сложных динамических интерфейсов.