Как проверить, какой ввод находится в фокусе при нажатии кнопки tab

#javascript #reactjs #jestjs #react-testing-library

#javascript #reactjs #jestjs #реагировать-тестирование-библиотека

Вопрос:

Я создаю компонент автозаполнения React и тестирую его с помощью Jest и React-testing-library.

У меня есть два входа. Когда input1 (с функцией автозаполнения) находится в фокусе, нажатие Tab кнопки должно либо автоматически заполнить input1 текстом, если input1 не пуст, либо переместить фокус на input2 (что является поведением форм по умолчанию), если input1 пуст.

form.jsx

     const onKeyDown = (e) => {
        if(e.key === 'Tab' amp;amp; 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.
    });
  

В настоящее время в моих тестах document.activeElement продолжает возвращаться Body элемент, но я ожидаю, что он вернет любой из двух входов. Также expect(input2).toHaveFocus() сбой.

Как я могу проверить, что фокус переместился с input1 на input2?

Ответ №1:

В итоге я использовал библиотеку @testing-library / user-event . Я заменил fireEvent на userEvent для Tab нажатия.

Теперь мой код выглядит так:

     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
    });
  

Ссылка: https://github.com/testing-library/user-event#tabshift-focustrap

Ответ №2:

Функция fireEvent.keyDown должна работать для вас, если вы выполните следующие действия:

  • Компонент и тест, оба должны использовать нажатие клавиши (использование нажатия клавиши было одной из моих проблем)

  • Тогда fireEvent можно вызвать следующим образом:

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

Для получения дополнительной информации о кодах клавиш