In my previous blog post Magic Backed For E2E Testing I have shown my new plugin cypress-magic-backend. The plugin can record the network API calls your web application makes during end-to-end tests, then replay them. Mocking network calls makes your front-end tests much faster. In this blog post I will show the other major feature of the plugin: the "Inspect" button labeled 🪄 🧐
.
🎁 You can find the source code used for this blog post in the repo cypress-magic-backend-example.
Many things can go wrong
Imagine a web application. It has JavaScript front-end code and it makes calls to the server APIs. If you are just testing the HTML page shown to the user, and things go wrong, where does the problem come from? Imagine the Cypress test was passing before, now it started failing. If we draw a simple diagram, there could be 3 potential error areas:
If a previously passing test is failing now, the problem could be in the code blocks "A", "B", or "C"
- A: The event handler code is handling the user event differently
- B: The server code is processing the same API request differently
- C: The page update logic that shows the API response has changed
We want to find the first place the change has happened; obviously if the code in step "A" produced a different API request, then the server is likely to respond with a difference response.
The problem with just testing the page UI
If we simply test the page DOM, then we cannot tell apart errors due to "A", "B", or "C" changes.
1 | beforeEach(() => { |
The test passes, each API request takes 100ms.
Imagine I have recorded the test execution using the cypress-magic-backend plugin's "🪄 🎥" button.
Great, we now have a JSON file with all API calls to the /todos
endpoint
1 | { |
Let's say a developer comes in and changes the following single line of the application's app.js
file
1 | const todo = { |
The developer changed the field name title
to be text
. What does the test show now?
Hmm, if you are debugging this failing test, where would you start looking? In the front-end code? Backend logic?
Inspect mode
This is where the "Inspect" mode button comes in handy. You MUST have pre-recorded API calls for this button to work. Let's see what it does in our test.
Notice that just happened. We see red triangles 🔺
and 🔻
in the Command Log. The up triangle means the cypress-magic-backend plugin has detected a difference in the structure of the outgoing request. If we click on the message, we will see the difference details:
The diff used by the cypress-magic-backend
is different from the standard "object difference" algorithms. It does not compare the values of objects and arrays, just "shapes". In our case, the POST /todos
call used to send an object with title
, completed
, and id
properties. Now it is sending text
, completed
, and id
properties. The plugin warns us: object added key "text" and lost key "title"
.
So it means we know where the root cause of the failed test lies. It is in the frontend JavaScript code block marked "A", since the request body sent to the server API has changed.
The Inspect mode shows the differences in the request and response bodies. Here is the 🔻
message output showing similar differences in the response to the POST /todos
call:
We can even use the names of the changed fields to narrow our search, especially once we inspect the Git changes in the front-end bundle
If we decide to rename the field, we can proceed with the matching HTML page changes:
1 | <!-- <label>{{ todo.title }}</label> --> |
The test is passing now, but the plugin is warning us about detected API changes.
It is important to make a decision about these warnings. Have we handled the title
to text
changes everywhere in our application? There might be field validation, for example, that no longer applies, since it does not see the field title
, so it silently passes. We need to re-record the API calls with the new requests, if we decide to go with the change.
Tip: Inspect mode compares the request and response bodies against the recorded JSON fixtures. If the data is an array, the plugin looks at the array length, and then compares each item in the array using keys and types. Only the first detected change is reported
Sweet.