Проверка последовательности строк

Protractor — инструмент для end-to-end тестирования веб-приложений на Angular и других фронтенд-фреймворках. Одной из часто встречающихся задач является проверка последовательности строк, например, в списках, таблицах или выпадающих меню. Этот процесс требует понимания работы с элементами страницы, ожиданиями и асинхронностью в JavaScript.


Получение текста элементов

Для проверки последовательности строк первым шагом является извлечение текста из элементов. Protractor использует element и element.all для поиска элементов на странице.

let items = element.all(by.css('.item-class'));

items.getText().then(function(texts) {
    console.log(texts);
});

element.all(...).getText() возвращает массив строк, соответствующих тексту каждого элемента. Важно учитывать, что этот метод возвращает Promise, поэтому работа с результатом всегда должна выполняться через then или async/await.

const texts = await items.getText();
console.log(texts); // ['Первый', 'Второй', 'Третий']

Проверка точного соответствия последовательности

Если нужно убедиться, что строки идут в точной последовательности, применяется строгая проверка массивов.

const expected = ['Первый', 'Второй', 'Третий'];
const actual = await items.getText();

expect(actual).toEqual(expected);

Метод toEqual проверяет точное соответствие массивов, включая порядок элементов и их значения. Если хотя бы один элемент не совпадает или порядок нарушен, тест не пройдет.


Проверка наличия элементов без строгого порядка

Иногда важно лишь, чтобы определенные строки присутствовали, но порядок их следования не имеет значения.

const expected = ['Первый', 'Третий'];
const actual = await items.getText();

expected.forEach(value => {
    expect(actual).toContain(value);
});

Метод toContain проверяет, что элемент массива присутствует в другом массиве, без учета позиции.


Использование фильтров и функций сортировки

Для более сложных сценариев последовательность строк можно проверять после фильтрации или сортировки.

const actual = await items.getText();

// Сортировка по алфавиту
const sortedActual = actual.slice().sort();
const expectedSorted = ['Первый', 'Второй', 'Третий'].sort();

expect(sortedActual).toEqual(expectedSorted);

slice() создаёт копию массива, чтобы не изменять исходный порядок элементов на странице.


Проверка динамически обновляемых списков

Если список элементов обновляется динамически (например, через Angular binding), необходимо учитывать ожидания появления элементов. Protractor предоставляет ExpectedConditions для синхронизации:

const EC = protractor.ExpectedConditions;
const items = element.all(by.css('.item-class'));

await browser.wait(EC.visibilityOf(items.first()), 5000);

const actual = await items.getText();
expect(actual).toEqual(['Первый', 'Второй', 'Третий']);

Здесь browser.wait гарантирует, что элементы полностью загрузились перед извлечением текста.


Проверка последовательности строк в таблицах

Для таблиц текст элементов часто нужно получать из ячеек строк.

const rows = element.all(by.css('table tbody tr'));

for (let i = 0; i < await rows.count(); i++) {
    const cells = rows.get(i).all(by.css('td'));
    const texts = await cells.getText();
    console.log(`Строка ${i}:`, texts);
}

Для проверки конкретной колонки:

const columnTexts = await rows.map(async (row) => {
    return await row.element(by.css('td:nth-child(2)')).getText();
});

expect(columnTexts).toEqual(['Значение1', 'Значение2', 'Значение3']);

map позволяет пройтись по всем строкам и собрать значения из нужной колонки.


Асинхронность и порядок выполнения

Protractor работает с промисами, поэтому при проверке последовательности строк важно использовать async/await. Например, некорректная последовательность действий:

const actual = items.getText();
expect(actual).toEqual(['Первый', 'Второй', 'Третий']); // Ошибка

Правильный вариант:

const actual = await items.getText();
expect(actual).toEqual(['Первый', 'Второй', 'Третий']);

await гарантирует, что массив текста будет полностью загружен перед сравнением.


Использование кастомных функций сравнения

Для сложных случаев можно написать функцию для проверки последовательности:

function isSequenceCorrect(actual, expected) {
    if (actual.length !== expected.length) return false;
    for (let i = 0; i < actual.length; i++) {
        if (actual[i] !== expected[i]) return false;
    }
    return true;
}

const actual = await items.getText();
expect(isSequenceCorrect(actual, ['Первый', 'Второй', 'Третий'])).toBe(true);

Такой подход полезен при необходимости добавления логирования или подробной диагностики несоответствий.


Резюме ключевых техник

  • Использовать element.all(...).getText() для извлечения текста всех элементов.
  • Применять await для корректной работы с асинхронными операциями.
  • Сравнивать последовательность с помощью toEqual для строгого порядка.
  • Проверять наличие элементов без строгого порядка через toContain.
  • Для динамически обновляемых списков применять ExpectedConditions.
  • Для таблиц и сложных структур использовать вложенные element.all и map.
  • При необходимости создавать кастомные функции сравнения для гибкой проверки последовательности.