Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite recursion when 3rd party libs are instrumenting XHR's #166

Closed
brian-mann opened this issue Jun 14, 2016 · 2 comments
Closed

Infinite recursion when 3rd party libs are instrumenting XHR's #166

brian-mann opened this issue Jun 14, 2016 · 2 comments
Assignees
Milestone

Comments

@brian-mann
Copy link
Member

brian-mann commented Jun 14, 2016

If a 3rd party lib such as new relic's js instrumentation library wraps XHR's the same way Cypress does, it's possible for there to be an infinite loop while we both call the backed up XHR methods.

I've paired down the root cause to this snippet of code which can cause it.

var handlers = ["onload", "onerror", "onreadystatechange"]

var wrapXhr = function(){
  var xhr = this

  handlers.forEach(function(handler){
    var bak = xhr[handler]

    xhr[handler] = function(){
      if (typeof bak === "function"){
        bak.apply(xhr, arguments)
      }
    }
  })
}

var xhr = new XMLHttpRequest
xhr.addEventListener("readystatechange", wrapXhr, false)
xhr.open("GET", "/comments.json")
xhr.onload = function(){
  // this should continue to hit
  debugger
}
xhr.send()
@brian-mann brian-mann changed the title Infinite recursion 3rd party libs are instrumenting XHR's Infinite recursion when 3rd party libs are instrumenting XHR's Jun 14, 2016
@brian-mann brian-mann self-assigned this Jun 14, 2016
@brian-mann brian-mann added this to the 0.16.3 milestone Jun 14, 2016
@brian-mann
Copy link
Member Author

Fixed in 0.16.3.

@cypress-io cypress-io locked as resolved and limited conversation to collaborators Dec 6, 2018
@flotwig
Copy link
Contributor

flotwig commented Jun 4, 2019

Having a similar issue in 3.3.1, when a user has the New Relic insturmentation code directly embedded in their page, New Relic will replace win.XMLHttpRequest with their own copy, which destroys the functions that we add on to the XMLHttpRequest object.

Doing something like this to rebind the XMLHttpRequest makes the tests pass roughly 50% of the time:

function stubXHR($win) {
  Cypress
  .state('server')
  .bindTo($win)
}

it('loads the page', () => {
  cy.server();
  cy.visit('https://' + server, {
    onBeforeLoad: stubXHR
  });
});

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants