-
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
CustomSelectControl (v1 & v2): Fix errors in unit test setup #59038
Changes from all commits
f7cec48
85def83
eb52aba
c6e546c
596452f
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 |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
* External dependencies | ||
*/ | ||
import { render, screen } from '@testing-library/react'; | ||
import { click, press, sleep, type } from '@ariakit/test'; | ||
import { click, press, sleep, type, waitFor } from '@ariakit/test'; | ||
|
||
/** | ||
* WordPress dependencies | ||
|
@@ -12,7 +12,7 @@ import { useState } from '@wordpress/element'; | |
/** | ||
* Internal dependencies | ||
*/ | ||
import { CustomSelect, CustomSelectItem } from '..'; | ||
import { CustomSelect as UncontrolledCustomSelect, CustomSelectItem } from '..'; | ||
import type { CustomSelectProps, LegacyCustomSelectProps } from '../types'; | ||
|
||
const customClass = 'amber-skies'; | ||
|
@@ -51,12 +51,18 @@ const legacyProps = { | |
|
||
const LegacyControlledCustomSelect = ( { | ||
options, | ||
onChange, | ||
...restProps | ||
}: LegacyCustomSelectProps ) => { | ||
const [ value, setValue ] = useState( options[ 0 ] ); | ||
return ( | ||
<CustomSelect | ||
{ ...legacyProps } | ||
onChange={ ( { selectedItem }: any ) => setValue( selectedItem ) } | ||
<UncontrolledCustomSelect | ||
{ ...restProps } | ||
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. Ensure that the props from each test instance are actually passed through, instead of just spreading the scaffolded |
||
options={ options } | ||
onChange={ ( args: any ) => { | ||
onChange?.( args ); | ||
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. Also pass through the |
||
setValue( args.selectedItem ); | ||
} } | ||
value={ options.find( | ||
( option: any ) => option.key === value.key | ||
) } | ||
|
@@ -66,7 +72,7 @@ const LegacyControlledCustomSelect = ( { | |
|
||
describe( 'With Legacy Props', () => { | ||
describe.each( [ | ||
[ 'Uncontrolled', CustomSelect ], | ||
[ 'Uncontrolled', UncontrolledCustomSelect ], | ||
[ 'Controlled', LegacyControlledCustomSelect ], | ||
] )( '%s', ( ...modeAndComponent ) => { | ||
const [ , Component ] = modeAndComponent; | ||
|
@@ -100,7 +106,7 @@ describe( 'With Legacy Props', () => { | |
} ); | ||
|
||
it( 'Should keep current selection if dropdown is closed without changing selection', async () => { | ||
render( <CustomSelect { ...legacyProps } /> ); | ||
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. These were all pointing to the uncontrolled version of the component, even though it was part of a uncontrolled/controlled matrix. 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. What a good find! |
||
render( <Component { ...legacyProps } /> ); | ||
|
||
const currentSelectedItem = screen.getByRole( 'combobox', { | ||
expanded: false, | ||
|
@@ -128,7 +134,7 @@ describe( 'With Legacy Props', () => { | |
} ); | ||
|
||
it( 'Should apply class only to options that have a className defined', async () => { | ||
render( <CustomSelect { ...legacyProps } /> ); | ||
render( <Component { ...legacyProps } /> ); | ||
|
||
await click( | ||
screen.getByRole( 'combobox', { | ||
|
@@ -165,7 +171,7 @@ describe( 'With Legacy Props', () => { | |
const customStyles = | ||
'background-color: rgb(127, 255, 212); rotate: 13deg;'; | ||
|
||
render( <CustomSelect { ...legacyProps } /> ); | ||
render( <Component { ...legacyProps } /> ); | ||
|
||
await click( | ||
screen.getByRole( 'combobox', { | ||
|
@@ -198,9 +204,9 @@ describe( 'With Legacy Props', () => { | |
); | ||
} ); | ||
|
||
it( 'does not show selected hint by default', () => { | ||
it( 'does not show selected hint by default', async () => { | ||
render( | ||
<CustomSelect | ||
<Component | ||
{ ...legacyProps } | ||
label="Custom select" | ||
options={ [ | ||
|
@@ -212,14 +218,16 @@ describe( 'With Legacy Props', () => { | |
] } | ||
/> | ||
); | ||
expect( | ||
screen.getByRole( 'combobox', { name: 'Custom select' } ) | ||
).not.toHaveTextContent( 'Hint' ); | ||
await waitFor( () => | ||
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. Some async wait is necessary for the controlled version. |
||
expect( | ||
screen.getByRole( 'combobox', { name: 'Custom select' } ) | ||
).not.toHaveTextContent( 'Hint' ) | ||
); | ||
} ); | ||
|
||
it( 'shows selected hint when __experimentalShowSelectedHint is set', async () => { | ||
render( | ||
<CustomSelect | ||
<Component | ||
{ ...legacyProps } | ||
label="Custom select" | ||
options={ [ | ||
|
@@ -233,16 +241,18 @@ describe( 'With Legacy Props', () => { | |
/> | ||
); | ||
|
||
expect( | ||
screen.getByRole( 'combobox', { | ||
expanded: false, | ||
} ) | ||
).toHaveTextContent( /hint/i ); | ||
await waitFor( () => | ||
expect( | ||
screen.getByRole( 'combobox', { | ||
expanded: false, | ||
} ) | ||
).toHaveTextContent( /hint/i ) | ||
); | ||
} ); | ||
|
||
it( 'shows selected hint in list of options when added', async () => { | ||
render( | ||
<CustomSelect | ||
<Component | ||
{ ...legacyProps } | ||
label="Custom select" | ||
options={ [ | ||
|
@@ -269,7 +279,7 @@ describe( 'With Legacy Props', () => { | |
const mockOnChange = jest.fn(); | ||
|
||
render( | ||
<CustomSelect { ...legacyProps } onChange={ mockOnChange } /> | ||
<Component { ...legacyProps } onChange={ mockOnChange } /> | ||
); | ||
|
||
await click( | ||
|
@@ -313,7 +323,7 @@ describe( 'With Legacy Props', () => { | |
); | ||
|
||
render( | ||
<CustomSelect { ...legacyProps } onChange={ mockOnChange } /> | ||
<Component { ...legacyProps } onChange={ mockOnChange } /> | ||
); | ||
|
||
await sleep(); | ||
|
@@ -332,7 +342,7 @@ describe( 'With Legacy Props', () => { | |
|
||
describe( 'Keyboard behavior and accessibility', () => { | ||
it( 'Should be able to change selection using keyboard', async () => { | ||
render( <CustomSelect { ...legacyProps } /> ); | ||
render( <Component { ...legacyProps } /> ); | ||
|
||
const currentSelectedItem = screen.getByRole( 'combobox', { | ||
expanded: false, | ||
|
@@ -358,7 +368,7 @@ describe( 'With Legacy Props', () => { | |
} ); | ||
|
||
it( 'Should be able to type characters to select matching options', async () => { | ||
render( <CustomSelect { ...legacyProps } /> ); | ||
render( <Component { ...legacyProps } /> ); | ||
|
||
const currentSelectedItem = screen.getByRole( 'combobox', { | ||
expanded: false, | ||
|
@@ -379,7 +389,7 @@ describe( 'With Legacy Props', () => { | |
} ); | ||
|
||
it( 'Can change selection with a focused input and closed dropdown if typed characters match an option', async () => { | ||
render( <CustomSelect { ...legacyProps } /> ); | ||
render( <Component { ...legacyProps } /> ); | ||
|
||
const currentSelectedItem = screen.getByRole( 'combobox', { | ||
expanded: false, | ||
|
@@ -403,7 +413,7 @@ describe( 'With Legacy Props', () => { | |
} ); | ||
|
||
it( 'Should have correct aria-selected value for selections', async () => { | ||
render( <CustomSelect { ...legacyProps } /> ); | ||
render( <Component { ...legacyProps } /> ); | ||
|
||
const currentSelectedItem = screen.getByRole( 'combobox', { | ||
expanded: false, | ||
|
@@ -460,29 +470,29 @@ describe( 'With Legacy Props', () => { | |
describe( 'static typing', () => { | ||
<> | ||
{ /* @ts-expect-error - when `options` prop is passed, `onChange` should have legacy signature */ } | ||
<CustomSelect | ||
<UncontrolledCustomSelect | ||
label="foo" | ||
options={ [] } | ||
onChange={ ( _: string | string[] ) => undefined } | ||
/> | ||
<CustomSelect | ||
<UncontrolledCustomSelect | ||
label="foo" | ||
options={ [] } | ||
onChange={ ( _: { selectedItem: unknown } ) => undefined } | ||
/> | ||
<CustomSelect | ||
<UncontrolledCustomSelect | ||
label="foo" | ||
onChange={ ( _: string | string[] ) => undefined } | ||
> | ||
foobar | ||
</CustomSelect> | ||
</UncontrolledCustomSelect> | ||
{ /* @ts-expect-error - when `children` are passed, `onChange` should have new default signature */ } | ||
<CustomSelect | ||
<UncontrolledCustomSelect | ||
label="foo" | ||
onChange={ ( _: { selectedItem: unknown } ) => undefined } | ||
> | ||
foobar | ||
</CustomSelect> | ||
</UncontrolledCustomSelect> | ||
</>; | ||
} ); | ||
|
||
|
@@ -496,7 +506,7 @@ const defaultProps = { | |
const ControlledCustomSelect = ( props: CustomSelectProps ) => { | ||
const [ value, setValue ] = useState< string | string[] >(); | ||
return ( | ||
<CustomSelect | ||
<UncontrolledCustomSelect | ||
{ ...props } | ||
onChange={ ( nextValue: string | string[] ) => { | ||
setValue( nextValue ); | ||
|
@@ -509,7 +519,7 @@ const ControlledCustomSelect = ( props: CustomSelectProps ) => { | |
|
||
describe( 'With Default Props', () => { | ||
describe.each( [ | ||
[ 'Uncontrolled', CustomSelect ], | ||
[ 'Uncontrolled', UncontrolledCustomSelect ], | ||
[ 'Controlled', ControlledCustomSelect ], | ||
] )( '%s', ( ...modeAndComponent ) => { | ||
const [ , Component ] = modeAndComponent; | ||
|
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.
Renamed to prevent accidental usage in a controlled/uncontrolled test matrix.