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

Viewed 1193

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?

1 Answers

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();
});
Related