Skip to content

Commit

Permalink
add selectOnMove unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
chad1008 committed Dec 4, 2023
1 parent 995acc9 commit 09ce42d
Showing 1 changed file with 213 additions and 1 deletion.
214 changes: 213 additions & 1 deletion packages/components/src/tabs/test/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import userEvent from '@testing-library/user-event';
/**
* WordPress dependencies
*/
import { useState } from '@wordpress/element';
import { useEffect, useState } from '@wordpress/element';

/**
* Internal dependencies
Expand Down Expand Up @@ -102,6 +102,10 @@ const ControlledTabs = ( {
string | undefined | null
>( props.selectedTabId );

useEffect( () => {
setSelectedTabId( props.selectedTabId );
}, [ props.selectedTabId ] );

return (
<Tabs
{ ...props }
Expand Down Expand Up @@ -820,6 +824,61 @@ describe( 'Tabs', () => {
} );
} );

describe( 'When `selectOnMove` is `true`', () => {
it( 'should automatically select a newly focused tab', async () => {
const user = userEvent.setup();

render( <UncontrolledTabs tabs={ TABS } /> );

// Tab should focus the currently selected tab, which is Alpha.
await user.keyboard( '[Tab]' );
expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
expect( await getSelectedTab() ).toHaveFocus();

// Arrow keys should select and move focus to the next tab.
await user.keyboard( '[ArrowRight]' );
expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );
expect( await getSelectedTab() ).toHaveFocus();
} );
} );

describe( 'When `selectOnMove` is `false`', () => {
it( 'should apply focus without automatically changing the selected tab', async () => {
const user = userEvent.setup();

render(
<UncontrolledTabs tabs={ TABS } selectOnMove={ false } />
);

// Tab should focus the currently selected tab, which is Alpha.
await user.keyboard( '[Tab]' );
expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
expect( await getSelectedTab() ).toHaveFocus();

// Arrow key should move focus but not automatically change the selected tab.
await user.keyboard( '[ArrowRight]' );
expect(
screen.getByRole( 'tab', { name: 'Beta' } )
).toHaveFocus();
expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );

// Pressing the spacebar should select the focused tab.
await user.keyboard( '[Space]' );
expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );

// Arrow key should move focus but not automatically change the selected tab.
await user.keyboard( '[ArrowRight]' );
expect(
screen.getByRole( 'tab', { name: 'Gamma' } )
).toHaveFocus();
expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );

// Pressing the enter/return should select the focused tab.
await user.keyboard( '[Enter]' );
expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );
} );
} );

describe( 'Disabled tab', () => {
it( 'should disable the tab when `disabled` is `true`', async () => {
const user = userEvent.setup();
Expand Down Expand Up @@ -1203,5 +1262,158 @@ describe( 'Tabs', () => {
).not.toBeInTheDocument();
} );
} );

describe( 'When `selectOnMove` is `true`', () => {
it( 'should automatically select a newly focused tab', async () => {
const user = userEvent.setup();

render( <ControlledTabs tabs={ TABS } selectedTabId="beta" /> );

// This assertion ensures the component has had time to fully
// render, preventing flakiness.
// see https://github.com/WordPress/gutenberg/pull/55950
await waitFor( async () =>
expect(
await screen.findByRole( 'tab', { name: 'Beta' } )
).toHaveAttribute( 'aria-selected', 'true' )
);

await user.keyboard( '[Tab]' );

// Tab key should focus the currently selected tab, which is Beta.
expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );
expect( await getSelectedTab() ).toHaveFocus();

// Arrow keys should select and move focus to the next tab.
await user.keyboard( '[ArrowRight]' );
expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );
expect( await getSelectedTab() ).toHaveFocus();
} );
it( 'should automatically update focus when the selected tab is changed by the controlling component', async () => {
const user = userEvent.setup();

const { rerender } = render(
<ControlledTabs tabs={ TABS } selectedTabId="beta" />
);

// This assertion ensures the component has had time to fully
// render, preventing flakiness.
// see https://github.com/WordPress/gutenberg/pull/55950
await waitFor( async () =>
expect(
await screen.findByRole( 'tab', { name: 'Beta' } )
).toHaveAttribute( 'aria-selected', 'true' )
);

// Tab key should focus the currently selected tab, which is Beta.
await user.keyboard( '[Tab]' );
expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );
expect( await getSelectedTab() ).toHaveFocus();

rerender(
<ControlledTabs tabs={ TABS } selectedTabId="gamma" />
);

// When the selected tab is changed, it should automatically receive focus.
expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );
expect( await getSelectedTab() ).toHaveFocus();
} );
} );
describe( 'When `selectOnMove` is `false`', () => {
it( 'should apply focus without automatically changing the selected tab', async () => {
const user = userEvent.setup();

render(
<ControlledTabs
tabs={ TABS }
selectedTabId="beta"
selectOnMove={ false }
/>
);

// This assertion ensures the component has had time to fully
// render, preventing flakiness.
// see https://github.com/WordPress/gutenberg/pull/55950
await waitFor( async () =>
expect(
await screen.findByRole( 'tab', { name: 'Beta' } )
).toHaveAttribute( 'aria-selected', 'true' )
);

expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );

// Tab key should focus the currently selected tab, which is Beta.
await user.keyboard( '[Tab]' );
expect(
await screen.findByRole( 'tab', { name: 'Beta' } )
).toHaveFocus();

// Arrow key should move focus but not automatically change the selected tab.
await user.keyboard( '[ArrowRight]' );
expect(
screen.getByRole( 'tab', { name: 'Gamma' } )
).toHaveFocus();
expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );

// Pressing the spacebar should select the focused tab.
await user.keyboard( '[Space]' );
expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );

// Arrow key should move focus but not automatically change the selected tab.
await user.keyboard( '[ArrowRight]' );
expect(
screen.getByRole( 'tab', { name: 'Alpha' } )
).toHaveFocus();
expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );

// Pressing the enter/return should select the focused tab.
await user.keyboard( '[Enter]' );
expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
} );
it( 'should not automatically update focus when the selected tab is changed by the controlling component', async () => {
const user = userEvent.setup();

const { rerender } = render(
<ControlledTabs
tabs={ TABS }
selectedTabId="beta"
selectOnMove={ false }
/>
);

// This assertion ensures the component has had time to fully
// render, preventing flakiness.
// see https://github.com/WordPress/gutenberg/pull/55950
await waitFor( async () =>
expect(
await screen.findByRole( 'tab', { name: 'Beta' } )
).toHaveAttribute( 'aria-selected', 'true' )
);

expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );

// Tab key should focus the currently selected tab, which is Beta.
await user.keyboard( '[Tab]' );
expect( await getSelectedTab() ).toHaveFocus();

rerender(
<ControlledTabs
tabs={ TABS }
selectedTabId="gamma"
selectOnMove={ false }
/>
);

// When the selected tab is changed, it should not automatically receive focus.
expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );
// `waitFor` is needed here to prevent testing library from
// throwing a 'not wrapped in `act()`' error.
await waitFor( () =>
expect(
screen.getByRole( 'tab', { name: 'Beta' } )
).toHaveFocus()
);
} );
} );
} );
} );

0 comments on commit 09ce42d

Please sign in to comment.