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

Error in cypress_runner.js is reported as "error originated from your application code, not from Cypress" #7594

Closed rhassingerr closed 3 years ago

rhassingerr commented 4 years ago

Current behavior:

When a failure happens in the test script, it's blaming the application code. In the example here, the cy.get() returns an object, but click() mysteriously fails. It does not fail if I remove the click(), but it will fail with the same CORS-related error if I change the image filename to something that doesn't exist on the page. The error takes up huge vertical space and is unhelpful despite all the verbiage.

image

This is an AngularJS 1.x SPA. There are no errors in the console. The app's .js file is served from the same origin as the html.

Intentionally bad code, such as cy.gxet(), shows an appropriate error, e.g.: "cy.gxet is not a function"

Desired behavior:

Tell me what really went wrong, if anything. It could be this is really an internal Cypress bug manifesting itself at cypress_runner.js:155859:20.

Test code to reproduce

describe("Click image button", () => {
  it('Flip image', () => {
    cy.visit("/puzzles/math-search.html");
    cy.get('[ng-src="/images/form/math_search_addition.gif"]').click();
  });
});

Versions

Cypress 4.7.0 MacOS 10.15.5 Chrome 83

rhassingerr commented 4 years ago

From the expanded stacktrace. It looks like the real error is happening somewhere in cypress_runner.js.

image

rhassingerr commented 4 years ago

Here's another try, this time with a super-simple script: just visit and wait. It fails on the wait, again blaming the web application. The web app came up in the browser OK and is usable, no errors in the Chrome browser console or server logs.

image

jennifer-shehane commented 4 years ago

@rhassingerr We'll need some test code that we can run exactly to see the error you are encountering. Can you provide the code with the math-search.html so we can run the test you provided?

Can you downgrade to 3.5.0 and show the behavior in that version of Cypress also?

Without this we'll have to close this issue as there is not enough information to reproduce the problem. This does not mean that your issue is not happening - it just means that we do not have a path to move forward.

Please comment in this issue with a reproducible example and we will consider reopening the issue.

srotak5 commented 4 years ago

I have the same problem, this new annoying error... I didnt have time to manage my tests for last 2 months or so and i come back to this.. Im trying to find the problem now.

At the moment i think that it happens when it wants to do many things at the same time before loading finishes.

But this wasnt happening before, now i have it in most of my tests

srotak5 commented 4 years ago

@jennifer-shehane I made simplest one i can. Hope its enough for analysis and that its the same problem as @rhassingerr has.

   context('Test', () => {
    beforeEach(() => {
        cy.visit('https://dev.commanderservices.eu/')
    });

    //Login//
    it('.type() - type into a DOM element', () => {
        cy.viewport(1920, 1080);

        cy.server()
            .route("POST", '/api/v1/auth/sign-in')
            .as('Login');

        cy.server()
            .route("GET", '/api/v1/user/vehicle/list')
            .as('Vehicle');

        cy.server()
            .route("POST", '/api/v1/ride-book/list-data')
            .as('Data');

        cy.server()
            .route("POST", '/api/v1/ride-book/list-settings')
            .as('Settings');

        cy.get('[data-cy="loginUsername"]')
            .type("test_reader")

        cy.get('[data-cy="loginPassword"]')
            .type("test_reader");

        cy.get('[data-cy="loginSubmit"]')
            .click();

        cy.wait('@Login', {timeout: 60000})
            .should('have.property', 'status', 200);

        cy.wait('@Vehicle', {timeout: 60000})
            .should('have.property', 'status', 200);

        cy.get('[data-cy="navigator-button-remove-all"]')
            .click();

        //Navigate to overview//
        cy.get('#link-4')
            .click();

        cy.wait('@Settings', {timeout: 60000}, {multiple: true})
            .should('have.property', 'status', 200);

        cy.get('#vehicle-49162')
            .click({force: true});

        cy.wait('@Settings', {timeout: 60000}, {multiple: true})
            .should('have.property', 'status', 200);

        cy.wait('@Data', {timeout: 60000}, {multiple: true})
            .should('have.property', 'status', 200);
    }); 
});

Running on Windows 10 Cypress 4.7.0 Chrome 83

rhassingerr commented 4 years ago

It would be complicated to provide more info due to the nature of the application, but I'm still exploring what's going on. Surprisingly, the problem does not happen when I run the same code against the production server - that gives me a really good idea of where to look. There are some differences in the production HTML to make it smaller, css names and json keys are minimized, no diagnostics code, etc. I would dearly like to use cypress instead of our complicated and brittle selenium setup, so I'm motivated to invest more time to find the issue.

rhassingerr commented 4 years ago

This is very strange. Cypress works perfectly if I run it against the production server which is behind Cloudflare. If I run Cypress against the same production server but its direct IP address, it fails.

rhassingerr commented 4 years ago

As suggested, I installed Cypress 3.5.0. It still fails in the same way, but different appearance.

What's strange is that the cy.visit() line works. It's the cy.wait(500) which does not work. What is cy.wait doing that it fails thinking that there was an error in the page? And why would running against the web app through Cloudflare make it work fine? I would think cy.wait would be completely internal to Cypress.

describe("Main page", () => {
    it("can visit the main page", () => {
        cy.visit("localhost:60606/");
        cy.wait(500);
    });
});

image

srotak5 commented 4 years ago

On my side i think the problem is also in my "Dynamic" waits because it doesnt wait until the assert is completed and want to continue the script. @rhassingerr you are doing more digging than cypress support :D

jennifer-shehane commented 4 years ago

@srotak5 This error is being thrown from a cross-origin script, so we don't have access to the error. This error is throwing from all versions of Cypress, so doesn't appear to be a recent regression. If you'd like to ignore Cypress failing when errors are thrown from cross-origin scripts, add the code below to your test file/suite.

Cypress.on('uncaught:exception', (err, runnable) => {
  // returning false here prevents Cypress from
  // failing the test
  return false
})

If I ignore failing - I can see this error in the console now. Perhaps this is the script error that should have been evident before - that Cypress is swallowing for some reason.

Without listener

Screen Shot 2020-06-10 at 2 08 06 PM

With listener

Screen Shot 2020-06-10 at 2 11 53 PM

@rhassingerr The error showing as (:0) is related to this https://github.com/cypress-io/cypress/issues/4717 Can you also try ignoring the exception from the cross origin script? It seems this error throws when running your app outside of production for some reason.

jennifer-shehane commented 4 years ago

Actually, now having the uncaught exception show up in the console I believe is a duplicate of this issue: #5698

srotak5 commented 4 years ago

@jennifer-shehane thank yout, this seems to work so far :)

rhassingerr commented 4 years ago

Is it possible that suppressed errors could be triggering the phantom error problem in cypress? Angular 1.x is well known for ignoring large numbers of errors caused by evals on missing objects and attributes in bits of code written inside HTML attributes. It chooses to do nothing rather than breaking and let the web developer figure it out. I'm in the process of upgrading to Angular 9 with Ivy, and its preprocessor is not letting me get away with anything. The conversion is still in the early stages, but cypress does not fail with the Angular 9 implementation.

rhassingerr commented 4 years ago

@jennifer-shehane I'm going to chalk this up to Angular 1.x behavior and not worth pursuing, unless @srotak5 comes back and says he's experiencing the same problem on a more current framework. I'm having zero problems on the Angular 9 rewrite so far.

jennifer-shehane commented 3 years ago

Since this issue hasn't had activity in a while, we'll close the issue until we can confirm this is still happening. Please comment if there is new information to provide concerning the original issue and we'd be happy to reopen.

ghost commented 3 years ago

@jennifer-shehane @I am facing when I run cypress test this is the error coming from cypress

**The following error originated from your test code, not from Cypress.
`Cannot read property 'firstName' of undefined`
When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.

Cypress could not associate this error to any specific test.

We dynamically generated a new test to display this failure.

Check your console for the stack trace or click this message to see where it originated from.**

And this is my code

const firstName = faker.name.firstName();
const lastName = faker.name.lastName();
const emailAddress = faker.name.firstName()+"@getnada.com";
const adminEmailAddress = faker.name.firstName()+"admin@getnada.com";
const password = 'Password1!';
const PhoneNumber = faker.phone.phoneNumber();
const PhoneNumberFormat = faker.phone.phoneNumberFormat();
const insurerPhoneNumber = faker.phone.phoneNumberFormat(1);
const todaysDate = Cypress.moment().format('l');
const template = faker.name.firstName()+"_Template";
const treatmentTemplate = faker.name.firstName()+"_treatment_Template";
const allergiesName = faker.name.firstName()+"_Allergies";

describe('Create patient from practice', () => {
  beforeEach(() => {
    cy.viewport(1600, 757)
    cy.visit(loginData.Dev_Hub_URL);
    cy.verifyTitle(loginData.title); // verify practicer login page title
    cy.enterText(loginPageSelectors.emailField,dispenserData.practiceEmail3); // enter practicer email
    cy.enterText(loginPageSelectors.passwordField,loginData.password); // enter practicer password
    cy.clickOnElement(loginPageSelectors.submitButton); //click on the sign-in button
  });

  it('Creating the patient successfully', () => {
    cy.clickOnElement(practicePageSelectors.addPatientId); // click on add patient button
    cy.clickOnElementTextWithForce(practiceData.addPatientLink)
    cy.enterText(practicePageSelectors.firstName,firstName); // enter first name of patient
    cy.enterText(practicePageSelectors.lastName,lastName); // enter last name of patient
    cy.enterText(practicePageSelectors.dateOfBirth,'11/07/1992'); // enter date of birth of patient
    cy.enterText(practicePageSelectors.phoneNumber,faker.phone.phoneNumber()); //enter phone number of patient
    cy.clickOnElement(practicePageSelectors.buttonId); // click on submit button
    //cy.verifyAccountVerificationMessage(practiceData.accountCreationMessage); // Verify the account creation message
    cy.clickOnElementUsingText(dispenserData.closeButton,practiceData.buttonTag); // click on the close button
  })
})

yesterday this code running proper but immediate error occurred Please any one help me to solve this error.

jennifer-shehane commented 3 years ago

@KrupalVaghasiya Likely your application is throwing an error. We can't help you because we cannot run the code you provided to see the Cypress tests run. Open your DevTools console and see if there's an error there.

mjkapkan commented 2 years ago

Hi, I have also observed this behaviour. However for me it only happens if I try to use the .click() function in separate it() functions.

For example, this works:

describe('Navigation check', () => {
    it('Open Modal 1 Check', () => {
      cy.contains('Modal1 Button Title').click()
      cy.contains('Modal1 Contents')
      cy.go('back')
      cy.contains('Modal2 Button Title').click
      cy.contains('Modal2 Contents')
      cy.go('back')
  })
})

But this doesn't:

describe('Navigation check', () => {
    it('Open Modal 1 Check', () => {
      cy.contains('Modal1 Button Title').click()
      cy.contains('Modal1 Contents')
      cy.go('back')
    })

    it('Open Modal 2 Check', () => {
      cy.contains('Modal2 Button Title').click
      cy.contains('Modal2 Contents')
      cy.go('back')
  })
})

My system details:

Operating System: Ubuntu 20.04.3 LTS
Kernel: Linux 5.11.0-43-generic
Architecture: x86-64

Cypress package version: 9.2.0
Cypress binary version: 9.2.0
Electron version: 15.2.0
Bundled Node version: 16.5.0
anilpujaraofficial commented 2 years ago

Capture

anilpujaraofficial commented 1 year ago

my problem

Screenshot from 2023-03-02 12-45-52