Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using styled-components or custom component with cypress

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?

like image 419
akibo Avatar asked Sep 19 '25 17:09

akibo


1 Answers

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:

  • block: required
  • element: optional
  • context: optional

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

like image 100
Mark Partola Avatar answered Sep 22 '25 07:09

Mark Partola