diff --git a/packages/react-dom/src/__tests__/ReactBrowserEventEmitter-test.js b/packages/react-dom/src/__tests__/ReactBrowserEventEmitter-test.js
index a226c3736bc26..1dd665ce01145 100644
--- a/packages/react-dom/src/__tests__/ReactBrowserEventEmitter-test.js
+++ b/packages/react-dom/src/__tests__/ReactBrowserEventEmitter-test.js
@@ -10,8 +10,9 @@
'use strict';
let React;
-let ReactDOM;
+let ReactDOMClient;
let ReactTestUtils;
+let act;
let idCallOrder;
const recordID = function (id) {
@@ -34,6 +35,7 @@ let PARENT;
let CHILD;
let BUTTON;
+let renderTree;
let putListener;
let deleteAllListeners;
@@ -47,9 +49,9 @@ describe('ReactBrowserEventEmitter', () => {
LISTENER.mockClear();
React = require('react');
- ReactDOM = require('react-dom');
+ ReactDOMClient = require('react-dom/client');
ReactTestUtils = require('react-dom/test-utils');
-
+ act = require('internal-test-utils').act;
container = document.createElement('div');
document.body.appendChild(container);
@@ -68,21 +70,26 @@ describe('ReactBrowserEventEmitter', () => {
}
}
- function renderTree() {
- ReactDOM.render(
-
(GRANDPARENT = c)} {...GRANDPARENT_PROPS}>
-
(PARENT = c)} {...PARENT_PROPS}>
-
-
-
,
- container,
- );
- }
-
- renderTree();
+ const root = ReactDOMClient.createRoot(container);
+
+ renderTree = async function () {
+ await act(() => {
+ root.render(
+ (GRANDPARENT = c)} {...GRANDPARENT_PROPS}>
+
(PARENT = c)} {...PARENT_PROPS}>
+
+
+
,
+ );
+ });
+ };
- putListener = function (node, eventName, listener) {
+ putListener = async function (node, eventName, listener) {
switch (node) {
case CHILD:
CHILD_PROPS[eventName] = listener;
@@ -98,9 +105,10 @@ describe('ReactBrowserEventEmitter', () => {
break;
}
// Rerender with new event listeners
- renderTree();
+ await renderTree();
};
- deleteAllListeners = function (node) {
+
+ deleteAllListeners = async function (node) {
switch (node) {
case CHILD:
CHILD_PROPS = {};
@@ -115,7 +123,7 @@ describe('ReactBrowserEventEmitter', () => {
BUTTON_PROPS = {};
break;
}
- renderTree();
+ await renderTree();
};
idCallOrder = [];
@@ -126,120 +134,178 @@ describe('ReactBrowserEventEmitter', () => {
container = null;
});
- it('should bubble simply', () => {
- putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, CHILD));
- putListener(PARENT, ON_CLICK_KEY, recordID.bind(null, PARENT));
- putListener(GRANDPARENT, ON_CLICK_KEY, recordID.bind(null, GRANDPARENT));
- CHILD.click();
+ it('should bubble simply', async () => {
+ await renderTree();
+ await putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, CHILD));
+ await putListener(PARENT, ON_CLICK_KEY, recordID.bind(null, PARENT));
+ await putListener(
+ GRANDPARENT,
+ ON_CLICK_KEY,
+ recordID.bind(null, GRANDPARENT),
+ );
+ await act(() => {
+ CHILD.click();
+ });
expect(idCallOrder.length).toBe(3);
expect(idCallOrder[0]).toBe(CHILD);
expect(idCallOrder[1]).toBe(PARENT);
expect(idCallOrder[2]).toBe(GRANDPARENT);
});
- it('should bubble to the right handler after an update', () => {
- putListener(GRANDPARENT, ON_CLICK_KEY, recordID.bind(null, 'GRANDPARENT'));
- putListener(PARENT, ON_CLICK_KEY, recordID.bind(null, 'PARENT'));
- putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, 'CHILD'));
- CHILD.click();
+ it('should bubble to the right handler after an update', async () => {
+ await renderTree();
+ await putListener(
+ GRANDPARENT,
+ ON_CLICK_KEY,
+ recordID.bind(null, 'GRANDPARENT'),
+ );
+ await putListener(PARENT, ON_CLICK_KEY, recordID.bind(null, 'PARENT'));
+ await putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, 'CHILD'));
+ await act(() => {
+ CHILD.click();
+ });
expect(idCallOrder).toEqual(['CHILD', 'PARENT', 'GRANDPARENT']);
idCallOrder = [];
// Update just the grand parent without updating the child.
- putListener(
+ await putListener(
GRANDPARENT,
ON_CLICK_KEY,
recordID.bind(null, 'UPDATED_GRANDPARENT'),
);
- CHILD.click();
+ await act(() => {
+ CHILD.click();
+ });
expect(idCallOrder).toEqual(['CHILD', 'PARENT', 'UPDATED_GRANDPARENT']);
});
- it('should continue bubbling if an error is thrown', () => {
- putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, CHILD));
- putListener(PARENT, ON_CLICK_KEY, function () {
+ it('should continue bubbling if an error is thrown', async () => {
+ await renderTree();
+ await putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, CHILD));
+ await putListener(PARENT, ON_CLICK_KEY, function () {
recordID(PARENT);
throw new Error('Handler interrupted');
});
- putListener(GRANDPARENT, ON_CLICK_KEY, recordID.bind(null, GRANDPARENT));
- expect(function () {
- ReactTestUtils.Simulate.click(CHILD);
- }).toThrow();
+ await putListener(
+ GRANDPARENT,
+ ON_CLICK_KEY,
+ recordID.bind(null, GRANDPARENT),
+ );
+ await expect(
+ act(() => {
+ ReactTestUtils.Simulate.click(CHILD);
+ }),
+ ).rejects.toThrow();
expect(idCallOrder.length).toBe(3);
expect(idCallOrder[0]).toBe(CHILD);
expect(idCallOrder[1]).toBe(PARENT);
expect(idCallOrder[2]).toBe(GRANDPARENT);
});
- it('should set currentTarget', () => {
- putListener(CHILD, ON_CLICK_KEY, function (event) {
+ it('should set currentTarget', async () => {
+ await renderTree();
+ await putListener(CHILD, ON_CLICK_KEY, function (event) {
recordID(CHILD);
expect(event.currentTarget).toBe(CHILD);
});
- putListener(PARENT, ON_CLICK_KEY, function (event) {
+ await putListener(PARENT, ON_CLICK_KEY, function (event) {
recordID(PARENT);
expect(event.currentTarget).toBe(PARENT);
});
- putListener(GRANDPARENT, ON_CLICK_KEY, function (event) {
+ await putListener(GRANDPARENT, ON_CLICK_KEY, function (event) {
recordID(GRANDPARENT);
expect(event.currentTarget).toBe(GRANDPARENT);
});
- CHILD.click();
+ await act(() => {
+ CHILD.click();
+ });
expect(idCallOrder.length).toBe(3);
expect(idCallOrder[0]).toBe(CHILD);
expect(idCallOrder[1]).toBe(PARENT);
expect(idCallOrder[2]).toBe(GRANDPARENT);
});
- it('should support stopPropagation()', () => {
- putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, CHILD));
- putListener(
+ it('should support stopPropagation()', async () => {
+ await renderTree();
+ await putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, CHILD));
+ await putListener(
PARENT,
ON_CLICK_KEY,
recordIDAndStopPropagation.bind(null, PARENT),
);
- putListener(GRANDPARENT, ON_CLICK_KEY, recordID.bind(null, GRANDPARENT));
- CHILD.click();
+ await putListener(
+ GRANDPARENT,
+ ON_CLICK_KEY,
+ recordID.bind(null, GRANDPARENT),
+ );
+ await act(() => {
+ CHILD.click();
+ });
expect(idCallOrder.length).toBe(2);
expect(idCallOrder[0]).toBe(CHILD);
expect(idCallOrder[1]).toBe(PARENT);
});
- it('should support overriding .isPropagationStopped()', () => {
+ it('should support overriding .isPropagationStopped()', async () => {
+ await renderTree();
// Ew. See D4504876.
- putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, CHILD));
- putListener(PARENT, ON_CLICK_KEY, function (e) {
+ await putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, CHILD));
+ await putListener(PARENT, ON_CLICK_KEY, function (e) {
recordID(PARENT, e);
// This stops React bubbling but avoids touching the native event
e.isPropagationStopped = () => true;
});
- putListener(GRANDPARENT, ON_CLICK_KEY, recordID.bind(null, GRANDPARENT));
- CHILD.click();
+ await putListener(
+ GRANDPARENT,
+ ON_CLICK_KEY,
+ recordID.bind(null, GRANDPARENT),
+ );
+ await act(() => {
+ CHILD.click();
+ });
expect(idCallOrder.length).toBe(2);
expect(idCallOrder[0]).toBe(CHILD);
expect(idCallOrder[1]).toBe(PARENT);
});
- it('should stop after first dispatch if stopPropagation', () => {
- putListener(
+ it('should stop after first dispatch if stopPropagation', async () => {
+ await renderTree();
+ await putListener(
CHILD,
ON_CLICK_KEY,
recordIDAndStopPropagation.bind(null, CHILD),
);
- putListener(PARENT, ON_CLICK_KEY, recordID.bind(null, PARENT));
- putListener(GRANDPARENT, ON_CLICK_KEY, recordID.bind(null, GRANDPARENT));
- CHILD.click();
+ await putListener(PARENT, ON_CLICK_KEY, recordID.bind(null, PARENT));
+ await putListener(
+ GRANDPARENT,
+ ON_CLICK_KEY,
+ recordID.bind(null, GRANDPARENT),
+ );
+ await act(() => {
+ CHILD.click();
+ });
expect(idCallOrder.length).toBe(1);
expect(idCallOrder[0]).toBe(CHILD);
});
- it('should not stopPropagation if false is returned', () => {
- putListener(CHILD, ON_CLICK_KEY, recordIDAndReturnFalse.bind(null, CHILD));
- putListener(PARENT, ON_CLICK_KEY, recordID.bind(null, PARENT));
- putListener(GRANDPARENT, ON_CLICK_KEY, recordID.bind(null, GRANDPARENT));
- CHILD.click();
+ it('should not stopPropagation if false is returned', async () => {
+ await renderTree();
+ await putListener(
+ CHILD,
+ ON_CLICK_KEY,
+ recordIDAndReturnFalse.bind(null, CHILD),
+ );
+ await putListener(PARENT, ON_CLICK_KEY, recordID.bind(null, PARENT));
+ await putListener(
+ GRANDPARENT,
+ ON_CLICK_KEY,
+ recordID.bind(null, GRANDPARENT),
+ );
+ await act(() => {
+ CHILD.click();
+ });
expect(idCallOrder.length).toBe(3);
expect(idCallOrder[0]).toBe(CHILD);
expect(idCallOrder[1]).toBe(PARENT);
@@ -255,30 +321,39 @@ describe('ReactBrowserEventEmitter', () => {
* these new listeners.
*/
- it('should invoke handlers that were removed while bubbling', () => {
+ it('should invoke handlers that were removed while bubbling', async () => {
+ await renderTree();
const handleParentClick = jest.fn();
- const handleChildClick = function (event) {
- deleteAllListeners(PARENT);
+ const handleChildClick = async function (event) {
+ await deleteAllListeners(PARENT);
};
- putListener(CHILD, ON_CLICK_KEY, handleChildClick);
- putListener(PARENT, ON_CLICK_KEY, handleParentClick);
- CHILD.click();
+ await putListener(CHILD, ON_CLICK_KEY, handleChildClick);
+ await putListener(PARENT, ON_CLICK_KEY, handleParentClick);
+ await act(() => {
+ CHILD.click();
+ });
expect(handleParentClick).toHaveBeenCalledTimes(1);
});
- it('should not invoke newly inserted handlers while bubbling', () => {
+ it('should not invoke newly inserted handlers while bubbling', async () => {
+ await renderTree();
const handleParentClick = jest.fn();
- const handleChildClick = function (event) {
- putListener(PARENT, ON_CLICK_KEY, handleParentClick);
+ const handleChildClick = async function (event) {
+ await putListener(PARENT, ON_CLICK_KEY, handleParentClick);
};
- putListener(CHILD, ON_CLICK_KEY, handleChildClick);
- CHILD.click();
+ await putListener(CHILD, ON_CLICK_KEY, handleChildClick);
+ await act(() => {
+ CHILD.click();
+ });
expect(handleParentClick).toHaveBeenCalledTimes(0);
});
- it('should have mouse enter simulated by test utils', () => {
- putListener(CHILD, ON_MOUSE_ENTER_KEY, recordID.bind(null, CHILD));
- ReactTestUtils.Simulate.mouseEnter(CHILD);
+ it('should have mouse enter simulated by test utils', async () => {
+ await renderTree();
+ await putListener(CHILD, ON_MOUSE_ENTER_KEY, recordID.bind(null, CHILD));
+ await act(() => {
+ ReactTestUtils.Simulate.mouseEnter(CHILD);
+ });
expect(idCallOrder.length).toBe(1);
expect(idCallOrder[0]).toBe(CHILD);
});