1
votes

I have a two-item "selector" component (like a segmented control), which is yellow when selected and grey when not selected. I want to test that a click on one of the options turns it to selected.

The element is a styled button:

const LeftButton = styled(Button)({
  borderTopLeftRadius: '10px',
  borderBottomLeftRadius: '10px',
  borderRight: 'solid 2px #545454',
});

const RightButton = styled(Button)({
  borderTopRightRadius: '10px',
  borderBottomRightRadius: '10px',
});

        <Group>
          <LeftButton
            data-testid={'OPTION_1'}
            active={option == 1}
            onClick={() => toggleParameter(1)}
          >
            1
          </LeftButton>
          <RightButton
            data-testid={'OPTION_2'}
            active={option === 2}
            onClick={() => toggleParameter(2)}
          >
            2
          </RightButton>
        </Group>

Looking at the rendered HTML it looks like the only available information is the class. For example here is what it looks like when option 1 is selected and option 2 is not:

<div data-testid="OPTION_1" class="css-1z12orh">1</div>
<div data-testid="OPTION_2" class="css-14vfpcp">2</div>

When option 2 is selected and option 1 is not, the classes don't switch, they actually generate new classes, though thankfully the classes generated are the same gobbledegook each time.

To assert in Cypress whether one is checked, I'd have to assert on this random classname, right? Is there any way to access the actual component's props so I can assert on props.active?

Does Cypress even know about the existence of react components, or does it only know about HTML elements?

1
Cypress can test the selected value if you actually use semantic elements. But no, it doesn't know about React; it is an E2E-level testing tool. - jonrsharpe
It's not clear why you don't do the obvious test - click on a button and test the color is yellow/grey, something like cy.get('the colored thing').should('have.css', 'color', 'rgb(244, 232, 104)'). - Ackroydd

1 Answers

2
votes

You can make use of cypress-react-selector

Save it as a dev-dependency:

npm i -D cypress-react-selector

You can get the React properties from a React element and validate the properties run time.

describe('It should validate cypress react selector', () => {
  before(() => {
    cy.visit('https://localhost:300');
    cy.waitForReact();
  });

  it('it should validate react selection', () => {
    cy.react('MyComponent').should('have.text', 'abcd');
  });
});

Use cypress-react-selector along with @cypress/react library for unit/component/integration tests. Few handy examples - https://github.com/abhinaba-ghosh/cypress-react-selector/tree/master/component