38

I'm using react-testing-libarary to test my react application. For some reason, I need to be able to find the element by id and not data-testid. There is no way to achieve this in the documentation.

Is there a way to achieve this?

I've the rendered output as:

const dom = render(<App />);

I'm looking for something in line of:

const input = dom.getElemenById('firstinput');
//or 
const input = dom.getById('firstinput');
aks
  • 6,072
  • 4
  • 43
  • 68

6 Answers6

43

I found a way to do this.

import App from './App';
import { render, queryByAttribute } from 'react-testing-library';

const getById = queryByAttribute.bind(null, 'id');

const dom = render(<App />);
const table = getById(dom.container, 'directory-table');

I hope this helps.

aks
  • 6,072
  • 4
  • 43
  • 68
  • 23
    Why they don't have this by default?? I can't believe it. – Victor May 19 '20 at 05:02
  • 5
    It's much easier to simply use `document.getElementById`. But the ID of an element is an implemention detail and I recommend against using it. – kentcdodds Aug 14 '20 at 13:33
  • @Victor Believe it. Users don't fill out elements by ID, so the test shouldn't either (at least according to react-testing-library's philosophy). They fill them out by label, so you should find your elements in the test the same way users will find them: by label or placeholder text or whatever. – lmat - Reinstate Monica Dec 08 '20 at 21:44
  • @Imat - Reinstate Monica , well, I discussed some scenarios where the #id solution can be the ideal one. Everything depends on scenarios. A simple example: when using a third-party library (like Kendo), which build their elements by your provided #id, you can create tests relying on the id to access the elements. Using the #id will maintain compatibility with new versions of the third party library and it also doesn't pollute our code with data-test-id's. I explained this more in-depth right here: https://github.com/testing-library/react-testing-library/issues/683#issuecomment-643392223 – Victor Dec 09 '20 at 05:07
  • Keep scrolling until @Liran H answer. – Alejandro Mar Mar 18 '21 at 21:10
33

I feel like none of the answers really gave a complete solution, so here it is:

const result = render(<SomeComponent />);
const someElement = result.container.querySelector('#some-id');
Liran H
  • 5,181
  • 4
  • 30
  • 39
25

It looks you have DOM node itself as a container. Therefore, you should be able to call .querySelector('#firstinput') with that.

Ali BARIN
  • 1,668
  • 16
  • 20
  • yes this works but the only issue here is now I'm not able to use the `react-testing-library` helpers on this returned node. – aks Oct 26 '18 at 07:40
  • 2
    Nothing wrong with not using the helpers if you don't need them – Giorgio Polvara - Gpx Oct 26 '18 at 12:30
  • 2
    "I'm not able to use the react-testing-library helpers on this returned node." This is incorrect. What helpers are you talking about? All helpers deal with regular DOM nodes, so it doesn't make a difference how you found it. But either way, finding an element by its ID is not included in the library because that's an implementation detail. Use one of the built-in queries. – kentcdodds Aug 14 '20 at 13:36
  • Liran H's answer is better. Some people might not understand what you mean. Giving a complete example like his is better imo. – ajpieri Jan 08 '21 at 15:25
  • This is the fastest and easiest means of achieving this. Hugs – Nkoro Joseph Ahamefula Mar 18 '21 at 19:17
6

You can set up with testIdAttribute in the configuration.

configure({ testIdAttribute: 'id' })

https://testing-library.com/docs/dom-testing-library/api-configuration


The setting has pros and cons. The benefit of it is that you can set an id for multiple uses. (Test id, marketing analytics, tag manager, ...etc) You don't have to add both id and test-id. It's good for the conciseness of the code.

But be careful, you might accidentally set the same id at two different components on the same page. Remember to add index or identification to a component id for list items.

Norman Lin
  • 355
  • 3
  • 5
  • `testIdAttribute`: The attribute used by getByTestId and related queries. Defaults to `data-testid`. – Norman Lin Oct 08 '20 at 09:57
  • This is a bad idea because ids are meant to be unique to a single element on an entire page, whereas a test id can be used on more than one element (list items, for example). – Lokua Jan 21 '21 at 19:58
  • Yeah, you're probably right. But there are some benefits for the setting if we need the ids for multiple purposes. (tag manager, for example) – Norman Lin Jan 26 '21 at 08:47
5

There are two ways to do so

  1. Simply use container.getElementById('id'). In the end, all the helpers are doing is making queries like this one under the hood
  2. If you want to have your custom query you can write a custom render. Check the documentation for more info https://github.com/kentcdodds/react-testing-library#getbytestidtext-textmatch-htmlelement

As a final note, if you can avoid looking for elements by id it's better.

Giorgio Polvara - Gpx
  • 12,268
  • 5
  • 53
  • 55
  • 4
    I don't think you have access to getElementById on the container. – djsoteric Mar 17 '20 at 18:33
  • 5
    This is the correct answer. (I'm the author of testing library). – kentcdodds Aug 14 '20 at 13:36
  • Try to log `container` my guess is that it's not what you're looking for – Giorgio Polvara - Gpx Aug 30 '20 at 18:43
  • @kentcdodds I mean, would be nice if that work that way (from 1.), but all i get is `TS2339: Property 'getElementById' does not exist on type 'HTMLElement'.` – pbialy Mar 25 '21 at 16:00
  • Same error as pbialy. -1 for @kentcdodds – Mihai Zamfir Apr 25 '21 at 17:41
  • `getElementById` is not even present on RTL docs '-' For me the correct way is using the this tool: https://chrome.google.com/webstore/detail/testing-playground/hejbmebodbijjdhflfknehhcgaklhano I never spent time adding/looking for ids again. – Lucas Andrade May 25 '21 at 14:35
  • `getElementById` is not in the docs because it's not an API of RTL, it's a DOM API, supported by all browsers. The error @pbialy and @mihai-zamfir are experiencing is a TypeScript error and has nothing to do with RTL. – Giorgio Polvara - Gpx May 25 '21 at 20:29
0

My advice: stop adding and searching by ids, this always takes to much time and effort because you have to add the ids (sometimes test-ids) and then find out the best way to query the element. But even if you really need an id, this tool will save you a lot of time by showing the best way to query any DOM element on your screen: Testing Playground

Lucas Andrade
  • 2,353
  • 2
  • 19
  • 38