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
data-testid="en-boards"
>
<a
aria-expanded="false"
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)
Environment
- macOS 12.5
- TypeScript 4.8.4
- React 18.2.0
- React-Bootstrap 2.5.0
- testing-library/react 13.4.0
I tryed to this issue's solution but it didn't work. Thank you to read. Can anyone solve it?
CodePudding user response:
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();
});