Two weeks ago, Cypress was open-sourced and made available to everyone.

Cypress is a tool, that (allegedly) lets you write your end to end tests faster, and with minimum to none setup.

Fast, easy and reliable testing for anything that runs in a browser.

Let’s give it a try and verify if that’s true!

We will integrate Cypress with one of our projects — Eedi. Eedi is a fantastic educational platform for UK teachers, students and their parents. It is crucial, that anyone who uses it, have nice and smooth experience while browsing, and that all works as expected.

Setup

Inside our application root folder, let’s add Cypress as a dev dependecy:

$ yarn add --dev cypress

Adjust the "scripts" entry in package.json:

Run your server locally, just like when normally developing, and then, in new terminal window lets open Cypress:

$ yarn run cypress:open

After a while, Cypress should open and we should see a window pop up.

Here we have access to all our tests, there’s even one provided out of the box!

Cypress have created new directory cypress with subfolders fixturesintegration and support. It also added empty cypress.json config file.

Since we will be accessing our root path often, it’s a good practice to abstract it to settings file. Open cypress.json file, and add an new entry with key baseUrl and url as a value:

In the example_spec.js file we can see ‘Kitchen Sink Tests’ that can come in handy when we want to browse some common testing scenarios. But let us write our own tests for now.


Testing Sign In

Signing in is one of most important features of any app. If it’s done poorly, users won’t be able to see the rest of our work, and there’s no point in doing anything else.

Create a new file login_spec.js . Here we will test all our logic regarding signing in.

Let’s go, and write our first test — let’s check if happy path is working as expected:

Testing happy path

Now, go to Cypress app and select test that we’ve just created. It should run all tests in a file, and we can watch how they perform:

At the left pane of test runner, we can see all actions performed by Cypress, elements found and redirects made by browser. We can also use nice time travel feature and inspect every single step of our tests.

Let’s brake something! Change line 12 of the test:

It fails. And that’s good, we have established that happy path is indeed happy. Cypress provides us with detailed stack trace — what went wrong and where it happened.

Add some more cases:

  • unsuccessful log-in action should yield error message, and
  • unauthorized user should not be able to visit restricted URLs.

After we save the test file, Cypress should re-run all tests:


Testing Sign Out

Next feature to cover is logout action. We would want to establish that user can sign out from our app correctly. Sounds easy, right?

But let’s think about it for a second… In order to log out, we need to be logged in in a first place, right? Should we reuse the code from the previous test, and then add some more logic to it? Sounds silly, we are developers, we can do better!

Cypress, comes with another handy feature — commands. They allow us to create our own custom actions that can be reused in any tests. And since most scenarios should be written for logged users, this action is perfect candidate for a custom command.

Open commands.js file located in support folder. Cypress provides us with some examples, and there’s even stub of login command already there!

Enhance this login command with our custom behaviour, but first let’s think about what we want to do.

We have tested logging in already, haven’t we? So there’s really no point in repeating the same steps with each and every test we will write next. We can even read in the docs:

Fully Test the Login Flow — But Only Once!

And further in same guide:

Do not use your UI to login before each test.

So what can we do?

We can make direct network request to our backend service using cy.request() to log in, and then proceed as we normally would. Here’s how it looks like:

login command

Now, inside every test, we can call cy.login('username','password') and it should perform login action without engaging UI.

Now we are ready to test logout actions. Create logout_spec.js and add some assertions:

Watch them fail:

Then fix lines 14 and 20 (changefirst() to last() and cy.visit('log-out') to cy.visit('logout')`and watch how tests pass:


TL;DR

In summary — writing tests with Cypress was real fun.

As advertised, setup is close to none, writing assertions is easy and feels natural, and GUI is, well, awesome! You can time travel, debug all steps, and since it all launches as an Electron app, we can even access developer tools to learn more about each action that happens.

The web has evolved. Finally, testing has too.

Let’s all write some tests, and may the force be with you!

No Comments