by.partialButtonText()

Метод by.partialButtonText() используется для поиска кнопок на веб-странице по частичному совпадению текста кнопки. Этот способ локализации элементов особенно полезен, когда полный текст кнопки может меняться, содержать динамические значения или быть слишком длинным для точного совпадения.

Основные особенности

  • Работает только с элементами <button> и <input> с типом button, submit или reset.
  • Позволяет искать кнопки по части текста, а не по полному содержимому.
  • Возвращает объект типа ElementFinder, который можно использовать для взаимодействий, таких как click(), getText() и т.д.
  • Синтаксис прост и лаконичен:
element(by.partialButtonText('Часть текста кнопки'));

Отличие от by.buttonText()

Метод by.buttonText() требует точного совпадения текста кнопки, тогда как by.partialButtonText() находит элемент, если в его тексте встречается заданная подстрока:

// Точная совпадение
element(by.buttonText('Отправить заявку'));

// Частичное совпадение
element(by.partialButtonText('Отправить'));

В первом случае локатор сработает только на кнопке с текстом «Отправить заявку». Во втором случае подойдет любая кнопка, содержащая слово «Отправить», например «Отправить форму» или «Отправить повторно».

Применение в тестах

Пример клика по кнопке с частичным текстом:

it('должен кликнуть по кнопке с частичным текстом', async () => {
    const submitButton = element(by.partialButtonText('Отправить'));
    await submitButton.click();
});

Получение текста кнопки:

it('должен получить текст кнопки', async () => {
    const buttonText = await element(by.partialButtonText('Отправить')).getText();
    console.log(buttonText); // Выведет полный текст кнопки, например 'Отправить форму'
});

Особенности работы с динамическим контентом

Когда текст кнопки динамически изменяется после загрузки страницы или на основе действий пользователя, by.partialButtonText() позволяет гибко находить элемент без необходимости точного совпадения. Для надёжного тестирования рекомендуется использовать ожидания:

const EC = protractor.ExpectedConditions;
const dynamicButton = element(by.partialButtonText('Продолжить'));

await browser.wait(EC.elementToBeClickable(dynamicButton), 5000);
await dynamicButton.click();

Это предотвращает ошибки, связанные с попыткой взаимодействия с ещё не отображенным или заблокированным элементом.

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

Метод можно применять для поиска нескольких кнопок одновременно. Если необходимо выбрать все кнопки, содержащие определённый текст:

const buttons = element.all(by.partialButtonText('Удалить'));
const count = await buttons.count();
console.log(`Найдено ${count} кнопок`);
await buttons.first().click();

Это полезно в интерфейсах с повторяющимися элементами, такими как таблицы или списки задач.

Советы по использованию

  • Для повышения стабильности тестов лучше избегать слишком общих подстрок, которые могут совпадать с несколькими кнопками.
  • В случае работы с мультиязычными интерфейсами можно использовать подстроки, независимые от языка, если полные тексты различаются.
  • Если кнопка имеет атрибут id или class, иногда лучше сочетать by.partialButtonText() с другими локаторами через element.all(...).filter(...) для точного выбора.
const specificButton = element.all(by.partialButtonText('Сохранить')).filter(async (btn) => {
    const parentClass = await btn.element(by.xpath('..')).getAttribute('class');
    return parentClass.includes('form-actions');
}).first();

await specificButton.click();

Совместимость и ограничения

  • Метод поддерживается во всех версиях Protractor, совместимых с Angular и не-Angular приложениями.
  • Не применим к элементам без текстового содержимого, например к иконкам <i> или <span> без текста.
  • Для <input> кнопок учитывается значение атрибута value вместо текста внутри тега.
// Для кнопки <input type="submit" value="Отправить форму">
element(by.partialButtonText('Отправить')); // Работает

Использование by.partialButtonText() обеспечивает гибкий и надёжный способ поиска кнопок, сокращает зависимость тестов от точных строк текста и повышает устойчивость к изменениям интерфейса.