Msw: cy.request is not intercepted by msw

Created on 18 Sep 2020  Â·  2Comments  Â·  Source: mswjs/msw

Environment

| Name | Version |
| ------- | ------- |
| msw | ^0.20.5 |
| browser | Chrome 85.0.4183.102 (Official Build) (64-bit) (cohort: Stable) |
| OS | Windows 10 |

Request handlers

I have request handlers set up correct because they work both in regular browser, in cypress with http reques triggered from browser and in the jest tests

Current behavior

I use mobx store for my apps global state, I have some util methods to apply some snapshot to test specific cases. I added corresponding endpoints to apply those snapshots.

They works when they are triggered by the app, but not triggered when I call them with cy.request, I made sure it's called after the msw is initialized.

Expected behavior

To msw to give back response as if it would be created from the app itself.

bug potentially solved browser

All 2 comments

Hi, @hakankaraduman đź‘‹

Let’s take a look how cy.request() works under the hood. The investigation we are about to perform is relevant for [email protected].

When cy.request() is called, it returns a Promise of Cypress.backend() call:

https://github.com/cypress-io/cypress/blob/2c8c15fa41796c269da6818a8bbfc01a25f5fcec/packages/driver/src/cy/commands/request.js#L285

Fast-forwarding to where .backend() method is defined:

https://github.com/cypress-io/cypress/blob/2c8c15fa41796c269da6818a8bbfc01a25f5fcec/packages/driver/src/cypress.js#L544

We can see that it creates a Promise (returned from cy.request()) and emits the ”backend:request" event. By searching the Cypress repository for that event we find this reference in the event manager:

https://github.com/cypress-io/cypress/blob/2c8c15fa41796c269da6818a8bbfc01a25f5fcec/packages/runner/src/lib/event-manager.js#L25

That event is listed as the one to be transported to the socket. I don’t have any knowledge on Cypress internals, so if this is unknown to you, that’s unknown to me as well. However, let’s see what driverToSocketEvents affects.

Here we see that they iterate over each such event and create an event listener for each. In the listener they propagate that event to the ws instance via ws.emit().

https://github.com/cypress-io/cypress/blob/2c8c15fa41796c269da6818a8bbfc01a25f5fcec/packages/runner/src/lib/event-manager.js#L290

And here’s the declaration for the ws instance:

https://github.com/cypress-io/cypress/blob/2c8c15fa41796c269da6818a8bbfc01a25f5fcec/packages/runner/src/lib/event-manager.js#L13-L16

Diving further down, that’s how the “backend:request” event is handled by the web socket:

https://github.com/cypress-io/cypress/blob/2c8c15fa41796c269da6818a8bbfc01a25f5fcec/packages/server/lib/socket.js#L367

I can assume that in case of HTTP request this switch case is what gets executed:

https://github.com/cypress-io/cypress/blob/2c8c15fa41796c269da6818a8bbfc01a25f5fcec/packages/server/lib/socket.js#L384-L385

Conclusions

There are two conclusions we can draw from this lengthy codebase journey:

  1. Cypress doesn’t perform an actual request in cy.request(), but rather treats it as an event emitter, signaling to the web socket server to handle that event.
  2. Cypress uses WebSockets to handle requests performed via cy.request().

Based on those conclusions I’m afraid there’s nothing MSW could (or should) do with this behavior. The request you make with cy.request() doesn’t leave your app as an HTTP request, but rather as a WebSocket event. We do not support Web Sockets yet, however, the implementation is in works (see #156). Bear in mind that even when we do support sockets, that won’t help in this case, as handling an HTTP request via Web Socket API is misleading at best. You shouldn’t go that deep into Cypress implementation detail to mock a request.

I highly recommend to perform the request as a usual request in your app. That means either via fetch, XMLHttpRequest, or any third-party request issuing libraries to your liking (axios, react-query, etc.). That would result into an actual HTTP request, and such request can be intercepted and mocked by MSW.

Hope this helps.

Hi @kettanaito

Thank you so much for this detailed explanation. I learned a lot and understood how to structure my tests for cypress. You're great.

Was this page helpful?
0 / 5 - 0 ratings