EDIT: Experimental network stubbing was released with v6 and
.route2()
command was renamed to.intercept()
. Also,.route()
command was deprecated in this version. To see how you can migrate your.route()
commands to.intercept()
, I recommend reading my blogpost on it. You’ll find examples and many useful links there.
In the beginning of September, Cypress released a new experimental feature called experimentalNetworkStubbing
. I was watching development on Github for a while and was really excited when I started seeing some rapid movement on the issue. I decided to have a closer look into what it does. I share code examples here, but if you want to play with this I have put together a quick and dirty repo. Clone → npm install, → npm start → npx cypress open and you’re good to go.
With version 5.1.0 or higher, you can enable this feature by adding following line into your cypress.json file:
This enables you to use .route2()
command which is described in Cypress documentation. Imagine .route()
command, but on steroids. You’ll see in a minute.
If anyone ever asked me about my favourite command in Cypress, it would be .route()
. With a simple syntax you can watch your api call being made:
After our app is opened, it loads a list of items from database. To do that, it calls a GET
request to the /todos
url. Response comes back as a simple json file which is then rendered in our app. If you want to change this response and provide your app with your own json list of items, just add another parameter:
This is simple, yet very powerful thing you do to test your application. .route()
command enables you to look into any xhr request your application makes and test it. You can combine your api and ui tests into one.
The problem with this command though, is that you can only work with xhr requests. This rules out fetch requests, or other assets loaded via network. If you tried to route fetch request, you would end up like this:
With .route2()
command you can route fetch requests just as you would do with XHR. Pretty neat.
That’s not all though. You can route static files such as css or images. This can become super handy if you want to test a website with lazy loaded images:
But there’s more! With .route2()
command you can not only change response of your api call, but also request itself. Let’s say we want to add a custom header to our request to let the server know that these are coming from application that is being tested at the moment. You can manipulate your request headers like this:
This new header cannot be observed in network panel in DevTools, because the request manipulation actually happens outside of browser - before the request is sent to the server. Because of that, DevTools show the original request headers. But in the terminal where you ran your npm start
command, you can see that I’m logging all request headers for POST /todos
request and our newly added header is visible there:
In the same way we have changed our headers, we are able to change request body. Our application takes title of todo item from our text input. Once we hit enter key, that input is sent via fetch request to our server. When using .route2()
we can actually change what is being sent to server, or even add our own data.
All these examples can be found in a repo that I have put together for this blog. Feel free to play around with it and let me know on Twitter, what you think of this new feature. In my perspective Cypress team has done amazing job here, and I’m excited about possibilities this change will bring.
EDIT: Gleb Bahmutov from Cypress wrote a really cool blog on differences between
.route()
and.route2()
commands, where he demonstrates some cool stuff you can do with.route2()
. You should definitely check it out.
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.