Intercept requests with Cypress

2021-07-19 3 min

Not long ago, a client asked us how they can integrate with their e2e tests the bridge to authorize their app. Usually, this kind of integration can be automated easily, except when there’s a captcha in the middle. Forget about automation. The main idea of captchas is to prevent robots from crawling logins and such stuff.

They insisted on using our dev API key to bypass the captcha. That’s not possible for multiple reasons. I’m not going to extend here, but the first reason that comes to my mind is security. Even not using a production environment, we’re not going to give an internal key to third-party clients.

Anyway, we had a 20 min discussion. I explained why it is not a good idea to rely on automated tests using third-party services, even if there are no captchas involved.

First of all, what happens if the environment used for testing is down? Or a new release is broken? Or some maintenances are being carried out? Well, some tests, if not the whole suite, are not going to pass. And perhaps, a confusing error message takes the dev team to waste some precious time investigating the error.

So, the best approach here is to stub those 3rd party requests with the most common scenarios that can happen with a provider: success, request error, server error, and no auth. However, if redirection to a provided URL of the service is expected, the only possible test is when the request works ok. Whatever the error scenario is, the redirection is never going to happen.

Since our partner and we use cypress for e2e testing, the solution is to intercept external API requests and return whatever the test expects. This method is the most reliable way to test third-party APIs while keeping our e2e tests as isolated and flawless as possible.

Remember, test your code, not the third-party providers. That’s up to them.

So, here is the code to intercept outgoing requests with cypress.

it('redirects after authorization', function () {
  cy.intercept(
    new RegExp(`https://whatever.site/auth/*`),
    req => {
      let urlRedirect = new URL(req.url).searchParams.get('redirect_uri'))
      req.redirect(urlRedirect)
    }
  ).as('request')
  cy.visit(`/path/executes/external/request`)
  cy.wait('@request')

  // Carry on with the expected test
})

The first thing is to use the cypress intercept command, which accepts multiple signatures. In this case, I opted out to match a URL with a RegExp class as the first argument and a function handler.

The service must perform a redirection callback. So, the function retrieves the query parameter containing the redirect URL to make the redirection.

It is also important to wait until the intercept promise completes to carry on with the test. Remember, most of the cypress commands are asynchronous.