import { FocusZone, AutoFocusZone } from '@fluentui/react-bindings'; import * as React from 'react'; import * as ReactTestUtils from 'react-dom/test-utils'; // rAF does not exist in node - let's mock it window.requestAnimationFrame = (callback: FrameRequestCallback) => { const r = window.setTimeout(callback, 0); jest.runAllTimers(); return r; }; const animationFrame = () => new Promise(resolve => window.requestAnimationFrame(resolve)); jest.useFakeTimers(); describe('AutoFocusZone', () => { let lastFocusedElement: HTMLElement | undefined; const _onFocus = (ev: any): void => (lastFocusedElement = ev.target); const setupElement = ( element: HTMLElement, { clientRect, isVisible = true, }: { clientRect: { top: number; left: number; bottom: number; right: number; }; isVisible?: boolean; }, ): void => { // @ts-ignore element.getBoundingClientRect = () => ({ top: clientRect.top, left: clientRect.left, bottom: clientRect.bottom, right: clientRect.right, width: clientRect.right - clientRect.left, height: clientRect.bottom - clientRect.top, }); element.setAttribute('data-is-visible', String(isVisible)); element.focus = () => ReactTestUtils.Simulate.focus(element); }; beforeEach(() => { lastFocusedElement = undefined; }); describe('Focusing the ATZ', () => { function setupTest(firstFocusableSelector?: string) { let autoFocusZoneRef: AutoFocusZone | null = null; const topLevelDiv = ReactTestUtils.renderIntoDocument<{}>(
{ autoFocusZoneRef = ftz; }} >
, ) as HTMLElement; const buttonF = topLevelDiv.querySelector('.f') as HTMLElement; const buttonA = topLevelDiv.querySelector('.a') as HTMLElement; const buttonB = topLevelDiv.querySelector('.b') as HTMLElement; const buttonZ = topLevelDiv.querySelector('.z') as HTMLElement; // Assign bounding locations to buttons. setupElement(buttonF, { clientRect: { top: 0, bottom: 10, left: 0, right: 10 } }); setupElement(buttonA, { clientRect: { top: 10, bottom: 20, left: 0, right: 10 } }); setupElement(buttonB, { clientRect: { top: 20, bottom: 30, left: 0, right: 10 } }); setupElement(buttonZ, { clientRect: { top: 30, bottom: 40, left: 0, right: 10 } }); return { autoFocusZone: autoFocusZoneRef, buttonF, buttonA, buttonB, buttonZ }; } it('goes to first focusable element when focusing the ATZ', async () => { expect.assertions(1); const { autoFocusZone, buttonF } = setupTest(); // By calling `componentDidMount`, AFZ will behave as just initialized and focus needed element // Focus within should go to 1st focusable inner element. // @ts-ignore autoFocusZone.componentDidMount(); await animationFrame(); expect(lastFocusedElement).toBe(buttonF); }); it('goes to the element with containing the firstFocusableSelector if provided when focusing the ATZ', async () => { expect.assertions(1); const { autoFocusZone, buttonB } = setupTest('.b'); // By calling `componentDidMount`, AFZ will behave as just initialized and focus needed element // Focus within should go to the element containing the selector. // @ts-ignore autoFocusZone.componentDidMount(); await animationFrame(); expect(lastFocusedElement).toBe(buttonB); }); }); });