Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use Jest to test that one text element comes before another?

I have a list I'm rendering in my React app, and I need to test that I'm listing the list items in alphabetical order.

Initially I tried testing this by querying the document this way:

const a = getByText("a_item");
const el = a.parentElement?.parentElement?.nextSibling?.firstChild?.textContent;
expect(el).toEqual("b_item");

But this proved to be brittle. I don't want to test the HTML structure of each item. I only want to test that the list is alphabetical.

How can I test that the list is alphabetical without depending on the current HTML structure of the list?

like image 571
Nathan Arthur Avatar asked Nov 14 '25 09:11

Nathan Arthur


2 Answers

You can use the compareDocumentPosition() method to check if one element is before another element in the DOM.

Example:

it("lists items alphabetically", () => {
    const itemA = screen.getByText('a_item');
    const itemB = screen.getByText('b_item');

    expect(itemA.compareDocumentPosition(itemB)).toEqual(
        Node.DOCUMENT_POSITION_FOLLOWING,
    );
}

where Node.DOCUMENT_POSITION_FOLLOWING is a constant property in DOM Node, which will be the value returned by compareDocumentPosition() if itemB is displayed following itemA.

like image 163
samhoooo Avatar answered Nov 17 '25 10:11

samhoooo


Use String.search to find the indices of the strings in the document's HTML, and then assert that indices are in the correct order:

it("lists items alphabetically", async () => {
  loadItems([
    "b_item",
    "a_item",
  ]);

  await render(<App/>);

  await waitFor(() => {
    const html = document.body.innerHTML;
    const a = html.search("a_item");
    const b = html.search("b_item");
    expect(a).toBeLessThan(b);
  });
});

Note that this may not be ideal since it accesses the dom directly, which isn't considered best practice when using React Testing Library. I haven't tested this, but it would probably be better to use a regex matcher with a built-in React Testing Library query method:

it("lists items alphabetically", async () => {
  loadItems([
    "b_item",
    "a_item",
  ]);

  await render(<App/>);

  expect(await screen.findByText(/a_item.+b_item/)).toBeInTheDocument();
});
like image 29
Nathan Arthur Avatar answered Nov 17 '25 08:11

Nathan Arthur



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!