Ari Friedgut
Ari Friedgut

Reputation: 23

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).

Upvotes: 2

Views: 93

Answers (2)

Ari Friedgut
Ari Friedgut

Reputation: 23

I figured out the resolution to this issue. I didn't realise that when has.text is applied to an array of elements, it runs for each element in the array and outputs the result as a concatenated string of the text values for each element.

I remedied this by changing the code to: cy.get('[data-test="test-cart-badge"]').each(($elem) => expect($elem).to.have.text('2')); (to use one line as an example)

Upvotes: 0

Manfredi
Manfredi

Reputation: 166

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')

Upvotes: 3

Related Questions