Autocompleting selectors in Cypress with TypeScript

November 15th, 2021
| v10.0.0
4 min read
Autocompleting selectors in Cypress with TypeScript

You will learn:

  • how to create custom command that will autocomplete your selectors
  • how perform a check on your tests that are written in TypeScript
  • how to grep selectors from your app
  • how to create warning if there are selectors in your app that you are not using

Cypress advises to use data-cy selectors as a best practice for selecting your elements on page. Recently, we had a great discussion on our discord server about whether this is a good practice. Personally I strongly lean to "yes". If you are in this camp as well, I have some nice tips for you today.

Using data-* selectors with custom commands

If you are using data-* selectors a lot, chances are you want to create a custom command.

Copy to clipboard
undefined

This way you can skip writing out [data-cy=''] part, when you are using a .get() command. If you’d like to create a fancier version of this, I wrote about an article on this topic, explaining how you can improve your logs for your custom command.

When using TypeScript, you can further define what kind of input will our newly created custom function receive. Usually we could go for something simple, like input: string. But we can instead create our own type, which will limit what kind of input we can pass to our function.

Copy to clipboard
undefined

This way, TypeScript will throw an error when we use a selector that is not allowed:

TypeScript error on unknown selector

Creating a selector file

The list of selectors might get quite big over time. That’s why it’s probably a good idea to keep it in a separate file. My approach is to create a selectors.d.ts file where I keep a list of all my selectors. I usually save this to the cypress/support/@types/ folder.

cypress/support/@types/selectors.d.ts
Copy to clipboard
undefined

Whenever I add a new selector to my application, I need to add it to my list, otherwise I’ll get an error. On the other hand, when I use a selector that is already in the list, I get a nice autocomplete in VS Code.

Autosuggesting selectors

Checking the selectors

Of course, we can get into a situation where we might delete a selector from our list, and we wouldn’t notice until we open the test file, or our tests run. Since we are using TypeScript, we can create a typecheck script, which will check for any TypeScript errors. This script will use --noEmit flag, because don’t need to compile our files. This is done by Cypress when we run our tests.

package.json
Copy to clipboard
undefined

Another thing we can do is to grep our selectors from our source code. This is of course a little tricky, because not all applications and frameworks work the same. In my Trello app project, I have a script that will grep these from my .vue files inside the src folder.

scripts/getSelectors.sh
Copy to clipboard
undefined

I then use this very cluncky way of generating all of the selectors into the cypress/support/@types/selectors.d.ts file. But hey, it works for me so far! 😅

scripts/getSelectors.sh
Copy to clipboard
undefined

This way, if any of my selectors from source code would be deleteed I would immediately notice when I run that npm run typecheck script.

Finding unused data-cy selectors

I started having way too much fun with this, so decided to grep my tests too. Then, I would compare these selectors with the ones find in my source code and print out warning if there are any extra.

scripts/getSelectors.sh
Copy to clipboard
undefined

I imagine there are some better ways to approach this, as I’m not really a shell script expert. I have this script in my Trello app project, feel free to add a comment or PR to improve this.

Let’s keep in touch

From time to time I send some useful tips to your inbox and let you know about upcoming events. Sign up if you want to stay in loop.

is required.

I treat your email address like I would my own. That means no ads. Just notifications of when I do cool stuff. Unsubscribe anytime. Click here to read about how I handle your data