Разделы портала

Онлайн-тренинги

.
Основы Cypress: проверка существования элемента
09.09.2021 00:00

Автор: Филип Рик (Filip Hric)
Оригинал статьи
Перевод: Ольга Алифанова

При тестировании приложения с Cypress вам в первую очередь может понадобиться проверка присутствия элемента. В этой статье я хочу рассмотреть, как проверить, существует ли элемент и видим ли он, а также обсудить некоторые хитрости таких тестов.

В ходе статьи я буду использовать мое приложение-клон Trello. Его можно скачать с GitHub и следовать за мной.

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

Начнем с самого простого сценария. На странице есть список досок. Я проверю видимость моей доски при помощи следующего кода:

it('has a board', () => {
 
    cy
        .visit('/');
 
    cy
        .get('[data-cy=board-item]')
         .should('be.visible');
 
});

Наш тест делает именно то, чего мы ожидаем. Он проверит видимость элемента, и тест будет пройден.

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

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

Теперь проверим нечто прямо противоположное. Удалю мою доску и проверю, что она невидима:

it('has a board', () => {
 
     cy
         .visit('/');
 
    cy
         .get('[data-cy=board-item]')
         .should('not.be.visible');
 
});

Удивительно, но теперь наш тест падает. Это вызвано тем, что Cypress проверяет, скрыт ли элемент, проверяя CSS-свойства вроде display: none или visibility: hidden. Но в нашем случае элемент, который мы проверяем, вообще отсутствует в нашем приложении. Поэтому наш тест падает. Вместо проверки видимости нужно убедиться в несуществовании, should('not.exist').

Будьте осторожны с негативными утверждениями – иногда причиной для несуществования может быть то, что элемент еще не отрисовался из-за лага сети. Если вам нужно убедиться, что элемент прекратил существование, лучше сначала проверить, что он видим (или существует):

it('deletes a board', () => {
 
     cy
         .visit('/');
 
    cy
         .get('[data-cy=board-item]')
         .should('exist');
 
    cy
          .request('DELETE', '/boards/2626653025');
 
     cy
           .get('[data-cy=board-item]')
           .should('not.exist');
 
});

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

Создадим длинный  список досок. Я проверю видимость всех этих досок. Происходит нечто неожиданное – тест срабатывает, но я получаю предупреждение для команды .get():

 

Это стоит держать в уме, проверяя несколько элементов разом. Важно понимать, что считается видимым элементом с точки зрения браузера. В нашем приложении есть элемент-контейнер со свойством overflow: scroll. Если бы это было не так, Cypress объявил бы все элементы видимыми. Даже последний.

overflow: scroll дает тут существенную разницу. Без него мой список растягивался бы так, как бы я пожелал. Даже если я не могу видеть все элементы из-за высоты окна браузера, они все равно считались бы видимыми. Но все меняется, если я считаю, что пользователю нужно скроллить, чтобы увидеть элементы, превышающие высоту контейнера. Некоторые элементы могут быть невидимыми.

Если расположение элементов на странице важно для вашего сценария (к примеру, домашняя страница должна быть точна до пикселя), лучше проверить это визуальным тестом. Человеческое понимание видимости может быть чуть иным в этих случаях.

it('has a board', () => {
 
    cy
        .visit('/');
 
    cy
        .get('[data-cy=board-item]')
        .last()
        .should('not.be.visible');
 
});

Этот тест пройдет. Элемент невидим из-за свойства контейнера overflow: scroll.

Видимость лучше объяснить при помощи простой демонстрации. Возьмем такой тест:

it('has a board', () => {
 
    cy
           .visit('/');
 
    cy
          .get('[data-cy=login-menu]')
          .click();
 
     cy
          .get('[data-cy=board-item]')
          .eq(1)
         .should('be.visible')
         .click();
 
});

Наш тест упадет на строке 14, а не 13. Наше утверждение should('be.visible') будет верным, потому что элемент не скрыт скроллом, и его видно. Но действие .click() не сработает, потому что элемент на доске перекрыт модулем авторизации.

Обсудить в форуме