Skip to content

Instantly share code, notes, and snippets.

@yagudaev
Last active September 16, 2021 08:46
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save yagudaev/2ad1ef4a21a2d1cfe0e7d96afc7170bc to your computer and use it in GitHub Desktop.
Save yagudaev/2ad1ef4a21a2d1cfe0e7d96afc7170bc to your computer and use it in GitHub Desktop.
Cypress Fetch Support Workaround - replaces fetch request with traditional XHR so cypress can track them
// cypress/support/hooks.js
// Cypress does not support listening to the fetch method
// Therefore, as a workaround we polyfill `fetch` with traditional XHR which
// are supported. See: https://github.com/cypress-io/cypress/issues/687
enableFetchWorkaround()
// private helpers
function enableFetchWorkaround() {
let polyfill
before(() => {
console.info('Load fetch XHR polyfill')
cy.readFile('./cypress/support/polyfills/unfetch.umd.js').then((content) => {
polyfill = content
})
})
Cypress.on('window:before:load', (win) => {
delete win.fetch
// since the application code does not ship with a polyfill
// load a polyfilled "fetch" from the test
win.eval(polyfill)
win.fetch = win.unfetch
})
}
// cypress/support/index.js
import './hooks'
// cypress/support/polyfills/unfetch.umd.js
// Version: 4.1.0
// from: https://unpkg.com/unfetch/dist/unfetch.umd.js
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):e.unfetch=n()}(this,function(){return function(e,n){return n=n||{},new Promise(function(t,o){var r=new XMLHttpRequest,s=[],u=[],i={},f=function(){return{ok:2==(r.status/100|0),statusText:r.statusText,status:r.status,url:r.responseURL,text:function(){return Promise.resolve(r.responseText)},json:function(){return Promise.resolve(JSON.parse(r.responseText))},blob:function(){return Promise.resolve(new Blob([r.response]))},clone:f,headers:{keys:function(){return s},entries:function(){return u},get:function(e){return i[e.toLowerCase()]},has:function(e){return e.toLowerCase()in i}}}};for(var a in r.open(n.method||"get",e,!0),r.onload=function(){r.getAllResponseHeaders().replace(/^(.*?):[^\S\n]*([\s\S]*?)$/gm,function(e,n,t){s.push(n=n.toLowerCase()),u.push([n,t]),i[n]=i[n]?i[n]+","+t:t}),t(f())},r.onerror=o,r.withCredentials="include"==n.credentials,n.headers)r.setRequestHeader(a,n.headers[a]);r.send(n.body||null)})}});
@stefanoimperiale
Copy link

stefanoimperiale commented Jun 29, 2020

This does not work for me. I use can-ndjson-stream to make the fetch requests.

I rewrite the polyfill file to work in my case. I hope it's all ok.

!function (e, n) {
  "object" == typeof exports && "undefined" != typeof module ? module.exports = n() : "function" == typeof define && define.amd ? define(n) : e.unfetch = n()
}(this, function () {
  return function (request) {
    return new Promise(function (success, rejected) {
        var r = new XMLHttpRequest;
        var keys = [];
        var values = [];
        var headers = {};
        var convertRequest = function () {
          var enc = new TextEncoder(); // always utf-8
          return {
            ok: 2 === (r.status / 100 | 0),
            statusText: r.statusText,
            status: r.status,
            url: r.responseURL,
            text: function () {
              return Promise.resolve(r.responseText)
            },
            text: function(){
                          return Promise.resolve(r.responseText)
            },
            json: function(){
                   return Promise.resolve(JSON.parse(r.responseText))
           },
            body: {
              getReader: function () {
                var stream = new ReadableStream({
                  start(controller) {
                    controller.enqueue(enc.encode(r.responseText));
                    controller.close();

                  }
                });
                return new ReadableStreamDefaultReader(stream);
              }
            },
            blob: function () {
              return Promise.resolve(new Blob([r.response]))
            },
            clone: convertRequest,
            headers: {
              keys: function () {
                return keys
              }, entries: function () {
                return values
              }, get: function (header) {
                return headers[header.toLowerCase()]
              }, has: function (header) {
                return header.toLowerCase() in headers
              }
            }
          }
        };

        r.open(request.method || "get", request.url, true);
        r.onload = function () {
          r.getAllResponseHeaders().replace(/^(.*?):[^\S\n]*([\s\S]*?)$/gm, function (match, key, value) {
            key = key.toLowerCase();
            keys.push(key);
            values.push([key, value]);
            headers[key] = headers[key] ? headers[key] + "," + value : value;
          });
          success(convertRequest());
        }
        r.onerror = rejected;
        r.withCredentials = "include" === request.credentials;
        request.headers.forEach((value, key) => r.setRequestHeader(key, value));
        request.text().then(body => r.send(body));
      }
    )
  }
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment