简体   繁体   中英

Cypress tests suddenly failing on click when upgrading to React18 / Next.js13

Summary
The cypress test suite on our project is consistently failing on a few tests on the branch updating React to version 18 and Next.js to version 13. It fails on clicking elements, with the 'element has detached from the DOM' error. The development environment is set to react strict mode, which the tests run on.

The Problem
We are using MUI 5, and the test is to check different inputs and buttons. The overall problem in the tests is that it is unable to click the checkbox input from MUI, as well as a link on a Card component from MUI as well. The checkbox is in a dialog modal component.

The test does not error on the click() command, and the test proceeds as if it clicked it, but the checkbox does not actually get clicked on the screen. Adding a cy.wait() after this click does result in the checkbox actually getting clicked, but I would prefer an alternative to wait.

The test does however fail on the click() command when clicking the link in the Card component, with the following error: Cypress Error on click()

Adding a wait to the click() that clicks the 'vehicle-card-link' element makes the test and the click quite flaky, and somehow makes other tests in the same test suite that were previously not failing, more flaky.

The Test Code
The following is the cypress test code that is failing, with added comments for context:

// The test
cy.getBySel('more-filters-button').click(); // Opens the MUI Dialog Modal
cy.get('input[name="condition"][value="New"]').click(); // Gets the Checkbox component and clicks on it
cy.getBySel('save-filter-modal').click(); // Clicks a button to close the modal
cy.getBySel('vehicle-card-link').first().click(); // Gets the first MUI Card and clicks on the link
cy.getBySel('vehicle-name').should('exist’); // Checks that the new page with a specific element has opened

// from the commands.js file, for context
Cypress.Commands.add('getBySel', (selector, args, operator = '') => cy.get(`[data-cy${operator}=${selector}]`, { ...args }));

Some More Context: We use the data-cy attribute on components to help with testing, and the custom command above helps to get those elements in cypress.

Important Notes

  1. This is one of the failing tests, the others follow a similar pattern and I have left them out. If you would like more examples, I can add them.
  2. This test does not fail on any other PR, neither is it very flaky on other PRs. The PR this is failing on only updates React to React18, and Next to Next13, along with a few changes to how images render with Next13, and should not be affecting this part of the app or code.
  3. There are other tests for other parts of the app that use checkbox and card components from MUI that are not failing.

Suspected Cause
I imagine this has to do with strict mode on React, and it reloading the elements on the page twice.

What I've Tried

  1. Adding guards before the click command:
    .should('exist'), and
    .should('be.visible')
    This does not affect the behaviour of the problematic tests.

  2. Adding a cy.wait(100) after the click.
    This makes the test go from failing every time to quite flaky as mentioned before, when it comes the vehicle-card-link MUI Card element.

  3. Adding a timeout or delay to the click command
    . click({delay: 1000}) or click({timeout: 1000})
    This does not affect the behaviour of the problematic tests.

The fundamental problem is there are zero checks on the page changes that occur after each action.

The tests will try to run at the fastest speed possible, and that means you can (sometimes) get stale elements picked up (hence detached errors).

Add some visual check after actions, as example

// open modal and confirm it's open
cy.getBySel('more-filters-button').click(); 
cy.contains('My Modal Title Here').should('be.visible')

// Change state, save, confirm modal is closed 
cy.get('input[name="condition"][value="New"]').click(); 
cy.getBySel('save-filter-modal').click(); 
cy.contains('My Modal Title Here')
  .should('not.be.visible')
//  .should('not.exist')     // or this one

// Carry on after save action is complete
cy.getBySel('vehicle-card-link').first().click(); 

Update to Cypress v12.2.0

The latest version of Cypress has revamped queries that detect detached errors and fixes them when the runner finds them.

This step alone should fix your issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM