Closed
Description
Pull Request (in progress): #4176
What users want
- To be able to stub any kind of HTTP request including
window.fetch
- note: temporary polyfill available polyfill window.fetch #7710 v4.9.0
- To blacklist certain domains (google analytics, new relic, intercom)
- To have more control over dynamically routing / stubbing requests and responses
- To more easily stub graphQL calls
What we do now
- We modify the host
XMLHttpRequest
object which limits us to only stubbing XHR's from the main application frame.
What we need to do
- Throw away the entire existing system for stubbing
- Move stubbing into the internal Cypress network proxy layer (outside of the browser)
- Synchronize the state of the browser tests with the backend (so its aware what needs to be stubbed / routed)
- Remove
cy.server
and instead just usecy.route
- Expand the API's for more advanced configuration
- Accept
blacklistDomains
option forcypress.json
- As each request comes in, if we expose callback functions we'll need to constantly communicate with the driver for guidance on what to do - whether to proceed - halt, etc. This can get pretty complicated and might have significant performance issues. We'll need to experiment
and we may not be able to provide callback functions anymore.
Things to consider
onRequest
andonResponse
currently provide the raw levelxhr
object. This would no longer be possible. We'd have to serialize the request / response into basic objects. No method calling would be available.- The
onError
callback could no longer exist - Additionally we hook into the
onerror
events for XHR's and will automatically fail the test if this is called. This would no longer be possible. - Blacklisting
https
cannot be dynamic. It would have to be set incypress.json
or environment variables. The reason is that for each blacklisted domain that goes over https, we would have to route that traffic to a self signed certificate. Browser freak out if traffic to https gets assigned one certificate, and then within the same session it gets another cert applied. What this means is that before spawning the browser we have to isolate that traffic and know ahead of time not to route it to the actual server. This enables us to send a single cert to the browser. - We could enable non https hosts to be dynamically blacklisted, but these API's would be async and likely difficult for users to understand / use. We might be able to bake these into
cy.route
but I'm not sure there's much of a use case here of only dynamically blacklisting non https traffic. - We will no longer be able to tell the difference between an
XHR
and any other kind ofhttp
request. We'd likely have to change the page events to sayREQ
andREQ STUB
instead ofXHR
andXHR STUB
. - It would be very difficult to provide accurate
onResponse
callback functions. It's possible for the internal server to know when an HTTP request has been completed, but it's not possible to know whether the browser has actually finished processing it. This may or may not be a problem. - How would we handle stubbing binary / streaming responses?
- How would we handle stubbing things like images? (This is likely pretty simple)
Bonus Points
- It would likely be possible to stub Websocket traffic in the same manner
- The problem with this is that most Websocket libraries (ie socket.io) add their own "encoding" pattern on top of each websocket message frame. The ergonomics around stubbing this would be odd. The problem is this is library (and even version of library) specific. This may be a better use case for
cy.stub
, or perhaps a 3rd party extension