Автокомплиты и suggestions

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


Работа с элементами автокомплита

Автокомплиты обычно состоят из двух ключевых элементов:

  1. Поле ввода (input) — принимает текст, который пользователь вводит.
  2. Список suggestions — отображает варианты на основе введенного текста.

Для Cypress важно корректно идентифицировать оба элемента. Использование уникальных селекторов или data-атрибутов (data-cy, data-test) обеспечивает стабильность тестов, даже при изменении структуры DOM.

Пример базовой структуры:

<input type="text" id="city-input" />
<ul id="city-suggestions">
  <li>Москва</li>
  <li>Московская область</li>
</ul>

Ввод текста и проверка появления suggestions

Чтобы проверить, что suggestions появляются корректно, необходимо симулировать ввод текста и дождаться появления списка. Cypress предоставляет цепочку команд для таких действий:

cy.get('#city-input')
  .type('Мос')
cy.get('#city-suggestions')
  .should('be.visible')
  .and('contain', 'Москва')
  .and('contain', 'Московская область')

Ключевые моменты:

  • Использование type() для симуляции ввода.
  • Проверка видимости списка с помощью should('be.visible').
  • Проверка содержимого через contain или have.length для количества элементов.

Обработка асинхронных запросов

Часто suggestions подгружаются через API-запросы. В Cypress это требует ожидания ответа сервера. Можно использовать cy.intercept() для перехвата и контроля запросов:

cy.intercept('GET', '/api/cities?query=Mos', { fixture: 'cities.json' }).as('getCities')

cy.get('#city-input').type('Mos')

cy.wait('@getCities')

cy.get('#city-suggestions li')
  .should('have.length', 2)
  .first()
  .should('contain.text', 'Москва')

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

  • cy.intercept() позволяет подменять ответы сервера или проверять реальные запросы.
  • cy.wait('@alias') гарантирует, что тест не продолжится до получения данных.
  • Использование fixtures упрощает тестирование предсказуемых данных.

Выбор элемента из списка suggestions

После появления списка важно проверить, что пользователь может выбрать элемент, и событие выбора корректно обрабатывается.

cy.get('#city-suggestions li')
  .contains('Москва')
  .click()

cy.get('#city-input').should('have.value', 'Москва')

Важные аспекты:

  • Использование contains() для выбора элемента по тексту.
  • Проверка, что значение поля ввода обновилось после клика.
  • Можно также проверять вызов событий или отправку формы после выбора.

Навигация с клавиатуры

Многие автокомплиты поддерживают выбор через клавиши ArrowDown и Enter. Cypress позволяет симулировать эти действия:

cy.get('#city-input')
  .type('Мос')
  .type('{downarrow}{downarrow}{enter}')

cy.get('#city-input').should('have.value', 'Московская область')

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

  • {downarrow} и {enter} имитируют навигацию и выбор.
  • Позволяет тестировать удобство использования без мыши.

Проверка отсутствия suggestions

Необходимо проверять, что suggestions исчезают при очистке поля или при вводе текста, не соответствующего ни одному варианту:

cy.get('#city-input')
  .clear()
cy.get('#city-suggestions').should('not.exist')

Ключевые моменты:

  • clear() очищает текстовое поле.
  • should('not.exist') проверяет, что список удалился из DOM.

Тестирование граничных случаев

Для надежности автокомплита важно учитывать:

  • Пустой ввод — список suggestions не появляется.
  • Специальные символы — корректная обработка или отсутствие ошибок.
  • Большое количество результатов — проверка скролла или пагинации в списке.
  • Быстрый ввод текста — suggestions должны обновляться без заиканий.

Пример теста для проверки быстрого ввода:

cy.get('#city-input')
  .type('Мо{backspace}ск')
cy.get('#city-suggestions li')
  .should('contain.text', 'Москва')

Работа с debounce и задержками

Многие автокомплиты используют debounce для уменьшения количества запросов. Cypress автоматически не учитывает задержку, поэтому нужно либо увеличивать таймауты, либо контролировать запрос через cy.intercept():

cy.intercept('/api/cities*').as('getCities')
cy.get('#city-input').type('Мос', { delay: 200 })
cy.wait('@getCities')

Советы:

  • delay помогает симулировать реальный пользовательский ввод.
  • Управление alias через cy.wait() обеспечивает стабильность теста при асинхронных данных.

Проверка accessibility и aria-атрибутов

Современные автокомплиты используют ARIA для доступности. Проверка этих атрибутов важна:

cy.get('#city-input').should('have.attr', 'aria-autocomplete', 'list')
cy.get('#city-suggestions').should('have.attr', 'role', 'listbox')
cy.get('#city-suggestions li').first().should('have.attr', 'role', 'option')

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

  • Проверка aria-autocomplete, role="listbox" и role="option" обеспечивает соответствие стандартам доступности.
  • В сочетании с визуальными проверками тест гарантирует корректную работу для всех пользователей.

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