autoFocus prop and react-testing-library
See original GitHub issueSummary
When testing react-select
inputs with @testing-library/react, it’s not possible to programatically open the select. This is with the latest version of react-select.
Reproduction
I created a reproduction repo. I pasted the relevant code below to make it easier to follow
//App.js
import React, { Component } from "react";
import Select from "react-select";
import "./App.css";
const fruits = [
{ label: "Papaya", value: "papaya" },
{ label: "Apple", value: "apple" }
];
class App extends Component {
render() {
return (
<div className="App">
<label htmlFor="selectInput">Select a fruit</label>
<Select
autoFocus={this.props.autoFocus}
id="selectInput"
options={fruits}
/>
</div>
);
}
}
App.defaultProps = {
autoFocus: false
};
export default App;
// App.test.js
import React from "react";
import { render, fireEvent } from "@testing-library/react";
import App from "./App";
describe("select input", () => {
describe("without autofocus", () => {
it("should be able to open", () => {
const { getByLabelText, getByText, debug } = render(<App />);
const input = getByLabelText("Select a fruit");
input.focus();
fireEvent.keyDown(input, { key: "ArrowDown" });
expect(getByText("Papaya")).toBeInTheDocument();
});
});
describe("with autofocus", () => {
it("should be able to open", () => {
const { getByLabelText, getByText, debug } = render(
<App autoFocus={true} />
);
const input = getByLabelText("Select a fruit");
input.focus();
fireEvent.keyDown(input, { key: "ArrowDown" });
expect(getByText("Papaya")).toBeInTheDocument();
});
});
});
When I run the test, this is the result
FAIL src/App.test.js
select input
without autofocus
✓ should be able to open (135ms)
with autofocus
✕ should be able to open (59ms)
● select input › with autofocus › should be able to open
Unable to find an element with the text: Papaya. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
<body>
<div>
<div
class="App"
>
<label
for="selectInput"
>
Select a fruit
</label>
<div
class=" css-2b097c-container"
id="selectInput"
>
<span
aria-live="polite"
class="css-1laao21-a11yText"
>
<p
id="aria-selection-event"
>
</p>
<p
id="aria-context"
>
0 results available. Select is focused ,type to refine list, press Down to open the menu,
</p>
</span>
<div
class=" css-1pahdxg-control"
>
<div
class=" css-1hwfws3"
>
<div
class=" css-1wa3eu0-placeholder"
>
Select...
</div>
<div
class="css-1g6gooi"
>
<div
class=""
style="display: inline-block;"
>
<input
aria-autocomplete="list"
autocapitalize="none"
autocomplete="off"
autocorrect="off"
id="react-select-3-input"
spellcheck="false"
style="box-sizing: content-box; width: 2px; border: 0px; font-size: inherit; opacity: 1; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
/>
<div
style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-size: inherit; font-family: -webkit-small-control; letter-spacing: normal; text-transform: none;"
/>
</div>
</div>
</div>
<div
class=" css-1wy0on6"
>
<span
class=" css-1okebmr-indicatorSeparator"
/>
<div
aria-hidden="true"
class=" css-1gtu0rj-indicatorContainer"
>
<svg
aria-hidden="true"
class="css-19bqh2r"
focusable="false"
height="20"
viewBox="0 0 20 20"
width="20"
>
<path
d="M4.516 7.548c0.436-0.446 1.043-0.481 1.576 0l3.908 3.747 3.908-3.747c0.533-0.481 1.141-0.446 1.574 0 0.436 0.445 0.408 1.197 0 1.615-0.406 0.418-4.695 4.502-4.695 4.502-0.217 0.223-0.502 0.335-0.787 0.335s-0.57-0.112-0.789-0.335c0 0-4.287-4.084-4.695-4.502s-0.436-1.17 0-1.615z"
/>
</svg>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
23 | input.focus();
24 | fireEvent.keyDown(input, { key: "ArrowDown" });
> 25 | expect(getByText("Papaya")).toBeInTheDocument();
| ^
26 | });
27 | });
28 | });
at getElementError (node_modules/@testing-library/dom/dist/query-helpers.js:46:10)
at args (node_modules/@testing-library/dom/dist/query-helpers.js:100:13)
at args (node_modules/@testing-library/dom/dist/query-helpers.js:83:17)
at Object.getByText (src/App.test.js:25:14)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 passed, 2 total
Snapshots: 0 total
Time: 1.91s
Ran all test suites.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:5
- Comments:8
Top Results From Across the Web
How to test which input has the focus when tab button is pressed
I'm building a React autocomplete component and testing it using Jest and React-testing-library. I have two inputs.
Read more >Testing User Interfaces For Beginners - Joy of Code
This is why Testing Library is framework agnostic with minor differences how you render and pass props to a component because whatever you...
Read more >Input Event - Testing Library
import React, {useState} from 'react' import {render, fireEvent} from '@testing-library/react' function CostInput() {
Read more >A Deep Dive on Managing Focus with React, Jest, and Enzyme
In our tests, this property comes from JSDOM, another library that's a dependency of Jest. Using Jest v25+. The update from Jest v24...
Read more >Error when using autofocus on an input element (Reactjs)
[Solved]-Error when using autofocus on an input element (Reactjs)-Reactjs ... find an element with the text: "myText" error when using react-testing-library ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@iamchanii thanks for your help!
I figured out the source of the problem.
When I did
the
input
that I was grabbing was not actually aninput
. It’s a div.So calling blur on that div doesn’t do what we need.
So instead, I do
and it works, because now the blur is being called on the actual input.
Thanks for your help! 🎉
I was even able to remove the async
Finally, I resolve this issue. there is two points: 1. You should simulate keydown event for display dropdown. 2. Dropdown renders menu asynchronously.
And don’t forget use
classNamePrefix
props for write test easy.Ref: https://stackoverflow.com/a/56183912