Skip to content

Commit

Permalink
Add test for useConstrainedTabbing first pass.
Browse files Browse the repository at this point in the history
  • Loading branch information
afercia committed Mar 3, 2023
1 parent d75ef59 commit 08e90b0
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 3 deletions.
5 changes: 2 additions & 3 deletions packages/compose/src/hooks/use-constrained-tabbing/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/**
* WordPress dependencies
*/
import { TAB } from '@wordpress/keycodes';
import { focus } from '@wordpress/dom';

/**
Expand Down Expand Up @@ -33,9 +32,9 @@ import useRefEffect from '../use-ref-effect';
function useConstrainedTabbing() {
return useRefEffect( ( /** @type {HTMLElement} */ node ) => {
function onKeyDown( /** @type {KeyboardEvent} */ event ) {
const { keyCode, shiftKey, target } = event;
const { code, shiftKey, target } = event;

if ( keyCode !== TAB ) {
if ( code !== 'Tab' ) {
return;
}

Expand Down
88 changes: 88 additions & 0 deletions packages/compose/src/hooks/use-constrained-tabbing/test/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/**
* External dependencies
*/
import { render, screen, waitFor, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

/**
* Internal dependencies
*/
import useConstrainedTabbing from '../';

describe( 'useConstrainedTabbing', () => {
function ConstrainedTabbingComponent() {
const constrainedTabbingRef = useConstrainedTabbing();
return (
<div ref={ constrainedTabbingRef } data-testid="test-component">
<button type="button">Button 1</button>
<div data-testid="test-component" tabIndex={ -1 } />
<button type="button">Button 2</button>
<button
type="button"
onClick={ () => {
const placeholder =
screen.getByTestId( 'test-component' );
placeholder.focus();
} }
>
Button 3
</button>
</div>
);
}

it( 'should constrain tabbing when tabbing forwards', async () => {
const user = userEvent.setup( { delay: 100 } );

render(
<div>
<button type="button">Focusable element before</button>
<ConstrainedTabbingComponent />
<button type="button">Focusable element after</button>
</div>
);

const focusableBefore = screen.getByRole( 'button', {
name: 'Focusable element before',
} );
const button1 = screen.getByRole( 'button', {
name: 'Button 1',
} );
const button2 = screen.getByRole( 'button', {
name: 'Button 2',
} );
const button3 = screen.getByRole( 'button', {
name: 'Button 3',
} );

await user.keyboard( '{Tab}' );
expect( focusableBefore ).toHaveFocus();

await user.keyboard( '{Tab}' );
expect( button1 ).toHaveFocus();

await user.keyboard( '{Tab}' );
expect( button2 ).toHaveFocus();

await user.keyboard( '{Tab}' );
expect( button3 ).toHaveFocus();

// Looks like the React Testing Library didn't implement event.keycode.
// Also, we can't use user.Tab() and the like, as the trap element is
// injected in the DOM while the Tab key is being pressed.
fireEvent.keyDown( button3, { code: 'Tab' } );

const component = screen.getByTestId( 'test-component' );
// eslint-disable-next-line testing-library/no-node-access
const trap = component.firstChild;

await waitFor( () =>
expect( trap.outerHTML ).toEqual( '<div tabindex="-1"></div>' )
);

expect( trap ).toHaveFocus();

// At this point, the trap element should be blurred.
// Then, the focused element should be Button 1.
} );
} );

0 comments on commit 08e90b0

Please sign in to comment.