I'm trying to test a React-Bootstrap NavDropdown element with a test-id attribute, but React Testing Library can't find a data-testid attribute.
MyNav.tsx
import Nav from 'react-bootstrap/Nav';
import Navbar from 'react-bootstrap/Navbar';
import NavDropdown from 'react-bootstrap/NavDropdown';
import LOGO from './logo.svg';
const MyNav = (): JSX.Element => (
<Navbar collapseOnSelect expand="lg" bg="dark" variant="dark">
<Navbar.Brand href="/">
<img src={LOGO} width="30" height="30" alt="React Bootstrap logo" />
BBS
</Navbar.Brand>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav">
<Nav className="mr-auto">
<NavDropdown
title="English"
id="navbarScrollingDropdown"
data-testid="en-boards"
>
<NavDropdown.Item href="#en-news" data-testid="en-news">
News
</NavDropdown.Item>
<NavDropdown.Item href="#en-sensitive-may">
Politics
</NavDropdown.Item>
</NavDropdown>
<NavDropdown title="日本語" id="navbarScrollingDropdown">
<NavDropdown.Item href="#ja-news">ニュース</NavDropdown.Item>
<NavDropdown.Item href="#ja-sensitive-may">政治</NavDropdown.Item>
</NavDropdown>
</Nav>
</Navbar.Collapse>
</Navbar>
);
export default MyNav;
MyNav.test.tsx
import React from 'react';
import { render, screen, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import MyNav from './MyNav';
test('renders nav', async () => {
const user = userEvent.setup();
render(<MyNav />);
const navBarBrandEl = screen.getByText('BBS');
const navDropDownElEn = screen.getByText('English');
const navDropDownElJa = screen.getByText('日本語');
expect(navBarBrandEl).toBeInTheDocument();
expect(navDropDownElEn).toBeInTheDocument();
expect(navDropDownElJa).toBeInTheDocument();
const enBoards = screen.getByTestId('en-boards');
await user.click(enBoards);
const enNews = within(enBoards).getByTestId('en-news');
expect(enNews).toBeInTheDocument();
});
and the test result is
TestingLibraryElementError: Unable to find an element by: [data-testid="en-news"]
Ignored nodes: comments, script, style
<div
class="nav-item dropdown"
data-testid="en-boards"
>
<a
aria-expanded="false"
class="dropdown-toggle nav-link"
href="#"
id="navbarScrollingDropdown"
role="button"
tabindex="0"
>
English
</a>
</div>
18 | const enBoards = screen.getByTestId('en-boards');
19 | await user.click(enBoards);
> 20 | const enNews = within(enBoards).getByTestId('en-news');
| ^
21 |
22 | expect(enNews).toBeInTheDocument();
23 | });
at Object.getElementError (node_modules/@testing-library/dom/dist/config.js:40:19)
at node_modules/@testing-library/dom/dist/query-helpers.js:90:38
at node_modules/@testing-library/dom/dist/query-helpers.js:62:17
at getByTestId (node_modules/@testing-library/dom/dist/query-helpers.js:111:19)
at Object.<anonymous> (src/MyNav.test.tsx:20:35)
I tryed to this issue's solution but it didn't work. Thank you to read. Can anyone solve it?
You should click the button inside enBoards instead of enBoards itself.
Here is the corrected snippet.
import React from 'react';
import { render, screen, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import MyNav from './MyNav';
test('renders nav', async () => {
render(<MyNav />);
const navBarBrandEl = screen.getByText('BBS');
const navDropDownElEn = screen.getByText('English');
const navDropDownElJa = screen.getByText('日本語');
expect(navBarBrandEl).toBeInTheDocument();
expect(navDropDownElEn).toBeInTheDocument();
expect(navDropDownElJa).toBeInTheDocument();
const enBoards = screen.getByTestId('en-boards');
const enBoardsButton = within(enBoards).getByRole('button');
await userEvent.click(enBoardsButton);
const enNews = within(enBoards).getByTestId('en-news');
expect(enNews).toBeInTheDocument();
});