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.
If you are using
data-* selectors a lot, chances are you want to create a custom command.
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.
This way, TypeScript will throw an error when we use a selector that is not allowed:
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
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.
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.
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
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! 😅
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.
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.
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.
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.