question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

userEvent.type only types last character or gives act warning when using Formik

See original GitHub issue

Either

  1. Act wrap missing warning when using userEvent.type with Formik, or
  2. Wrap userEvent with act, and have the tests failing due to only the last character being entered.

The issue has been mentioned here, but it seems to have been closed?

I’m able to reproduce the error after creating a new CRA project yesterday, but not on CodeSandbox?

App.js

import React from "react";
import { useFormik } from "formik";

export default function App() {
  const formik = useFormik({
    initialValues: {
      firstName: "",
    },
  });

  const { values, handleChange, handleSubmit } = formik;

  return (
    <div className="App">
      <form onSubmit={handleSubmit}>
        <input
          data-testid="firstName"
          value={values.firstName}
          onChange={handleChange}
          id="firstName"
          type="text"
        />
      </form>
    </div>
  );
}

App.test.js

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

describe("App", () => {
  test("Input text in formik form passes but with act warning", () => {
    render(<App />);

    const firstNameInput = screen.getByTestId("firstName");

    userEvent.type(firstNameInput, "MyFirstName");

    expect(firstNameInput.value).toBe("MyFirstName");
  });

  test("Input text in formik form doesn't pass, but without act warning", () => {
    render(<App />);

    const firstNameInput = screen.getByTestId("firstName");

    act(() => {
      userEvent.type(firstNameInput, "MyFirstName");
    });

    expect(firstNameInput.value).toBe("MyFirstName");
  });
});

What you did: Created a new project using npx create-react-app, added formik

What happened:

 FAIL  src/App.test.js
  App
    ✓ Input text in formik form passes but with act warning (137 ms)
    ✕ Input text in formik form doesn't pass, but without act warning (45 ms)

  ● App › Input text in formik form doesn't pass, but without act warning

    expect(received).toBe(expected) // Object.is equality

    Expected: "MyFirstName"
    Received: "e"

      24 |     });
      25 | 
    > 26 |     expect(firstNameInput.value).toBe("MyFirstName");
         |                                  ^
      27 |   });
      28 | });
      29 | 

      at Object.<anonymous> (src/App.test.js:26:34)

  console.error
    Warning: An update to App inside a test was not wrapped in act(...).
    
    When testing, code that causes React state updates should be wrapped into act(...):
    
    act(() => {
      /* fire events that update state */
    });
    /* assert on the output */
    
    This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
        at App (/Users/stefan/formik-testing-library-bug/src/App.js:5:18)

      at printWarning (node_modules/react-dom/cjs/react-dom.development.js:67:30)
      at error (node_modules/react-dom/cjs/react-dom.development.js:43:5)
      at warnIfNotCurrentlyActingUpdatesInDEV (node_modules/react-dom/cjs/react-dom.development.js:24064:9)
      at dispatch (node_modules/react-dom/cjs/react-dom.development.js:16135:9)
      at node_modules/formik/src/Formik.tsx:327:11  

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 passed, 2 total
Snapshots:   0 total
Time:        1.382 s
Ran all test suites.

Reproduction repository: https://github.com/Hyllesen/testing-library-formik-bug I could not reproduce the error in codesandbox, https://codesandbox.io/s/youthful-river-0wxrz

@testing-library/user-event: v12.6.0 @testing-library/jest-dom: ^5.11.4 @testing-library/react: ^11.1.0 @testing-library/user-event: 12.6.0 formik": "^2.2.6 node@v14.15.1

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

8reactions
ph-fritschecommented, Jan 5, 2021

Sry, stupid mistake on my part - didn’t await/return the Promise. The test does fail when written correctly:

return waitFor(() => expect(firstNameInput.value).toBe("e"));

This is the fix for your test:

  test("fixed", async () => {
    render(<App />);

    const firstNameInput = screen.getByTestId("firstName");

    await userEvent.type(firstNameInput, "MyFirstName", { delay: 1 });

    expect(firstNameInput.value).toBe("MyFirstName");
  });

Formik applies the state change asynchronously. That’s why they happen out of the act-wrapped event handler. If wrapped in extra act React defers the state changes, so userEvent.type picks up the unchanged value and applies the next character. So you only end up with “e”. delay solves both problems.

2reactions
cmacdonnachacommented, Sep 3, 2021

FYI await userEvent.type worked for me without the delay.

Read more comments on GitHub >

github_iconTop Results From Across the Web

userEvent.type inputs only last character when wrapped in act
I did drop the userEvent and now my test pass but I keep getting the warning about wrapping user events in act. What...
Read more >
userEvent.type only types last character or gives act warning ...
Either 1. Act wrap missing warning when using userEvent.type with Formik, or 2. Wrap userEvent with act, and have the tests failing due...
Read more >
Testing Formik with react-testing-library - Scott Sauber
Formik validation happens asynchronously, so you need to use react-testing-library's findBy* methods and await for the validation to finish ( ...
Read more >
react testing library referenceerror: document is not defined
In trying out shallow rendering, tests only work with some of my components. A few of my components, however, contain charts made using...
Read more >
userEvent.type inputs only last character when wrapped in act ...
Related Query · userEvent. · When testing, code that causes React state updates should be wrapped into act · Element type error in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found