You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
import{render}from'@testing-library/react'importParentfrom'Components/LazyLoadInconsistency/Parent'importReactfrom'react'test('single test 1',async()=>{const{findByText}=render(<Parent/>)expect(awaitfindByText(/Countis2/i)).toBeInTheDocument()})test('single test 2',async()=>{const{findByText}=render(<Parent/>)expect(awaitfindByText(/Countis2/i)).toBeInTheDocument()})
Parent.js
importReact,{Suspense,useEffect,useRef,useState}from'react'constLazyChild=React.lazy(()=>import('Components/LazyLoadInconsistency/LazyChild'),)classApi{constructor(onSearch){this.onSearch=onSearch}onReady(){this.ready=truethis.search()}search(){if(!this.ready){return}this.onSearch()}}exportdefaultfunctionParent(){const[count,setCount]=useState(0)constapiRef=useRef(newApi(()=>setCount(prevCount=>prevCount+1)))useEffect(()=>{apiRef.current.onReady()},[])return(<Suspensefallback={null}><LazyChildapiRef={apiRef}/><span>Count is {count}</span></Suspense>)}
When I debugged this test run inconsistency, I noticed that React.lazy() is called only once. Because of it, useEffect from LazyChild is fired faster than useEffect from Parent, as it was on the first run, and it is in the real environment, and we see inconsistency when running tests in different modes. Recorded screencast with debugging logging
Suggested solution:
I don't know which side it should be fixed, but I think React.lazy should be fired on each test run to be as close to the real environment as possible. Here is only one call to React.lazy() recorded.
The text was updated successfully, but these errors were encountered:
There is no guarantee for the effect call order in React which changes depending on whether React.lazy is pending or already resolved. Only cleanups have stable order. See facebook/react#16728 and facebook/react#15281 for more information.
This is unfortunately how React.lazy behaves: In the first test the Child won't resolve immediately so you call onReady() in the parent and later, once it resolves, search() in the child. However, in the second test Child will already be resolved and mount immediately. In that case child effects run before parent effects and search() will be called while this.ready is still false (because the parent didn't call onReady yet).
For a different scenario with a similar issue see #716. It also includes a workaround: #716 (comment)
@testing-library/react
version: 11.0.4jest
: 26.4.2jsdom
: 16.4.0Relevant code or config:
Parent.test.js
Parent.js
LazyChild.js
What you did:
I'm running multiple tests from Parent.test.js during a single run.
What happened:
The second test fails even if it is the same as the first one, which passed successfully.
Reproduction:
Please use this repo https://github.com/pahan35/web-ui-boilerplate and branch
bug/lazy-inconsistency
to reproduce the described problem.bug/lazy-inconsistency
.npm i
.It fails :(
Here is a failure on Travis CI.
Problem description:
When I debugged this test run inconsistency, I noticed that
React.lazy()
is called only once. Because of it, useEffect fromLazyChild
is fired faster than useEffect from Parent, as it was on the first run, and it is in the real environment, and we see inconsistency when running tests in different modes. Recorded screencast with debugging loggingSuggested solution:
I don't know which side it should be fixed, but I think
React.lazy
should be fired on each test run to be as close to the real environment as possible. Here is only one call toReact.lazy()
recorded.The text was updated successfully, but these errors were encountered: