How To Setup Cypress Testing Library? A Smarter Way To Select Elements.
Tags: testing, javascript, testinglibrary, cypress
Published: 2022-12-18 00:28:12


![Testing Library](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0vujcdyxfh9nyrn0jbao.png)
## What is Cypress Testing Library?

Testing Library is a family of packages that helps you select and test UI components in a user-centric way. Simply put, it helps you select and interact with elements at a high level - without being too granular in selecting elements - with accessible roles instead of using CSS selectors.

Writing tests while keeping the user in mind gives you confidence that you won’t have to rewrite the script on every refactor.

## The Problem with Traditional CSS Selectors?

How we select elements should not decide if our test passes. However, using the traditional ways of selecting elements often fails to be dependable. A major refactor or change in CSS selectors can cause our test to fail. Also, the user needs to know how CSS selectors work in the first place, which can get quite complicated.

Let's see an example:

![Sign In Button of Guild Education](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i0y4r6b34ff6drno906u.png)

The Sign In button in the picture above can be selected in different ways.

*   Using `Fragile Selector`

![Fragile Selector](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/65e4aacpclodf3hsxsq9.png)

The first way is to use the selector shown above. You can get this selector by right-clicking on the element you want to select and copying the selector. This selector depends on child divs of `#root` element. On a website refactor, or for any reason, if a position of one of the divs is changed, you will need to refactor your test code.


*   Using `Good Selector`

![Good Selector](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/42c5rk0k8v4p57m6nzdu.png)

Another way to select the element is to do something like this. This is what cypress suggests on its selector playground as well.  
Basically, we are selecting a parent and its child with a unique value of an attribute. This is more dependable than before because element selection is not relying on a bunch of elements' positions in the document.


*   With Cypress Testing Library, we can avoid CSS altogether and use accessible properties of elements and select them reliably with the following API.

```javascript
cy.findByRole()
```
We will see how to use this later in this article.

## Installing Testing Library

Follow [this instruction](https://testing-library.com/docs/cypress-testing-library/intro) of the official document, but TLDR is below.

```bash
yarn add --dev cypress @testing-library/cypress 
# using npm 
npm install --save-dev cypress @testing-library/cypress
```

If you are using typescript with Cypress, add the following in `tsconfig.json`

```json
{
  "compilerOptions": {
    "types": ["cypress", "@testing-library/cypress"]
  }
}
```

The testing library can also be used with other testing tools like Nightwatch, Jasmine, Playwright, Puppeteer, and so on. Although Inspired by the Testing library, Playwright built similar APIs. You can find Testing Library's all repositories on [GitHub](https://github.com/testing-library).

## Why should you use the testing library?

The testing library uses the accessible role of an element to query the DOM, so it is much more reliable to create a testing framework since the role of an element does not change on refactoring.

It helps avoid changing your test code on every component refactor.

*   This means you don't have to mess around with selecting the element with CSS property, which can get very annoying.

*   Avoiding CSS selectors helps you speed up your work too, especially while selecting elements with similar roles.


## A more brilliant way to select elements.

For our example above, we can use the testing library's API to select elements like this.

![Testing Library's findByRole API](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/19ddfeunndb4tf4bndig.png)

*   Here: I am using `cy.findAllByRole` because the example page has multiple `Sign In` links.


Testing library also has multiple other APIs. For example

```javascript
cy.findByRole();
cy.findAllByRole();
cy.findByText();
cy.findByDisplayValue();
```

### How to find the accessible properties of elements.

*   On google Chrome, right-click and inspect the elements you want to select. Then, Select Accessibility on the CSS section.

![Google Chrome Inspector](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wl2gtnmss7c6o6lcn8zh.png)

*   In the Computed Properties section, you can find all the information you need.

![Developer tools](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p2jskwq9wkygx02b2554.png)

### Use Regular Expressions.

Cypress testing library accepts regular expressions on its name property. So, instead of a passing string as shown above use Regular Expression (RegEx) because it is much faster and easier to parse a string.

Consider the following Example:

![Without regex](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wrof7wb625rutbl0ug5j.png)

with regular expression, you can simply do the following.

![Regular Expresion Usage](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nxl7nfe4ydep5980r2o4.png)

Here, I am using regular expression to match certain part of the text, not the whole sentence.

> HOT TIP: If you are new to regular expression, use ChatGPT to quickly generate regular expression.

## Usage Example

Here is another example of how you can leverage the testing library to efficiently select elements.

![Footer Links Guild Education](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aqsjkedj8l6oqlxwogk0.png)

To verify all the links of the footer you can do something like this.

![Code to verify Footer Link](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rgz5dsknomrx6uxsklo4.png)

In the picture above,

*   First, I am creating a class Name Called `SelectLink`

*   Then, inside I have a method named `verifyLik` which takes in `linkName` (a regular expression) as an argument. This method finds the link and verifies it exists in the document.

*   Next, I have another method `verifyNavFooter`. Inside the method, there is a regular Expression array with all the links I want to verify.

    *   I am using Javascript's `Array.forEach` property to quickly go through all the arrays of regular expressions.


## Navigating around Errors:

*   Although the library is special, you will most likely encounter many errors during the process. When you run the cypress runner, the error spits out by the testing library looks something like this in Cypress runner. It also lists elements that have accessible roles.

![Error](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/70k046lbx6mekz3qwrrg.png)

Also, just because the element is shown as accessible in the browser, does not mean that the testing library will let you use them. In such case please refer to the list of accessible elements generated by the Testing Library during the test run (as seen in the picture above)

For example, placeholder text is accepted as a name for a button in Chrome but is not supported by `@testing-library/cypress`. See the pictures below.

![HTML Input Element](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrcxzbi7qcyszqdhp34q.png)

![Chrome's Accessible Name](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wy36otg9zlhgtrn5hi4c.png)


Although chrome displays name as `It must be 9 digits` which is a placeholder text. The element's actual name is `phone`

```javascript
// this works 
cy.findByRole('textbox',{name: /phone/i})
// this does not
cy.findByRole('textbox',{name: /it must be 9 digits/i})
```