cypress-io / cypress

Fast, easy and reliable testing for anything that runs in a browser.
https://cypress.io
MIT License
46.72k stars 3.16k forks source link

Rewrite 3rd party JS code to enforce that parent + top references are always correct #1467

Closed whites11 closed 4 years ago

whites11 commented 6 years ago

Current behavior:

I setup a very simple test that searches for a link in a web page (given an id) and clicks it. Than it checks the content of another element to check it's correct. What happens is that selectors are found but the test fails. In fact the web page is behaving correctly. I can see an error in the inspector:

Uncaught SyntaxError: Unexpected token <

And another one:

Unhandled rejection TypeError: Cannot read property 'currentRetry' of undefined

Desired behavior:

The test to pass.

How to reproduce:

Just run the test below.

Test code:

describe('Check properties worldwide page', function() {
  beforeEach(function () {
    cy.visit('https://beta.hostelsclub.com/en/hostels');
  })

  it('Opens the correct country page', function () {
    cy.get('a#usa').click();
    cy.get('header.header-country .intro h1').contains('Best hostels in USA');
  })
});

Additional Info (images, stack traces, etc)

err2

jennifer-shehane commented 6 years ago

Usually when there is an error like this, Uncaught SyntaxError: Unexpected token <, my first suspect is that a Network request is responding with HTML when it is expected that it should respond with non-HTML data.

And indeed, there is a Network Request on your end for a default-hostels.jpg returning html content. I would fix this response on your end to respond with an image and maybe write some logic to handle onerror for images.

screen shot 2018-03-15 at 3 09 09 pm

I guess there is the unanswered question of why this error appears this way instead of indicating that there was an error in your application code. 🤔

whites11 commented 6 years ago

Hi Jennifer, thanks for your answer. Your was a good guess, but apparently that is not the problem. I removed the reference to the broken image from the web page but the problem still occours.

Is it possible to know which request is actually causing the error? I had a look at all of them and they look all fine to me now.

jennifer-shehane commented 6 years ago

Yeah, I haven't been able to figure out why this error is not bubbling up correctly in Cypress. There is definitely an error being thrown in our runner. I logged out all of the data for the test run.

Edited: removed logs because it was just noise that just distracts from real issue

whites11 commented 6 years ago

Ok thanks for the update. Any idea on how I can prevent the error (workaround) or why the problem suddently appeared while my tests were running fine since yesterday morning?

brian-mann commented 6 years ago

We investigated the problem - and its being caused exclusively by sidecar-loader.js which is 3rd party code.

The reason is partly Cypress' fault - when the sidecar-loader.js evaluates within Cypress, it will receive a different window.document reference - which then causes failures in its logic.

When it's evaluated outside of Cypress the window.document references are correct. This is in the same similar vein as what we do to prevent obstructive code from preventing Cypress from working - and we think the solution is that we can add additional checks to force javascript code to evaluate correctly (as if it's not running in Cypress).

Workaround

You can simply workaround this problem by blacklisting the 3rd party sidecar code from loading, which will instantly make everything work. To do that, read about blacklisting. You'll need to blacklist sidecar.hoperator.com

Here are my notes / thoughts just for internal reference on rewriting 3rd party JS code to enforce that parent + top references are always correct.

["parent"] ['parent] .parent getters => {
  (window.parent && window.parent.__Cypress__ ? window : window.parent)
}
whites11 commented 6 years ago

Hi Brian. I confirm the workaround works. Thanks a lot for your help guys, I was running out of options!

matthewshirley commented 5 years ago

I believe I have reproduced similar behavior with an internal application. I cannot block the 3rd party JS code that is being evaluated. Is there another workaround I can use?

SurajAbhinandan commented 4 years ago

Any update on this issue please, i am also facing same issue, please suggest if we have any workaround

cypress-bot[bot] commented 4 years ago

The code for this is done in cypress-io/cypress#5273, but has yet to be released. We'll update this issue and reference the changelog when it's released.

cypress-bot[bot] commented 4 years ago

Released in 4.6.0.

This comment thread has been locked. If you are still experiencing this issue after upgrading to Cypress v4.6.0, please open a new issue.

flotwig commented 4 years ago

This fix is available starting in 4.6.0 as an experiment which you can access by setting this config option in your cypress.json or elsewhere:

{
    "experimentalSourceRewriting": true
}

The fix is experimental, so there may be some situations where the this is not fixed.

If you're still this issue while setting the experimentalSourceRewriting to true in 4.6.0 - open a new issue with a reproducible example + screenshots, etc - filling out our issue template.