Q26 of 48 · Cypress

How do you assert on a list of items in the DOM?

CypressMidcypressassertionslistsmid

Short answer

Short answer: Use `cy.get(selector)` and assert on the count with `should('have.length', N)`, then iterate with `.each` to assert per-item, or extract texts with `.invoke('map', ...)` and assert the array. Avoid `.then` snapshots if items can change after load.

Detail

Three patterns cover most list assertions:

1. Count.

cy.get('[data-test=cart-row]').should('have.length', 3);

This retries — Cypress re-queries until the count matches or the timeout expires. Useful when items appear asynchronously.

2. Per-item assertions with .each.

const expected = ['Apples', 'Bread', 'Cheese'];
cy.get('[data-test=cart-row] [data-test=name]')
  .each(($el, i) => {
    cy.wrap($el).should('have.text', expected[i]);
  });

.each iterates inside the queue, so each cy.wrap(...).should(...) retries.

3. Extract texts and assert the whole array.

cy.get('[data-test=cart-row] [data-test=name]')
  .then(($els) => [...$els].map((el) => el.innerText))
  .should('deep.equal', ['Apples', 'Bread', 'Cheese']);

This snapshots once inside .then. If items can still change, prefer .each so each assertion retries independently.

For ordering-sensitive checks, the array form is cleanest. For "this list contains these items in any order", use .should('include.members', [...]) after extracting.

Avoid the anti-pattern of asserting on each item by index in separate commands:

// Verbose and brittle
cy.get('[data-test=cart-row]').eq(0).should('contain', 'Apples');
cy.get('[data-test=cart-row]').eq(1).should('contain', 'Bread');

Use .each or array extraction instead.

// EXAMPLE

// Count
cy.get('[data-test=cart-row]').should('have.length', 3);

// Per-item with retry
const expected = ['Apples', 'Bread', 'Cheese'];
cy.get('[data-test=cart-row] [data-test=name]').each(($el, i) => {
  cy.wrap($el).should('have.text', expected[i]);
});

// Whole-array deep equal
cy.get('[data-test=cart-row] [data-test=name]')
  .then(($els) => Cypress.$.makeArray($els).map((el) => el.innerText))
  .should('deep.equal', ['Apples', 'Bread', 'Cheese']);

// Order-insensitive — does the cart contain these items?
cy.get('[data-test=cart-row] [data-test=name]')
  .then(($els) => Cypress.$.makeArray($els).map((el) => el.innerText))
  .should('include.members', ['Apples', 'Cheese']);

// WHAT INTERVIEWERS LOOK FOR

Knowing all three patterns (count, `.each`, array extraction) and which retries vs snapshots.

// COMMON PITFALL

Using `cy.get(...).eq(N)` repeatedly — it's verbose, brittle, and harder to debug than `.each`.