Ramping up our test efforts with Cypress — part 2: Covering some special needs
In the previous post, I wrote about how we at Coverwallet set up Cypress to keep up with many new features coming to our web applications. In this one, I want to share some interesting tweaks we built to cover a few edgy cases.
Play 1: Intercepting carrier responses
Coverwallet is an online insurance broker. As such, we have to deal a lot with insurance carriers. This means that we need to develop and maintain integrations with them to provide our clients with insurance quotes.
Technically, we get data through our frontend app, pass it on to our backend and send it (secured) to the different insurance carriers to get estimations for the quotes that will be offered. We do that in more than one environment which complicates the work a little further.
When we started including the automatic tests in the test environment, such integrations ended up being a big pain. After a few iterations, we saw that we needed to change how we did things, and mocking those requests was the way to go.
First of all, we needed to create the fixtures as JSON files within the
fixtures/ folder in the project. One per carrier and industry that we tested. The content of such JSON files is just the answers that we’d expect going through a happy path scenario.
Now we can proceed to our spec file:
We use the intercept method to be able to set up the mock. There we indicate over which XHRs we want to use (only those containing
/chubb/gl/), which fixture file we will be using (it has to coincide with the fixture file name) and we set the
getChubbUw alias for it.
Now the test starts and when it gets to the point we need to use the mock, we leave it like this:
We just do a
cy.wait along with our alias right at the moment that we expect the XHR to happen. As it already has information on what to respond with, it will automatically send the content of the JSON file passed on completing the mock.
Doing this trick in all the tests that needed to deal with carriers helped us to keep this test collection more stable and reliable.
Play 2: Log me in!
Another important feature of our product is the Wallet and the possibility for the user to log in and see what insurance products they have bought plus their being able to handle documents and requests. Access to the Wallet is allowed by providing the users with credentials once they have purchased a product.
At some point, we decided to include the login tests in the regression suite that is meant to be run after every code push to the test environment. Historical data plus the number of features coming up around the Wallet revealed that we needed this too.
We created those tests as independent spec files where we included different
it for the happy path and the error scenarios.
Then we replicated this into every application mode we have (reusing some key pieces in separate js files). I am only showing two here.
So now we’re testing also the login in the pipeline where we run all those specs. Is that it? No, now comes a more interesting part.
We know that we can break the login from other parts of the platform, such as the Identity provider — a service that we use. As part of the project, we partnered with devs to try to understand the architecture and see where we should also run the tests from.
We found out there were 2 services that could impact the login functionality so we set up the tests to be run from there as well. We added a new job to our Circle-CI pipelines like the following using the Cypress orb:
To clarify some data: We use an executor where we indicate which image it needs to run. We also set the
login tag to have them separated in the Dashboard.
Especial mention to the
spec entry: here we filter by the spec file(s) we want to run. As it is, it will find all the login specs within the project and leave the rest (because we don’t need to test other stuff from there).
For the other entries, we just require the deployment to be run as the trigger of the tests and we set the filter to only be run in the
What if we wanted to run those login tests against production too? Easy. In your Cypress project, you can create a new Cypress json config file to be used for other envs, for example
cypress.prod.json. In there, you leave configuration for your production environment such as the
baseUrl you’re going to use. Then you’d need to create a new job in the pipeline which will be very similar to the previous one but with a couple of tweaks:
You will need to indicate your new config file. For the
tag you may want a new one to have them separated in the Dashboard and then the filter for the pipeline branch.
This project was more DevOps-ish but it helped us understand more the application architecture plus we added some coverage that we definitely were missing. It paid off since day 1.
Play 3: Authenticating through the backend
This one is another example of how working closely with devs can boost the effectiveness of the test automation we create.
What we intend here is to use the backend to log in on our apps and forget about going through the UI every time we need to test something that requires us to be logged in. We are already testing the login in a different spec, so we don’t need to go through it again and again.
For it, we have created this piece.
getSSOToken is a function that runs a
cy.request() against one of our services and grabs the token, to be used in the
With this, all we have to do in our spec file is to call the function:
If the URL assertion passes, it will mean that we are logged in, so that will be our precondition for this test to start. If we don’t have it, it will mean that for some reason the login didn’t make it so we are not even interested in starting with the test.
For sure I could continue to share here more examples of interesting tweaks that we’ve worked on along with devs, but I am not willing to make this article endless. These are just a representation of how given a problem that we have — related to testing — we come up with a solution using available technology.
We also put a lot of focus on not just coming up with anything that solves the problem, but something that scales and works in the long term. Another point that I want to remark is how we work as a team to build these things and share knowledge. Very few pieces of this kind are built by individuals, there usually is a group of people behind them.
I hope you found this one interesting and helpful 💚