Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing event directly results in strange values inside state change function while running tests #111

Open
stefan-fast opened this issue Jan 26, 2023 · 4 comments

Comments

@stefan-fast
Copy link

I came across an issue when writing tests with testing library where text typed into an text area becomes completly messed up when directly passing the event into setter function created by useImmer:

export default function App() {
  const [test, setTest] = useImmer({ text: "" });

  return (
    <div className="App">
      <Form.Group controlId="formDescription">
        <Form.Label>{"TestInput"}</Form.Label>
        <Form.Control
          as="textarea"
          type="text"
          placeholder={"Enter input"}
          value={test.text}
          onChange={(event) => {
            const value = event.target.value;
            setTest((draft) => {
              draft.text = event.target.value; // wrong value for event.target.value inside test; gets really messed up
              //draft.text = value; // works fine
            });
          }}
        />
      </Form.Group>
    </div>
  );
}

On the other hand, when using useState the following works just fine:

export default function App() {
  const [foo, setFoo] = useState({ text: "" });

  return (
    <div className="App">
      <Form.Group controlId="formDescription">
        <Form.Label>{"TestInput"}</Form.Label>
        <Form.Control
          as="textarea"
          type="text"
          placeholder={"Enter input"}
          value={test.text}
          onChange={(event) => {
            setFoo((prevState) => {
              const newState = { ...prevState };
              newState.text = event.target.value; // works fine
              return newState;
            });
          }}
        />
      </Form.Group>
    </div>
  );

The test:

import { render } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import App from "./App";
import { screen } from "@testing-library/dom";

test("fill in", async () => {
  const user = userEvent.setup({ document });
  render(<App />);

  const description = "This is a test description.";

  await user.type(
    screen.getByRole("textbox", { name: "TestInput" }),
    description
  );
  expect(screen.getByText(description)).not.toBeNull();
});

Instead of This is a test description. the text area somehow contains Ti sats ecito. when running the test.

Using the text area manually in a browser seems to always work fine though. I am not sure if there can anything be done here and if this only happens in combination with testing library.

CSB: https://codesandbox.io/s/billowing-dew-0mdbjx

@yashug
Copy link

yashug commented Apr 13, 2023

@stefan-fast were you able to find any root cause for this?

@ofersinnovid
Copy link

I experience the same issue, any plan to solve this issue?

@aushev-vadim
Copy link

I have the same issue.
@stefan-fast thank you for solution!

@mweststrate
Copy link
Collaborator

@stefan-fast mind sharing what the solution was?

wondering if it could be a similar issue as downshift-js/downshift#1597: multiple relevant event handlers being triggered simultaneously.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants