Reputation: 161
I am testing my App component and in the first test, it starts from home and I have to click on a drink-preview in order to get to a recipe. However, in the very next test, which is supposed to follow the same steps to get to recipe, I get the error
Unable to find an element by: [data-testid="drink-preview"]
I came to realize that this is because it seems to start already from the recipe so it does not render the home page for it to click on the drink-preview. Just to be sure I copy-pasted the exact-same test that went from home -> click"drink-preview" -> recipe and surely the second time around, it has the same issue. The error log shows that it is rendering recipe straightway instead of home thus not able to find drink-preview to click on it.
test('should contain default texts in recipe -HOW TO MIX etc.', () => {
const { container, getAllByTestId, getByTestId } = renderWithRouterRedux(<App />)
fireEvent.click(getAllByTestId('drink-preview')[0])
expect(container).toHaveTextContent('HOW TO MIX')
expect(container).toHaveTextContent('Glass')
expect(container).toHaveTextContent('Method')
expect(container).toHaveTextContent('Garnish')
})
export const renderWithRouterRedux= (component, { initialState, store = createStore(reducer, initialState) } = {}) => {
const history = createMemoryHistory()
return {
...render(<Provider store={store}>
<Router history={history}>
{component}
</Router>
</Provider>),
store,
}
}
Why is this behavior occurring?
Upvotes: 1
Views: 215
Reputation: 161
The problem, it appears was that in my testng, I was renderi my {component} App in a BrowserRouter at two levels; the test level and as the App component's first child.
Original
//App component
<div className="App" data-testid="app">
<BrowserRouter>
<Switch>
<Route path="/">
<SomeComponent/>
</Route>
</Switch>
</BrowserRouter>
</div>
//index.js
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
On top of the App component alreeady having a BrowserRouter, I was rendeing in the test file in a Router again whhic his unnecessary.
The solution was to move the to the index.js so that it wraps the when rendering in browser. Which then also allows me to use a in the tests to wrap the app component safely
Solution
//App component
<div className="App" data-testid="app">
<Switch>
<Route path="/">
<SomeComponent/>
</Route>
</Switch>
</div>
//index.js
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>,
document.getElementById('root')
)
This Rithm School video about testing React-Router gave me the eureka
Upvotes: 1