Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
2.
Custom Queries
3.
buildQueries
3.1.
Other Assertion Libraries
4.
getNodeText
5.
Within Method
6.
FAQs
7.
Key Takeaways
Last Updated: Mar 27, 2024
Easy

Custom Queries and within Method

Author Toohina Barua
0 upvote

Introduction

The core library, DOM Testing Library, is a lightweight solution for querying and interacting with DOM nodes to test web pages. Several frameworks, including React, Angular, and Vue, have been wrapped around the core library to provide ergonomic APIs. There's also a Cypress plugin that uses testing-library queries for end-to-end tests, as well as a React Native implementation. We can also create custom queries using this library! 
From this article, we are going to learn how to use custom queries and within method. So let us dive in!

Custom Queries

Many of the helper functions used to implement the default queries are exposed by the DOM Testing Library. The helpers can be used to create custom queries. For example, the code below demonstrates how to use a different data-attribute than the default testId queries.

test-utils.js

const domTestingLib = require('@testing-library/dom')
const {queryHelpers} = domTestingLib

export const queryByTestId = queryHelpers.queryByAttribute.bind(
 null,
 'data-test-id',
)
export const queryAllByTestId = queryHelpers.queryAllByAttribute.bind(
 null,
 'data-test-id',
)

export function getAllByTestId(container, id, ...rest) {
 const els = queryAllByTestId(container, id, ...rest)
 if (!els.length) {
   throw queryHelpers.getElementError(
     `Unable to find an element by: [data-test-id="${id}"]`,
     container,
   )
 }
 return els
}

export function getByTestId(container, id, ...rest) {
 // result >= 1
 const result = getAllByTestId(container, id, ...rest)
 if (result.length > 1) {
   throw queryHelpers.getElementError(
     `Found multiple elements with the [data-test-id="${id}"]`,
     container,
   )
 }
 return result[0]
}

// re-export with overrides
module.exports = {
 ...domTestingLib,
 getByTestId,
 getAllByTestId,
 queryByTestId,
 queryAllByTestId,
}

buildQueries

The buildQueries helper combines all of the standard queries in testing-library to create custom queries.

Other Assertion Libraries

If you don't use jest, you might be able to find a set of custom assertions for your preferred library. For other popular assertion libraries, Chai-dom is an alternative to jest-dom.

getNodeText

getNodeText(node: HTMLElement) returns the entire text content of an HTML element, minus any whitespace. The goal is to treat text in nodes exactly like it is seen by users in a browser, with any extra whitespace between words in the html code having no effect on how the text is rendered.

// <div>
//   Hello
//     World  !
// </div>
const text = getNodeText(container.querySelector('div')) // "Hello World !"


Internally, this function is used to query nodes based on their text content. This allows functions like getByText and queryByText to function as expected, locating elements in the DOM in the same way that users would.

For some input elements, the function behaves differently:

// <input type="submit" value="Send data" />
// <input type="button" value="Push me" />
const submitText = getNodeText(container.querySelector('input[type=submit]')) // "Send data"
const buttonText = getNodeText(container.querySelector('input[type=button]')) // "Push me"


These elements use the attribute `value` and display its value to the user.

Within Method

within (an alias for getQueriesForElement) binds a DOM element to the raw query functions, allowing them to be used without having to specify a container. It's the recommended approach for libraries built on this API, and it's what React Testing Library and Vue Testing Library use behind the scenes.

For example, to get the text 'hello' only in the 'messages' section, you could do:

Native

import {within} from '@testing-library/dom'

const messages = document.getElementById('messages')
const helloMessage = within(messages).getByText('hello')

FAQs

  1. How can custom queries can be added to React Testing Library's render method?
    Custom queries can be added to React Testing Library's render method by adding queries to the options config object.
  2. How to use the within() in React? Show with an example.
    To get the text 'hello' only within a section called 'messages', you could do:
    import {render, within} from '@testing-library/react'

    const {getByText} = render(<MyComponent />)
    const messages = getByText('messages')
    const helloMessage = within(messages).getByText('hello')
  3. How to use the within() in Cypress? Show with an example.
    To get the text 'hello' only within a section called 'messages', you could do:
    cy.findByText('messages').within(() => {
    cy.findByText('hello')
    })
  4. What is the alias of the within method?
    The within method is an alias to getQueriesForElement.
  5. What should you consider when using custom queries for react-testing-library?
    You should consider whether your new queries encourage you to test in a user-centric way, without testing implementation details.

Key Takeaways

In this article, we have extensively discussed the theoretical and practical implementation of Custom Queries and within method. 
We hope that this blog has helped you enhance your knowledge regarding Custom Queries and within method, and if you would like to learn more, check out our articles on Coding Ninjas Studio. Do upvote our blog to help other ninjas grow. Happy Coding!

Read more: Introduction to JQuery

Live masterclass