by.buttonText()

Метод by.buttonText() используется для поиска кнопок на веб-странице по видимому тексту внутри элемента <button> или элементов с ролью кнопки (<input type="button">, <input type="submit">). Он является частью системы локаторов Protractor и строится поверх WebDriverJS, предоставляя удобный способ взаимодействия с кнопками без необходимости прописывать сложные CSS-селекторы или XPath-запросы.


Синтаксис и базовое использование

element(by.buttonText('Сохранить')).click();
  • element — функция для поиска одного элемента на странице.
  • by.buttonText('Сохранить') — локатор, который ищет элемент <button> или <input type="button"> с точным текстом Сохранить.
  • .click() — действие, выполняемое над найденной кнопкой.

Важно: текст должен совпадать точно, включая пробелы и регистр символов.


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

Метод by.partialButtonText() позволяет искать кнопки по частичному совпадению текста:

element(by.partialButtonText('Сохр')).click();

Этот локатор полезен, когда текст кнопки динамический или может содержать дополнительный текст, например: Сохранить изменения.

Ключевой момент: by.buttonText() всегда ищет полное совпадение, by.partialButtonText() — подстроку.


Примеры сложных сценариев

  1. Кнопки с пробелами или переносами строки
<button>
    Сохранить
    изменения
</button>

В этом случае by.buttonText('Сохранить изменения') не сработает напрямую, так как браузер воспринимает перенос строки как символ. Решение — использовать by.partialButtonText() или привести текст к одному формату в тесте.

element(by.partialButtonText('Сохранить')).click();
  1. Кнопки внутри динамически подгружаемых элементов

Protractor по умолчанию ожидает Angular-приложения, но если кнопка появляется через setTimeout или AJAX, необходимо использовать ожидания:

let saveButton = element(by.buttonText('Сохранить'));
browser.wait(protractor.ExpectedConditions.elementToBeClickable(saveButton), 5000);
saveButton.click();

Это гарантирует, что элемент доступен для взаимодействия.

  1. Кнопки с различными типами

Метод работает не только с <button>, но и с <input type="button">, <input type="submit">:

<input type="submit" value="Отправить">
element(by.buttonText('Отправить')).click();

Важный нюанс: значение атрибута value для input кнопок рассматривается как текст кнопки.


Совместимость с Angular и не-Angular страницами

Protractor по умолчанию рассчитан на Angular-приложения. Для не-Angular страниц необходимо отключить синхронизацию:

browser.waitForAngularEnabled(false);
element(by.buttonText('Войти')).click();

После выполнения действий можно снова включить синхронизацию для Angular:

browser.waitForAngularEnabled(true);

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

  • Всегда использовать browser.wait() с ExpectedConditions, чтобы избежать ElementNotInteractableError.
  • Предпочтительно комбинировать by.buttonText() с родительскими элементами, если на странице несколько кнопок с одинаковым текстом:
element(by.css('.form-container'))
       .element(by.buttonText('Сохранить'))
       .click();
  • Для кнопок с динамическим текстом использовать by.partialButtonText().
  • Избегать локаторов, зависящих от CSS-классов, если текст кнопки стабильный. Это повышает читаемость теста.

Отладка локаторов

Для проверки корректности локатора можно использовать консоль браузера или Protractor REPL:

element(by.buttonText('Сохранить')).getText().then(console.log);

Если элемент не найден, ошибка NoSuchElementError укажет, что текст или структура DOM не совпадают с ожиданиями. В таких случаях стоит проверить пробелы, переносы строк и регистр символов.


Примеры комплексного использования

describe('Тест формы', () => {
    it('должен нажать кнопку Сохранить', async () => {
        await browser.get('http://example.com/form');

        let saveButton = element(by.buttonText('Сохранить'));

        await browser.wait(protractor.ExpectedConditions.elementToBeClickable(saveButton), 5000);
        await saveButton.click();

        let successMessage = element(by.css('.alert-success'));
        expect(await successMessage.isDisplayed()).toBe(true);
    });
});

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


Использование by.buttonText() делает тесты более читаемыми и декларативными, так как сразу видно, какая именно кнопка взаимодействует с тестом. Правильное применение локатора повышает стабильность и сокращает количество ошибок, связанных с изменением структуры DOM.