Ожидание изменения текста элемента

В тестировании веб-приложений одним из часто встречающихся сценариев является необходимость дождаться изменения текста в определённом элементе страницы. Это особенно актуально при работе с динамическим контентом, который обновляется через AJAX-запросы, WebSocket-сообщения или анимации. Protractor предоставляет гибкие инструменты для реализации таких ожиданий, основанные на использовании Expected Conditions (EC) и асинхронного API.


Использование ExpectedConditions.textToBePresentInElement

Protractor содержит встроенные условия, позволяющие проверять наличие определённого текста в элементе. Ключевая функция для этой задачи — ExpectedConditions.textToBePresentInElement.

const EC = protractor.ExpectedConditions;
const myElement = element(by.id('status'));

browser.wait(EC.textToBePresentInElement(myElement, 'Готово'), 5000, 'Текст не изменился на "Готово"');
  • EC.textToBePresentInElement(elementFinder, text): возвращает функцию, которая проверяет, содержит ли элемент указанный текст.
  • browser.wait(condition, timeout, message): ожидает выполнения условия в течение заданного времени. Если условие не выполняется, выбрасывается ошибка с указанным сообщением.
  • 5000: время ожидания в миллисекундах.

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


Динамическая проверка текста с использованием функции обратного вызова

Если требуется дождаться любого изменения текста, а не конкретного значения, можно использовать функцию обратного вызова в browser.wait.

const myElement = element(by.css('.message'));
let initialText;

myElement.getText().then(text => {
    initialText = text;
});

browser.wait(() => {
    return myElement.getText().then(currentText => currentText !== initialText);
}, 5000, 'Текст элемента не изменился в течение 5 секунд');
  • Сначала сохраняется исходный текст элемента.
  • Затем browser.wait проверяет, что текущее значение текста отличается от исходного.
  • Этот подход универсален для сценариев, когда новое значение заранее неизвестно.

Использование асинхронного синтаксиса async/await

В современных версиях Protractor рекомендуется использовать синтаксис async/await для улучшения читаемости кода:

const EC = protractor.ExpectedConditions;
const myElement = element(by.css('.notification'));

async function waitForTextChange() {
    const initialText = await myElement.getText();

    await browser.wait(async () => {
        const currentText = await myElement.getText();
        return currentText !== initialText;
    }, 5000, 'Текст элемента не изменился');
}

await waitForTextChange();
  • Асинхронный синтаксис позволяет избавиться от вложенных .then() и сделать код линейным.
  • Повышается читаемость и снижается вероятность ошибок при работе с промисами.

Проверка текста с регулярным выражением

В некоторых случаях текст может меняться динамически, например, включать переменные значения (Загрузка 20%, Загрузка 40% и т.д.). В таких сценариях удобнее использовать регулярные выражения:

const myElement = element(by.css('.progress'));
const regex = /Загрузка \d+%/;

await browser.wait(async () => {
    const text = await myElement.getText();
    return regex.test(text);
}, 5000, 'Текст элемента не соответствует ожидаемому шаблону');
  • Регулярное выражение позволяет проверять шаблон текста, а не точное значение.
  • Такой подход эффективен для индикаторов прогресса, счетчиков или сообщений с динамическими данными.

Комбинация с другими условиями

Protractor позволяет комбинировать проверку текста с другими условиями, например, видимостью элемента или доступностью для взаимодействия:

const EC = protractor.ExpectedConditions;
const myElement = element(by.id('alert'));

await browser.wait(
    EC.and(
        EC.visibilityOf(myElement),
        async () => {
            const text = await myElement.getText();
            return text.includes('Ошибка');
        }
    ),
    5000,
    'Элемент не виден или текст не содержит "Ошибка"'
);
  • EC.and(condition1, condition2): объединяет несколько условий.
  • Это позволяет гарантировать, что проверка текста выполняется только для видимого элемента, исключая ложные срабатывания.

Важные рекомендации

  1. Избегать статических ожиданий с помощью browser.sleep(). Они увеличивают время выполнения тестов и делают их нестабильными.
  2. Использовать browser.wait с EC или пользовательскими функциями для надежного синхронного поведения.
  3. Всегда указывать адекватный таймаут. 3–5 секунд подходит для большинства сценариев, но для медленных операций может потребоваться больше.
  4. Для массовых обновлений текста применять функции обратного вызова с проверкой на отличие от предыдущего значения.

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