tips for choosing an element using getByTestId that matches a particular value in react-testing-library

When working with React, I have a scenario where I am mapping out elements from an array. For instance:

{options.map((option)=>{
  return <div data-testid="option">{option}</div>
})

In some cases, I need to select an option without knowing its exact text content. In such situations, I use data-testid="option" as an identifier and select the first option with

screenGetAllByTestId('option')[0]
...

However, there are instances where I know the specific option I want and would like to use getByTestId, but it becomes challenging as all options share the same data-testid.

My goal is to achieve something akin to the following pseudo code:

screen.getAllByTestId('option').getByText("Apples")

This code snippet is designed to fetch all options and then pinpoint the one that contains the text "Apples".

Answer №1

If you need to create custom matching functions, you can do so by:

screen.getByText((content, element) => {
  return element.tagName.toLowerCase() === 'span' && content.startsWith('Hello')
})

Refer to the documentation for more examples

In your specific scenario, this would translate to:

screen.getByText((content, element) => {
  return element.getAttribute('data-testid').toLowerCase() === 'option' && content === 'Apples'
})

An alternative approach could be to assign clear text labels to each group of options for better test readability:

// Locate the header for the fruits list
const fruitsListHeader = screen.getByText('Fruits list');

// Find the container containing the menu
// Traditional query selectors can be used
const fruitsList = fruitsListHeader.closest('[role="menu"]')

// Search for the specific option in the correct location, instead of 
// assuming there are no duplicated options on the page.
const appleOption = within(fruitsList.closest('[role="menu"))
  .getByText('Apples');

within - additional information

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error in Typescript due to delegate function not being recognized post minification

Here is a code snippet that uses delegate: <pre> $.ajax(this.validateURL, { type: "post", url: this.validateURL, data: JSON.stringify(i), contentType: "application/json; charset=utf-8", dataType: "json", success: i => t.pro ...

What methods are available to expedite webpack compilation (or decouple it from server restart)?

My current setup includes the following configurations: import path from 'path' import type {Configuration} from 'webpack' const config: Configuration = { mode: 'development', entry: path.join(__dirname, '../..&apos ...

Deactivate the submit button when the form is not valid in angularjs

I am currently facing a challenge with my form that contains multiple input fields. To simplify, let's consider an example with just two inputs below. My goal is to have the submit button disabled until all required inputs are filled out. Here is wha ...

What is the best way to confirm a validation error in sequelizejs unit test using jest?

I'm currently in the process of unit testing a User model to ensure that the user's name is not empty. Below is the unit test that I have written: it('should reject no name', async () => { name = ''; expect(await Use ...

Error: The $http variable in Vue Resource is not defined

I encountered an issue with the following code snippet inside my ready method: this.$http.get('url',{},{ headers: { "X-App-Token": "token" } }).then( (data) => this.$set('cdata',data.data)) ...

interactive switch using font awesome icons and jquery

Initially, I assumed this would be an easy task, but I've encountered some difficulties in making it function smoothly. Although I am able to toggle once using .show and .hide, I am unable to toggle back. Any assistance would be greatly appreciated. ...

What is the correct way to wrap an http.get in TypeScript?

My understanding of Typescript is limited, so I have a basic question related to my web application's frontend. In most http get-requests, I need to include two parameters. To simplify this process, I created a simple wrapper for HttpClient (from "ang ...

What is the best way for Cucumber to move on to the next annotation only after ensuring all async requests from the previous one have finished processing?

I am looking to set up a basic test using Selenium and Cucumber for logging into my web application and confirming that the main page is displayed correctly. Currently, all three tests are returning true even before the page is fully loaded. The issue ar ...

Guide: Generating a DIV Element with DOM Instead of Using jQuery

Generate dynamic and user-defined positioning requires input parameters: offsetHeight, offsetLeft, offsetParent, offsetTop, offsetWidth ...

What is the process for determining the types of arguments for multiple functions in TypeScript?

const foo = (a: string, b: string) => { console.log('foo', a, b); }; const bar = (a: number, b: number) => { console.log('bar', a, b); }; const multiFactory = <M extends typeof foo | typeof bar>(method: M) => (. ...

Unveiling the Power of Ionic and React for Component Repetition

I'm having trouble figuring out how to repeat my component multiple times using react in Ionic. Can someone assist me with this? Here's an example: In my Component.tsx file, I have the following code: import React from 'react'; import ...

Error: An unexpected symbol '||=' was found

I'm facing an issue while trying to create a nextjs project with PDFViewer using @react-pdf-viewer. The error I encountered is "SyntaxError: Unexpected token '||=' when collecting pages. This problem seems to be originating from pdf.js in t ...

Error encountered when attempting to retrieve data from an API route using s3, resulting in an uncaught promise with the message "SyntaxError: Unexpected token < in JSON at position 0

I'm attempting to retrieve a JSON file from an S3 bucket. Here is the API route I'm using to fetch the json file: const {GetObjectCommand, S3Client} = require("@aws-sdk/client-s3"); const client = new S3Client() // Add opts to S3 if nee ...

What is the significance of parentheses when used in a type definition?

The index.d.ts file in React contains an interface definition that includes the following code snippet. Can you explain the significance of the third line shown below? (props: P & { children?: ReactNode }, context?: any): ReactElement<any> | nu ...

The connection between IE11 and Google is not functioning properly

Currently, I am working on an IE11 extension, which involves using an XMLHttpRequest (GET) to retrieve data from Google's settings page. The code is executed on the extension's background page. Here are the specific details I am including in the ...

Modify the divs in two separate occasions when submitting different forms

Within my form, I have radio buttons located inside div1, a captcha code to be solved in div2, and additional content in div3. My goal is to have div1 replaced by div2 when a radio button is checked and submitted. Then, after completing the captcha in div2 ...

Acquiring the content of elements contained within a div container

On a webpage, I have included multiple div elements with unique IDs and the following structure: <div class="alert alert-info" id="1"> <p><b><span class="adName">Name</span></b><br> ...

GWT Validation - Enhance Your Application with a Third Party Library

Is there a reliable JavaScript library available for validating GWT fields such as Email, Text Length, Phone Number, Date & SSN, etc.? I am unable to use the GWT Validation Framework or GWT Errai in my application because I receive responses as JSON r ...

I am looking to modify various attributes linked to Rails

My Desire for Reality I am looking to update multiple related values in Rails by sending an update request from JavaScript. While creating data was seamless, I encountered difficulties when attempting to update it. #Code JavaScript* export const actions ...

React Native: Avoiding Infinite Loops in useEffect

I am facing an issue where my app goes into an infinite loop because pointsData is inside the useEffect function. How can I resolve this situation? function useGetPoints() { const [pointsData, setPointsData] = useState<PointTbleType[]>([]); ...