UNPKG

@wordpress/components

Version:
122 lines (92 loc) 3.08 kB
/** * External dependencies */ import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; /** * WordPress dependencies */ import { Component } from '@wordpress/element'; /** * Internal dependencies */ import withFocusOutside from '../'; let onFocusOutside; describe( 'withFocusOutside', () => { let origHasFocus; const EnhancedComponent = withFocusOutside( class extends Component { handleFocusOutside() { this.props.onFocusOutside(); } render() { return ( <div> <input type="text" /> <input type="button" /> </div> ); } } ); class TestComponent extends Component { render() { return <EnhancedComponent { ...this.props } />; } } beforeEach( () => { // Mock document.hasFocus() to always be true for testing // note: we overide this for some tests. origHasFocus = document.hasFocus; document.hasFocus = () => true; onFocusOutside = jest.fn(); } ); afterEach( () => { document.hasFocus = origHasFocus; } ); it( 'should not call handler if focus shifts to element within component', async () => { render( <TestComponent onFocusOutside={ onFocusOutside } /> ); const input = screen.getByRole( 'textbox' ); const button = screen.getByRole( 'button' ); input.focus(); input.blur(); button.focus(); await waitFor( () => expect( onFocusOutside ).not.toHaveBeenCalled() ); } ); it( 'should not call handler if focus transitions via click to button', async () => { const user = userEvent.setup(); render( <TestComponent onFocusOutside={ onFocusOutside } /> ); const input = screen.getByRole( 'textbox' ); const button = screen.getByRole( 'button' ); input.focus(); await user.click( button ); await waitFor( () => expect( onFocusOutside ).not.toHaveBeenCalled() ); } ); it( 'should call handler if focus doesn’t shift to element within component', async () => { render( <TestComponent onFocusOutside={ onFocusOutside } /> ); const input = screen.getByRole( 'textbox' ); input.focus(); input.blur(); await waitFor( () => expect( onFocusOutside ).toHaveBeenCalled() ); } ); it( 'should not call handler if focus shifts outside the component when the document does not have focus', async () => { render( <TestComponent onFocusOutside={ onFocusOutside } /> ); // Force document.hasFocus() to return false to simulate the window/document losing focus // See https://developer.mozilla.org/en-US/docs/Web/API/Document/hasFocus. document.hasFocus = () => false; const input = screen.getByRole( 'textbox' ); input.focus(); input.blur(); await waitFor( () => expect( onFocusOutside ).not.toHaveBeenCalled() ); } ); it( 'should cancel check when unmounting while queued', async () => { const { rerender } = render( <TestComponent onFocusOutside={ onFocusOutside } /> ); const input = screen.getByRole( 'textbox' ); input.focus(); input.blur(); rerender( <div /> ); await waitFor( () => expect( onFocusOutside ).not.toHaveBeenCalled() ); } ); } );