JavaScript for Cypress testing

I have always had a preference for starting things in the beginning and then continuing linearly. It doesn’t feel right to be learning about the consequences of an event before knowing what the causation was in the first place. I don’t, for instance, see how you can fully appreciate the advantages of people having alarm clocks in the home if you didn’t know that a private employee with a stick was once relied on to get you out of bed.

That fact alone makes me utterly grateful to own an alarm clock. But I digress.

As software testers, we know that the best time to start testing is as early as possible in the lifecycle of a project. And I think the same is true of knowledge building (just not the being involved part – unless you have a time machine). If you have knowledge on the building blocks that a larger project is built on top of. Then you are in a better position to become more knowledgable, efficient and productive with the particular skill and knowledge area that you are working in.

The test automation framework Cypress is easy enough to pick up on its own. I think if someone took some time to read their documentation and tinkered around with some of the provided examples. They could probably come away with some code that would meet their needs. That’s all a tool of any kind has to achieve afterall.

“The secret to getting ahead is getting started.”

However, if you want Cypress to exceed your expectations and really work for you in a way that makes your life as an automation engineer as easy as possible. Then you need to take some time to brush up on some JavaScript fundamentals. But since JavaScript is a monolithic beast with use cases ranging from creating and powering web servers, creating rich and engaging animations, or even powering entire operating systems in the browser. It can be hard to know where to start or even know what is relevant to you.

One thing that I’ve discovered with Cypress is that you don’t need to know a lot to do a lot. There is really only a handful of core operations that you really should be aware of before diving into the framework. Partially because you won’t think that Cypress is magic and doing multiple things for you out of the box (it certainly does help you in certain areas). But like I’ve said above. Understanding what it’s doing and how it’s doing it. Will not only make you more knowledge but also a far more effective and efficient user of the framework.

This, of course, isn’t an entire overview of every JavaScript function that is used with Cypress. I strongly encourage you do your own research into what you want to achieve and work back from there to gain your own understanding.

In stead think of this as an introduction to some core features of the language that you’ll need to be familiar with to work with Cypress on a daily basis.

Closures and Promises

Closures and promises are one of the most common JavaScript features that you’ll be using within your tests (whether you know it or not). A promise allows us to run callback functions on the code that is returned on successful completion.

promise.then(function(result) {
console.log(result); // "Stuff worked!"
}, function(err) {
console.log(err); // Error: "It broke"
});

In Cypress, the most common form of a promise is the .should method which takes in an assertion you would like to make and the value that you would like to assert on.

For example:

cy.get(.item).should("be.visible)

Assertions made via .should also have built-in retry-ability meaning that any assertions made through the command will be automatically called again until there is a time out, or it is successful.

var vs let vs const

Typically, you don’t need to use assignments in Cypress (you should use an alias instead). But there certainly are some use cases which I feel doesn’t totally invalidate this explanation.

For example, you may want to issue a Promise using the .then command which allows you to assert the contents of a div without making multiple calls to the DOM.

cy.get('.div').should(($div) => {
    const $body = $div.contents().find("body");
    expect($body).to.contain("Hello World!");
})

Here I am using a const to keep track of the body and then running assertions on its contents. Why am I using const here? Essentially, const values (short for constant, can’t be changed and will throw an error if you try to reassign them.

let/var are fairly interchangeable outside of functions (read up on an in-depth comparison here as their scope does vary).

Object deconstruction

This is probably most useful if you are passing multiple objects between your test cases and need a way to access the contents of the object without passing every key in one at a time.

So given something this this.

const user = {
    "email": "something@example.io",
    "password": "12345"
  };
  const email = user.email;
  const password = user.password;

We don’t have to make our test cases look like this.

cy.login({
    userEmail: user.email,
    userPassword: user.password,
});

Arguably, this is already clean code, it’s declarative and easy to follow and understand what it is doing. But it does get fairly repetitive after a while. Plus, what if you didn’t want to pass in one line at a time and instead only wanted to pass in the user object? After all, it contains all the key values that you want to reference.

This is where deconstruction can help and essentially takes one large object and instead of making multiple line assignments. You only need to write a single line.

const { email, password} = user;

What this code is saying is: ‘Give me a variable called email and password and take it from the user object”.

cy.login({ user });

Doesn’t that look nicer?

Like I say, JavaScript is a huge language and to do a complete overview couldn’t fit into one blog post.

If you are interested though. I would recommend taking a look at the ForEach loop that JavaScript offers. Combining these with fixtures is an excellent way to generate dynamic test cases from predefined data in JSON format.

This was a brief overview of the common JavaScript features that you’ll be using in Cypress. But if you have a JavaScript or test automation question. Feel free to contact me on Twitter, Linkedin or via my contact form.

Posted by Kevin Tuck

Kevin Tuck is an ISTQB qualified software tester with nearly a decade of professional experience. Well versed in creating versatile and effective testing strategies. He offers a variety of collaborative software testing services. From managing your testing strategy, creating valuable automation assets, or serving as an additional resource.

Leave a Reply