Проверка видимости элементов

В автоматизированном тестировании веб-приложений критически важно определять не только наличие элемента на странице, но и его видимость для пользователя. Эффективная проверка видимости позволяет гарантировать корректное взаимодействие с интерфейсом и предотвращает ошибки, связанные с попыткой работы с невидимыми элементами. В Protractor это достигается сочетанием WebDriver API, методов ElementFinder и утилит ExpectedConditions.


Основные методы проверки видимости

  1. isDisplayed()

Метод isDisplayed() проверяет, видим ли элемент на странице. Он возвращает промис, который резолвится в true или false. В отличие от проверки наличия через isPresent(), isDisplayed() учитывает CSS-свойства display, visibility и размеры элемента.

Пример использования:

let button = element(by.css('.submit-btn'));

button.isDisplayed().then(function(visible) {
    console.log('Кнопка видима: ' + visible);
});

Особенности:

  • Возвращает false, если элемент скрыт (display: none, visibility: hidden).
  • Выбрасывает ошибку, если элемент отсутствует в DOM. Чтобы избежать этого, сначала можно проверить isPresent().

  1. isPresent() + isDisplayed()

Для безопасной проверки видимости лучше использовать сочетание:

let dialog = element(by.css('.modal-dialog'));

dialog.isPresent().then(function(present) {
    if (present) {
        dialog.isDisplayed().then(function(visible) {
            console.log('Диалог видим: ' + visible);
        });
    } else {
        console.log('Диалог отсутствует в DOM');
    }
});

Такой подход предотвращает исключения при попытке вызвать isDisplayed() на несуществующем элементе.


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

Protractor предоставляет набор готовых условий для удобного ожидания видимости элементов через browser.wait(). Ключевой объект — protractor.ExpectedConditions (EC).

Основные методы EC для видимости:

  • visibilityOf(element) — возвращает функцию, которая резолвится, когда элемент видим.
  • invisibilityOf(element) — ожидает, пока элемент станет невидимым или исчезнет из DOM.

Пример ожидания:

let EC = protractor.ExpectedConditions;
let loader = element(by.css('.loading-spinner'));

// Ожидаем, пока спиннер исчезнет
browser.wait(EC.invisibilityOf(loader), 5000, 'Спиннер не исчез за 5 секунд');

Преимущества:

  • Исключает необходимость ручного создания циклов ожидания.
  • Улучшает стабильность тестов при динамических интерфейсах.
  • Позволяет задавать таймауты и кастомные сообщения ошибок.

Проверка видимости группы элементов

Иногда требуется убедиться, что несколько элементов видимы одновременно. Для этого можно использовать комбинацию map и Promise.all:

let items = element.all(by.css('.list-item'));

Promise.all(items.map(item => item.isDisplayed())).then(results => {
    results.forEach((visible, index) => {
        console.log(`Элемент ${index + 1} видим: ${visible}`);
    });
});

Такой подход подходит для тестирования таблиц, списков и галерей.


Отслеживание динамических изменений

В веб-приложениях элементы часто меняют видимость динамически. Protractor позволяет проверять это без использования sleep(), применяя ExpectedConditions с повторным ожиданием:

let notification = element(by.css('.toast-message'));
let EC = protractor.ExpectedConditions;

// Ожидание появления уведомления
browser.wait(EC.visibilityOf(notification), 3000, 'Уведомление не появилось');

// Ожидание исчезновения уведомления
browser.wait(EC.invisibilityOf(notification), 5000, 'Уведомление не скрыто');

Такой метод обеспечивает точное управление временем ожидания и предотвращает нестабильность тестов при асинхронных обновлениях интерфейса.


Частые ошибки при проверке видимости

  1. Попытка вызвать isDisplayed() на несуществующем элементе. Решение: использовать isPresent() или ExpectedConditions.presenceOf().
  2. Игнорирование CSS-свойств opacity, которые делают элемент визуально прозрачным, но технически видимым. В этом случае isDisplayed() вернет true.
  3. Использование sleep() вместо browser.wait() для динамических элементов, что снижает надежность тестов.
  4. Проверка видимости элемента внутри iframe без переключения контекста с помощью browser.switchTo().frame().

Проверка видимости через CSS-селекторы

Иногда необходимо проверить, виден ли элемент в конкретной области или с определенными стилями:

let banner = element(by.css('.promo-banner'));

banner.getCssValue('display').then(display => {
    console.log('Display:', display); // none или block
});

banner.getCssValue('visibility').then(visibility => {
    console.log('Visibility:', visibility); // hidden или visible
});

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


Вывод

Проверка видимости элементов в Protractor — это комплексная задача, требующая внимательного использования isDisplayed(), isPresent(), ExpectedConditions и методов работы с CSS. Грамотно построенные проверки повышают надежность тестов, позволяют корректно работать с динамическими интерфейсами и минимизируют вероятность ошибок при взаимодействии с элементами страницы.