How to involve your customers in Cypress Testing?
Tags: webdev, javascript, tutorial, tooling
Published: 2022-11-30 10:00:00

I'm working as a consultant for an IT company, Some customer projects are not ready for E2E tests and it is not always easy to include them if you haven’t a clear idea of the code business domain flow.

It is also common, that we don't know how the customers use the application from the front-end side, and this could lead to some discrepancies between the devs and the customer's teams in the use cases.

That is why it could be useful to make our **customers write tests** on their own.

In these cases, Cypress helps us, providing some great features for writing some E2E tests.

One of these features is **Cypress Studio**, which allows you to write tests simply by clicking on the web page and tracking the interactions with your software.

### How to enable Cypress Studio?

If we want to enable Cypress Studio we first need to add Cypress to our React project, which can be done with the command `npm install cypress -D`.

Once installed, you can run Cypress with `npx cypress open` and make the initial configuration.

After that, open the file _"cypress.config.ts"_ and in the entry `e2e` insert this line: `experimentalStudio: true`.

The file should look like this now:

![Cypress config](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ev4iyo19ok3qeh6rg2o.png)

### Problems:
- If the elements we want to click are not distinguished by an id, Cypress Studio can't always keep track of the button interactions consistently.
- As developers, our input values for tests are not the real values that the customers use.

### How can we solve these problems?

One solution could be to get the elements by their tag or their label; however, with this solution, we can't directly use the tests written with Cypress Studio. 
Because they would need a re-elaboration by the devs to convert the tests in a way where elements are clicked based on the content of their label.

One of the first things we had in mind was to assign a `data-cy` attribute to every element on the page because Cypress studio can keep track of these elements.

So we wrote a function that whenever there is an update in the body of our webpage, assigns to each element an attribute `data-cy=[num]`, where num is the counter of the elements of the page:

![idManager v1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x55jj4bnr2zixjelwqd8.png)

We inserted a new script into the 'package.json' and edited our app to make the idManager work only when we run it in test mode.

![package.json script](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jzyxbfxj0grc7im7ax2z.png)

![call to idManager](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ml0caaklp3smt24eww7.png)

At first, we were satisfied with this solution, we managed to create lots of tests and they all run perfectly, even when including them in our **GitHub actions**.
Another cool fact was that there were no repercussions on the responsiveness of our application since the idManager was used only if we built the app for test.

It was all fun and games until we developed a new feature, the result of our GitHub Action was ` FAILED: 0 tests passed `.
Ok cool, what's wrong now?

Debugging, we figured out that the ids of the webpage were all different from the ones in the tests, due to the modifications we applied for the feature. So we understood that assigning the ids with a **counter was not a good choice**.

### How to make the idManager more solid toward modifications?

After some brainstorming, we ended up with a solution:
give the ` data-cy ` a value equal to the one present in some predetermined attributes, like in the following example.

```HTML
// BEFORE idManager
<input name="email" />
// AFTER idManager
<input name="email" data-cy="email" />
```
It's not enough, in some cases, we need to get the `textContent` too; to obtain something like this:

```HTML
// BEFORE idManager
<span>Users</span>
// AFTER idManager
<span data-cy="users">Users</span>
```
After some modifications, that's how we choose the value of `data-cy`:

![getDataCy function](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7nemaytiu17pq8oc0f22.png)

We first check if the tag has one of the attributes that we want to check, if it doesn't we check its `textContent` (only if it's one of the tags that we are interested to check).

Now that the `data-cy` is based on some **distinctive values** we can edit their positions as we want and the tests will always execute the right way.

Here is an example of the use of Cypress Studio with a webpage using our idManager: 

{%embed https://youtu.be/zrz8la9j8nc %}

As you can see, the test runs successfully. 
However, it is good to apply a little modification: make the assert check the text in the body instead of the div; with this little tweak, we can be sure that the text we are looking for is **inside the page**, even if we decide to put it in another element.

Our final test will result in this code:

![Test Login](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vu7rfjl7hnd2oyv3m1du.png)

Thank you very much for being here with me, I hope you find this article helpful!

If you've liked it don't forget to leave a ❤️ and comment with your opinions 👀