jestjsreact-testing-library

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?


Solution

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