Skip to content

userEvent.selectOptions does not trigger onChange event #358

@khalidwilliams

Description

@khalidwilliams

Relevant code or config

// Select.js
import React from "react";

const Select = props => {
  const handleChange = e => {
    console.log(e.target.value);
    props.test(e.target.value);

  };
  return (
    <select data-testid="select" onChange={handleChange}>
      <option data-testid="first" value="first">
        first
      </option>
      <option data-testid="second" value="second">
        second
      </option>
      <option data-testid="third" value="third">
        third
      </option>
    </select>
  );
};
export default Select;

// Select.test.js
  import React from 'react';
  import Select from './Select';
  import userEvent from '@testing-library/userEvent';
  import render from '@testing-library/react';


  test("`userEvent.selectOptions` should trigger an onChange event", () => {
    const mockTest = jest.fn().mockImplementation(val => console.log(val));
    const { getByTestId, debug } = render(<Select test={mockTest} />);
    const select = getByTestId("select");
    const second = getByTestId("second");

    userEvent.selectOptions(select, ["second"]);
    debug();
    console.log(select.value)
    expect(mockTest).toHaveBeenCalledTimes(1);
    expect(mockTest).toHaveBeenCalledWith('second');
    expect(second.selected).toBe(true);
  });

What you did:
I first noticed this behavior in a larger project, so I made a small repo to reproduce.

I made a <select/> element in React that fires a function received from props onChange. This behavior works as expected in the browser. When testing the behavior, I can successfully assert that a mocked version of that onChange function is called when I trigger a change event (via importing fireEvent from RTL), but cannot assert that the same mock is called when using userEvent.selectOptions.

What happened:
Screen Shot 2020-06-16 at 9 28 24 AM

Reproduction repository:
https://github.com/khalidwilliams/select-test-demo

Problem description:
userEvent.selectOptions doesn't trigger a change event. onChange handlers won't fire in tests that use this method, leading to problems with testing any change-dependent behavior.

Suggested solution:
I'm not sure what the best solution is, it seems like this line may not be firing as expected? Please let me know if there's something I'm missing here -- I'm happy to keep digging!

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingreleased

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions