jQuery :contains and custom pseudo-selectors

You can select multiple elements using partial text match and jQuery :containsopen in new window pseudo-selector. You can even make your own new pseudo-selectors.

<ul id="people">
  <li>John Resig</li>
  <li>George Martin</li>
  <li>Malcom john Sinclair</li>
  <li>J. Ohn</li>
</ul>
cy.get('#people li').should('have.length', 4)

Cypress query command cy.containsopen in new window returns a single element with the partial text match.

cy.log('**cy.contains**')
cy.contains('li', 'John').should('have.text', 'John Resig')

By default cy.contains is case-sensitive

cy.contains('li', 'john').should(
  'have.text',
  'Malcom john Sinclair',
)

You can tell cy.contains to ignore case

cy.contains('li', 'john', { matchCase: false }).should(
  'have.text',
  'John Resig',
)

Let's find all items with the text "John" in them, the case should match

cy.log('**jQuery :contains**')
cy.get('#people li:contains("John")').should('read', [
  'John Resig',
])

Let's ignore string case and find both "John" and "john" and even "jOhN". We can create a new jQuery pseudo-selector

Cypress.$.expr[':'].icontains = Cypress.$.expr.createPseudo(
  function (arg) {
    return function (elem) {
      return (
        Cypress.$(elem)
          .text()
          .toUpperCase()
          .indexOf(arg.toUpperCase()) >= 0
      )
    }
  },
)

Use the :icontains custom selector to find both items. I will use should read assertion from cypress-mapopen in new window to confirm the elements.

cy.get('#people li:icontains("John")').should('read', [
  'John Resig',
  'Malcom john Sinclair',
])