Instead of resorting to the native DOM, in certain situations you can select the element by role (or, less ideally, by test id), then assert that the attribute in question exists, in lieu of an all-in-one getBy
call:
expect(screen.getByRole("textbox")).toHaveAttribute("name", "userName");
Unfortunately,
screen.getByRole("textbox", {name: "userName"});
doesn't work as it seems like it should. See What is the name option in react-testing-library? for an explanation.
Proof:
import React from "react"; // 18.2.0
import {render, screen} from "@testing-library/react"; // 13.4.0
import "@testing-library/jest-dom/extend-expect"; // ^5.16.5
describe("getByRole experiments", () => {
beforeEach(() => render(<input type="text" name="userName" />));
it("should work with a plain getByRole", () => {
expect(screen.getByRole("textbox"))
.toHaveAttribute("name", "userName"); // OK
});
it("will fail specifying {name: /userName/i}", () => {
screen.getByRole("textbox", {name: /userName/i}); // Fails
});
it('will also fail specifying {name: "userName"}', () => {
screen.getByRole("textbox", {name: "userName"}); // Fails
});
});
Partial output (the name: "userName"
assertion failure is basically the same):
TestingLibraryElementError: Unable to find an accessible element with the role "textbox" and name `/userName/i`
Here are the accessible roles:
textbox:
Name "":
<input
name="userName"
/>
--------------------------------------------------
Ignored nodes: comments, <script />, <style />
<body>
<div>
<input
name="userName"
/>
</div>
</body>
See also React testing library: how to getByRole on custom role.
name
here. It's the aria accessible name, not thename="userName"
attribute. See What is the name option in react-testing-library?. – Canvasback