Repository: facebook/react
Pull request: Convert EnterLeaveEventPlugin to createRoot


Changed files:
filename: packages/react-dom/src/events/plugins/__tests__/EnterLeaveEventPlugin-test.js
patch: @@ -11,6 +11,8 @@
 
 let React;
 let ReactDOM;
+let ReactDOMClient;
+let act;
 
 describe('EnterLeaveEventPlugin', () => {
   let container;
@@ -20,6 +22,8 @@ describe('EnterLeaveEventPlugin', () => {
 
     React = require('react');
     ReactDOM = require('react-dom');
+    ReactDOMClient = require('react-dom/client');
+    act = require('internal-test-utils').act;
 
     // The container has to be attached for events to fire.
     container = document.createElement('div');
@@ -31,7 +35,7 @@ describe('EnterLeaveEventPlugin', () => {
     container = null;
   });
 
-  it('should set onMouseLeave relatedTarget properly in iframe', () => {
+  it('should set onMouseLeave relatedTarget properly in iframe', async () => {
     const iframe = document.createElement('iframe');
     container.appendChild(iframe);
     const iframeDocument = iframe.contentDocument;
@@ -41,30 +45,36 @@ describe('EnterLeaveEventPlugin', () => {
     iframeDocument.close();
 
     const leaveEvents = [];
-    const node = ReactDOM.render(
-      <div
-        onMouseLeave={e => {
-          e.persist();
-          leaveEvents.push(e);
-        }}
-      />,
+    const root = ReactDOMClient.createRoot(
       iframeDocument.body.getElementsByTagName('div')[0],
     );
-
-    node.dispatchEvent(
-      new MouseEvent('mouseout', {
-        bubbles: true,
-        cancelable: true,
-        relatedTarget: iframe.contentWindow,
-      }),
-    );
+    await act(() => {
+      root.render(
+        <div
+          onMouseLeave={e => {
+            e.persist();
+            leaveEvents.push(e);
+          }}
+        />,
+      );
+    });
+    const node = iframeDocument.body.getElementsByTagName('div')[0].firstChild;
+    await act(() => {
+      node.dispatchEvent(
+        new MouseEvent('mouseout', {
+          bubbles: true,
+          cancelable: true,
+          relatedTarget: iframe.contentWindow,
+        }),
+      );
+    });
 
     expect(leaveEvents.length).toBe(1);
     expect(leaveEvents[0].target).toBe(node);
     expect(leaveEvents[0].relatedTarget).toBe(iframe.contentWindow);
   });
 
-  it('should set onMouseEnter relatedTarget properly in iframe', () => {
+  it('should set onMouseEnter relatedTarget properly in iframe', async () => {
     const iframe = document.createElement('iframe');
     container.appendChild(iframe);
     const iframeDocument = iframe.contentDocument;
@@ -74,31 +84,37 @@ describe('EnterLeaveEventPlugin', () => {
     iframeDocument.close();
 
     const enterEvents = [];
-    const node = ReactDOM.render(
-      <div
-        onMouseEnter={e => {
-          e.persist();
-          enterEvents.push(e);
-        }}
-      />,
+    const root = ReactDOMClient.createRoot(
       iframeDocument.body.getElementsByTagName('div')[0],
     );
-
-    node.dispatchEvent(
-      new MouseEvent('mouseover', {
-        bubbles: true,
-        cancelable: true,
-        relatedTarget: null,
-      }),
-    );
+    await act(() => {
+      root.render(
+        <div
+          onMouseEnter={e => {
+            e.persist();
+            enterEvents.push(e);
+          }}
+        />,
+      );
+    });
+    const node = iframeDocument.body.getElementsByTagName('div')[0].firstChild;
+    await act(() => {
+      node.dispatchEvent(
+        new MouseEvent('mouseover', {
+          bubbles: true,
+          cancelable: true,
+          relatedTarget: null,
+        }),
+      );
+    });
 
     expect(enterEvents.length).toBe(1);
     expect(enterEvents[0].target).toBe(node);
     expect(enterEvents[0].relatedTarget).toBe(iframe.contentWindow);
   });
 
   // Regression test for https://github.com/facebook/react/issues/10906.
-  it('should find the common parent after updates', () => {
+  it('should find the common parent after updates', async () => {
     let parentEnterCalls = 0;
     let childEnterCalls = 0;
     let parent = null;
@@ -117,26 +133,32 @@ describe('EnterLeaveEventPlugin', () => {
       }
     }
 
-    ReactDOM.render(<Parent />, container);
-    // The issue only reproduced on insertion during the first update.
-    ReactDOM.render(<Parent showChild={true} />, container);
+    const root = ReactDOMClient.createRoot(container);
+    await act(() => {
+      root.render(<Parent />);
+    });
+    await act(() => {
+      root.render(<Parent showChild={true} />);
+    });
 
     // Enter from parent into the child.
-    parent.dispatchEvent(
-      new MouseEvent('mouseout', {
-        bubbles: true,
-        cancelable: true,
-        relatedTarget: parent.firstChild,
-      }),
-    );
+    await act(() => {
+      parent.dispatchEvent(
+        new MouseEvent('mouseout', {
+          bubbles: true,
+          cancelable: true,
+          relatedTarget: parent.firstChild,
+        }),
+      );
+    });
 
     // Entering a child should fire on the child, not on the parent.
     expect(childEnterCalls).toBe(1);
     expect(parentEnterCalls).toBe(0);
   });
 
   // Test for https://github.com/facebook/react/issues/16763.
-  it('should call mouseEnter once from sibling rendered inside a rendered component', done => {
+  it('should call mouseEnter once from sibling rendered inside a rendered component in legacy roots', done => {
     const mockFn = jest.fn();
 
     class Parent extends React.Component {
@@ -186,7 +208,7 @@ describe('EnterLeaveEventPlugin', () => {
     ReactDOM.render(<Parent />, container);
   });
 
-  it('should call mouseEnter when pressing a non tracked React node', done => {
+  it('should call mouseEnter when pressing a non tracked React node in legacy root', done => {
     const mockFn = jest.fn();
 
     class Parent extends React.Component {
@@ -237,7 +259,7 @@ describe('EnterLeaveEventPlugin', () => {
     ReactDOM.render(<Parent />, container);
   });
 
-  it('should work with portals outside of the root that has onMouseLeave', () => {
+  it('should work with portals outside of the root that has onMouseLeave', async () => {
     const divRef = React.createRef();
     const onMouseLeave = jest.fn();
 
@@ -249,21 +271,27 @@ describe('EnterLeaveEventPlugin', () => {
       );
     }
 
-    ReactDOM.render(<Component />, container);
+    const root = ReactDOMClient.createRoot(container);
+
+    await act(() => {
+      root.render(<Component />);
+    });
 
     // Leave from the portal div
-    divRef.current.dispatchEvent(
-      new MouseEvent('mouseout', {
-        bubbles: true,
-        cancelable: true,
-        relatedTarget: document.body,
-      }),
-    );
+    await act(() => {
+      divRef.current.dispatchEvent(
+        new MouseEvent('mouseout', {
+          bubbles: true,
+          cancelable: true,
+          relatedTarget: document.body,
+        }),
+      );
+    });
 
     expect(onMouseLeave).toHaveBeenCalledTimes(1);
   });
 
-  it('should work with portals that have onMouseEnter outside of the root ', () => {
+  it('should work with portals that have onMouseEnter outside of the root ', async () => {
     const divRef = React.createRef();
     const otherDivRef = React.createRef();
     const onMouseEnter = jest.fn();
@@ -279,7 +307,11 @@ describe('EnterLeaveEventPlugin', () => {
       );
     }
 
-    ReactDOM.render(<Component />, container);
+    const root = ReactDOMClient.createRoot(container);
+
+    await act(() => {
+      root.render(<Component />);
+    });
 
     // Leave from the portal div
     divRef.current.dispatchEvent(