Search code examples
javascriptreactjscypressweb-component

How to tell if a React web-component button is disabled in Cypress?


We're in the process of replacing our custom react components with components from the company's design system. These are web-components and it has been made a react-wrapper to make them work in React.

The element is rendered like this in our app:

<custom-button title="" data-test-id="save" disabled mode="primary">
    #shadow-root
        <button data-mode="primary" size="small" type="button" title="" disabled>Save</button>
</custom-button>

In Cypress I have tried to check if it is disabled like so:

cy.getByTestId('save').should('be.disabled'); //Doesn't work, but its the way I want to do it
cy.getByTestId('save').find('button').should('be.disabled'); // Works

The first way doesn't work but its the way i want to do it because thats how all our tests work today. I want to having having to do the second way because that means we have to handle buttons from our design-system different from regular buttons.

Does anyone know why the first way doesnt work? Even though the <custom-button> has the disabled attribute applied to it in the DOM?


Solution

  • The difference is between attribute and property.

    Under the hood cy.getByTestId('save').should('be.disabled') is checking that the element has property disabled. The standard button translates the attribute disabled into a corresponding property, so it passes the above assertion.

    The custom button obviously does not have that behavior, so it might be difficult to treat custom-button the same as button.


    One thing that works for your sample is

    cy.getByTestId('save').should('have.attr', 'disabled')
    

    This should work for all occurrences of custom-button (if my assumption about it's behavior is correct).

    If you have trouble with standard button, you can check both:

    cy.getByTestId('save').should($el => {
      return $el.attr('disabled').length > 0 || $el.prop('disabled').length > 0
    })
    

    You can make a custom assertion if that's a pain to code everywhere.


    IMO using .find('button') isn't optimal, since it's an internal implementation of the custom-button.