Each Text Content

📺 Find this recipe explained in the video The Text Of Each Element Starts With The Given Stringopen in new window.

List updates after a delay

<label>State name</label>
<input name="state" />
<ul id="search-results"></ul>
<script>
  document
    .querySelector('[name=state]')
    .addEventListener('input', (e) => {
      if (e.target.value === 'mi') {
        setTimeout(() => {
          document.getElementById('search-results').innerHTML = `
            <li>Michigan</li>
            <li>Minnesota</li>
            <li>Mississippi</li>
            <li>Missouri</li>
          `
        }, 1000)
      }
    })
</script>
cy.get('[name=state]').type('mi')

After slight delay, the results should show several states. Each state name should start with "Mi" (let's ignore case)

cy.get('#search-results li')
  .should('exist')
  .each((li, k) => {
    const name = li.text()
    expect(name, `state ${k + 1}`).to.match(/^mi/i)
  })

Using cypress-map queries

If we are using cypress-mapopen in new window plugin, we have additional queries that make writing the test much simpler.

<label>State name</label>
<input name="state" />
<ul id="search-results"></ul>
<script>
  document
    .querySelector('[name=state]')
    .addEventListener('input', (e) => {
      if (e.target.value === 'mi') {
        setTimeout(() => {
          document.getElementById('search-results').innerHTML = `
            <li>Michigan</li>
            <li>Minnesota</li>
            <li>Mississippi</li>
            <li>Missouri</li>
          `
        }, 1000)
      }
    })
</script>
cy.get('[name=state]').type('mi')

After slight delay, the results should show several states. Each state name should start with "Mi" (let's ignore case). We query the DOM, map each found element to its text content, then check each string.

cy.get('#search-results li')
  .map('innerText')
  .should((names) => {
    names.forEach((name, k) => {
      expect(name, `state ${k + 1}`).to.match(/^mi/i)
    })
  })

Using cypress-map queries and chai-each assertion

📺 Watch this recipe explained in the video Chai-each Plugin Exampleopen in new window.

We can refactor the above solution using chai-eachopen in new window assertion library.

<label>State name</label>
<input name="state" />
<ul id="search-results"></ul>
<script>
  document
    .querySelector('[name=state]')
    .addEventListener('input', (e) => {
      if (e.target.value === 'mi') {
        setTimeout(() => {
          document.getElementById('search-results').innerHTML = `
            <li>Michigan</li>
            <li>Minnesota</li>
            <li>Mississippi</li>
            <li>Missouri</li>
          `
        }, 1000)
      }
    })
</script>
cy.get('[name=state]').type('mi')

After slight delay, the results should show several states. Each state name should start with "Mi" (let's ignore case). We query the DOM, map each found element to its text content, then check each string using each.match assertion:

cy.get('#search-results li')
  .map('innerText')
  .should('each.match', /^mi/i)

Important: Cypress UI shows the last assertion only, but it does validate every string in the string[] subject.