ReactJS - scryRenderedDOMComponentsWithClass()



As we all know React is a very popular library for creating responsive and interactive web applications. There is a function called scryRenderedDOMComponentsWithClass() available in the React library. This function locates all DOM elements of components in a rendered tree. It looks for DOM components with a class name that matches the one we specify.

Assume we have a tree, similar to a family tree, but for our website. Each branch symbolizes a separate part of our website. Now, scryRenderedDOMComponentsWithClass() traverses each branch and selects the elements that have a specific class.

Syntax

scryRenderedDOMComponentsWithClass(
   tree,
   className
)

Parameters

You put two things inside the parentheses: tree and className.

  • tree − The word tree refers to our family tree.

  • className − className is similar to instructing the function to "find things with this specific name or class."

Return Value

This function returns a list of all the DOM elements of the displayed tree's components that match the given class name.

The scryRenderedDOMComponentsWithClass() function is commonly used to test React components. It is a component of the React TestUtils package, which is used to test React components in a number of methods. So we will see different ways to use scryRenderedDOMComponentsWithClass() in different testing scenarios.

Examples

Example − Testing a Counter Component

Let us say we have a counter component and we have to test it.

CounterComponent.js

import React, { useState } from 'react';

const CounterComponent = () => {
   const [count, setCount] = useState(0);   
   const increment = () => {
      setCount(count + 1);
   };   
   return (
      <div>
         <p className="counter-display">Count: {count}</p>
         <button className="increment-btn" onClick={increment}>
            Increment
         </button>
      </div>
   );
};

export default CounterComponent;

CounterComponent.test.js

import React from 'react';
import { render, scryRenderedDOMComponentsWithClass } from '@testing-library/react';
import CounterComponent from './CounterComponent';

test('Counter increments correctly', () => {
   const { container } = render(<CounterComponent />);
   const incrementButton = scryRenderedDOMComponentsWithClass(container, 'increment-btn')[0];   
   expect(incrementButton).toBeDefined();   
   incrementButton.click();
   
   // Check if the count has been updated
   const counterDisplay = scryRenderedDOMComponentsWithClass(container, 'counter-display')[0];
   expect(counterDisplay.textContent).toBe('Count: 1');
});

Output

count9 increment

Explanation − This is similar to a magic button that keeps track of how many times we click it. When we open the website, we will notice a button that says "Click me!" and a count. The number increases by one with each press of the button. It is just like keeping track of how many times we clicked the button.

Example − Testing a Toggle Visibility

Suppose we have a React app in which we have a toggle visibility functionality. So when we click the button it will be visible and again if we press the button the content will disappear.

ToggleComponent.js

import React, { useState } from 'react';
import './App.css';

const ToggleComponent = () => {
   const [isVisible, setIsVisible] = useState(true);   
   const toggleVisibility = () => {
      setIsVisible(!isVisible);
   };
   
   return (
      <div className='App'>
         <button className="toggle-btn" onClick={toggleVisibility}>
            Toggle Visibility
         </button>
         {isVisible && <p className="visible-content">This content is visible!</p>}
      </div>
   );
};

export default ToggleComponent;

ToggleComponent.test.js

import React from 'react';
import { render, scryRenderedDOMComponentsWithClass } from '@testing-library/react';
import ToggleComponent from './ToggleComponent';

test('Toggle visibility correctly', () => {
   const { container } = render(<ToggleComponent />);
   const toggleButton = scryRenderedDOMComponentsWithClass(container, 'toggle-btn')[0];   
   expect(toggleButton).toBeDefined();
   
   // Simulate a click on the button
   toggleButton.click();
   
   // Check if the content is now hidden
   const visibleContent = scryRenderedDOMComponentsWithClass(container, 'visible-content');
   expect(visibleContent.length).toBe(0);
});

Output

toggle visibility content visible

Explanation − Let's test our button that hides and shows items. We tell the code to click the button to see if anything appears, then to press it again to see if it disappears. If our code answers, "Yes, the hiding and showing is working!" we know our button is working.

Example − Testing a List Filter Component

Let us say we have a component which filters a list. So now we will write a test to check that the list is filtered correctly. See the code below to test the ListFilterComponent −

ListFilterComponent.js

import React, { useState } from 'react';
import './App.css';

const ListFilterComponent = () => {
   const [filterText, setFilterText] = useState('');
   const items = ['Apple', 'Banana', 'Orange'];   
   const handleFilterChange = (event) => {
      setFilterText(event.target.value);
   };
   
   return (
      <div className='App'>
         <input
            type="text"
            className="filter-input"
            placeholder="Filter list"
            value={filterText}
            onChange={handleFilterChange}
         />
         <ul className="filtered-list">
            {items
            .filter((item) => item.toLowerCase().includes(filterText.toLowerCase()))
            .map((item, index) => (
               <li key={index} className="list-item">
                  {item}
               </li>
            ))}
         </ul>
      </div>
   );
};

export default ListFilterComponent;

ListFilterComponent.test.js

 
import React from 'react';
import { render, scryRenderedDOMComponentsWithClass } from '@testing-library/react';
import ListFilterComponent from './ListFilterComponent';

test('Filter list correctly', () => {
   const { container } = render(<ListFilterComponent />);
   const filterInput = scryRenderedDOMComponentsWithClass(container, 'filter-input')[0];   
   expect(filterInput).toBeDefined();
   
   // Simulate typing in the filter input
   filterInput.value = 'Banana';
   filterInput.dispatchEvent(new Event('input', { bubbles: true }));
   
   // Check if the list is correctly filtered
   const filteredListItems = scryRenderedDOMComponentsWithClass(container, 'list-item');
   expect(filteredListItems.length).toBe(1);
   expect(filteredListItems[0].textContent).toBe('Banana');
});

Output

list banana

Explanation − the application functions similarly to a smart list, displaying only what we choose. There is a box where we can type our query. Following that is a list of items like "Apple," "Banana," and "Orange." As we type in the box, the list displays only the things that match to what we typed. It makes it simpler to find items in the list.

For this app, we want to see if our list properly filters items. We tell our testing code to type some words into the box and see if the list only displays items that match. The testing code types "Banana" and checks to see if there are just bananas on the list. If everything goes as planned, our code gives us positive feedback.

Summary

scryRenderedDOMComponentsWithClass() is a React testing function. It allows testers to locate and verify items in a rendered React component by their class names. This function is like having a testing helper who knows classes and helps us in checking that our React components are acting correctly.

reactjs_reference_api.htm
Advertisements