How to test which input has the focus when tab button is pressed
Asked Answered
A

2

18

I'm building a React autocomplete component and testing it using Jest and React-testing-library.

I have two inputs. When input1(with autocomplete functionality) is in focus, clicking the Tab button should either auto fill input1 with a text if input1 isn't empty, or move the focus to input2(which is the default behaviour of forms) if input1 is empty.

form.jsx

    const onKeyDown = (e) => {
        if(e.key === 'Tab' && e.target.value !== '') {
            setInput1Text('some-autocomplete-text');
            e.preventDefault(); //prevent focus from moving to the next input(input2)
        }
    };

form.test.jsx

    test('pressing Tab button should move focus to input2 as input1 is empty', () => {
        const input1 = container.getElementsByTagName('input')[0];
        const input2 = container.getElementsByTagName('input')[1];

        fireEvent.change(input1, { target: { value: '' } });
        fireEvent.keyDown(input1, { key: 'Tab' });

        expect(input2).toBe(document.activeElement) //failing, activeElement returns <Body>
        // OR
        expect(input2).toHaveFocus(); //failing as well.
    });

Currently, in my tests, document.activeElement keeps returning the Body element but I expect it to return either of the two inputs. Also expect(input2).toHaveFocus() fails.

How can I test that the focus has moved from input1 to input2?

Azores answered 23/10, 2020 at 0:59 Comment(0)
A
28

I ended up using the @testing-library/user-event library. I replaced fireEvent with userEvent for the Tab press.

My code now looks like this:

    import userEvent from '@testing-library/user-event';

    test('pressing Tab button should move focus to input2 as input1 is empty', () => {
        const input1 = container.getElementsByTagName('input')[0];
        const input2 = container.getElementsByTagName('input')[1];

        input1.focus();
        fireEvent.change(input1, { target: { value: '' } });
        userEvent.tab(); //this line made it work

        expect(input2).toHaveFocus(); //passing now
    });

Reference: https://github.com/testing-library/user-event#tabshift-focustrap

Azores answered 23/10, 2020 at 13:20 Comment(0)
K
0

The function fireEvent.keyDown should work for you if you do the following:

  • The component and the test, both have to use KeyDown, (using KeyPressed was one of my problems)

  • Then the fireEvent can be called like this:

      fireEvent.keyDown(Element, {key: 'Tab', code: 'Tab', charCode: 9})
    

For more info on key codes

Kinship answered 21/11, 2022 at 17:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.