-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
In a test file comprised of two tests, I first tried matching a React rendered container (obtained from render
) against a snapshot, which issued a success as expected. In the second test, I used fireEvent
to issue a click and the DOM apparently didn't update as it should. Funny thing is, if I invert the test order both of them works. Even funnier: when I put up a codesandbox to recreate the issue (URL below), it fails on the first time it is seen and then it succeeds if I change the order of tests and then change it back.
I put a log call to see whether the events are being fired on this possibly buggy case, and it turns out they aren't.
A relevant detail is that I'm not rendering the element on top of the standard element provided, but rather (as it is a TD) I'm rendering on top of a table/tr.
@testing-library/react
version: 10.0.1react
version: 16.13.0node
version: 12.11.1npm
(oryarn
) version: 6.11.3
Relevant code or config:
Component:
import React, { useState } from "react";
const Component = ({ initialValue }) => {
const [text, setText] = useState(initialValue || "");
const handleTextChange = event => {
setText(event.target.value);
};
return (
<td className="x">
<textarea value={text || ""} onChange={handleTextChange} />
</td>
);
};
export default Component;
Test:
import React from "react";
import { render, fireEvent } from "@testing-library/react";
import App from "./App";
const table = document.createElement("table");
const tr = document.createElement("tr");
const renderOptions = {
container: document.body.appendChild(table.appendChild(tr))
};
describe("<App />", () => {
it("with defaults (read-only user)", () => {
const { container } = render(<App initialValue="blah" />, renderOptions);
expect(container).toBeTruthy(); // I was comparing to snaphots, but it's not needed
});
it("should change text on textarea", () => {
const utils = render(<App initialValue="initial value" />, renderOptions);
const textarea = utils.getByRole("textbox");
fireEvent.change(textarea, { target: { value: "modified text" } });
expect(textarea.innerHTML).toEqual("modified text");
});
});
What you did:
Set up the tests above against the component, also above, and it fails when the tests have the order above. If I invert the order of tests or swap the TD to a DIV and don't render against the table/tr, they work.
What happened:
expect(received).toEqual(expected)
Expected value to equal:
"modified text"
Received:
"initial value"
19 | const textarea = utils.getByRole("textbox");
20 | fireEvent.change(textarea, { target: { value: "abc" } });
> 22 | expect(textarea.innerHTML).toEqual("abc");
23 | });
24 | });
Reproduction:
https://codesandbox.io/s/testing-lib-react-445bv
Problem description:
Unless I'm missing something, this is not only an inconsistency but a bug, as the test above should succeed at all times, no matter the order of tests on the test file.
Suggested solution:
I don't know what would be the solution but I would guess it has something to do with the fact that I am issuing render
with a different container
option, in this case a table row (table/tr), rather than going with the default body/div.