Skip to content

Commit

Permalink
BorderControl: improve popover waiting
Browse files Browse the repository at this point in the history
  • Loading branch information
jsnajdr committed Dec 21, 2022
1 parent efab914 commit dcf4b20
Showing 1 changed file with 55 additions and 54 deletions.
109 changes: 55 additions & 54 deletions packages/components/src/border-control/test/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
/**
* External dependencies
*/
import { act, fireEvent, render, screen } from '@testing-library/react';
import {
act,
fireEvent,
render,
screen,
waitFor,
} from '@testing-library/react';

/**
* Internal dependencies
Expand Down Expand Up @@ -37,29 +43,24 @@ function createProps( customProps ) {

const toggleLabelRegex = /Border color( and style)* picker/;

const renderBorderControl = async ( props ) => {
const view = render( <BorderControl { ...props } /> );
// When the `Popover` component is rendered or updated, the `useFloating`
// hook from the `floating-ui` package will schedule a state update in a
// promise handler. We need to wait for this promise handler to execute
// before checking results. That's what this async `act()` call achieves.
// See also: https://floating-ui.com/docs/react-dom#testing
await act( () => Promise.resolve() );
return view;
};

const rerenderBorderControl = async ( rerender, props ) => {
const view = rerender( <BorderControl { ...props } /> );
// Same reason to `act()` as in `renderBorderControl` above.
await act( () => Promise.resolve() );
return view;
};
function getWrappingPopoverElement( element ) {
return element.closest( '.components-popover' );
}

const openPopover = async () => {
const toggleButton = screen.getByLabelText( toggleLabelRegex );
fireEvent.click( toggleButton );
// Same reason to `act()` as in `renderBorderControl` above.
await act( () => Promise.resolve() );

// Wait for color picker popover to fully appear
const pickerButton = screen.getByRole( 'button', {
name: /^Custom color picker/,
} );

await waitFor( () =>
expect(
getWrappingPopoverElement( pickerButton )
).toBePositionedPopover()
);
};

const getButton = ( name ) => {
Expand Down Expand Up @@ -95,7 +96,7 @@ describe( 'BorderControl', () => {
describe( 'basic rendering', () => {
it( 'should render standard border control', async () => {
const props = createProps();
await renderBorderControl( props );
render( <BorderControl { ...props } /> );

const label = screen.getByText( props.label );
const colorButton = screen.getByLabelText( toggleLabelRegex );
Expand All @@ -116,7 +117,7 @@ describe( 'BorderControl', () => {

it( 'should hide label', async () => {
const props = createProps( { hideLabelFromVision: true } );
await renderBorderControl( props );
render( <BorderControl { ...props } /> );
const label = screen.getByText( props.label );

// As visually hidden labels are still included in the document
Expand All @@ -130,23 +131,23 @@ describe( 'BorderControl', () => {

it( 'should render with slider', async () => {
const props = createProps( { withSlider: true } );
await renderBorderControl( props );
render( <BorderControl { ...props } /> );

const slider = getSliderInput();
expect( slider ).toBeInTheDocument();
} );

it( 'should render placeholder in UnitControl', async () => {
const props = createProps( { placeholder: 'Mixed' } );
await renderBorderControl( props );
render( <BorderControl { ...props } /> );

const widthInput = getWidthInput();
expect( widthInput ).toHaveAttribute( 'placeholder', 'Mixed' );
} );

it( 'should render color and style popover', async () => {
const props = createProps();
await renderBorderControl( props );
render( <BorderControl { ...props } /> );
await openPopover();

const customColorPicker = getButton( /Custom color picker/ );
Expand All @@ -170,7 +171,7 @@ describe( 'BorderControl', () => {

it( 'should render color and style popover header', async () => {
const props = createProps( { showDropdownHeader: true } );
await renderBorderControl( props );
render( <BorderControl { ...props } /> );
await openPopover();

const headerLabel = screen.getByText( 'Border color' );
Expand All @@ -182,7 +183,7 @@ describe( 'BorderControl', () => {

it( 'should not render style options when opted out of', async () => {
const props = createProps( { enableStyle: false } );
await renderBorderControl( props );
render( <BorderControl { ...props } /> );
await openPopover();

const styleLabel = screen.queryByText( 'Style' );
Expand All @@ -201,7 +202,7 @@ describe( 'BorderControl', () => {
describe( 'with style selection enabled', () => {
it( 'should include both color and style in label', async () => {
const props = createProps( { value: undefined } );
await renderBorderControl( props );
render( <BorderControl { ...props } /> );

expect(
screen.getByLabelText( 'Border color and style picker.' )
Expand All @@ -210,7 +211,7 @@ describe( 'BorderControl', () => {

it( 'should correctly describe named color selection', async () => {
const props = createProps( { value: { color: '#72aee6' } } );
await renderBorderControl( props );
render( <BorderControl { ...props } /> );

expect(
screen.getByLabelText(
Expand All @@ -221,7 +222,7 @@ describe( 'BorderControl', () => {

it( 'should correctly describe custom color selection', async () => {
const props = createProps( { value: { color: '#4b1d80' } } );
await renderBorderControl( props );
render( <BorderControl { ...props } /> );

expect(
screen.getByLabelText(
Expand All @@ -234,7 +235,7 @@ describe( 'BorderControl', () => {
const props = createProps( {
value: { color: '#72aee6', style: 'dotted' },
} );
await renderBorderControl( props );
render( <BorderControl { ...props } /> );

expect(
screen.getByLabelText(
Expand All @@ -247,7 +248,7 @@ describe( 'BorderControl', () => {
const props = createProps( {
value: { color: '#4b1d80', style: 'dashed' },
} );
await renderBorderControl( props );
render( <BorderControl { ...props } /> );

expect(
screen.getByLabelText(
Expand All @@ -263,7 +264,7 @@ describe( 'BorderControl', () => {
value: undefined,
enableStyle: false,
} );
await renderBorderControl( props );
render( <BorderControl { ...props } /> );

expect(
screen.getByLabelText( 'Border color picker.' )
Expand All @@ -275,7 +276,7 @@ describe( 'BorderControl', () => {
value: { color: '#72aee6' },
enableStyle: false,
} );
await renderBorderControl( props );
render( <BorderControl { ...props } /> );

expect(
screen.getByLabelText(
Expand All @@ -289,7 +290,7 @@ describe( 'BorderControl', () => {
value: { color: '#4b1d80' },
enableStyle: false,
} );
await renderBorderControl( props );
render( <BorderControl { ...props } /> );

expect(
screen.getByLabelText(
Expand All @@ -303,7 +304,7 @@ describe( 'BorderControl', () => {
describe( 'onChange handling', () => {
it( 'should update width with slider value', async () => {
const props = createProps( { withSlider: true } );
const { rerender } = await renderBorderControl( props );
const { rerender } = render( <BorderControl { ...props } /> );

const slider = getSliderInput();
fireEvent.change( slider, { target: { value: '5' } } );
Expand All @@ -313,15 +314,15 @@ describe( 'BorderControl', () => {
width: '5px',
} );

await rerenderBorderControl( rerender, props );
rerender( <BorderControl { ...props } /> );
const widthInput = getWidthInput();

expect( widthInput.value ).toEqual( '5' );
} );

it( 'should update color selection', async () => {
const props = createProps();
await renderBorderControl( props );
render( <BorderControl { ...props } /> );
await openPopover();
clickButton( 'Color: Green' );

Expand All @@ -333,7 +334,7 @@ describe( 'BorderControl', () => {

it( 'should clear color selection when toggling swatch off', async () => {
const props = createProps();
await renderBorderControl( props );
render( <BorderControl { ...props } /> );
await openPopover();
clickButton( 'Color: Blue' );

Expand All @@ -345,7 +346,7 @@ describe( 'BorderControl', () => {

it( 'should update style selection', async () => {
const props = createProps();
await renderBorderControl( props );
render( <BorderControl { ...props } /> );
await openPopover();
clickButton( 'Dashed' );

Expand All @@ -357,7 +358,7 @@ describe( 'BorderControl', () => {

it( 'should take no action when color and style popover is closed', async () => {
const props = createProps( { showDropdownHeader: true } );
await renderBorderControl( props );
render( <BorderControl { ...props } /> );
await openPopover();
clickButton( 'Close border color' );

Expand All @@ -366,7 +367,7 @@ describe( 'BorderControl', () => {

it( 'should reset color and style only when popover reset button clicked', async () => {
const props = createProps();
await renderBorderControl( props );
render( <BorderControl { ...props } /> );
await openPopover();
clickButton( 'Reset to default' );

Expand All @@ -379,9 +380,9 @@ describe( 'BorderControl', () => {

it( 'should sanitize border when width and color are undefined', async () => {
const props = createProps();
const { rerender } = await renderBorderControl( props );
const { rerender } = render( <BorderControl { ...props } /> );
clearWidthInput();
await rerenderBorderControl( rerender, props );
rerender( <BorderControl { ...props } /> );
await openPopover();
clickButton( 'Color: Blue' );

Expand All @@ -392,9 +393,9 @@ describe( 'BorderControl', () => {
const props = createProps( {
shouldSanitizeBorder: false,
} );
const { rerender } = await renderBorderControl( props );
const { rerender } = render( <BorderControl { ...props } /> );
clearWidthInput();
await rerenderBorderControl( rerender, props );
rerender( <BorderControl { ...props } /> );
await openPopover();
clickButton( 'Color: Blue' );

Expand All @@ -407,7 +408,7 @@ describe( 'BorderControl', () => {

it( 'should clear color and set style to `none` when setting zero width', async () => {
const props = createProps();
await renderBorderControl( props );
render( <BorderControl { ...props } /> );
await openPopover();
clickButton( 'Color: Green' );
clickButton( 'Dotted' );
Expand All @@ -422,12 +423,12 @@ describe( 'BorderControl', () => {

it( 'should reselect color and style selections when changing to non-zero width', async () => {
const props = createProps();
const { rerender } = await renderBorderControl( props );
const { rerender } = render( <BorderControl { ...props } /> );
await openPopover();
clickButton( 'Color: Green' );
await rerenderBorderControl( rerender, props );
rerender( <BorderControl { ...props } /> );
clickButton( 'Dotted' );
await rerenderBorderControl( rerender, props );
rerender( <BorderControl { ...props } /> );
setWidthInput( '0' );
setWidthInput( '5' );

Expand All @@ -440,7 +441,7 @@ describe( 'BorderControl', () => {

it( 'should set a non-zero width when applying color to zero width border', async () => {
const props = createProps( { value: undefined } );
const { rerender } = await renderBorderControl( props );
const { rerender } = render( <BorderControl { ...props } /> );
await openPopover();
clickButton( 'Color: Yellow' );

Expand All @@ -451,7 +452,7 @@ describe( 'BorderControl', () => {
} );

setWidthInput( '0' );
await rerenderBorderControl( rerender, props );
rerender( <BorderControl { ...props } /> );
clickButton( 'Color: Green' );

expect( props.onChange ).toHaveBeenCalledWith( {
Expand All @@ -466,7 +467,7 @@ describe( 'BorderControl', () => {
value: undefined,
shouldSanitizeBorder: false,
} );
const { rerender } = await renderBorderControl( props );
const { rerender } = render( <BorderControl { ...props } /> );
await openPopover();
clickButton( 'Dashed' );

Expand All @@ -477,7 +478,7 @@ describe( 'BorderControl', () => {
} );

setWidthInput( '0' );
await rerenderBorderControl( rerender, props );
rerender( <BorderControl { ...props } /> );
clickButton( 'Dotted' );

expect( props.onChange ).toHaveBeenCalledWith( {
Expand Down

0 comments on commit dcf4b20

Please sign in to comment.