Hone logo
Hone
Problems

Jest Screen Queries: Navigating the DOM Tree

This challenge focuses on leveraging Jest and the screen object from the @testing-library/react (or equivalent for other frameworks) to query elements on a virtual DOM. Mastering screen queries is crucial for writing robust and user-centric tests that accurately reflect how users interact with your application.

Problem Description

Your task is to write Jest tests for a simple React component (or a similar framework component) that displays a list of items. You will use Jest's screen object to find and assert on various elements within this component's rendered output. The goal is to demonstrate proficiency in using different screen query methods to locate elements by their text, role, label, and other accessible attributes.

What needs to be achieved:

  • Write Jest tests for a given React component.
  • Use screen queries to find specific elements.
  • Make assertions about the presence, content, and attributes of these elements.

Key requirements:

  • Utilize a variety of screen query methods (e.g., getByText, getByRole, getByLabelText, queryByText, getAllByRole).
  • Ensure tests are readable and clearly indicate what is being tested.
  • Handle cases where an element might or might not be present.

Expected behavior:

  • Tests should pass if the correct elements are found and assertions are met.
  • Tests should fail if elements are not found as expected or if assertions are incorrect.

Important edge cases to consider:

  • What happens when an element is not found? (Use queryBy methods).
  • How to find multiple elements? (Use getAllBy methods).
  • How to deal with case sensitivity and whitespace in text queries?

Examples

Example 1: Finding an element by text

Let's assume a component renders the following HTML:

<div>
  <h1>Welcome!</h1>
  <p>This is a sample paragraph.</p>
</div>

Input: A React component that renders the above HTML.

Test Snippet (Conceptual):

import { render, screen } from '@testing-library/react';

// Assume MyComponent renders the HTML above

test('should find the heading by text', () => {
  render(<MyComponent />);
  const headingElement = screen.getByText('Welcome!');
  expect(headingElement).toBeInTheDocument();
});

Output: The test should pass, confirming the presence of the <h1> element with the text "Welcome!".

Explanation: screen.getByText('Welcome!') searches for an element containing the exact text "Welcome!". If found, it returns the element; otherwise, it throws an error. toBeInTheDocument() is a Jest-DOM matcher that asserts the element exists in the DOM.

Example 2: Finding an element by role

Consider a component rendering a button:

<button type="button">Click Me</button>

Input: A React component that renders the above HTML.

Test Snippet (Conceptual):

import { render, screen } from '@testing-library/react';

// Assume ButtonComponent renders the button above

test('should find the button by role', () => {
  render(<ButtonComponent />);
  const buttonElement = screen.getByRole('button', { name: 'Click Me' });
  expect(buttonElement).toBeInTheDocument();
});

Output: The test should pass, confirming the presence of the button with the accessible name "Click Me".

Explanation: screen.getByRole('button', { name: 'Click Me' }) queries for an element with the ARIA role of "button" and an accessible name that matches "Click Me". This is a more robust way to find interactive elements.

Example 3: Handling a missing element

Suppose a component conditionally renders an element:

<div>
  {showDetails && <p>More details here</p>}
</div>

Input: A React component where showDetails is initially false.

Test Snippet (Conceptual):

import { render, screen } from '@testing-library/react';

// Assume ConditionalComponent renders the above HTML

test('should not find details when not shown', () => {
  render(<ConditionalComponent showDetails={false} />);
  const detailsElement = screen.queryByText('More details here');
  expect(detailsElement).not.toBeInTheDocument();
});

Output: The test should pass, confirming that the paragraph is not present in the DOM.

Explanation: screen.queryByText('More details here') is used here. Unlike getByText, queryByText returns null if the element is not found, instead of throwing an error. This allows us to assert that an element does not exist.

Constraints

  • The target framework for the component is React.
  • You will be provided with simple React components to test.
  • Each test file should be written in TypeScript.
  • Aim for clear and concise tests.
  • Avoid using data-testid unless absolutely necessary (prefer accessible queries).

Notes

  • Familiarize yourself with the various screen query types available in @testing-library/react.
  • Consider the order of specificity when choosing queries. For example, getByRole with a name is often preferred over getByText for interactive elements.
  • Think about how a user would perceive and interact with your component when deciding what to test.
  • The core idea is to test the behavior of your component from a user's perspective, not its internal implementation details.
Loading editor...
typescript