Hone logo
Hone
Problems

Testing User Interactions with Jest and React

User event testing is crucial for ensuring your React components behave as expected when users interact with them. This challenge focuses on implementing user event testing using Jest and React Testing Library to simulate user actions like clicks, typing, and form submissions, verifying that the component responds correctly. Successfully completing this challenge will demonstrate your ability to write robust and reliable tests for interactive UI elements.

Problem Description

You are tasked with creating a Jest test suite for a simple React component called Counter. The Counter component displays a count and has two buttons: "Increment" and "Decrement". Clicking "Increment" increases the count by 1, and clicking "Decrement" decreases it by 1. The component also has an input field where the user can type a number, and a "Reset" button that sets the count to the value entered in the input field.

Your test suite should:

  1. Verify initial state: Ensure the counter starts at 0.
  2. Test increment button: Simulate a click on the "Increment" button and verify that the count increases by 1.
  3. Test decrement button: Simulate a click on the "Decrement" button and verify that the count decreases by 1.
  4. Test reset button:
    • Type a number (e.g., "10") into the input field.
    • Simulate a click on the "Reset" button.
    • Verify that the count is updated to the value entered in the input field (e.g., 10).
  5. Handle invalid input: If the input field is empty when the "Reset" button is clicked, the count should remain unchanged.

Key Requirements:

  • Use React Testing Library for rendering the component and interacting with it.
  • Use Jest for assertions.
  • Utilize userEvent to simulate user interactions (clicks, typing).
  • Ensure your tests are readable and maintainable.

Examples

Example 1:

Input: Initial Counter component state
Output: The counter displays '0'.
Explanation: The component should initialize with a count of 0.

Example 2:

Input: Click "Increment" button
Output: The counter displays '1'.
Explanation: Clicking the increment button should increase the count by 1.

Example 3:

Input: Type "5" into the input field, then click "Reset"
Output: The counter displays '5'.
Explanation: Typing a value into the input and clicking reset should update the counter to that value.

Example 4:

Input: Click "Reset" button with an empty input field
Output: The counter displays '0'.
Explanation: Clicking reset with an empty input should not change the counter.

Constraints

  • The Counter component is provided below. Do not modify the component itself.
  • You must use userEvent for simulating user interactions.
  • Tests should be written in TypeScript.
  • The tests should be concise and focused on verifying the component's behavior.

Notes

  • Consider using screen.getByRole or screen.getByTestId to locate elements within the component.
  • userEvent provides a more realistic simulation of user interactions compared to directly manipulating the DOM.
  • Think about how to handle asynchronous updates to the component's state. You might need to use waitFor or act from React Testing Library.
  • Focus on testing the behavior of the component, not the implementation details.
// Counter.tsx (Provided Component - DO NOT MODIFY)
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  const [inputValue, setInputValue] = useState('');

  const increment = () => {
    setCount(count + 1);
  };

  const decrement = () => {
    setCount(count - 1);
  };

  const reset = () => {
    if (inputValue !== '') {
      setCount(parseInt(inputValue, 10) || 0);
    }
  };

  const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setInputValue(event.target.value);
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
      <input type="text" value={inputValue} onChange={handleInputChange} />
      <button onClick={reset}>Reset</button>
    </div>
  );
}

export default Counter;
Loading editor...
typescript