Итерация по элементам таблицы

Protractor предоставляет удобные методы для работы с коллекциями элементов на веб-странице, что особенно актуально при автоматизации тестирования таблиц. Таблицы часто содержат динамически создаваемые строки и ячейки, поэтому важно понимать, как безопасно и эффективно перебирать их содержимое.

Получение коллекции строк и ячеек

Основной способ взаимодействия с элементами таблицы — использование element и element.all. Например, чтобы получить все строки таблицы:

let rows = element.all(by.css('table#myTable tbody tr'));

Каждая строка может содержать несколько ячеек, которые также можно получить через element.all относительно строки:

rows.each(async (row) => {
    let cells = row.all(by.css('td'));
    await cells.each(async (cell) => {
        let text = await cell.getText();
        console.log(text);
    });
});

Здесь используется метод each, который позволяет итерировать по коллекции элементов и выполнять асинхронные действия для каждой ячейки.

Использование методов get и count

Для более точного доступа к элементам коллекции применяются методы get и count. Метод count возвращает количество элементов в коллекции, что полезно для построения циклов:

let rowCount = await rows.count();
for (let i = 0; i < rowCount; i++) {
    let row = rows.get(i);
    let cellCount = await row.all(by.css('td')).count();
    for (let j = 0; j < cellCount; j++) {
        let cellText = await row.all(by.css('td')).get(j).getText();
        console.log(`Строка ${i}, Ячейка ${j}: ${cellText}`);
    }
}

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

Фильтрация и поиск элементов

Protractor поддерживает фильтрацию коллекций через метод filter. Это особенно полезно при поиске строк с определённым текстом или атрибутом:

let targetRows = rows.filter(async (row) => {
    let firstCellText = await row.element(by.css('td:first-child')).getText();
    return firstCellText.includes('Искомое значение');
});

await targetRows.each(async (row) => {
    let cellText = await row.element(by.css('td:last-child')).getText();
    console.log(cellText);
});

Метод filter возвращает новую коллекцию элементов, удовлетворяющих условию. При этом проверка может быть асинхронной, что делает фильтрацию гибкой и безопасной для динамического контента.

Работа с динамическими таблицами

Многие современные веб-приложения используют динамическую загрузку данных. Для таких таблиц важно учитывать ожидания элементов с помощью ExpectedConditions:

const EC = protractor.ExpectedConditions;
let table = element(by.id('myTable'));

await browser.wait(EC.presenceOf(table), 5000);

let rows = table.all(by.css('tbody tr'));
await rows.each(async (row) => {
    let cells = row.all(by.css('td'));
    for (let i = 0; i < await cells.count(); i++) {
        console.log(await cells.get(i).getText());
    }
});

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

Асинхронные операции и async/await

Все методы Protractor, возвращающие ElementFinder или ElementArrayFinder, являются промисами. Для корректной итерации по таблицам необходимо использовать async/await:

let rows = element.all(by.css('table#myTable tbody tr'));
for (let i = 0; i < await rows.count(); i++) {
    let row = rows.get(i);
    let cells = row.all(by.css('td'));
    for (let j = 0; j < await cells.count(); j++) {
        let text = await cells.get(j).getText();
        console.log(text);
    }
}

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

Сравнение и проверка содержимого

При итерации по таблицам часто возникает необходимость проверки значений ячеек. Для этого можно использовать стандартные методы сравнения:

let expectedValue = 'Тест';
let rows = element.all(by.css('table#myTable tbody tr'));

await rows.each(async (row) => {
    let firstCellText = await row.element(by.css('td:first-child')).getText();
    if (firstCellText === expectedValue) {
        console.log('Совпадение найдено');
    }
});

Подобные проверки можно комбинировать с фильтрацией, сортировкой и другими методами для создания сложных тестовых сценариев.

Итоговые рекомендации

  • Использовать element.all для работы с коллекциями строк и ячеек.
  • Применять each, get, count для безопасной и детальной итерации.
  • Фильтровать элементы через filter для поиска конкретных данных.
  • Использовать ExpectedConditions для работы с динамическими таблицами.
  • Всегда применять async/await для корректной работы с промисами.

Эти техники позволяют строить стабильные, масштабируемые тесты для любых таблиц в веб-приложениях на базе Protractor.