reactjsreact-testing-libraryvitest

Input still gets values even if disabled in React Testing Library


I have this test (React, Vitest & Testing Library):

import { describe, expect, it } from 'vitest';
import { fireEvent, render, screen } from '@testing-library/react';

describe('App button Problem', () => {
  it('types in the input correctly', async () => {
      render(<input type={'text'} disabled={false}/> );
      const input : HTMLInputElement = screen.getByRole('textbox');
      fireEvent.input(input, { target: { value: 'test' } });
      expect( input.value).toBe('test'); // this is ok
  });
  it('does not types in the input if disabled', async () => {
      render(<input type={'text'} disabled={true}/> );
      const input : HTMLInputElement = screen.getByRole('textbox');
      fireEvent.input(input, { target: { value: 'test' } });
      expect( input.value).toBe(''); // this fails (why?)
  }); 
});

I get this error:

AssertionError: expected 'test' to be '' // Object.is equality
Expected :
Actual   :test

Any idea why?


Solution

  • fireEvent.input() doesn't respect the disabled attribute of the input element by default in the test environment.

    But you could replace fireEvent with userEvent from @testing-library/user-event, which respects the disabled attribute:

    import { describe, expect, it } from 'vitest';
    import { render, screen } from '@testing-library/react';
    import userEvent from '@testing-library/user-event';
    
    describe('App button Problem', () => {
        it('types in the input correctly', async () => {
            render(<input type={'text'} disabled={false} />);
            const input: HTMLInputElement = screen.getByRole('textbox');
            await userEvent.type(input, 'test');
        expect(input.value).toBe('test'); // this is ok
    });
    
    it('does not type in the input if disabled', async () => {
        render(<input type={'text'} disabled={true} />);
        const input: HTMLInputElement = screen.getByRole('textbox');
    
        // Try to type in the input (userEvent respects disabled attribute)
        await userEvent.type(input, 'test');
    
        // The input value should remain unchanged
        expect(input.value).toBe(''); 
      });
    });