-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Block Editor: Improve act()
usage in BlockSwitcher
tests
#46227
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,7 +1,7 @@ | ||||||||||||||||||
/** | ||||||||||||||||||
* External dependencies | ||||||||||||||||||
*/ | ||||||||||||||||||
import { render, screen, within } from '@testing-library/react'; | ||||||||||||||||||
import { render, screen, waitFor, within } from '@testing-library/react'; | ||||||||||||||||||
import userEvent from '@testing-library/user-event'; | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
|
@@ -15,13 +15,22 @@ import { copy } from '@wordpress/icons'; | |||||||||||||||||
* Internal dependencies | ||||||||||||||||||
*/ | ||||||||||||||||||
import { BlockSwitcher, BlockSwitcherDropdownMenu } from '../'; | ||||||||||||||||||
import { act } from 'react-test-renderer'; | ||||||||||||||||||
|
||||||||||||||||||
jest.mock( '@wordpress/data/src/components/use-select', () => jest.fn() ); | ||||||||||||||||||
jest.mock( '../../block-title/use-block-display-title', () => | ||||||||||||||||||
jest.fn().mockReturnValue( 'Block Name' ) | ||||||||||||||||||
); | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* Returns the first found popover element up the DOM tree. | ||||||||||||||||||
* | ||||||||||||||||||
* @param {HTMLElement} element Element to start with. | ||||||||||||||||||
* @return {HTMLElement|null} Popover element, or `null` if not found. | ||||||||||||||||||
*/ | ||||||||||||||||||
function getWrappingPopoverElement( element ) { | ||||||||||||||||||
return element.closest( '.components-popover' ); | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
describe( 'BlockSwitcher', () => { | ||||||||||||||||||
test( 'should not render block switcher without blocks', () => { | ||||||||||||||||||
useSelect.mockImplementation( () => ( {} ) ); | ||||||||||||||||||
|
@@ -211,7 +220,18 @@ describe( 'BlockSwitcherDropdownMenu', () => { | |||||||||||||||||
} ), | ||||||||||||||||||
'[ArrowDown]' | ||||||||||||||||||
); | ||||||||||||||||||
await act( () => Promise.resolve() ); | ||||||||||||||||||
|
||||||||||||||||||
const menu = screen.getByRole( 'menu', { | ||||||||||||||||||
name: 'Block Name', | ||||||||||||||||||
} ); | ||||||||||||||||||
|
||||||||||||||||||
expect( menu ).not.toBeVisible(); | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This The animation and positioning are completely independent from each other. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exactly. |
||||||||||||||||||
|
||||||||||||||||||
await waitFor( () => | ||||||||||||||||||
expect( | ||||||||||||||||||
getWrappingPopoverElement( menu ) | ||||||||||||||||||
).toBePositionedPopover() | ||||||||||||||||||
); | ||||||||||||||||||
|
||||||||||||||||||
expect( | ||||||||||||||||||
screen.getByRole( 'button', { | ||||||||||||||||||
|
@@ -220,11 +240,8 @@ describe( 'BlockSwitcherDropdownMenu', () => { | |||||||||||||||||
} ) | ||||||||||||||||||
).toBeVisible(); | ||||||||||||||||||
|
||||||||||||||||||
const menu = screen.getByRole( 'menu', { | ||||||||||||||||||
name: 'Block Name', | ||||||||||||||||||
} ); | ||||||||||||||||||
expect( menu ).toBeInTheDocument(); | ||||||||||||||||||
expect( menu ).not.toBeVisible(); | ||||||||||||||||||
expect( menu ).toBeVisible(); | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At this moment, if you check it with a snapshot, the opacity is not yet 1, but "only" 0.9994. There is an animation frame loop (in We should do another wait with: await waitFor( () => expect(popover).toHaveStyle( { opacity: 1 } ); Or integrate it into There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, I was thinking about that. I think this is a worthy improvement, let me work on it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, this is interesting. I haven't debugged thoroughly yet, but the moment I add the assertion you mentioned, or extend There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I debugged this and the gutenberg/packages/components/src/popover/index.tsx Lines 120 to 123 in 5fcf00d
When @ciampo I'm curious what are we preventing with this If There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hey @jsnajdr , if I recall correctly that state variable is in place to avoid the animation from re-running when the gutenberg/packages/components/src/popover/index.tsx Lines 109 to 112 in b120213
If I remember correctly, without this flag, the animation would run again if the value of the Feel free to play around with it and remove it if we find a better solution to the problem! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This is however not true, at least with the version of I verified that when debugging I think we can either remove There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good to me, then! Please do ping me on the PR if you're going to work on it, happy to help with reviewing and testing. |
||||||||||||||||||
} ); | ||||||||||||||||||
|
||||||||||||||||||
test( 'should simulate a click event, which should call onToggle.', async () => { | ||||||||||||||||||
|
@@ -254,7 +271,18 @@ describe( 'BlockSwitcherDropdownMenu', () => { | |||||||||||||||||
expanded: false, | ||||||||||||||||||
} ) | ||||||||||||||||||
); | ||||||||||||||||||
await act( () => Promise.resolve() ); | ||||||||||||||||||
|
||||||||||||||||||
const menu = screen.getByRole( 'menu', { | ||||||||||||||||||
name: 'Block Name', | ||||||||||||||||||
} ); | ||||||||||||||||||
|
||||||||||||||||||
expect( menu ).not.toBeVisible(); | ||||||||||||||||||
|
||||||||||||||||||
await waitFor( () => | ||||||||||||||||||
expect( | ||||||||||||||||||
getWrappingPopoverElement( menu ) | ||||||||||||||||||
).toBePositionedPopover() | ||||||||||||||||||
); | ||||||||||||||||||
|
||||||||||||||||||
expect( | ||||||||||||||||||
screen.getByRole( 'button', { | ||||||||||||||||||
|
@@ -263,11 +291,7 @@ describe( 'BlockSwitcherDropdownMenu', () => { | |||||||||||||||||
} ) | ||||||||||||||||||
).toBeVisible(); | ||||||||||||||||||
|
||||||||||||||||||
const menu = screen.getByRole( 'menu', { | ||||||||||||||||||
name: 'Block Name', | ||||||||||||||||||
} ); | ||||||||||||||||||
expect( menu ).toBeInTheDocument(); | ||||||||||||||||||
expect( menu ).not.toBeVisible(); | ||||||||||||||||||
expect( menu ).toBeVisible(); | ||||||||||||||||||
} ); | ||||||||||||||||||
|
||||||||||||||||||
test( 'should create the transform items for the chosen block.', async () => { | ||||||||||||||||||
|
@@ -285,14 +309,19 @@ describe( 'BlockSwitcherDropdownMenu', () => { | |||||||||||||||||
expanded: false, | ||||||||||||||||||
} ) | ||||||||||||||||||
); | ||||||||||||||||||
await act( () => Promise.resolve() ); | ||||||||||||||||||
|
||||||||||||||||||
const menu = screen.getByRole( 'menu', { | ||||||||||||||||||
name: 'Block Name', | ||||||||||||||||||
} ); | ||||||||||||||||||
|
||||||||||||||||||
await waitFor( () => | ||||||||||||||||||
expect( | ||||||||||||||||||
getWrappingPopoverElement( menu ) | ||||||||||||||||||
).toBePositionedPopover() | ||||||||||||||||||
); | ||||||||||||||||||
|
||||||||||||||||||
expect( | ||||||||||||||||||
within( | ||||||||||||||||||
screen.getByRole( 'menu', { | ||||||||||||||||||
name: 'Block Name', | ||||||||||||||||||
} ) | ||||||||||||||||||
).getByRole( 'menuitem' ) | ||||||||||||||||||
within( menu ).getByRole( 'menuitem' ) | ||||||||||||||||||
).toBeInTheDocument(); | ||||||||||||||||||
} ); | ||||||||||||||||||
} ); | ||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, we didn't remove all of them yet? 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think some of those fixes got lost in the thousand rebases 😅 We'll clean them up, don't worry.