How to check elements are rendered with a specific sorting with react-testing-library?
Asked Answered
G

4

22

With its user-centric approach, my understanding of RTL is that testing sorting of elements should look something like.

const foo = queryByText('foo');
const bar = queryByText('bar');
expect(foo).toBeInTheDocument();
expect(bar).toBeInTheDocument();
expect(foo).toShowBefore(bar); // THIS IS MY PSEUDOCODE

However, I couldn't find a .toShowBefore() or equivalent function in RTL. What's the correct way to test that content is displayed in a certain order?

Glossology answered 10/4, 2020 at 21:21 Comment(1)
atkinsondev.com/post/react-testing-library-order looks promising but I haven't tried it myself.Costello
D
23

You can use compareDocumentPosition.

For example

const e1 = getByText('a');
const e2 = getByText('b');
expect(e1.compareDocumentPosition(e2)).toBe(2); 

Here getByText is returned from the render function.

Dimmer answered 31/10, 2022 at 8:17 Comment(3)
Very good if you cannot add a test-idHartzog
adding test-id is too manual and also polluting codesDimmer
If you're expecting 'a' to come before 'b' then the result should be Node.DOCUMENT_POSITION_FOLLOWING (which is 4)Bullpen
F
4

I don't believe React Testing Library has an idiomatic way to do this. But if you can parse your DOM, then you should be able to get the textContent of various Elements and assert on that.

const select = screen.getByTestId('select');
const children = select.children;

expect(children.item(0)?.textContent).toEqual('Interface A');
expect(children.item(1)?.textContent).toEqual('Interface B');
expect(children.item(2)?.textContent).toEqual('Interface C');
Fortyfive answered 10/2, 2021 at 15:24 Comment(0)
C
4

You could give each row a test id:

<tr data-testid='row'>...</tr> 

and then expect the rows to be in order:

const rows = screen.getAllByTestId('row')

expect(within(rows[0]).queryByText('A')).toBeInTheDocument()
expect(within(rows[1]).queryByText('B')).toBeInTheDocument()
expect(within(rows[2]).queryByText('C')).toBeInTheDocument()
Curtilage answered 20/10, 2021 at 8:27 Comment(0)
S
0

I created a helper function for these cases like so:

const expectElementsToBeInOrder = (elements: [HTMLElement, HTMLElement, ...HTMLElement[]]) => {
 for (let i = 1; i < elements.length; i++) {
   expect(elements[i - 1].compareDocumentPosition(elements[i])).toBe(Node.DOCUMENT_POSITION_FOLLOWING);
 }
};

It accepts 2 or more HtmlElements and with the use of compareDocumentPosition expects them to be in the order specified in the array.

So for your example the solution would be to use it like: expectElementsToBeInOrder(foo, bar)

Statehood answered 2/7, 2024 at 12:39 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.