@@ -13,6 +13,7 @@ let React;
13
13
14
14
let ReactDOM ;
15
15
let Scheduler ;
16
+ let act ;
16
17
17
18
describe ( 'ReactDOMNativeEventHeuristic-test' , ( ) => {
18
19
let container ;
@@ -23,6 +24,7 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
23
24
React = require ( 'react' ) ;
24
25
ReactDOM = require ( 'react-dom' ) ;
25
26
Scheduler = require ( 'scheduler' ) ;
27
+ act = require ( 'react-dom/test-utils' ) . unstable_concurrentAct ;
26
28
27
29
document . body . appendChild ( container ) ;
28
30
} ) ;
@@ -225,4 +227,68 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
225
227
// Therefore the form should have been submitted.
226
228
expect ( formSubmitted ) . toBe ( true ) ;
227
229
} ) ;
230
+
231
+ // @gate experimental
232
+ // @gate enableDiscreteEventMicroTasks && enableNativeEventPriorityInference
233
+ it ( 'mouse over should be user-blocking but not discrete' , async ( ) => {
234
+ const root = ReactDOM . unstable_createRoot ( container ) ;
235
+
236
+ const target = React . createRef ( null ) ;
237
+ function Foo ( ) {
238
+ const [ isHover , setHover ] = React . useState ( false ) ;
239
+ React . useLayoutEffect ( ( ) => {
240
+ target . current . onmouseover = ( ) => setHover ( true ) ;
241
+ } ) ;
242
+ return < div ref = { target } > { isHover ? 'hovered' : 'not hovered' } </ div > ;
243
+ }
244
+
245
+ await act ( async ( ) => {
246
+ root . render ( < Foo /> ) ;
247
+ } ) ;
248
+ expect ( container . textContent ) . toEqual ( 'not hovered' ) ;
249
+
250
+ await act ( async ( ) => {
251
+ const mouseOverEvent = document . createEvent ( 'MouseEvents' ) ;
252
+ mouseOverEvent . initEvent ( 'mouseover' , true , true ) ;
253
+ dispatchAndSetCurrentEvent ( target . current , mouseOverEvent ) ;
254
+
255
+ // 3s should be enough to expire the updates
256
+ Scheduler . unstable_advanceTime ( 3000 ) ;
257
+ expect ( Scheduler ) . toFlushExpired ( [ ] ) ;
258
+ expect ( container . textContent ) . toEqual ( 'hovered' ) ;
259
+ } ) ;
260
+ } ) ;
261
+
262
+ // @gate experimental
263
+ // @gate enableDiscreteEventMicroTasks && enableNativeEventPriorityInference
264
+ it ( 'mouse enter should be user-blocking but not discrete' , async ( ) => {
265
+ const root = ReactDOM . unstable_createRoot ( container ) ;
266
+
267
+ const target = React . createRef ( null ) ;
268
+ function Foo ( ) {
269
+ const [ isHover , setHover ] = React . useState ( false ) ;
270
+ React . useLayoutEffect ( ( ) => {
271
+ target . current . onmouseenter = ( ) => setHover ( true ) ;
272
+ } ) ;
273
+ return < div ref = { target } > { isHover ? 'hovered' : 'not hovered' } </ div > ;
274
+ }
275
+
276
+ await act ( async ( ) => {
277
+ root . render ( < Foo /> ) ;
278
+ } ) ;
279
+ expect ( container . textContent ) . toEqual ( 'not hovered' ) ;
280
+
281
+ await act ( async ( ) => {
282
+ // Note: React does not use native mouseenter/mouseleave events
283
+ // but we should still correctly determine their priority.
284
+ const mouseEnterEvent = document . createEvent ( 'MouseEvents' ) ;
285
+ mouseEnterEvent . initEvent ( 'mouseenter' , true , true ) ;
286
+ dispatchAndSetCurrentEvent ( target . current , mouseEnterEvent ) ;
287
+
288
+ // 3s should be enough to expire the updates
289
+ Scheduler . unstable_advanceTime ( 3000 ) ;
290
+ expect ( Scheduler ) . toFlushExpired ( [ ] ) ;
291
+ expect ( container . textContent ) . toEqual ( 'hovered' ) ;
292
+ } ) ;
293
+ } ) ;
228
294
} ) ;
0 commit comments