Writing Cypress custom commands like a PRO

ido mor
Yotpo Engineering
Published in
3 min readDec 5, 2022

Cypress has enormous capabilities, one of which is creating custom commands.

In this article, I’ll demonstrate how custom commands can simplify your test, ensure its readability, and show that there are clear boundaries between business and test logic.

If you, like me, are eager to understand Cypress and write less flaky tests, I am sure that you will find this post interesting. And if you agree with me that testing your test utilities is a must, keep reading to learn how to test your custom commands.

Cypress bits and bytes

Cypress has a great custom commands feature, which lets you create your test helpers and integrate them smoothly into the test structure. You can chain custom commands to increase the readability of your test.

Everyone can write custom commands. But not everyone can do it perfectly.

The mediocre approach

Imagine that you are creating a custom command which does something with an actual HTML element.

have.css assertion changes the subject — reacquire of the element is needed

What’s wrong with that, you might ask?

  • It makes the test less readable and less maintainable. The test maintainer must be familiar with complicated coding techniques (callbacks) rather than just writing simple assertions.
  • Mix and match test logic and technical aspects of doing something with an HTML element. While assertions represent product requirements, our custom command might have nothing to do with a requirement. It might be related to test logging and therefore not really test logic related.

Don’t get me wrong. This would work just fine. But there is a better way of achieving the same outcome.

The PRO approach

Let’s define some requirements from our custom command:

  • Should extract the HTML element by itself: By that, we would make using our custom command much more straightforward. Coding knowledge is not a must and tests could be written by others than developers.
  • Must NOT change the subject: Well, Cypress is all about chains. We can combine most assertions to create a firm and readable test without needing to reacquire the same element multiple times. Even more so if assertions or commands are not changing the test subject after execution.

For more information, visit Cypress's introduction tutorial.

Now let’s see what our test would look like:

Without a doubt, the test would be much more readable.

Bonus — unit testing

If you got this far in the article, you probably agree that tests are essential. So why not test your tests?

Let’s see what a unit test of a custom command might look like:

What are we doing here?

  1. We are using a static HTML page as our fixture. This is much faster than launching an entire application.
  2. Using good old jQuery, we store a reference ($element) to an element with a selector (‘.element’).
  3. We execute doSomthing on an element with selector (‘.element’) and then get a closer look at the HTML element ($el) returned from doSomthing.
  4. We make sure that $el and $element are identical.

Conclusion

Cypress came to the world for several reasons — one of them is to make our tests more readable. That’s why we should do our best to write the tests that way.

On a personal note, I learned a lot just by looking at the Cypress code base. If you are looking for inspiration or knowledge about an open source you are using, then you should definitely investigate it. You will be amazed by the number of things you will find out.

--

--