Reading and testing JSON object in Cypress

April 19th, 2021
6 min read
Loading views...

You can start learning Cypress with fairly little knowledge of JavaScript. At least, that was my experience. The first roadblock I hit when I started learning was understanding how to access data in a JSON formatted response. This article is for everyone at the same point of the journey. I hope this will help you get over the roadblock.

Accessing items in object

Let’s start simple, before we dive into the whole JSON. Let’s say we have a super-simple JSON object, that contains just a couple of keys:

fixtures/cars.json
Copy to clipboard

To test such an object we can write a following test. Of course, in real world we would probably not test a fixture, but to demonstrate the point I like to keep things simple. Instead of .fixture() you can imagine a .wait() command that intercepts a network call.

Copy to clipboard

It does not matter what kind of value our object attribute has, we can access it using so-called dot notation. This is the objectname.attribute notation, separated by a dot, hence the name. We can use a so called bracket notation, which does exactly the same thing, but with slightly different syntax:

Copy to clipboard

You might ask why would anyone choose this syntax over the dot notation which looks much more polished, especially if we were to access an attribute that’s few levels deep. With bracket syntax, you can actually pass a variable, so you can write something like this:

Copy to clipboard

While we are at it, I suggest you look into my blog on destructuring, which has some more tips on how to access properties inside a JSON object.

Accessing items in array

Let’s now add another item in our car.json fixture. This will be a list of feature formatted as an array:

Copy to clipboard

Let’s say we’d like to write a test for couple of these feature items. That test would look something like this.

Copy to clipboard

Notice how we use a similar style as the mentioned bracket notation. This is how you access items in and array. However, there is no dot notation for arrays, so attemting to write something like features.1 would result in an error.

Arrays are widely used and can sometimes contain a lot of information. If you want to test an array for just a single item, you can use include assertion:

Copy to clipboard

Fun fact - strings in JavaScript can behave like arrays. That means, we can access each letter using bracket notation, and we can use the same include assertion as we did in previous example:

Copy to clipboard

There are tons of different assertions you can use with arrays, and I suggest you check out the documentation to learn more.

Array of objects

Let’s now combine arrays and object. Our car fixture will now have multiple objects inside it - a common situation when working with api that returns a list of items. Our JSON file will look something like this:

fixtures/cars.json
Copy to clipboard

To test e.g. the color of our second item, we will to combine two mentioned approaches - referencing array item & referencing object key:

Copy to clipboard

With cars[1], we are selecting the second item from our array of objects, and within that object, we are using .color to select the proper value from that object. In other words, we are travelling through the JSON structure. We could of course also use bracket notation and write the same thing like this:

Copy to clipboard

These combinations can be overwhelming at first, but they become natural after a while. Chrome DevTools can be a great help here. Right click on a JSON object can trigger a menu from where you can copy an attribute path to a given value. This works across many places in Chrome DevTools.

Copy property path in DevTools

Common error #1 - Comparing arrays

While trying to find your way around JSON objects, you might come across different errors. For example, there’s this strange behavior when you try to compare our car.features array to another array. Let’s say we have an assertion like this:

Copy to clipboard

Although it looks like it should definitely pass, our test will fail. What’s even weirder, is the error in the console:

Equal does not work

Everything looks the same, so why does the test fail?

The reason why this is happening is because of how comparison is made in JavaScript. It is very similar to the reason why '1' == 1 will return true, but '1' === 1 will return false. The difference is connected to how strict that comparison is. When comparing two arrays, we need to use deep.eq instead of eq in our test.

Common error #2 - Cannot read property 'x' of undefined

Mistakes happen while figuring out the proper path to a property. You may have already encountered an error similar to the one mentioned in subheading. This error can get super confusing and does not tell us a whole lot about what is the problem.

To dive deeper into the problem, let’s expand our JSON file with some extra attributes:

fixtures/cars.json
Copy to clipboard

We’ve added some engine attributes, so let’s test them with following test:

Copy to clipboard

This test will fail with a following error:

![Cannot read property 'x' of undefined](cannot-read-property-x-of-undefined.png" shadow="shadow-md)

The reason why this test fails is that the horsepower key cannot be found. The of undefined part points us closer to the reason. It seems that key that should be inside engines attribute is not defined.

What I usually do in these types of cases is that instead of the whole path, I try to console.log() out the parent attribute and then continue up with each parent until I find something that can help me find a way.

If I do it in this case, I quickly realize that I made a typo and instead of engines I should have typed engine. This seems like an obvious mistake in this example. But things can get pretty tricky with huge payloads that contain multiple levels of information.

I hope this will help you with working with JSON objects. I write a blog like this every week, so if you’d like to get notified, signup for the newlsetter (form is in footer) and follow me on Twitter or LinkedIn.

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