`cy.clock`/`cy.tick` not working with component testing
Current behavior
My organization recently upgraded from React 17 to React 18 and some tests we had that utilized cy.clock and cy.tick stopped working in our component tests. It seems setTimeout and setInterval are no longer invoked after the cy.tick.
Desired behavior
cy.clock and cy.tick should work in React 18.
Test code to reproduce
To eliminate something in our setup, I create a simple next js app to reproduce. The reproduction can be found here: https://github.com/carpie/cypress-clock-issue
In this repo, I took the sample code and added a useState to set a default message. I added a useEffect that runs a setTimeout that changes the message 2 seconds later. The test checks the default message, cy.ticks for 4 seconds, and checks for the updated message. It appears in React 18, the setTimeout doesn't happen.
Interestingly, if in cypress/support/component.js, I change:
import { mount } from 'cypress/react18'
to
import { mount } from 'cypress/react'
I get warnings about React17, but the test reliably passes.
Steps to reproduce:
git clone https://github.com/carpie/cypress-clock-issue
cd cypress-clock-issue
npm ci
npx cypress open
- Select
Component Testing - Select
Electron - Click
Start Component Testing in Electron - Click
indexHome.cy.js - Test fails
You can also reproduce headlessly:
npx cypress run --component --headless
Cypress Version
13.6.4
Node version
v20.11.0
Operating System
macOS 14.2.1
Debug Logs
No response
Other
No response
@carpie Thanks for the repoduction and opening the issue.
Same.
Same here, @jennifer-shehane. Any updates on when this will be addressed?
Possibly related in Angular: https://github.com/cypress-io/cypress/issues/29810
Is there any update on this? The only thing that keeps us from using component testing is that issue
Hi,
We are also getting the same issue, but it's not really consistent.
Changing the mount import to 'cypress/react' changes how the test behaves and seem to help a lot, however we cannot have warnings on our pipeline.
Is there any update on this?
Thanks,
Louis
Any updates on this?
Still broken in React 19.
Hi, same issue on my side with vanilla Javascript and on e2e tests (#31320 ).
I've debugged it a bit and found out that there's a problem with the way cy.clock is queued in the cypress execution queue. Sometimes it will correctly execute the cy.clock, sometimes it will not. In a successful run it will correctly overwrite the setTimeout and other functions, in other cases the setTimeout function is never triggered.
If I put it in a beforeEach like this it seems to work:
describe('<Home />', () => {
beforeEach(() => {
cy.clock();
})
it('renders', () => {
// see: https://on.cypress.io/mounting-react
cy.mount(<Home />)
cy.get('p').contains('Waiting for timeout');
cy.tick(40000);
cy.get('p').contains('Timeout complete');
})
})
Hi, thank you @denshade for sharing. I try on a JS vanilla exemple, but still not able to make it working.
I have added some additionnal informations to the ticket #31320 thanks to you.