Skip to content

Commit

Permalink
Improve testing for correct ARIA combobox pattern.
Browse files Browse the repository at this point in the history
  • Loading branch information
afercia committed Jan 16, 2023
1 parent 228b4bf commit e32866a
Showing 1 changed file with 106 additions and 31 deletions.
137 changes: 106 additions & 31 deletions packages/block-editor/src/components/link-control/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ describe( 'Basic rendering', () => {
// Search Input UI.
const searchInput = screen.getByRole( 'combobox', { name: 'URL' } );

expect( searchInput ).toBeInTheDocument();
expect( searchInput ).toBeVisible();
} );

it( 'should have aria-owns attribute to follow the ARIA 1.0 pattern', () => {
Expand All @@ -146,11 +146,113 @@ describe( 'Basic rendering', () => {
// Search Input UI.
const searchInput = screen.getByRole( 'combobox', { name: 'URL' } );

expect( searchInput ).toBeInTheDocument();
expect( searchInput ).toBeVisible();
expect( searchInput ).not.toHaveAttribute( 'aria-controls' );
expect( searchInput ).toHaveAttribute( 'aria-owns' );
} );

it( 'should have aria-selected attribute only on the highlighted item', async () => {
const user = userEvent.setup();

let resolver;
mockFetchSearchSuggestions.mockImplementation(
() =>
new Promise( ( resolve ) => {
resolver = resolve;
} )
);

render( <LinkControl /> );

// Search Input UI.
const searchInput = screen.getByRole( 'combobox', { name: 'URL' } );

// Simulate searching for a term.
await user.type( searchInput, 'Hello' );

// Wait for the spinner SVG icon to be rendered.
expect( await screen.findByRole( 'presentation' ) ).toBeVisible();
// Check the suggestions list is not rendered yet.
expect( screen.queryByRole( 'listbox' ) ).not.toBeInTheDocument();

// Make the search suggestions fetch return a response.
resolver( fauxEntitySuggestions );

const resultsList = await screen.findByRole( 'listbox', {
name: 'Search results for "Hello"',
} );

// Check the suggestions list is rendered.
expect( resultsList ).toBeVisible();
// Check the spinner SVG icon is not rendered any longer.
expect( screen.queryByRole( 'presentation' ) ).not.toBeInTheDocument();

const searchResultElements =
within( resultsList ).getAllByRole( 'option' );

expect( searchResultElements ).toHaveLength(
// The fauxEntitySuggestions length plus the 'Press ENTER to add this link' button.
fauxEntitySuggestions.length + 1
);

// Step down into the search results, highlighting the first result item.
triggerArrowDown( searchInput );

const firstSearchSuggestion = searchResultElements[ 0 ];
const secondSearchSuggestion = searchResultElements[ 1 ];

let selectedSearchResultElement = screen.getByRole( 'option', {
selected: true,
} );

// We should have highlighted the first item using the keyboard.
expect( selectedSearchResultElement ).toEqual( firstSearchSuggestion );

// Check the aria-selected attribute is set on the highlighted item.
expect( firstSearchSuggestion ).toHaveAttribute(
'aria-selected',
'true'
);
// Check the aria-selected attribute is omitted on the non-highlighted items.
expect( secondSearchSuggestion ).not.toHaveAttribute( 'aria-selected' );

// Step down into the search results, highlighting the second result item.
triggerArrowDown( searchInput );

selectedSearchResultElement = screen.getByRole( 'option', {
selected: true,
} );

// We should have highlighted the first item using the keyboard.
expect( selectedSearchResultElement ).toEqual( secondSearchSuggestion );

// Check the aria-selected attribute is omitted on non-highlighted items.
expect( firstSearchSuggestion ).not.toHaveAttribute( 'aria-selected' );
// Check the aria-selected attribute is set on the highlighted item.
expect( secondSearchSuggestion ).toHaveAttribute(
'aria-selected',
'true'
);

// Step up into the search results, highlighting the first result item.
triggerArrowUp( searchInput );

selectedSearchResultElement = screen.getByRole( 'option', {
selected: true,
} );

// We should be back to highlighting the first search result again.
expect( selectedSearchResultElement ).toEqual( firstSearchSuggestion );

// Check the aria-selected attribute is set on the highlighted item.
expect( firstSearchSuggestion ).toHaveAttribute(
'aria-selected',
'true'
);
// Check the aria-selected attribute is omitted on non-highlighted items.
expect( secondSearchSuggestion ).not.toHaveAttribute( 'aria-selected' );
} );

it( 'should not render protocol in links', async () => {
const user = userEvent.setup();
mockFetchSearchSuggestions.mockImplementation( () =>
Expand Down Expand Up @@ -570,7 +672,7 @@ describe( 'Manual link entry', () => {
} );

// Verify the UI hasn't allowed submission.
expect( searchInput ).toBeInTheDocument();
expect( searchInput ).toBeVisible();
expect( submitButton ).toBeDisabled();
expect( submitButton ).toBeVisible();
}
Expand Down Expand Up @@ -612,7 +714,7 @@ describe( 'Manual link entry', () => {
} );

// Verify the UI hasn't allowed submission.
expect( searchInput ).toBeInTheDocument();
expect( searchInput ).toBeVisible();
expect( submitButton ).toBeDisabled();
expect( submitButton ).toBeVisible();
}
Expand Down Expand Up @@ -1386,15 +1488,6 @@ describe( 'Selecting links', () => {
firstSearchSuggestion
);

// Check aria-selected attribute is omitted on non-highlighted items.
expect( firstSearchSuggestion ).toHaveAttribute(
'aria-selected',
'true'
);
expect( secondSearchSuggestion ).not.toHaveAttribute(
'aria-selected'
);

// Check we can go down again using the down arrow.
triggerArrowDown( searchInput );

Expand All @@ -1407,15 +1500,6 @@ describe( 'Selecting links', () => {
secondSearchSuggestion
);

// Check aria-selected attribute is omitted on non-highlighted items.
expect( firstSearchSuggestion ).not.toHaveAttribute(
'aria-selected'
);
expect( secondSearchSuggestion ).toHaveAttribute(
'aria-selected',
'true'
);

// Check we can go back up via up arrow.
triggerArrowUp( searchInput );

Expand All @@ -1428,15 +1512,6 @@ describe( 'Selecting links', () => {
firstSearchSuggestion
);

// Check aria-selected attribute is omitted on non-highlighted items.
expect( firstSearchSuggestion ).toHaveAttribute(
'aria-selected',
'true'
);
expect( secondSearchSuggestion ).not.toHaveAttribute(
'aria-selected'
);

expect( mockFetchSearchSuggestions ).toHaveBeenCalledTimes( 1 );
} );
} );
Expand Down

0 comments on commit e32866a

Please sign in to comment.