Search code examples
cypressend-to-end

Cypress 'have.text' assertion coming up with doubled-up values


In testing an element's text content, the test seems to be finding doubled-up values of whatever the innerText actually is. For example, If I check if an element has the text content of "0" It should return true if this is the case. Instead, "00" is being returned.

The Test Code

describe('ProductCard add to cart increment count to 1', () => {
  it('should reveal corresponding Add to Cart buttons on hover and add to cart triggers an increase in cart count', () => {
    cy.visit('http://localhost:3000');

    // Check if the cart badge exists and has an inner text of 0
    cy.get('[data-test="test-cart-badge"]').should('exist').and('have.text', '0');

    // Get the first ProductCard as an example
    cy.get('[data-test="product-card-test"]')
      .first()
      .invoke('show')
      .scrollIntoView()
      .invoke('attr', 'data-test-id')
      .then((productId) => {
        // Hover over the ProductCard
        cy.get(`[data-test="product-card-test"][data-test-id="${productId}"]`).first().trigger('mouseover');

        // Check if the corresponding Add to Cart buttons are visible
        cy.get(`[data-test="product-card-size-button-test"][data-test-id="${productId}"]`)
          .first()
          .click({ force: true });

        cy.get('[data-test="test-cart-badge"]').should('have.text', '1');
        cy.get('[data-test="test-cart-open-icon"]').click({ force: true });
        cy.get('[data-test="cart-plus-button-test"]').click({ force: true });
        cy.get('[data-test="test-cart-badge"]').should('have.text', '2');
        cy.get('[data-test="cart-minus-button-test"]').click({ force: true });
        cy.get('[data-test="test-cart-badge"]').should('have.text', '1');
        cy.get('[data-test="cart-minus-button-test"]').click({ force: true });
        cy.get('[data-test="test-cart-badge"]').should('have.text', '0');
      });
  });
});

The Offending Lines

cy.get('[data-test="test-cart-badge"]').should('exist').and('have.text', '0');

cy.get('[data-test="test-cart-badge"]').should('have.text', '1');

cy.get('[data-test="test-cart-badge"]').should('have.text', '2');

The Element Being Tested

<div class="mantine-Badge-root size-[1.3rem] mt-[0.25rem] mr-[0.25rem] mantine-15p6f3j" data-test="test-cart-badge">
  <span class="mantine-1t45alw mantine-Badge-inner">1</span>
</div>

The First Assertion Error

Timed out retrying after 4000ms: expected '[ <div.mantine-Badge-root.size-[1.3rem].mt-[0.25rem].mr-[0.25rem].mantine-4r1tww>, 1 more... ]' to have text '0', but the text was '00'

I've tried logging the actual value in the console and it is coming up correctly (eg it's coming up as 0 for the example provided in the first paragraph).


Solution

  • This can happen if there are multiple versions of an element on the page, the cy.get() query will pick up all of them and concatenate the text.

    Try appending .first() filter or :visible qualifyer.

    cy.get('[data-test="test-cart-badge"]')
      .first()
      .should('have.text', '1')
    
    cy.get('[data-test="test-cart-badge"]:visible')
      .should('have.text', '1')