← Back to React Testing Library Mastery
Basic18 min read

Queries & Selectors

Choose getBy, queryBy, and findBy queries following Testing Library priority.

Query Priority

Prefer queries in order: getByRole (with accessible name), getByLabelText, getByPlaceholderText, getByText, getByDisplayValue, getByAltText, getByTitle, last resort getByTestId.

Accessible queries keep tests aligned with screen readers and keyboard users—improving both test quality and app a11y.

screen.getByRole("button", { name: /submit/i });
screen.getByLabelText("Email address");
screen.getByTestId("custom-widget"); // when no accessible handle

getBy Queries

getBy* throws if element not found or multiple matches—fail fast in happy path tests. Use regex or exact string for name and text options.

Within getByRole, name matches accessible name computation from aria-label, labelledby, or element text.

  • Multiple elements error—use getAllBy* or narrow with within()
  • Hidden elements excluded by default; { hidden: true } overrides
  • Selector option on getByRole filters role subset
screen.getByRole("heading", { level: 1, name: "Dashboard" });
screen.getByText((content, element) => content.startsWith("Welcome"));

queryBy Queries

queryBy* returns null if absent—use for asserting element does not exist. Combine with expect(...).not.toBeInTheDocument().

Do not use queryBy when element should exist—getBy gives better error message on failure.

expect(screen.queryByText("Error")).not.toBeInTheDocument();

findBy Queries

findBy* returns Promise resolving when element appears—default 1000ms timeout. Use for async data fetch rendering content after mount.

await screen.findByRole("alert") waits for success message. All findAllBy variants exist for lists.

render(<UserProfile userId="1" />);
expect(await screen.findByText("Ada Lovelace")).toBeInTheDocument();

within and Custom Queries

within(container) scopes queries to subtree—tables, modals, list items. buildQueries creates reusable custom query bundles for repeated patterns.

Avoid container.querySelector—it bypasses Testing Library visibility and accessibility checks.

const row = screen.getByRole("row", { name: /Ada/ });
within(row).getByRole("button", { name: "Edit" });

Get In Touch


Ready to discuss your next project? Drop me a message.