App.js
import React, { Component } from "react"; import Select from "react-select"; const SELECT_OPTIONS = ["FOO", "BAR"].map(e => { return { value: e, label: e }; }); class App extends Component { state = { selected: SELECT_OPTIONS[0].value }; handleSelectChange = e => { this.setState({ selected: e.value }); }; render() { const { selected } = this.state; const value = { value: selected, label: selected }; return ( <div className="App"> <div data-testid="select"> <Select multi={false} value={value} options={SELECT_OPTIONS} onChange={this.handleSelectChange} /> </div> <p data-testid="select-output">{selected}</p> </div> ); } } export default App;
App.test.js
import React from "react"; import { render, fireEvent, cleanup, waitForElement, getByText } from "react-testing-library"; import App from "./App"; afterEach(cleanup); const setup = () => { const utils = render(<App />); const selectOutput = utils.getByTestId("select-output"); const selectInput = document.getElementById("react-select-2-input"); return { selectOutput, selectInput }; }; test("it can change selected item", async () => { const { selectOutput, selectInput } = setup(); getByText(selectOutput, "FOO"); fireEvent.change(selectInput, { target: { value: "BAR" } }); await waitForElement(() => getByText(selectOutput, "BAR")); });
This minimal example works as expected in the browser but the test fails. I think the onChange handler in is not invoked. How can I trigger the onChange callback in the test? What is the preferred way to find the element to fireEvent at? Thank you
To select a default option in React, the selected attribute is used in the option element. In React, though, instead of using the selected attribute, the value prop is used on the root select element. So, you can set a default value by passing the value of the option in the value prop of the select input element.
const component = mount(<MyComponent/>); component. find("#dropdown"). simulate("change", { target: { value: "item1", selectedIndex: 1 } });
In my project, I'm using react-testing-library and jest-dom. I ran into same problem - after some investigation I found solution, based on thread: https://github.com/airbnb/enzyme/issues/400
Notice that the top-level function for render has to be async, as well as individual steps.
There is no need to use focus event in this case, and it will allow to select multiple values.
Also, there has to be async callback inside getSelectItem.
const DOWN_ARROW = { keyCode: 40 }; it('renders and values can be filled then submitted', async () => { const { asFragment, getByLabelText, getByText, } = render(<MyComponent />); ( ... ) // the function const getSelectItem = (getByLabelText, getByText) => async (selectLabel, itemText) => { fireEvent.keyDown(getByLabelText(selectLabel), DOWN_ARROW); await waitForElement(() => getByText(itemText)); fireEvent.click(getByText(itemText)); } // usage const selectItem = getSelectItem(getByLabelText, getByText); await selectItem('Label', 'Option'); ( ... ) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With