Parent, child и dual команды

В Cypress тестирование строится на взаимодействии с элементами DOM, где ключевую роль играют цепочки команд. Понимание Parent, Child и Dual команд позволяет создавать более точные, устойчивые и читаемые тесты, минимизируя вероятность ошибок из-за изменения структуры страницы.


Parent команды

Parent команды направлены на выборку элементов верхнего уровня, относительно которых будут выполняться последующие действия. Обычно это команды, возвращающие коллекцию элементов, из которых можно производить фильтрацию или навигацию. Основная команда — cy.get().

cy.get('.list-item')
  .should('have.length', 5)

Здесь .list-item выбирает все элементы с указанным классом. Parent команды не ограничивают глубину поиска, они ищут элементы по всему DOM или по заданному контейнеру.

Другие важные Parent команды:

  • cy.contains() — находит элемент по тексту.
  • cy.find() — поиск внутри уже выбранного контейнера, может рассматриваться как child относительно parent, если используется внутри цепочки.
  • cy.root() — возвращает корневой элемент текущей области поиска.

Особенность Parent команд заключается в возврате jQuery-объекта, что позволяет применять цепочку фильтров и проверок:

cy.get('.menu')
  .find('li')
  .should('have.length.greaterThan', 3)

Child команды

Child команды предназначены для выбора дочерних элементов внутри родителя. Основные способы навигации к детям:

  • children() — возвращает прямых потомков выбранного элемента.
  • first(), last() — выбирают первый или последний дочерний элемент.
  • eq(index) — выбор дочернего элемента по индексу.

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

cy.get('.menu')
  .children('li')
  .first()
  .click()

Здесь:

  1. cy.get('.menu') — родительский контейнер.
  2. children('li') — выбор всех дочерних элементов li.
  3. first() — выбор первого элемента.
  4. click() — взаимодействие с выбранным элементом.

Child команды ограничивают область поиска выбранным родителем, что повышает точность теста и снижает риск ложноположительных результатов, особенно при сложных DOM-структурах.


Dual команды

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

Примеры Dual команд:

  • within() — ограничивает область поиска дочерними элементами, выполняя вложенные команды внутри блока.
  • closest() — поднимается к ближайшему родителю, соответствующему селектору.
  • parent() — возвращает непосредственного родителя выбранного элемента.

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

cy.get('.form')
  .within(() => {
    cy.get('input[name="email"]').type('user@example.com')
    cy.get('input[name="password"]').type('password123')
    cy.get('button[type="submit"]').click()
  })

Здесь:

  • .form — контейнер, ограничивающий область поиска.
  • Внутри within все команды применяются только к дочерним элементам этого контейнера.
  • within экономит необходимость писать длинные селекторы, повышая читаемость и устойчивость теста.

Использование closest():

cy.get('.error-message')
  .closest('.form-group')
  .should('have.class', 'has-error')
  • .error-message — выбранный элемент ошибки.
  • closest('.form-group') — поднимается к ближайшему контейнеру формы.
  • Проверка класса подтверждает наличие ошибки на уровне родителя.

Особенности взаимодействия Parent, Child и Dual команд

  1. Цепочка команд всегда возвращает объект jQuery, позволяя продолжать навигацию и применять проверки.
  2. Parent команды задают область поиска, Child команды уточняют её, а Dual команды позволяют работать с родителем и детьми одновременно.
  3. Использование Dual команд особенно важно при динамическом DOM, когда структура элементов может изменяться, а селекторы должны оставаться устойчивыми.
  4. Комбинирование команд повышает читаемость и надежность тестов:
cy.get('.container')
  .children('.card')
  .first()
  .within(() => {
    cy.get('.title').should('contain.text', 'Welcome')
    cy.get('button').click()
  })
  • .container — Parent
  • .children('.card').first() — Child
  • within() — Dual для работы с потомками внутри выбранной карточки

Рекомендации по использованию

  • Предпочтительно использовать Child и Dual команды для конкретизации поиска, чтобы уменьшить зависимость теста от внешнего DOM.
  • Parent команды подходят для широкого захвата элементов при проверке общего количества или существования элементов.
  • Использование within() делает тесты локализованными и менее подверженными ошибкам, особенно при работе с формами и повторяющимися блоками.
  • Методы навигации parent(), children(), closest() позволяют в точности управлять уровнем DOM, что критично для сложных интерфейсов.