Методы взаимодействия: click()

Метод click() в Protractor является базовым инструментом для имитации действия пользователя по щелчку на веб-элемент. Он позволяет тестам эмулировать взаимодействие с кнопками, ссылками, чекбоксами и другими элементами интерфейса, которые реагируют на событие click. Несмотря на кажущуюся простоту, правильное использование click() требует понимания особенностей асинхронной модели Protractor, работы с элементами DOM и управления ожиданиями.


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

element(by.css('button.submit')).click();

Здесь element(by.css('button.submit')) возвращает объект ElementFinder, представляющий элемент на странице, а метод click() инициирует клик.

Ключевой момент: click() возвращает Promise, поэтому для корректной работы в асинхронных тестах нужно использовать await или цепочку then():

await element(by.css('button.submit')).click();

// или
element(by.css('button.submit')).click().then(() => {
    console.log('Клик выполнен');
});

Взаимодействие с видимыми и невидимыми элементами

Protractor использует WebDriverJS, который взаимодействует с элементами, видимыми на странице. Если элемент скрыт (display: none, visibility: hidden) или перекрыт другим элементом, вызов click() приведет к ошибке.

Для проверки видимости перед кликом применяются методы:

const btn = element(by.id('save'));
await btn.isDisplayed().then(displayed => {
    if (displayed) {
        btn.click();
    }
});

Или с использованием await:

const btn = element(by.id('save'));
if (await btn.isDisplayed()) {
    await btn.click();
}

Ожидания перед кликом

Одной из частых проблем является попытка клика по элементу, который ещё не готов к взаимодействию. Для решения применяются ожидания (ExpectedConditions):

const EC = protractor.ExpectedConditions;
const btn = element(by.id('save'));

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

Пояснение: elementToBeClickable проверяет одновременно видимость элемента и его интерактивность. Таймаут в 5000 миллисекунд позволяет дождаться появления элемента, предотвращая ошибки.


Клики по ссылкам и кнопкам

click() одинаково хорошо работает для кнопок и ссылок, но поведение может отличаться:

  • Для <button> или <input type="button"> событие click инициирует обработчики JS.
  • Для <a href=""> клик инициирует переход по URL. В Protractor важно управлять ожиданием перехода:
await element(by.linkText('Перейти')).click();
await browser.wait(EC.urlContains('targetPage'), 5000);

Клики на чекбоксы и радио-кнопки

При работе с чекбоксами и радио-кнопками важно учитывать их текущее состояние:

const checkbox = element(by.id('agree'));
if (!await checkbox.isSelected()) {
    await checkbox.click();
}

isSelected() возвращает true, если элемент уже отмечен, что позволяет избежать лишних кликов.


Клики по динамическим элементам

В приложениях с динамическим DOM (например, Angular SPA) элемент может появиться после асинхронного запроса. Для безопасного клика рекомендуется использовать ExpectedConditions:

const EC = protractor.ExpectedConditions;
const dynamicButton = element(by.css('.dynamic-btn'));

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

Примечание: presenceOf проверяет наличие элемента в DOM, elementToBeClickable — возможность взаимодействия.


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

Иногда click() не срабатывает из-за перекрытия элементов или специфики CSS-анимаций. В таких случаях используют JavaScript-клик:

const btn = element(by.css('.hidden-button'));
await browser.executeScript("arguments[0].click();", btn.getWebElement());

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


Обработка ошибок при клике

Наиболее частые ошибки при использовании click():

  1. ElementNotVisibleError — элемент невидим.
  2. ElementNotInteractableError — элемент не кликабелен.
  3. StaleElementReferenceError — элемент обновился в DOM после поиска.

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


Советы по эффективному использованию

  • Всегда использовать await для синхронизации клика с другими действиями.
  • Проверять видимость и кликабельность элементов перед вызовом click().
  • Для динамического DOM применять ожидания presenceOf и elementToBeClickable.
  • Для тестов с Angular использовать Protractor-функции синхронизации с зоной Angular (browser.waitForAngular()).
  • JavaScript-клик использовать только при явной необходимости обхода ограничений интерфейса.

Метод click() — это центральный инструмент взаимодействия с UI в Protractor. Его корректное использование требует сочетания асинхронного контроля, проверок состояния элементов и грамотного применения ожиданий для стабильности и надежности тестов.