{"action":"created","issue":{"url":"https://api.github.com/repos/cypress-io/cypress/issues/687","repository_url":"https://api.github.com/repos/cypress-io/cypress","labels_url":"https://api.github.com/repos/cypress-io/cypress/issues/687/labels{/name}","comments_url":"https://api.github.com/repos/cypress-io/cypress/issues/687/comments","events_url":"https://api.github.com/repos/cypress-io/cypress/issues/687/events","html_url":"https://github.com/cypress-io/cypress/issues/687","id":260034227,"node_id":"MDU6SXNzdWUyNjAwMzQyMjc=","number":687,"title":"Full Network Layer Stubbing / fetch support","user":{"login":"brian-mann","id":1268976,"node_id":"MDQ6VXNlcjEyNjg5NzY=","avatar_url":"https://avatars2.githubusercontent.com/u/1268976?v=4","gravatar_id":"","url":"https://api.github.com/users/brian-mann","html_url":"https://github.com/brian-mann","followers_url":"https://api.github.com/users/brian-mann/followers","following_url":"https://api.github.com/users/brian-mann/following{/other_user}","gists_url":"https://api.github.com/users/brian-mann/gists{/gist_id}","starred_url":"https://api.github.com/users/brian-mann/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brian-mann/subscriptions","organizations_url":"https://api.github.com/users/brian-mann/orgs","repos_url":"https://api.github.com/users/brian-mann/repos","events_url":"https://api.github.com/users/brian-mann/events{/privacy}","received_events_url":"https://api.github.com/users/brian-mann/received_events","type":"User","site_admin":false},"labels":[{"id":702393938,"node_id":"MDU6TGFiZWw3MDIzOTM5Mzg=","url":"https://api.github.com/repos/cypress-io/cypress/labels/pkg/https-proxy","name":"pkg/https-proxy","color":"c5def5","default":false},{"id":702414064,"node_id":"MDU6TGFiZWw3MDI0MTQwNjQ=","url":"https://api.github.com/repos/cypress-io/cypress/labels/stage:%20in%20progress","name":"stage: in progress","color":"ffdf7f","default":false},{"id":194176883,"node_id":"MDU6TGFiZWwxOTQxNzY4ODM=","url":"https://api.github.com/repos/cypress-io/cypress/labels/type:%20feature","name":"type: feature","color":"009800","default":false}],"state":"open","locked":false,"assignee":{"login":"bahmutov","id":2212006,"node_id":"MDQ6VXNlcjIyMTIwMDY=","avatar_url":"https://avatars1.githubusercontent.com/u/2212006?v=4","gravatar_id":"","url":"https://api.github.com/users/bahmutov","html_url":"https://github.com/bahmutov","followers_url":"https://api.github.com/users/bahmutov/followers","following_url":"https://api.github.com/users/bahmutov/following{/other_user}","gists_url":"https://api.github.com/users/bahmutov/gists{/gist_id}","starred_url":"https://api.github.com/users/bahmutov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bahmutov/subscriptions","organizations_url":"https://api.github.com/users/bahmutov/orgs","repos_url":"https://api.github.com/users/bahmutov/repos","events_url":"https://api.github.com/users/bahmutov/events{/privacy}","received_events_url":"https://api.github.com/users/bahmutov/received_events","type":"User","site_admin":false},"assignees":[{"login":"bahmutov","id":2212006,"node_id":"MDQ6VXNlcjIyMTIwMDY=","avatar_url":"https://avatars1.githubusercontent.com/u/2212006?v=4","gravatar_id":"","url":"https://api.github.com/users/bahmutov","html_url":"https://github.com/bahmutov","followers_url":"https://api.github.com/users/bahmutov/followers","following_url":"https://api.github.com/users/bahmutov/following{/other_user}","gists_url":"https://api.github.com/users/bahmutov/gists{/gist_id}","starred_url":"https://api.github.com/users/bahmutov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bahmutov/subscriptions","organizations_url":"https://api.github.com/users/bahmutov/orgs","repos_url":"https://api.github.com/users/bahmutov/repos","events_url":"https://api.github.com/users/bahmutov/events{/privacy}","received_events_url":"https://api.github.com/users/bahmutov/received_events","type":"User","site_admin":false}],"milestone":null,"comments":42,"created_at":"2017-09-23T19:46:09Z","updated_at":"2018-11-19T04:08:22Z","closed_at":null,"author_association":"MEMBER","body":"## What users want\r\n- To be able to stub any kind of HTTP request including `window.fetch` \r\n- To blacklist certain domains (google analytics, new relic, intercom)\r\n- To have more control over dynamically routing / stubbing requests and responses\r\n- To more easily stub graphQL calls\r\n\r\n## What we do now\r\n- We modify the host `XMLHttpRequest` object which limits us to only stubbing XHR's from the main application frame.\r\n\r\n## What we need to do\r\n- Throw away the entire existing system for stubbing\r\n- Move stubbing into the internal Cypress network proxy layer (outside of the browser)\r\n- Synchronize the state of the browser tests with the backend (so its aware what needs to be stubbed / routed)\r\n- Remove `cy.server` and instead just use `cy.route`\r\n- Expand the API's for more advanced configuration\r\n- Accept `blacklistDomains` option for `cypress.json`\r\n- 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.\r\n\r\n## Things to consider\r\n- `onRequest` and `onResponse` currently provide the raw level `xhr` object. This would no longer be possible. We'd have to serialize the request / response into basic objects. No method calling would be available.\r\n- The `onError` callback could no longer exist\r\n- 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.\r\n- Blacklisting `https` cannot be dynamic. It would have to be set in `cypress.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.\r\n- 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.\r\n- We will no longer be able to tell the difference between an `XHR` and any other kind of `http` request. We'd likely have to change the page events to say `REQ` and `REQ STUB` instead of `XHR` and `XHR STUB`.\r\n- 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.\r\n- How would we handle stubbing binary / streaming responses?\r\n- How would we handle stubbing things like images? (This is likely pretty simple)\r\n\r\n## Bonus Points\r\n- It would likely be possible to stub Websocket traffic in the same manner\r\n- 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"},"comment":{"url":"https://api.github.com/repos/cypress-io/cypress/issues/comments/439765967","html_url":"https://github.com/cypress-io/cypress/issues/687#issuecomment-439765967","issue_url":"https://api.github.com/repos/cypress-io/cypress/issues/687","id":439765967,"node_id":"MDEyOklzc3VlQ29tbWVudDQzOTc2NTk2Nw==","user":{"login":"psachs21","id":11449728,"node_id":"MDQ6VXNlcjExNDQ5NzI4","avatar_url":"https://avatars2.githubusercontent.com/u/11449728?v=4","gravatar_id":"","url":"https://api.github.com/users/psachs21","html_url":"https://github.com/psachs21","followers_url":"https://api.github.com/users/psachs21/followers","following_url":"https://api.github.com/users/psachs21/following{/other_user}","gists_url":"https://api.github.com/users/psachs21/gists{/gist_id}","starred_url":"https://api.github.com/users/psachs21/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/psachs21/subscriptions","organizations_url":"https://api.github.com/users/psachs21/orgs","repos_url":"https://api.github.com/users/psachs21/repos","events_url":"https://api.github.com/users/psachs21/events{/privacy}","received_events_url":"https://api.github.com/users/psachs21/received_events","type":"User","site_admin":false},"created_at":"2018-11-19T04:08:22Z","updated_at":"2018-11-19T04:08:22Z","author_association":"NONE","body":"I've been trying to get XMLHttpRequest mocking going using [pollyjs](https://github.com/Netflix/pollyjs) and the basics have been working (after replacing the xhr adapter with one that works with cypress). I am seeing issues in some cases though, a maximum call stack issue keeps happening. Trying to track it down. Don't know if anyone else has had any luck with pollyjs."}}
{"actor":{"display_login":"psachs21"}}