cypress-io / cypress

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

Cypress 10.0.2 is bypassing resize observer loop error handler #22113

Open mlberkow opened 2 years ago

mlberkow commented 2 years ago

Current behavior

This error is showing up on tests that are set to ignore the error.

The following error originated from your test code, not from Cypress.
  > ResizeObserver loop limit exceeded
When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.
Because this error occurred during a after all hook we are skipping all of the remaining tests.
Although you have test retries enabled, we do not retry tests when before all or after all hooks fail

This was working correctly prior to the Cypress 10 upgrade.

Desired behavior

Optimally the error would just be ignored

Test code to reproduce

const resizeObserverLoopErrRe = /^[^(ResizeObserver loop limit exceeded)]/;

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

Cypress Version

10.0.2

Other

No response

lmiller1990 commented 2 years ago

Hi! Thanks for the bug report. Can you provide your OS/Browser? Does it happen in all of them?

If you could provide a minimal repository, that would be really helpful in debugging.

If it helps, we also have a similar snippet for some of our component tests: https://github.com/cypress-io/cypress/blob/a8ed29ecbbf7ca29466dc48dd0d91903e1851e5e/packages/app/cypress/component/support/index.ts#L52

I wonder if some white space changed, that's messing with the regular expression you are using :thinking:

mlberkow commented 2 years ago

So far, I've only tested it with Electron. I'll give it a shot with the other browsers tomorrow.

It is relatively inconsistent, in that it seems to only happen every few test runs. It happens on the same test when it does happen, but it isn't every run.

AtofStryker commented 2 years ago

@mlberkow is the error always originating from the test code in your case? What happens if you try the fail handler in stead of the uncaught:exception, out of curiosity? Similar to https://github.com/cypress-io/cypress/issues/22129#issuecomment-1150340007?

mjhenkes commented 2 years ago

@mlberkow any update to @AtofStryker's question?

mlberkow commented 2 years ago

@AtofStryker it didn't make any difference, the test still fails pretty often. This problem is most definitely new with 10.x

AtofStryker commented 2 years ago

@AtofStryker it didn't make any difference, the test still fails pretty often. This problem is most definitely new with 10.x

@mlberkow I'm having some trouble reproducing it. Is there any way you could provide a test case / reproduction to showcase the error to determine a potential root cause?

mjhenkes commented 2 years ago

Right now there doesn't seem to be enough information to reproduce the problem on our end. We'll have to close this issue until we can reproduce it. This does not mean that your issue is not happening - it just means that we do not have a path to move forward.

Please open a new issue with a reproducible example and link to this issue. Here are some tips for providing a Short, Self Contained, Correct, Example and our own Troubleshooting Cypress guide.

nielsuit227 commented 2 years ago

Experiencing the same. It's hard to make a correct reproducible example with an obscure error such as this. If only I knew where the problem was coming from... Meanwhile we're stuck and reverting to Cypress 9.

AtofStryker commented 2 years ago

Experiencing the same. It's hard to make a correct reproducible example with an obscure error such as this. If only I knew where the problem was coming from... Meanwhile we're stuck and reverting to Cypress 9.

@nielsuit227 Any idea if the error is being thrown from the application or the test code?

nielsuit227 commented 2 years ago

@AtofStryker Cypress throws the error, but indicates it came from the application code. We have experienced this error from the application code, so that could very well be.

AtofStryker commented 2 years ago

@nielsuit227 have you tried the work around @lmiller1990 proposed https://github.com/cypress-io/cypress/issues/22113#issuecomment-1146948262? If the error is occurring in a cy.origin block you will also need to declare the handler there.

ottopaulsen commented 2 years ago

Did anyone find a solution to this problem? I am seeing the same when running a loop testing hundreds of pages in an MPA. The error comes after running many pages using cypress run. If I run all 371 pages using cypress open, it does not fail. It fails both using chrome and electron, but not the exact same pages. The pages are similar (but with some differences).

I do not understand how you can close the issue if it has not been fixed.

ottopaulsen commented 2 years ago

I solved this by increasing the viewport size for cypress.

nestor-aleks commented 2 years ago

@ottopaulsen can you share your dimension, please? For me, it's still failing with viewports

  viewportWidth: 1536,
  viewportHeight: 960,

macbook-16 from https://docs.cypress.io/api/commands/viewport#Arguments

ottopaulsen commented 1 year ago

I just set

  "viewportHeight": 667,
  "viewportWidth": 375

in this case, @nestor-aleks.

Fewwy commented 1 year ago

Got the same error when I was writing a test that included an interception of the network request made by graphql. Viewport changes didn't help

lmiller1990 commented 1 year ago

@Fewwy what version of Cypress are you on? Can you share a little more information (End to End or Component Testing, version of libraries, etc)? Did you try Firefox? A minimal reproduction would be great, although maybe tough.

tedscape commented 1 year ago

@lmiller1990 , The issue occurs for me as well. We are on cypress 12.7.0. I get this resize observer mode when running headless. When I run in the interactive mode, it passes on chrome, electron and firefox. We do e2e with mocked API's. This has been happening after upgrading to cypress 12. We were on 9 before. Unfortunately, I cannot share the code.

joeprivettsmart commented 1 year ago

We are experiencing the same issue. Using v10.11.0. Tests fail based on cy:command ✘ uncaught exception Error: ResizeObserver loop limit exceeded showing up in the test run, using headless browser in Electron 106, Node v 16.13.0. When using --headed flag in the command line, the same test does show this exception and, therefore, does not fail.

Adding Cypress.on('uncaught:exception', err => !err.message.includes('ResizeObserver')) to e2e.ts does not capture the exceptions.

We're not using cy.origin in any of our tests.

An example of the test that throws this exception is:

const headerTests = (isMobile = false) => {
  beforeEach(() => {
    isMobile && cy.viewport('iphone-x')
    cy.ensureSessionAndVisitUrl('account_live', '/', 'AUTH_EMAIL_LIVE')
  })

  specify('navigate by all items after menu open', () => {
    cy.wrap(HAMBURGER_MENU_NAVIGATION_LINKS).each(({ link, path }: TNavLink) => {
      cy.visit(paths.dashboard.board)
      cy.findByText('Menu').click()
      cy.findByText('Signed in as')
      cy.findByText('Mr Alex Smith')
      cy.waitForTextAndClick(link, 0, path)
      cy.findByText('Signed in as').should('not.exist')
      cy.findByText('Mr Alex Smith').should('not.exist')
      cy.url().should('include', path)
    })
  })
})

The message we see in the terminal is:

Although you have test retries enabled, we do not retry tests when before all or after all hooks fail at (https://localhost:3001/__/#/specs/runner?file=tests/account_live/layout/header.spec.ts:0:0)]]>

lazovskih commented 1 year ago

Hello. Just to support the investigation. We have the same issue (!!!) only when run headless on chrome browser.

Here is some info:

cypress version Cypress package version: 12.5.1 Cypress binary version: 12.5.1 Electron version: 21.0.0 Bundled Node version: 16.16.0 cypress info

Displaying Cypress info...

Chrome

  • Name: chrome
  • Channel: stable
  • Version: 112.0.5615.121
  • Executable: google-chrome
  • Profile: /home/{user}/.config/Cypress/cy/production/browsers/chrome-stable

In e2e.js we have the following:

import './commands';
Cypress.setMaxListeners(40);
Cypress.on('uncaught:exception', (err, runnable) => {
  console.log(`----------- 1 uncaught:exception: ${err}`);
  const resizeObserverLoopLimitExcedError = 'ResizeObserver loop limit exceeded';
  const resizeObserverLoopNotificationError =
    'ResizeObserver loop completed with undelivered notifications';
  if (
    err.message.includes(resizeObserverLoopLimitExcedError) ||
    err.message.includes(resizeObserverLoopNotificationError)
  )  return false;
});

Looks like this code do not execute, as the handler does not catch the error and we do not get logs in the console.

I attempted to put the same code in test file (*.spec.js) and I attempted to use it in the page open function (where we have cy.visit()). Nether worked.

I got this in console: Error: The following error originated from your test code, not from Cypress.

ResizeObserver loop limit exceeded When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.

The only workaround solution is to open page by click on menu item with the link to the same page. This makes tests pass even 'ResizeObserver loop limit exceeded' still observed, but ignored.

Please note, in both cases it is ignored when run in browser mode (cypress open).

Please let me know if you need more info. Thanks!

zuzusik commented 1 year ago

We are experiencing ResizeObserver loop limit exceeded error when running component tests in headless mode with official Cypress Docker image.

When running headless with electron outside of Docker this error is not present. Running in headed mode doesn't produce error either.

Cypress version: 12.3.0 Docker image: cypress/included:12.3.0

mschile commented 1 year ago

Thanks for the updates everyone. Would anyone be able to provide a reproduction repository by forking cypress-test-tiny or by any other means?

Would anyone be able to provide the DEBUG logs?

lmiller1990 commented 1 year ago
mschile commented 1 year ago

@lmiller1990, this issue is for scenarios where the uncaught:exception handler is not firing. Unfortunately, we don't have a reproduction for that scenario yet.

Fabo95 commented 1 year ago

The output of DEBUG=cypress: seems to be very long, so which part is helpful for debugging?

mschile commented 1 year ago

The output of DEBUG=cypress: seems to be very long, so which part is helpful for debugging?

@Fabo95, I'm not sure right now. I was hoping something around when the error occurred might be helpful. Ultimately, we'll probably need a reproduction so we can investigate.

chrisbreiding commented 1 year ago

Right now there doesn't seem to be enough information to reproduce the problem on our end. Unless we receive a reliable reproduction, we'll eventually have to close this issue until we can reproduce it. This does not mean that this issue is not happening - it just means that we do not have a path to move forward.

jogelin commented 1 year ago

We also had that issue with Monaco Editor because it is using ResizeObserver internally.

To fix it, we patched the original API by doing:

class CalmResizeObserver extends ResizeObserver {
  constructor(callback: ResizeObserverCallback) {
    super((entries, observer) => {
      requestAnimationFrame(() => {
        callback(entries, observer);
      });
    });
  }
}

win.ResizeObserver = CalmResizeObserver;
chrisbreiding commented 1 year ago

I'm going close this since there still isn't a reproduction we can use to debug it. Please comment with a minimal reproduction and we can re-open this.

Fabo95 commented 1 year ago

Until now i can not reproduce it and we can not share the original project where the error happens.

So i dived into the cypress project code and saw that the "top.addEventListener('error', onTopError('error'))" inside of onTopError handler function is responsibile for the ResizeObserver error from spec files. This handler is only triggered in headless mode. So i tried to compare version 12.13 with version 9.7 but could not find any differences realted to this behaviour. Therefore i want to ask you if there are major changes realted to this behaviour? Or could it be browser related because (in my case) the error occurs not in firefox.

agugut-nexgen commented 1 year ago

Hello Team I'm having the same issue with cypress 12.15.0 I have this config // Add this uncaught to avoid chrome error on pre prod Cypress.on('uncaught:exception', (err) => { const resizeObserverLoopErrRe = /^[^(ResizeObserver loop limit exceeded)]/; if ( err.message.includes("Cannot set property 'status' of undefined") || err.message.includes("Cannot read property 'method' of undefined") || err.message.includes('Cannot set properties of undefined') || err.message.includes('Cannot read properties of undefined') || err.message.includes('timeLeftSeconds') || resizeObserverLoopErrRe.test(err.message) ) { // returning false here prevents Cypress from // failing the test return false; } return true; }); And the test is failing i n the after each with timeLeftSeconds

mike-plummer commented 1 year ago

@agugut If you can provide a reproducible example (ideally in the form of a git project we can clone and run ourselves) we would be happy to take another look at this issue. Without an example spec + config that generates the error it is extremely difficult to identify what could be causing the problem.

mattleonowicz commented 1 year ago

Same case here. I upgraded from 9 to 12 and the handler stopped catching it. In my case this issue only happened when run on GitLab CI. Im using running it on images like cypress/browsers:node18.12.0-chrome107 with headless mode.

The only thing that fixed it on CI was running with --browser chrome --headed params. I hope it helps someone.

For headless electron on CI, I did try to do some logging inside of the Cypress.on('unhandled:error') with the help of ELECTRON_ENABLE_LOGGING=true cypress run ... and it seems like the handler is run, and going into the branch where it's returning false, but either returning "false" does not work in this scenario, or the handler runs for some instances of the error, and doesn't for the others.

This is my handler: in e2e.ts

Cypress.on('uncaught:exception', (err, _runnable, promise) => {
  console.log('uncaught:exception - err', err.message);
  console.log('uncaught:exception - err.cause', err.cause);
  console.log('uncaught:exception - promise', promise);
  if (err.message.includes('ResizeObserver')) {
    console.log('uncaught:exception should ignore');
    // returning false here prevents Cypress from failing the test
    return false;
  }
  console.log('uncaught:exception - NOT IGNORING ERROR');
  return true;
});

Thats the output from CI console.

Screenshot 2023-07-13 at 14 52 44

I'm sorry I can't share the source code, nor can I easily create a minimal reproducible example. I wonder if this is only Linux related issue? It never does this on my local Mac.

nagash77 commented 1 year ago

Hi @mattleonowicz , I'm curious what happens if you use a docker image with the a version of chrome >112. Can you try that out?

mattleonowicz commented 1 year ago

@nagash77 It doesn't have any impact. I just tested on you latest cypress/browsers:node-18.16.0-chrome-114.0.5735.133-1-ff-114.0.2-edge-114.0.1823.51-1 image.

So headless Chrome 114 has the same behaviour as headless Electron 106 or headless Chrome 107.

lmiller1990 commented 1 year ago

Unfortunate - it was worth a try. I don't think much can be done with a minimal reproduction - without one, we are just stumbling around and hoping to get lucky with a fix.

Fabo95 commented 10 months ago

In our case the error is getting triggered by layout elements rendered in the frontend. I was confused about that because the error message "The following error originated from your test code, not from Cypress." expresses that something is broken inside the test. For me it seems like that for some reason cypress is throughing errors as test errors even they are comming from the application.

We fixed this with a work around by overwriting the ResizeObserver callback with a debounce instance of it inside of onBeforeLoad property of the visit function options.


 onBeforeLoad(win: Cypress.AUTWindow) {
            const originalResizeObserver = win.ResizeObserver;

            const debouncedResizeObserver = (callback: () => void) => {
                const debouncedCallback = debounce(callback, 50);
                return new originalResizeObserver(debouncedCallback);
            };

            cy.stub(win, "ResizeObserver").callsFake(debouncedResizeObserver);
        }, 

We are totally aware that this is not the perfect solution, but hopefully it helps other folks to fully understand the issue.

mikoca commented 10 months ago

This issue is still persist in cypress 13.6.1.

dominics commented 10 months ago

I think a minimal reproduction has to include the contents of the page, because I think it's influenced by things like using a MUI TextArea on the page being resized. That's as far as I've got. Any minimal reproduction that tries to remove the original app context tends to make the issue disappear.

A minimal reproduction should aim to:

  • Cause a resize loop (already hard, because it depends on the exact layout, viewport size, etc.), that...
  • Comes from the outer frame, so the error comes through as "not from the code under test"
stefan-krajnik commented 7 months ago

The issue is still present in 13.6.6

stephsavoie commented 6 months ago

I just experienced that issue (in headed mode, though). In my case, Cypress seems to throw when the test renders a component that uses the ResizeObserver API (it uses useElementSize composable from VueUse library.). When I comment the composer function in the code, Cypress runs the test without any error.

Cypress 13.2, Node 20.8, Viewport size 1000x1000

[edit] Well, it doesn't seem to be directly related to that, the same component used in a sibling page does not trigger the error in a new Cypress test...

felipecao commented 6 months ago

I'm having trouble with Cypress v13.7.2 as well (headed mode)

Here's a mini example using a GSuite account, which throws the following error and makes the test fail: (uncaught exception)Error: ResizeObserver loop completed with undelivered notifications.

describe('Authentication', () => {
  it('should be able to log in', () => {
    const email = 'test@<your gsuite domain>.com';
    const password = 'some random password';

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

    cy.visit("https://mail.google.com");

    cy.get('input#identifierId').should('be.visible').type(email);
    cy.get('input#identifierId').should('contain.value', email);
    cy.contains('span', 'Next').click();
    cy.get('input[type="password"]').should('be.visible', {timeout: 30000}).type(password);
    cy.get('button[type="button"]').eq(1).should('be.enabled').click({force: true});

  });
});
DevPerers commented 2 months ago

for me its works , when I add the following code into cypress/support/e2e.ts file

const resizeObserverLoopErrRe = /^[^(ResizeObserver loop limit exceeded)]/
Cypress.on('uncaught:exception', (err) => {
    // returning false here prevents Cypress from failing the test
    if (resizeObserverLoopErrRe.test(err.message)) {
        return false
    }
})