Non-breaking space

Dealing with   character aka Non-breaking spaceopen in new window.

Via cy.contains

When using cy.containsopen in new window command Cypress automatically converts the   entity into space character. Thus cy.contains finds element that include  .

<div data-testid="testattr">
  <div><span>GBP 0.50</span></div>
</div>
// both commands work
cy.contains('[data-testid=testattr]', 'GBP 0.50').should(
  'be.visible',
)
cy.get('[data-testid=testattr]')
  .filter(':contains("GBP 0.50")')
  .should('have.length', 1)

Asserting text

But if the HTML contains the whitespace special character &nbsp; then checking elements by text is tricky. See #9530open in new window for example. This is because .filteropen in new window uses jQuery :contains selectoropen in new window which uses literal text match.

<div data-testid="testattr">
  <div><span>GBP&nbsp;0.50</span></div>
</div>
cy.contains('[data-testid=testattr]', 'GBP 0.50').should(
  'be.visible',
)
<div data-testid="testattr">
  <div><span>GBP&nbsp;0.50</span></div>
</div>
// we can filter by text before the &nbsp;
cy.get('[data-testid=testattr]')
  .filter(':contains("GBP")')
  .should('have.length', 1)

cy.get('[data-testid=testattr]')
  // the following filter DOES NOT WORK
  // .filter(':contains("GBP 0.50")')
  // the following filter DOES NOT WORK
  // .filter(':contains("GBP&nbsp;0.50")')
  // but the Unicode representation of non-breaking space character works
  .filter(':contains("GBP\u00a00.50")')
  .should('have.length', 1)
<div data-testid="testattr">
  <div><span>GBP&nbsp;0.50</span></div>
</div>
cy.get('[data-testid=testattr]')
  .find('span')
  .should('have.text', 'GBP\u00a00.50')

Be careful with newlines and white space

<div id="network-message">
  Warning: this message has multiple spaces

  and empty lines
</div>
const message = `
  Warning: this message has multiple spaces

  and empty lines
`
// 🚨 INCORRECT, this will fail, demo only
// the newlines and empty lanes break the comparison
cy.contains('#network-message', message)
// ✅ use "should(callback)" function to get the full text
// and compare it ourselves without whitespace removal
// as it is done by the cy.contains command
cy.get('#network-message').should($el => {
  const text = $el.text()
  expect(text, 'the original text').to.equal(message)
})

Even better is to use the included Chai-jQuery assertion have.text

// equivalent and and shorter Chai-jQuery assertion
cy.get('#network-message').should('have.text', message)
// if you know only part of the expected text
cy.get('#network-message').should('include.text', message)

Watch the video A Quick Should Have Text Example With Multiline Textopen in new window.

Filtering using cy.filter

Just checking how .filter(:contains) works

<ul>
  <li>Home</li>
  <li>Services</li>
  <li>Advanced Services</li>
  <li>Pricing</li>
  <li>Contact</li>
</ul>
cy.get('li')
  .filter(':contains("Services")')
  .should('have.length', 2)