Component test using `cypress/react18` behaves differently than `cypress/react`
See original GitHub issueCurrent behavior
I have a component test that is testing a slate (slatejs.org) editor by simply typing some text. Using the import cypress/react
the test works fine. Using the import cypress/react18
the test fails. The issue seems to be something due to it calling setFocus
and updating the react state when focus is gained. The test fails as no text is ever entered in to the editor.
Commenting out the setFocus
state update means the test passes under react 18.
Desired behavior
The test should pass the same using cypress/react
and cypress/react18
.
Test code to reproduce
import React, { useState } from 'react';
import { Slate, Editable, withReact } from 'slate-react';
import { mount } from 'cypress/react18';
import { createEditor, Descendant } from 'slate';
const MyComponent = () => {
const [, setFocused] = useState<true | false>();
const [editor] = useState(() => withReact(createEditor()));
const [editorValue, setEditorValue] = useState<Descendant[]>([{
type: 'paragraph',
children: [{ text: '' }],
}]);
return (
<Slate
editor={editor}
value={editorValue}
onChange={(newValue) => {
setEditorValue(newValue);
}}>
<Editable
data-testid="styled-text-input"
placeholder="Please enter a value..."
onFocus={(event) => {
setFocused(true);
}} />
</Slate>
);
};
describe('MyComponent', () => {
it('should render text when typed', () => {
mount(
<MyComponent />,
);
// Check component is in it's default state.
cy.get('[data-testid="styled-text-input"]').should('be.visible');
cy.get('[data-testid="styled-text-input"]').should('contain.text', 'Please enter a value...');
// Brag about some coconuts.
cy.get('[data-testid="styled-text-input"]').click();
cy.get('[data-testid="styled-text-input"]').type('I\'ve got a lovely bunch of coconuts');
cy.get('[data-testid="styled-text-input"]').should('have.text', 'I\'ve got a lovely bunch of coconuts');
});
});
Cypress Version
10.6.0
Node version
18.3.0
Operating System
macOS 12.4
Debug Logs
No response
Other
React: 18.2.0 Slate: 0.72.8
Issue Analytics
- State:
- Created a year ago
- Comments:9 (5 by maintainers)
Top Results From Across the Web
React Component Testing Using Cypress
In this type of testing, objects can be tested independently as individual components without integrating with other components e.g., modules, ...
Read more >My Vision for Component Tests in Cypress - Gleb Bahmutov
The component test directly imports TodoForm from the application code and mounts it using mount method from the cypress-react-unit-test .
Read more >Testing Environments - React
End-to-end tests are used for testing longer flows across multiple pages, ... like Cypress, puppeteer and webdriver are useful for running end-to-end tests....
Read more >How to Test React Components: the Complete Guide
Mount/render is typically used for integration testing and shallow is used for unit testing. shallow rendering only renders the single component ...
Read more >Getting Started with Cypress Component Testing (React)
As of Cypress 7.0, the new Component Test Runner is now bundled with Cypress! It builds on our learnings from the original component...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Hm this is strange. Nice that you’ve found a work around, but this is definitely not ideal and seems like a bug.
I will look into this a bit more, but I can’t commit to patching this in the near future, since I’m unsure of the scope of changes required.
I find it very strange this only impacts React 18. Something obviously has changed internally - our React 18 adapter code is identical except for using
react-dom/client
(new, recommended API).We should try reproducing this with a regular input controlled by React - I’ve got a sneaking suspicion this is something to do with how
react-slate
is implemented. Is this areact-slate
only bug?https://github.com/cypress-io/cypress/issues/23589 is similar. Both related to React and Cypress typing really fast, this one is React 17, though.
I don’t know how React 18 works internally, but iirc older versions of React (and maybe v18) has a kind of synthetic event system (not just regular DOM events, it wraps or intercepts them in some fashion). I wonder if this is related to that. Regular DOM events are synchronous, which Cypress assumes to be the case - perhaps there is something specific about React that doesn’t play well with rapidly fired DOM events.
I wonder if we could write a custom command that does something like
typeAndWait
where it will not trigger the net character input until the previous one is actually rendered. Something likeJust throwing ideas out there, since it’s not entirely clear if this is a bug in Cypress, or just a side effect of a series of assumptions Cypress makes about typing and DOM events (or something entirely different).