diff --git a/packages/react-dom/src/events/__tests__/SyntheticKeyboardEvent-test.js b/packages/react-dom/src/events/__tests__/SyntheticKeyboardEvent-test.js index 5f8919e3fe275..f616a7c44f594 100644 --- a/packages/react-dom/src/events/__tests__/SyntheticKeyboardEvent-test.js +++ b/packages/react-dom/src/events/__tests__/SyntheticKeyboardEvent-test.js @@ -10,20 +10,30 @@ 'use strict'; let React; -let ReactDOM; +let ReactDOMClient; + +let act; describe('SyntheticKeyboardEvent', () => { let container; + let root; beforeEach(() => { 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'); + root = ReactDOMClient.createRoot(container); document.body.appendChild(container); }); - afterEach(() => { + afterEach(async () => { + await act(() => { + root.unmount(); + }); document.body.removeChild(container); container = null; }); @@ -32,17 +42,18 @@ describe('SyntheticKeyboardEvent', () => { describe('charCode', () => { describe('when event is `keypress`', () => { describe('when charCode is present in nativeEvent', () => { - it('when charCode is 0 and keyCode is 13, returns 13', () => { + it('when charCode is 0 and keyCode is 13, returns 13', async () => { let charCode = null; - const node = ReactDOM.render( - { - charCode = e.charCode; - }} - />, - container, - ); - node.dispatchEvent( + await act(() => { + root.render( + { + charCode = e.charCode; + }} + />, + ); + }); + container.firstChild.dispatchEvent( new KeyboardEvent('keypress', { charCode: 0, keyCode: 13, @@ -53,17 +64,18 @@ describe('SyntheticKeyboardEvent', () => { expect(charCode).toBe(13); }); - it('when charCode is 32 or bigger and keyCode is missing, returns charCode', () => { + it('when charCode is 32 or bigger and keyCode is missing, returns charCode', async () => { let charCode = null; - const node = ReactDOM.render( - { - charCode = e.charCode; - }} - />, - container, - ); - node.dispatchEvent( + await act(() => { + root.render( + { + charCode = e.charCode; + }} + />, + ); + }); + container.firstChild.dispatchEvent( new KeyboardEvent('keypress', { charCode: 32, bubbles: true, @@ -73,17 +85,18 @@ describe('SyntheticKeyboardEvent', () => { expect(charCode).toBe(32); }); - it('when charCode is 13 and keyCode is missing, returns charCode', () => { + it('when charCode is 13 and keyCode is missing, returns charCode', async () => { let charCode = null; - const node = ReactDOM.render( - { - charCode = e.charCode; - }} - />, - container, - ); - node.dispatchEvent( + await act(() => { + root.render( + { + charCode = e.charCode; + }} + />, + ); + }); + container.firstChild.dispatchEvent( new KeyboardEvent('keypress', { charCode: 13, bubbles: true, @@ -96,17 +109,18 @@ describe('SyntheticKeyboardEvent', () => { // Firefox creates a keypress event for function keys too. This removes // the unwanted keypress events. Enter is however both printable and // non-printable. One would expect Tab to be as well (but it isn't). - it('when charCode is smaller than 32 but is not 13, and keyCode is missing, ignores keypress', () => { + it('when charCode is smaller than 32 but is not 13, and keyCode is missing, ignores keypress', async () => { let called = false; - const node = ReactDOM.render( - { - called = true; - }} - />, - container, - ); - node.dispatchEvent( + await act(() => { + root.render( + { + called = true; + }} + />, + ); + }); + container.firstChild.dispatchEvent( new KeyboardEvent('keypress', { charCode: 31, bubbles: true, @@ -116,17 +130,18 @@ describe('SyntheticKeyboardEvent', () => { expect(called).toBe(false); }); - it('when charCode is 10, returns 13', () => { + it('when charCode is 10, returns 13', async () => { let charCode = null; - const node = ReactDOM.render( - { - charCode = e.charCode; - }} - />, - container, - ); - node.dispatchEvent( + await act(() => { + root.render( + { + charCode = e.charCode; + }} + />, + ); + }); + container.firstChild.dispatchEvent( new KeyboardEvent('keypress', { charCode: 10, bubbles: true, @@ -136,17 +151,18 @@ describe('SyntheticKeyboardEvent', () => { expect(charCode).toBe(13); }); - it('when charCode is 10 and ctrl is pressed, returns 13', () => { + it('when charCode is 10 and ctrl is pressed, returns 13', async () => { let charCode = null; - const node = ReactDOM.render( - { - charCode = e.charCode; - }} - />, - container, - ); - node.dispatchEvent( + await act(() => { + root.render( + { + charCode = e.charCode; + }} + />, + ); + }); + container.firstChild.dispatchEvent( new KeyboardEvent('keypress', { charCode: 10, ctrlKey: true, @@ -181,17 +197,18 @@ describe('SyntheticKeyboardEvent', () => { charCodeDescriptor = null; }); - it('when keyCode is 32 or bigger, returns keyCode', () => { + it('when keyCode is 32 or bigger, returns keyCode', async () => { let charCode = null; - const node = ReactDOM.render( - { - charCode = e.charCode; - }} - />, - container, - ); - node.dispatchEvent( + await act(() => { + root.render( + { + charCode = e.charCode; + }} + />, + ); + }); + container.firstChild.dispatchEvent( new KeyboardEvent('keypress', { keyCode: 32, bubbles: true, @@ -201,17 +218,18 @@ describe('SyntheticKeyboardEvent', () => { expect(charCode).toBe(32); }); - it('when keyCode is 13, returns 13', () => { + it('when keyCode is 13, returns 13', async () => { let charCode = null; - const node = ReactDOM.render( - { - charCode = e.charCode; - }} - />, - container, - ); - node.dispatchEvent( + await act(() => { + root.render( + { + charCode = e.charCode; + }} + />, + ); + }); + container.firstChild.dispatchEvent( new KeyboardEvent('keypress', { keyCode: 13, bubbles: true, @@ -221,17 +239,18 @@ describe('SyntheticKeyboardEvent', () => { expect(charCode).toBe(13); }); - it('when keyCode is smaller than 32 and is not 13, ignores keypress', () => { + it('when keyCode is smaller than 32 and is not 13, ignores keypress', async () => { let called = false; - const node = ReactDOM.render( - { - called = true; - }} - />, - container, - ); - node.dispatchEvent( + await act(() => { + root.render( + { + called = true; + }} + />, + ); + }); + container.firstChild.dispatchEvent( new KeyboardEvent('keypress', { keyCode: 31, bubbles: true, @@ -244,28 +263,29 @@ describe('SyntheticKeyboardEvent', () => { }); describe('when event is not `keypress`', () => { - it('returns 0', () => { + it('returns 0', async () => { let charCodeDown = null; let charCodeUp = null; - const node = ReactDOM.render( - { - charCodeDown = e.charCode; - }} - onKeyUp={e => { - charCodeUp = e.charCode; - }} - />, - container, - ); - node.dispatchEvent( + await act(() => { + root.render( + { + charCodeDown = e.charCode; + }} + onKeyUp={e => { + charCodeUp = e.charCode; + }} + />, + ); + }); + container.firstChild.dispatchEvent( new KeyboardEvent('keydown', { key: 'Del', bubbles: true, cancelable: true, }), ); - node.dispatchEvent( + container.firstChild.dispatchEvent( new KeyboardEvent('keyup', { key: 'Del', bubbles: true, @@ -277,17 +297,18 @@ describe('SyntheticKeyboardEvent', () => { }); }); - it('when charCode is smaller than 32 but is not 13, and keyCode is missing, charCode is 0', () => { + it('when charCode is smaller than 32 but is not 13, and keyCode is missing, charCode is 0', async () => { let charCode = null; - const node = ReactDOM.render( - { - charCode = e.charCode; - }} - />, - container, - ); - node.dispatchEvent( + await act(() => { + root.render( + { + charCode = e.charCode; + }} + />, + ); + }); + container.firstChild.dispatchEvent( new KeyboardEvent('keydown', { charCode: 31, bubbles: true, @@ -300,28 +321,29 @@ describe('SyntheticKeyboardEvent', () => { describe('keyCode', () => { describe('when event is `keydown` or `keyup`', () => { - it('returns a passed keyCode', () => { + it('returns a passed keyCode', async () => { let keyCodeDown = null; let keyCodeUp = null; - const node = ReactDOM.render( - { - keyCodeDown = e.keyCode; - }} - onKeyUp={e => { - keyCodeUp = e.keyCode; - }} - />, - container, - ); - node.dispatchEvent( + await act(() => { + root.render( + { + keyCodeDown = e.keyCode; + }} + onKeyUp={e => { + keyCodeUp = e.keyCode; + }} + />, + ); + }); + container.firstChild.dispatchEvent( new KeyboardEvent('keydown', { keyCode: 40, bubbles: true, cancelable: true, }), ); - node.dispatchEvent( + container.firstChild.dispatchEvent( new KeyboardEvent('keyup', { keyCode: 40, bubbles: true, @@ -334,17 +356,18 @@ describe('SyntheticKeyboardEvent', () => { }); describe('when event is `keypress`', () => { - it('returns 0', () => { + it('returns 0', async () => { let keyCode = null; - const node = ReactDOM.render( - { - keyCode = e.keyCode; - }} - />, - container, - ); - node.dispatchEvent( + await act(() => { + root.render( + { + keyCode = e.keyCode; + }} + />, + ); + }); + container.firstChild.dispatchEvent( new KeyboardEvent('keypress', { charCode: 65, bubbles: true, @@ -358,19 +381,20 @@ describe('SyntheticKeyboardEvent', () => { describe('which', () => { describe('when event is `keypress`', () => { - it('is consistent with `charCode`', () => { + it('is consistent with `charCode`', async () => { let calls = 0; - const node = ReactDOM.render( - { - expect(e.which).toBe(e.charCode); - calls++; - }} - />, - container, - ); + await act(() => { + root.render( + { + expect(e.which).toBe(e.charCode); + calls++; + }} + />, + ); + }); // Try different combinations from other tests. - node.dispatchEvent( + container.firstChild.dispatchEvent( new KeyboardEvent('keypress', { charCode: 0, keyCode: 13, @@ -378,14 +402,14 @@ describe('SyntheticKeyboardEvent', () => { cancelable: true, }), ); - node.dispatchEvent( + container.firstChild.dispatchEvent( new KeyboardEvent('keypress', { charCode: 32, bubbles: true, cancelable: true, }), ); - node.dispatchEvent( + container.firstChild.dispatchEvent( new KeyboardEvent('keypress', { charCode: 13, bubbles: true, @@ -397,50 +421,51 @@ describe('SyntheticKeyboardEvent', () => { }); describe('when event is `keydown` or `keyup`', () => { - it('is consistent with `keyCode`', () => { + it('is consistent with `keyCode`', async () => { let calls = 0; - const node = ReactDOM.render( - { - expect(e.which).toBe(e.keyCode); - calls++; - }} - onKeyUp={e => { - expect(e.which).toBe(e.keyCode); - calls++; - }} - />, - container, - ); - node.dispatchEvent( + await act(() => { + root.render( + { + expect(e.which).toBe(e.keyCode); + calls++; + }} + onKeyUp={e => { + expect(e.which).toBe(e.keyCode); + calls++; + }} + />, + ); + }); + container.firstChild.dispatchEvent( new KeyboardEvent('keydown', { key: 'Del', bubbles: true, cancelable: true, }), ); - node.dispatchEvent( + container.firstChild.dispatchEvent( new KeyboardEvent('keydown', { charCode: 31, bubbles: true, cancelable: true, }), ); - node.dispatchEvent( + container.firstChild.dispatchEvent( new KeyboardEvent('keydown', { keyCode: 40, bubbles: true, cancelable: true, }), ); - node.dispatchEvent( + container.firstChild.dispatchEvent( new KeyboardEvent('keyup', { key: 'Del', bubbles: true, cancelable: true, }), ); - node.dispatchEvent( + container.firstChild.dispatchEvent( new KeyboardEvent('keyup', { keyCode: 40, bubbles: true, @@ -453,39 +478,40 @@ describe('SyntheticKeyboardEvent', () => { }); describe('code', () => { - it('returns code on `keydown`, `keyup` and `keypress`', () => { + it('returns code on `keydown`, `keyup` and `keypress`', async () => { let codeDown = null; let codeUp = null; let codePress = null; - const node = ReactDOM.render( - { - codeDown = e.code; - }} - onKeyUp={e => { - codeUp = e.code; - }} - onKeyPress={e => { - codePress = e.code; - }} - />, - container, - ); - node.dispatchEvent( + await act(() => { + root.render( + { + codeDown = e.code; + }} + onKeyUp={e => { + codeUp = e.code; + }} + onKeyPress={e => { + codePress = e.code; + }} + />, + ); + }); + container.firstChild.dispatchEvent( new KeyboardEvent('keydown', { code: 'KeyQ', bubbles: true, cancelable: true, }), ); - node.dispatchEvent( + container.firstChild.dispatchEvent( new KeyboardEvent('keyup', { code: 'KeyQ', bubbles: true, cancelable: true, }), ); - node.dispatchEvent( + container.firstChild.dispatchEvent( new KeyboardEvent('keypress', { code: 'KeyQ', charCode: 113, @@ -501,7 +527,7 @@ describe('SyntheticKeyboardEvent', () => { }); describe('EventInterface', () => { - it('is able to `preventDefault` and `stopPropagation`', () => { + it('is able to `preventDefault` and `stopPropagation`', async () => { let expectedCount = 0; const eventHandler = event => { expect(event.isDefaultPrevented()).toBe(false); @@ -513,30 +539,31 @@ describe('SyntheticKeyboardEvent', () => { expect(event.isPropagationStopped()).toBe(true); expectedCount++; }; - const div = ReactDOM.render( -
, - container, - ); + await act(() => { + root.render( +
, + ); + }); - div.dispatchEvent( + container.firstChild.dispatchEvent( new KeyboardEvent('keydown', { keyCode: 40, bubbles: true, cancelable: true, }), ); - div.dispatchEvent( + container.firstChild.dispatchEvent( new KeyboardEvent('keyup', { keyCode: 40, bubbles: true, cancelable: true, }), ); - div.dispatchEvent( + container.firstChild.dispatchEvent( new KeyboardEvent('keypress', { charCode: 40, keyCode: 40,