Cypress selector is easy, just do cy.get('.myComp')
and <input className="myComp" />
will be selected but with styled-component
maybe we need to use custom attribute like cy-data, cy-testid etc. I guess there's no other shortcut than flood our component with those custom attribute right?
The other hassle using cypress is when you use css module, where the class is generated differently every build, and imagine your component is , then you need to pass your the custom attribute all the way down
<Custom cy-data="btn1" />
const Custom = ({cy-data}) => <button cy-data={cy-data} />
any workaround to avoid this pain?
We use data-test-target
attribute and write in manually in JSX.
In simple version it's all that you need. But if you have complex cases like two forms on the same page with the same fields you need to distinct them.
So that we do this:
Target can be built by 3 parameters:
Imagine you have a React component and want to set test targets. For example you have 2 buttons in the component: remove and edit, so it would look like
<button data-test-target="component-name:remove">Remove</button>
<button data-test-target="component-name">Edit</button>
If you have more then one this component on the page you should pass a context in props:
<button data-test-target="component-name:remove::todo-list">Remove</button>
Helper that I use to follow this idea:
import dashify from 'dashify';
export const createTestAttribute = ({
block: blockPart,
element,
context,
}) => {
const elementPart = element ? `:${dashify(element)}` : '';
const contextPart = context ? `::${dashify(context)}` : '';
return `${blockPart}${elementPart}${contextPart}`;
};
Usage:
<button
data-test-target={createTestAttribute({
block: 'component-name',
element: 'remove',
context: props.testContext,
})}
>
Remove
</button>
Using it tests will be stable and they won't depend on your markup structure and class names
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With