Search code examples
vue.jsjestjstesting-libraryjest-domvue-testing-library

Can't test the input checkbox properly when the element is disabled using @testing-library/vue


I'm trying to create some tests for a checkbox component but looks like I can't make an assertion for an input[type="checkbox"] when is disabled.

In the first two blocks I'm testing if the checkbox can be checked/uncheck if the element is disabled, everything ok here.

For the last two blocks, I'm trying that same, to check/uncheck but now I set the attribute disabled to the element but looks like the library is ignoring the attribute

Here are my tests

import { fireEvent, render, screen } from '@testing-library/vue';

it('should uncheck if is not disabled', async () => {
  render({
    template: '<input data-test-id="checkbox" type="checkbox" checked />',
  });

  const el = screen.getByTestId('checkbox');

  await fireEvent.click(el);

  expect(el).not.toBeDisabled();
  expect(el).not.toBeChecked();
});

it('should check if is not disabled', async () => {
  render({
    template: '<input data-test-id="checkbox" type="checkbox" />',
  });

  const el = screen.getByTestId('checkbox');

  await fireEvent.click(el);

  expect(el).not.toBeDisabled();
  expect(el).toBeChecked();
});

it('should not uncheck if is disabled', async () => {
  render({
    template: '<input data-test-id="checkbox" type="checkbox" checked disabled />',
  });

  const el = screen.getByTestId('checkbox');

  await fireEvent.click(el);

  expect(el).toBeDisabled();
  expect(el).toBeChecked(); // ! FAIL
});

it('should not check if is disabled', async () => {
  render({
    template: '<input data-test-id="checkbox" type="checkbox" disabled />',
  });

  const el = screen.getByTestId('checkbox');

  await fireEvent.click(el);

  expect(el).toBeDisabled();
  expect(el).not.toBeChecked(); // ! FAIL
});

And the console output

 FAIL  Checkbox.spec.js
  ✓ should uncheck if is not disabled (24ms)
  ✓ should check if is not disabled (3ms)
  ✕ should not uncheck if is disabled (5ms)
  ✕ should not check if is disabled (3ms)

  ● should not uncheck if is disabled

    expect(element).toBeChecked()

    Received element is not checked:
      <input checked="checked" data-test-id="checkbox" disabled="disabled" type="checkbox" />

      37 |
      38 |   expect(el).toBeDisabled();
    > 39 |   expect(el).toBeChecked(); // ! FAIL
         |              ^
      40 | });
      41 |
      42 | it('should not check if is disabled', async () => {

      at Object.<anonymous> (Checkbox.spec.js:39:14)

  ● should not check if is disabled

    expect(element).not.toBeChecked()

    Received element is checked:
      <input data-test-id="checkbox" disabled="disabled" type="checkbox" />

      50 |
      51 |   expect(el).toBeDisabled();
    > 52 |   expect(el).not.toBeChecked(); // ! FAIL
         |                  ^
      53 | });
      54 |

      at Object.<anonymous> (Checkbox.spec.js:52:18)

Test Suites: 1 failed, 1 total
Tests:       2 failed, 2 passed, 4 total
Snapshots:   0 total
Time:        1.707s, estimated 3s

Solution

  • You can see that there is a similar issue in testing-library github which is exactly your problem.

    According to user-event docs, you should use userEvent instead of fireEvent:

    user-event tries to simulate the real events that would happen in the browser as the user interacts with it. For example userEvent.click(checkbox) would change the state of the checkbox.

    You can visit @testing-library/user-event github in this link.

    So follow below steps:

    1. So first you should install this using npm install --save-dev @testing-library/user-event.

    2. Then import it at the top of your tests import userEvent from "@testing-library/user-event";

    3. Replace every fireEvent with userEvent.

    Final code is something like this:

    import { fireEvent, render, screen } from "@testing-library/vue";
    import "@testing-library/jest-dom";
    import userEvent from "@testing-library/user-event";
    
    it("should uncheck if is not disabled", async () => {
      render({
        template: '<input data-testid="checkbox" type="checkbox" checked />',
      });
    
      const el = screen.getByTestId("checkbox");
    
      await userEvent.click(el);
    
      expect(el).not.toBeDisabled();
      expect(el).not.toBeChecked();
    });
    
    it("should check if is not disabled", async () => {
      render({
        template: '<input data-testid="checkbox" type="checkbox" />',
      });
    
      const el = screen.getByTestId("checkbox");
    
      await userEvent.click(el);
    
      expect(el).not.toBeDisabled();
      expect(el).toBeChecked();
    });
    
    it("should not uncheck if is disabled", async () => {
      render({
        template:
          '<input data-testid="checkbox" type="checkbox" checked disabled />',
      });
    
      const el = screen.getByTestId("checkbox");
    
      // await userEvent.click(el);
    
      console.log(el.checked);
    
      expect(el).toBeDisabled();
      expect(el).toBeChecked(); // ! FAIL
    });
    
    it("should not check if is disabled", async () => {
      render({
        template: '<input data-testid="checkbox" type="checkbox" disabled />',
      });
    
      const el = screen.getByTestId("checkbox");
    
      await userEvent.click(el);
    
      expect(el).toBeDisabled();
      expect(el).not.toBeChecked(); // ! FAIL
    });