In my React Testing Library unit test, I am unable to get the Navlink by role.
getByRole('link', { name: 'help' }) - This fails
The Navlink does not have text, rather it has a help icon which seems to be the problem.
The error I recieve is:
TestingLibraryElementError: Unable to find an accessible element with the role "link" and name "help"
Here are the accessible roles:
link:
Name "Home":
<a
class="active"
href="home"
name="home"
/>
Name "About":
<a
class="inactive"
href="/about"
name="about"
/>
Name "": <--- No name for link with icon
<a
class="inactive"
href="/help"
name="help"
/>
My NavBar:
const NavBar = () => {
return (
<>
<div className="navbar">
<ul>
<li>
<NavLink to="home" className={({isActive}) => (isActive ? 'active' : 'inactive')}>Home</NavLink>
</li>
<li>
<NavLink to="about" className={({isActive}) => (isActive ? 'active' : 'inactive')}>About</NavLink>
</li>
<li>
<NavLink to="help" name="help" className={({isActive}) => (isActive ? 'active' : 'inactive')}><FaQuestionCircle size='1.5rem' className="helpicon"/></NavLink>
</li>
</ul>
</div>
</>
);
};
export default NavBar;
The failing unit test:
describe(Navbar, () => {
const mockedNavigation = jest.fn();
it('should navigate to help page', () => {
const { getByRole } = render(<Navbar />, { wrapper: Router });
fireEvent.click(getByRole('link', { name: 'help' }));
expect(mockedNavigation).toHaveBeenCalledWith(
"help",
{
preventScrollReset: undefined,
relative: undefined,
replace: false,
state: undefined,
unstable_viewTransition: undefined
});
});
});
How do I select a Navlink that does not have text, but uses an icon instead?
Maybe I can use classNames? Add an additional class as well as the active/inactive? Another method would be easier though and more readable.
The <NavLink/>
component can't accept the name
property. If you use TypeScript, you will get a TS-type error:
Type '{ children: Element; to: string; name: string; className: ({ isActive }: NavLinkRenderProps) => "active" | "inactive"; }' is not assignable to type 'IntrinsicAttributes & NavLinkProps & RefAttributes<HTMLAnchorElement>'.
Property 'name' does not exist on type 'IntrinsicAttributes & NavLinkProps & RefAttributes<HTMLAnchorElement>'.ts(2322)
Instead, you can pass a title
prop to the icon component as the accessible name of the <NavLink/>
. E.g.
import React from 'react';
import { NavLink } from 'react-router-dom';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faQuestionCircle } from '@fortawesome/free-solid-svg-icons';
const NavBar = () => {
return (
<>
<div className="navbar">
<ul>
<li>
<NavLink to="/home" className={({ isActive }) => (isActive ? 'active' : 'inactive')}>
Home
</NavLink>
</li>
<li>
<NavLink to="/about" className={({ isActive }) => (isActive ? 'active' : 'inactive')}>
About
</NavLink>
</li>
<li>
<NavLink to="/help" className={({ isActive }) => (isActive ? 'active' : 'inactive')}>
<FontAwesomeIcon icon={faQuestionCircle} className="helpicon" title="help" />
</NavLink>
</li>
</ul>
</div>
</>
);
};
export default NavBar;
NavBar.test.tsx
:
import React from 'react';
import { fireEvent, render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import NavBar from './NavBar';
import { MemoryRouter } from 'react-router-dom';
describe('Navbar', () => {
it('should navigate to help page', () => {
render(
<MemoryRouter initialEntries={['/help']}>
<NavBar />
</MemoryRouter>,
);
const navLink = screen.getByRole('link', { name: 'help' });
console.log('🚀 ~ it ~ navLink:', navLink);
fireEvent.click(navLink);
expect(navLink).toHaveClass('active');
});
});
Test result:
PASS stackoverflow/77897051/NavBar.test.tsx
Navbar
√ should navigate to help page (109 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.627 s
Ran all test suites related to changed files.
package version:
"@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-solid-svg-icons": "^6.5.1",
"@fortawesome/react-fontawesome": "^0.2.0",
"react": "^18.2.0",
"react-router-dom": "^6.21.1",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"@testing-library/jest-dom": "^6.1.4",
"@testing-library/react": "^14.1.2",