Testing Cell Input With RTL (React Testing Library)

Tags: #<Tag:0x00007efc7041ead8> #<Tag:0x00007efc7041e998>

Hello,

Our team recently implemented RTL (React Testing Library) for component level testing. However, when we try to manually input values into one of our handsontable tables in an RTL test, it seems like the test cannot execute the cell editing action. The test is able to locate and identify table cells, but cell editing actions are not executed. Here is our attempt at cell editing in an RTL test:

it("Cell input validation works", async () => {
    const {getAllByRole, getByRole} = rendered;
    let cells = getAllByRole("cell");
    expect(cells[1]).toHaveTextContent("40");
    fireEvent.focus(cells[1]);
    fireEvent.keyDown(cells[1], {key: "a", code: "KeyA", charCode: 65});
    fireEvent.keyDown(cells[1], {key: "Tab", code: 9});
    /* Test fails on the following line because the cell value was not updated in the above steps: */
    expect(cells[1]).toHaveTextContent("a");
    expect(cells[1]).toHaveStyle({color: "#FCE7E7"});
    let textbox = getByRole("textbox", {hidden: true});
    expect(textbox).toHaveTextContent("Must be a valid positive or negative number.");
});

Has anyone found a way to manipulate cell values in an RTL test?

Hi @george1

Unfortunately, we don’t have experience with React Testing Library and we are not able to share any best practices in that case.

We had a topic related to this here: Adding Tests with React Testing Library Best Approach where the user shared some information on how he approached the testing.

Hey @george1

Just wanted to add some other comments around this and what we currently do.

We give every instance of our tables and unique class name and then get the table like so hotContainer = document.querySelector(.${myAwesomeUniqueClassName} .handsontable). Before this you probably want to have await waitFor() especially if you are dealing with data from an api or something.

With this we’re able to get the instance by getting the __reactFiber key. Once we have this we get this we can then do hotContainer?.[fiberKey] as any)?.return?.stateNode?.hotInstance this gives us access to the HOT api which allows you to use all the methods etc… We only ever use this for testing.

We have used this for a while and does work well for the most part. Again this is not a perfect solution, but having access to methods such as setDataAtCell is a life saver! I would be aware of act.

We also now have an ever growing number of component tests https://docs.cypress.io/guides/component-testing/overview, I think playwright has this as well, but found this had a few issues as its still in testing.

I would also look in to e2e for this. We use https://playwright.dev/ which can work well as well.

If anybody has any better ways it would be great if we can share them too. Maybe this is something that can be added to the docs or something, once we figure out the best solution @adrian.szymanski

Cheers, James