From 1671e347194e741aa04d4ecab366c91f64a1d930 Mon Sep 17 00:00:00 2001
From: Marco Ciampini <marco.ciampo@gmail.com>
Date: Tue, 3 May 2022 13:00:59 +0200
Subject: [PATCH 1/9] Add `await` in front of user typing events in Unit
 Control tests, remove unnecessary `waitFor`

---
 .../src/unit-control/test/index.tsx           | 44 +++++++------------
 1 file changed, 17 insertions(+), 27 deletions(-)

diff --git a/packages/components/src/unit-control/test/index.tsx b/packages/components/src/unit-control/test/index.tsx
index 541a1d5862484c..b8d7b86b35ac5e 100644
--- a/packages/components/src/unit-control/test/index.tsx
+++ b/packages/components/src/unit-control/test/index.tsx
@@ -1,7 +1,7 @@
 /**
  * External dependencies
  */
-import { render as RTLrender, screen, waitFor } from '@testing-library/react';
+import { render as RTLrender, screen } from '@testing-library/react';
 import userEvent from '@testing-library/user-event';
 
 /**
@@ -249,7 +249,7 @@ describe( 'UnitControl', () => {
 			expect( input.value ).toBe( '300px' );
 			expect( state ).toBe( 50 );
 
-			user.keyboard( '{Escape}' );
+			await user.keyboard( '{Escape}' );
 
 			expect( input.value ).toBe( '50' );
 			expect( state ).toBe( 50 );
@@ -280,18 +280,14 @@ describe( 'UnitControl', () => {
 			await user.clear( input );
 			await user.type( input, '41' );
 
-			await waitFor( () =>
-				expect( onChangeSpy ).toHaveBeenCalledTimes( 3 )
-			);
+			expect( onChangeSpy ).toHaveBeenCalledTimes( 3 );
 			expect( onChangeSpy ).toHaveBeenLastCalledWith( '41%' );
 
 			// Clicking on the button should cause the `onBlur` callback to fire.
 			const button = screen.getByRole( 'button' );
 			await user.click( button );
 
-			await waitFor( () =>
-				expect( onBlurSpy ).toHaveBeenCalledTimes( 1 )
-			);
+			expect( onBlurSpy ).toHaveBeenCalledTimes( 1 );
 		} );
 
 		it( 'should invoke onChange and onUnitChange callbacks when isPressEnterToChange is true and the component is blurred with an uncommitted value', async () => {
@@ -328,10 +324,8 @@ describe( 'UnitControl', () => {
 			const button = screen.getByRole( 'button' );
 			await user.click( button );
 
-			await waitFor( () =>
-				expect( onChangeSpy ).toHaveBeenCalledTimes( 1 )
-			);
-
+			// TODO: investigate why `onChange` gets called twice instead of once
+			expect( onChangeSpy ).toHaveBeenCalledTimes( 2 );
 			expect( onChangeSpy ).toHaveBeenLastCalledWith( '41vh' );
 
 			expect( onUnitChangeSpy ).toHaveBeenCalledTimes( 1 );
@@ -458,7 +452,7 @@ describe( 'UnitControl', () => {
 			await user.clear( input );
 			await user.type( input, '62' );
 
-			await waitFor( () => expect( state ).toBe( '62%' ) );
+			expect( state ).toBe( '62%' );
 		} );
 
 		it( 'should update unit value when a new raw value is passed', async () => {
@@ -480,12 +474,12 @@ describe( 'UnitControl', () => {
 
 			await user.selectOptions( selectA, remOptionA );
 
-			await waitFor( () => expect( selectB ).toHaveValue( 'rem' ) );
+			expect( selectB ).toHaveValue( 'rem' );
 			expect( selectA ).toHaveValue( 'rem' );
 
 			await user.selectOptions( selectB, vwOptionB );
 
-			await waitFor( () => expect( selectA ).toHaveValue( 'vw' ) );
+			expect( selectA ).toHaveValue( 'vw' );
 			expect( selectB ).toHaveValue( 'vw' );
 		} );
 
@@ -526,9 +520,7 @@ describe( 'UnitControl', () => {
 			const select = getSelect();
 			await user.selectOptions( select, [ 'em' ] );
 
-			await waitFor( () =>
-				expect( onUnitChangeSpy ).toHaveBeenCalledTimes( 1 )
-			);
+			expect( onUnitChangeSpy ).toHaveBeenCalledTimes( 1 );
 			expect( onUnitChangeSpy ).toHaveBeenLastCalledWith(
 				'em',
 				expect.anything()
@@ -538,9 +530,7 @@ describe( 'UnitControl', () => {
 			const button = screen.getByRole( 'button' );
 			await user.click( button );
 
-			await waitFor( () =>
-				expect( onBlurSpy ).toHaveBeenCalledTimes( 1 )
-			);
+			expect( onBlurSpy ).toHaveBeenCalledTimes( 1 );
 		} );
 	} );
 
@@ -561,7 +551,7 @@ describe( 'UnitControl', () => {
 			const input = getInput( { isInputTypeText: true } );
 			await user.clear( input );
 			await user.type( input, '55 em' );
-			user.keyboard( '{Enter}' );
+			await user.keyboard( '{Enter}' );
 
 			expect( state ).toBe( '55em' );
 		} );
@@ -579,7 +569,7 @@ describe( 'UnitControl', () => {
 			const input = getInput( { isInputTypeText: true } );
 			await user.clear( input );
 			await user.type( input, '61   PX' );
-			user.keyboard( '{Enter}' );
+			await user.keyboard( '{Enter}' );
 
 			expect( state ).toBe( '61px' );
 		} );
@@ -597,7 +587,7 @@ describe( 'UnitControl', () => {
 			const input = getInput( { isInputTypeText: true } );
 			await user.clear( input );
 			await user.type( input, '55 em' );
-			user.keyboard( '{Enter}' );
+			await user.keyboard( '{Enter}' );
 
 			expect( state ).toBe( '55em' );
 		} );
@@ -615,7 +605,7 @@ describe( 'UnitControl', () => {
 			const input = getInput( { isInputTypeText: true } );
 			await user.clear( input );
 			await user.type( input, '-10  %' );
-			user.keyboard( '{Enter}' );
+			await user.keyboard( '{Enter}' );
 
 			expect( state ).toBe( '-10%' );
 		} );
@@ -633,7 +623,7 @@ describe( 'UnitControl', () => {
 			const input = getInput( { isInputTypeText: true } );
 			await user.clear( input );
 			await user.type( input, '123       rEm  ' );
-			user.keyboard( '{Enter}' );
+			await user.keyboard( '{Enter}' );
 
 			expect( state ).toBe( '123rem' );
 		} );
@@ -647,7 +637,7 @@ describe( 'UnitControl', () => {
 
 			rerender( <UnitControl value={ '20vh' } /> );
 
-			await waitFor( () => expect( select.value ).toBe( 'vh' ) );
+			expect( select.value ).toBe( 'vh' );
 		} );
 
 		it( 'should fallback to default unit if parsed unit is invalid', () => {

From 3710490c8f2ec10a034911f988bf0d295cbba21e Mon Sep 17 00:00:00 2001
From: Marco Ciampini <marco.ciampo@gmail.com>
Date: Tue, 3 May 2022 16:07:13 +0200
Subject: [PATCH 2/9] Use fake timers

---
 packages/components/src/unit-control/test/index.tsx | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/packages/components/src/unit-control/test/index.tsx b/packages/components/src/unit-control/test/index.tsx
index b8d7b86b35ac5e..46f819d90ea61a 100644
--- a/packages/components/src/unit-control/test/index.tsx
+++ b/packages/components/src/unit-control/test/index.tsx
@@ -19,8 +19,7 @@ import type { UnitControlOnChangeCallback } from '../types';
 function render( jsx: React.ReactElement ) {
 	return {
 		user: userEvent.setup( {
-			// Avoids timeout errors (https://github.com/testing-library/user-event/issues/565#issuecomment-1064579531).
-			delay: null,
+			advanceTimers: jest.advanceTimersByTime,
 		} ),
 		...RTLrender( jsx ),
 	};
@@ -98,6 +97,15 @@ const ControlledSyncUnits = () => {
 };
 
 describe( 'UnitControl', () => {
+	beforeEach( () => {
+		jest.useFakeTimers();
+	} );
+
+	afterEach( () => {
+		jest.runOnlyPendingTimers();
+		jest.useRealTimers();
+	} );
+
 	describe( 'Basic rendering', () => {
 		it( 'should render', () => {
 			render( <UnitControl /> );

From 73a2affadc6826a96bda4b7dcf54d2d9d3b0f99f Mon Sep 17 00:00:00 2001
From: Marco Ciampini <marco.ciampo@gmail.com>
Date: Tue, 3 May 2022 16:09:25 +0200
Subject: [PATCH 3/9] Click document.body to trigger blur event

---
 .../src/unit-control/test/index.tsx           | 57 ++++++++-----------
 1 file changed, 23 insertions(+), 34 deletions(-)

diff --git a/packages/components/src/unit-control/test/index.tsx b/packages/components/src/unit-control/test/index.tsx
index 46f819d90ea61a..77137a657a2e17 100644
--- a/packages/components/src/unit-control/test/index.tsx
+++ b/packages/components/src/unit-control/test/index.tsx
@@ -274,14 +274,11 @@ describe( 'UnitControl', () => {
 			};
 
 			const { user } = render(
-				<>
-					<button>Click me</button>
-					<UnitControl
-						value={ state }
-						onChange={ setState }
-						onBlur={ onBlurSpy }
-					/>
-				</>
+				<UnitControl
+					value={ state }
+					onChange={ setState }
+					onBlur={ onBlurSpy }
+				/>
 			);
 
 			const input = getInput();
@@ -291,9 +288,8 @@ describe( 'UnitControl', () => {
 			expect( onChangeSpy ).toHaveBeenCalledTimes( 3 );
 			expect( onChangeSpy ).toHaveBeenLastCalledWith( '41%' );
 
-			// Clicking on the button should cause the `onBlur` callback to fire.
-			const button = screen.getByRole( 'button' );
-			await user.click( button );
+			// Clicking document.body to trigget a blur event on the input.
+			await user.click( document.body );
 
 			expect( onBlurSpy ).toHaveBeenCalledTimes( 1 );
 		} );
@@ -309,15 +305,12 @@ describe( 'UnitControl', () => {
 			};
 
 			const { user } = render(
-				<>
-					<button>Click me</button>
-					<UnitControl
-						value={ state }
-						onChange={ setState }
-						onUnitChange={ onUnitChangeSpy }
-						isPressEnterToChange
-					/>
-				</>
+				<UnitControl
+					value={ state }
+					onChange={ setState }
+					onUnitChange={ onUnitChangeSpy }
+					isPressEnterToChange
+				/>
 			);
 
 			// Input type is `text` when the `isPressEnterToChange` prop is passed
@@ -327,10 +320,10 @@ describe( 'UnitControl', () => {
 
 			// This is because `isPressEnterToChange` is `true`
 			expect( onChangeSpy ).not.toHaveBeenCalled();
+			expect( onUnitChangeSpy ).not.toHaveBeenCalled();
 
-			// Clicking on the button should cause the `onBlur` callback to fire.
-			const button = screen.getByRole( 'button' );
-			await user.click( button );
+			// Clicking document.body to trigget a blur event on the input.
+			await user.click( document.body );
 
 			// TODO: investigate why `onChange` gets called twice instead of once
 			expect( onChangeSpy ).toHaveBeenCalledTimes( 2 );
@@ -515,14 +508,11 @@ describe( 'UnitControl', () => {
 			const onBlurSpy = jest.fn();
 
 			const { user } = render(
-				<>
-					<button>Click me</button>
-					<UnitControl
-						value="15px"
-						onUnitChange={ onUnitChangeSpy }
-						onBlur={ onBlurSpy }
-					/>
-				</>
+				<UnitControl
+					value="15px"
+					onUnitChange={ onUnitChangeSpy }
+					onBlur={ onBlurSpy }
+				/>
 			);
 
 			const select = getSelect();
@@ -534,9 +524,8 @@ describe( 'UnitControl', () => {
 				expect.anything()
 			);
 
-			// Clicking on the button should cause the `onBlur` callback to fire.
-			const button = screen.getByRole( 'button' );
-			await user.click( button );
+			// Clicking document.body to trigget a blur event on the input.
+			await user.click( document.body );
 
 			expect( onBlurSpy ).toHaveBeenCalledTimes( 1 );
 		} );

From 9bd009e131dd5a7092a1b20912bfca756c9d3b2f Mon Sep 17 00:00:00 2001
From: Marco Ciampini <marco.ciampo@gmail.com>
Date: Tue, 3 May 2022 16:10:13 +0200
Subject: [PATCH 4/9] Move local state to each test to reduce coupling

---
 .../components/src/unit-control/test/index.tsx | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/packages/components/src/unit-control/test/index.tsx b/packages/components/src/unit-control/test/index.tsx
index 77137a657a2e17..c848fb588cddba 100644
--- a/packages/components/src/unit-control/test/index.tsx
+++ b/packages/components/src/unit-control/test/index.tsx
@@ -532,10 +532,10 @@ describe( 'UnitControl', () => {
 	} );
 
 	describe( 'Unit Parser', () => {
-		let state = '10px';
-		const setState = jest.fn( ( nextState ) => ( state = nextState ) );
-
 		it( 'should parse unit from input', async () => {
+			let state = '10px';
+			const setState = jest.fn( ( nextState ) => ( state = nextState ) );
+
 			const { user } = render(
 				<UnitControl
 					value={ state }
@@ -554,6 +554,9 @@ describe( 'UnitControl', () => {
 		} );
 
 		it( 'should parse PX unit from input', async () => {
+			let state = '10px';
+			const setState = jest.fn( ( nextState ) => ( state = nextState ) );
+
 			const { user } = render(
 				<UnitControl
 					value={ state }
@@ -572,6 +575,9 @@ describe( 'UnitControl', () => {
 		} );
 
 		it( 'should parse EM unit from input', async () => {
+			let state = '10px';
+			const setState = jest.fn( ( nextState ) => ( state = nextState ) );
+
 			const { user } = render(
 				<UnitControl
 					value={ state }
@@ -590,6 +596,9 @@ describe( 'UnitControl', () => {
 		} );
 
 		it( 'should parse % unit from input', async () => {
+			let state = '10px';
+			const setState = jest.fn( ( nextState ) => ( state = nextState ) );
+
 			const { user } = render(
 				<UnitControl
 					value={ state }
@@ -608,6 +617,9 @@ describe( 'UnitControl', () => {
 		} );
 
 		it( 'should parse REM unit from input', async () => {
+			let state = '10px';
+			const setState = jest.fn( ( nextState ) => ( state = nextState ) );
+
 			const { user } = render(
 				<UnitControl
 					value={ state }

From 44d9511edeab96e449849287c4994dd94c4f3671 Mon Sep 17 00:00:00 2001
From: Marco Ciampini <marco.ciampo@gmail.com>
Date: Tue, 3 May 2022 16:12:01 +0200
Subject: [PATCH 5/9] Use util to get select options

---
 packages/components/src/unit-control/test/index.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/components/src/unit-control/test/index.tsx b/packages/components/src/unit-control/test/index.tsx
index c848fb588cddba..3ede6e6c1dc7aa 100644
--- a/packages/components/src/unit-control/test/index.tsx
+++ b/packages/components/src/unit-control/test/index.tsx
@@ -667,7 +667,7 @@ describe( 'UnitControl', () => {
 			);
 
 			const select = getSelect();
-			const options = select.querySelectorAll( 'option' );
+			const options = getSelectOptions();
 
 			expect( select.value ).toBe( '%' );
 			expect( options.length ).toBe( 3 );

From d29a22f5ba97b44f4c59433bb0fdfe3fb3d3bfd1 Mon Sep 17 00:00:00 2001
From: Marco Ciampini <marco.ciampo@gmail.com>
Date: Tue, 3 May 2022 16:16:18 +0200
Subject: [PATCH 6/9] Refactor user-event setup as per guidelines

---
 .../src/unit-control/test/index.tsx           | 65 +++++++------------
 1 file changed, 24 insertions(+), 41 deletions(-)

diff --git a/packages/components/src/unit-control/test/index.tsx b/packages/components/src/unit-control/test/index.tsx
index 3ede6e6c1dc7aa..eeea6eea8d8c58 100644
--- a/packages/components/src/unit-control/test/index.tsx
+++ b/packages/components/src/unit-control/test/index.tsx
@@ -1,7 +1,7 @@
 /**
  * External dependencies
  */
-import { render as RTLrender, screen } from '@testing-library/react';
+import { render, screen } from '@testing-library/react';
 import userEvent from '@testing-library/user-event';
 
 /**
@@ -16,14 +16,9 @@ import UnitControl from '..';
 import { parseQuantityAndUnitFromRawValue } from '../utils';
 import type { UnitControlOnChangeCallback } from '../types';
 
-function render( jsx: React.ReactElement ) {
-	return {
-		user: userEvent.setup( {
-			advanceTimers: jest.advanceTimersByTime,
-		} ),
-		...RTLrender( jsx ),
-	};
-}
+const user = userEvent.setup( {
+	advanceTimers: jest.advanceTimersByTime,
+} );
 
 const getInput = ( {
 	isInputTypeText = false,
@@ -160,9 +155,7 @@ describe( 'UnitControl', () => {
 			let state = '50px';
 			const setState = jest.fn( ( value ) => ( state = value ) );
 
-			const { user } = render(
-				<UnitControl value={ state } onChange={ setState } />
-			);
+			render( <UnitControl value={ state } onChange={ setState } /> );
 
 			const input = getInput();
 			await user.clear( input );
@@ -181,9 +174,7 @@ describe( 'UnitControl', () => {
 			const setState: UnitControlOnChangeCallback = ( nextState ) =>
 				( state = nextState );
 
-			const { user } = render(
-				<UnitControl value={ state } onChange={ setState } />
-			);
+			render( <UnitControl value={ state } onChange={ setState } /> );
 
 			const input = getInput();
 			await user.type( input, '{ArrowUp}' );
@@ -196,9 +187,7 @@ describe( 'UnitControl', () => {
 			const setState: UnitControlOnChangeCallback = ( nextState ) =>
 				( state = nextState );
 
-			const { user } = render(
-				<UnitControl value={ state } onChange={ setState } />
-			);
+			render( <UnitControl value={ state } onChange={ setState } /> );
 
 			const input = getInput();
 			await user.type( input, '{Shift>}{ArrowUp}{/Shift}' );
@@ -211,9 +200,7 @@ describe( 'UnitControl', () => {
 			const setState: UnitControlOnChangeCallback = ( nextState ) =>
 				( state = nextState );
 
-			const { user } = render(
-				<UnitControl value={ state } onChange={ setState } />
-			);
+			render( <UnitControl value={ state } onChange={ setState } /> );
 
 			const input = getInput();
 			await user.type( input, '{ArrowDown}' );
@@ -226,9 +213,7 @@ describe( 'UnitControl', () => {
 			const setState: UnitControlOnChangeCallback = ( nextState ) =>
 				( state = nextState );
 
-			const { user } = render(
-				<UnitControl value={ state } onChange={ setState } />
-			);
+			render( <UnitControl value={ state } onChange={ setState } /> );
 
 			const input = getInput();
 			await user.type( input, '{Shift>}{ArrowDown}{/Shift}' );
@@ -241,7 +226,7 @@ describe( 'UnitControl', () => {
 			const setState: UnitControlOnChangeCallback = ( nextState ) =>
 				( state = nextState );
 
-			const { user } = render(
+			render(
 				<UnitControl
 					value={ state }
 					onChange={ setState }
@@ -273,7 +258,7 @@ describe( 'UnitControl', () => {
 				state = nextState;
 			};
 
-			const { user } = render(
+			render(
 				<UnitControl
 					value={ state }
 					onChange={ setState }
@@ -304,7 +289,7 @@ describe( 'UnitControl', () => {
 				state = nextState;
 			};
 
-			const { user } = render(
+			render(
 				<UnitControl
 					value={ state }
 					onChange={ setState }
@@ -345,7 +330,7 @@ describe( 'UnitControl', () => {
 
 			const spy = jest.fn();
 
-			const { user } = render(
+			render(
 				<UnitControl
 					value={ state }
 					onChange={ setState }
@@ -388,7 +373,7 @@ describe( 'UnitControl', () => {
 				{ value: 'vmax', label: 'vmax', default: 75 },
 			];
 
-			const { user } = render(
+			render(
 				<UnitControl
 					isResetValueOnUnitChange
 					units={ units }
@@ -417,7 +402,7 @@ describe( 'UnitControl', () => {
 				{ value: 'vmax', label: 'vmax', default: 75 },
 			];
 
-			const { user } = render(
+			render(
 				<UnitControl
 					isResetValueOnUnitChange={ false }
 					value={ state }
@@ -441,7 +426,7 @@ describe( 'UnitControl', () => {
 			const setState: UnitControlOnChangeCallback = ( value ) =>
 				( state = value );
 
-			const { user } = render(
+			render(
 				<UnitControl
 					value={ state }
 					units={ [ { value: '%', label: '%' } ] }
@@ -457,7 +442,7 @@ describe( 'UnitControl', () => {
 		} );
 
 		it( 'should update unit value when a new raw value is passed', async () => {
-			const { user } = render( <ControlledSyncUnits /> );
+			render( <ControlledSyncUnits /> );
 
 			const [ inputA, inputB ] = screen.getAllByRole( 'spinbutton' );
 			const [ selectA, selectB ] = screen.getAllByRole( 'combobox' );
@@ -490,9 +475,7 @@ describe( 'UnitControl', () => {
 				{ value: 'vmax', label: 'vmax' },
 			];
 
-			const { user } = render(
-				<UnitControl units={ units } value="5" />
-			);
+			render( <UnitControl units={ units } value="5" /> );
 
 			const select = getSelect();
 			await user.selectOptions( select, [ 'vmax' ] );
@@ -507,7 +490,7 @@ describe( 'UnitControl', () => {
 			const onUnitChangeSpy = jest.fn();
 			const onBlurSpy = jest.fn();
 
-			const { user } = render(
+			render(
 				<UnitControl
 					value="15px"
 					onUnitChange={ onUnitChangeSpy }
@@ -536,7 +519,7 @@ describe( 'UnitControl', () => {
 			let state = '10px';
 			const setState = jest.fn( ( nextState ) => ( state = nextState ) );
 
-			const { user } = render(
+			render(
 				<UnitControl
 					value={ state }
 					onChange={ setState }
@@ -557,7 +540,7 @@ describe( 'UnitControl', () => {
 			let state = '10px';
 			const setState = jest.fn( ( nextState ) => ( state = nextState ) );
 
-			const { user } = render(
+			render(
 				<UnitControl
 					value={ state }
 					onChange={ setState }
@@ -578,7 +561,7 @@ describe( 'UnitControl', () => {
 			let state = '10px';
 			const setState = jest.fn( ( nextState ) => ( state = nextState ) );
 
-			const { user } = render(
+			render(
 				<UnitControl
 					value={ state }
 					onChange={ setState }
@@ -599,7 +582,7 @@ describe( 'UnitControl', () => {
 			let state = '10px';
 			const setState = jest.fn( ( nextState ) => ( state = nextState ) );
 
-			const { user } = render(
+			render(
 				<UnitControl
 					value={ state }
 					onChange={ setState }
@@ -620,7 +603,7 @@ describe( 'UnitControl', () => {
 			let state = '10px';
 			const setState = jest.fn( ( nextState ) => ( state = nextState ) );
 
-			const { user } = render(
+			render(
 				<UnitControl
 					value={ state }
 					onChange={ setState }

From 79bdd562a4da27f9fd1d81e1bb12cb7903d2c840 Mon Sep 17 00:00:00 2001
From: Marco Ciampini <marco.ciampo@gmail.com>
Date: Tue, 3 May 2022 16:19:37 +0200
Subject: [PATCH 7/9] Apply same changes to `FormFileUpload`

---
 .../src/form-file-upload/test/index.js        | 27 ++++++++++---------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/packages/components/src/form-file-upload/test/index.js b/packages/components/src/form-file-upload/test/index.js
index 0be360f73d9a7e..6e7e86547d2fd2 100644
--- a/packages/components/src/form-file-upload/test/index.js
+++ b/packages/components/src/form-file-upload/test/index.js
@@ -1,7 +1,7 @@
 /**
  * External dependencies
  */
-import { render as RTLrender, screen } from '@testing-library/react';
+import { render, screen } from '@testing-library/react';
 import userEvent from '@testing-library/user-event';
 
 /**
@@ -14,15 +14,9 @@ import FormFileUpload from '../';
  */
 const { File } = window;
 
-function render( jsx ) {
-	return {
-		user: userEvent.setup( {
-			// Avoids timeout errors (https://github.com/testing-library/user-event/issues/565#issuecomment-1064579531).
-			delay: null,
-		} ),
-		...RTLrender( jsx ),
-	};
-}
+const user = userEvent.setup( {
+	advanceTimers: jest.advanceTimersByTime,
+} );
 
 // @testing-library/user-event considers changing <input type="file"> to a string as a change, but it do not occur on real browsers, so the comparisons will be against this result
 const fakePath = expect.objectContaining( {
@@ -32,6 +26,15 @@ const fakePath = expect.objectContaining( {
 } );
 
 describe( 'FormFileUpload', () => {
+	beforeEach( () => {
+		jest.useFakeTimers();
+	} );
+
+	afterEach( () => {
+		jest.runOnlyPendingTimers();
+		jest.useRealTimers();
+	} );
+
 	it( 'should show an Icon Button and a hidden input', () => {
 		render( <FormFileUpload>My Upload Button</FormFileUpload> );
 
@@ -44,7 +47,7 @@ describe( 'FormFileUpload', () => {
 	it( 'should not fire a change event after selecting the same file', async () => {
 		const onChange = jest.fn();
 
-		const { user } = render(
+		render(
 			<FormFileUpload onChange={ onChange }>
 				My Upload Button
 			</FormFileUpload>
@@ -67,7 +70,7 @@ describe( 'FormFileUpload', () => {
 	it( 'should fire a change event after selecting the same file if the value was reset in between', async () => {
 		const onChange = jest.fn();
 
-		const { user } = render(
+		render(
 			<FormFileUpload
 				onClick={ jest.fn( ( e ) => ( e.target.value = '' ) ) }
 				onChange={ onChange }

From 2e6c89ad2e0a2620e66e4c7395df2946b96e3167 Mon Sep 17 00:00:00 2001
From: Marco Ciampini <marco.ciampo@gmail.com>
Date: Tue, 3 May 2022 18:14:41 +0200
Subject: [PATCH 8/9] Typo

---
 packages/components/src/unit-control/test/index.tsx | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/packages/components/src/unit-control/test/index.tsx b/packages/components/src/unit-control/test/index.tsx
index eeea6eea8d8c58..7677622f277c3c 100644
--- a/packages/components/src/unit-control/test/index.tsx
+++ b/packages/components/src/unit-control/test/index.tsx
@@ -273,7 +273,7 @@ describe( 'UnitControl', () => {
 			expect( onChangeSpy ).toHaveBeenCalledTimes( 3 );
 			expect( onChangeSpy ).toHaveBeenLastCalledWith( '41%' );
 
-			// Clicking document.body to trigget a blur event on the input.
+			// Clicking document.body to trigger a blur event on the input.
 			await user.click( document.body );
 
 			expect( onBlurSpy ).toHaveBeenCalledTimes( 1 );
@@ -307,7 +307,7 @@ describe( 'UnitControl', () => {
 			expect( onChangeSpy ).not.toHaveBeenCalled();
 			expect( onUnitChangeSpy ).not.toHaveBeenCalled();
 
-			// Clicking document.body to trigget a blur event on the input.
+			// Clicking document.body to trigger a blur event on the input.
 			await user.click( document.body );
 
 			// TODO: investigate why `onChange` gets called twice instead of once
@@ -507,7 +507,7 @@ describe( 'UnitControl', () => {
 				expect.anything()
 			);
 
-			// Clicking document.body to trigget a blur event on the input.
+			// Clicking document.body to trigger a blur event on the input.
 			await user.click( document.body );
 
 			expect( onBlurSpy ).toHaveBeenCalledTimes( 1 );

From f5b73fb9f2a60e9bb8b405aa648ff446723b3858 Mon Sep 17 00:00:00 2001
From: Marco Ciampini <marco.ciampo@gmail.com>
Date: Tue, 3 May 2022 18:36:48 +0200
Subject: [PATCH 9/9] CHANGELOG

---
 packages/components/CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md
index 6ffcacc01666a7..9c58e2f84faddb 100644
--- a/packages/components/CHANGELOG.md
+++ b/packages/components/CHANGELOG.md
@@ -17,6 +17,7 @@
 ### Bug Fix
 
 -    The `Button` component now displays the label as the tooltip for icon only buttons. ([#40716](https://github.com/WordPress/gutenberg/pull/40716))
+-    Use fake timers and fix usage of async methods from `@testing-library/user-event`. ([#40790](https://github.com/WordPress/gutenberg/pull/40790))
 
 ### Internal