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

Should be wrapped in act(...) #60

Closed
razzeee opened this issue May 19, 2023 · 5 comments
Closed

Should be wrapped in act(...) #60

razzeee opened this issue May 19, 2023 · 5 comments
Labels
bug Something isn't working

Comments

@razzeee
Copy link

razzeee commented May 19, 2023

Use Version
Use version when bugs appear:

  • Headless UI: v1.7.14
  • Headless UI Float: v0.11.2
  • Framework: react v18.2
  • @floating-ui/core: v1.2.6
  • @floating-ui/dom: v1.2.7

Describe the bug
Running tests with the file under test using this component causes:

  console.error
    Warning: An update to Float 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 /home/klampe/dev/slashskills/node_modules/@headlessui-float/react/dist/headlessui-float.cjs:27:11232
        at div
        at OpenClosedProvider (/home/klampe/dev/slashskills/node_modules/@headlessui/react/dist/headlessui.dev.cjs:1011:31)
        at PopoverFn (/home/klampe/dev/slashskills/node_modules/@headlessui/react/dist/headlessui.dev.cjs:4828:54)

There is also an issue over at testing-library/testing-library-docs#1255

It seemed to only show up after the react 18 update, but I'm unsure. Maybe it's even expected, that we need to do that, as the docs don't have any test examples :)

@razzeee razzeee added the bug Something isn't working label May 19, 2023
@ycs77
Copy link
Owner

ycs77 commented Aug 21, 2023

Hi @razzeee, please provide a minimal reproducible example (like github repo, codesandbox, stackblitz...), it is recommended to fork the Headless UI Flaot's Online Demo to reproduce.

@razzeee
Copy link
Author

razzeee commented Aug 23, 2023

FYI, we currently have to add act (or waitFor in our case) around every component render, that headlessui-float is used in.

it('renders positive', async () => {
    render(<HoursPillRelative hours={-9} />)

    await waitFor(() => expect(screen.getByText('+9h')).toBeInTheDocument())
  })

That's our workaround for now. If it can be done in the library, it would spare quiet some work. I'll look into creating a repro asap.

@razzeee
Copy link
Author

razzeee commented Aug 26, 2023

I found it quiet hard to work it into the online demo, as there is no testing integrated at all. Creating a new redwoodjs app might just be easier for me.

@ycs77
Copy link
Owner

ycs77 commented Aug 26, 2023

Yes, I think may not need to use the online demo. I just need a minimal reproducible example.

I can only do my best to help you with the act() error, but I can't guarantee that I can solve it. The main reason is that I usually use Vue, not React, and I'm not very familiar with React.

However, I can give you a reference code: Headless UI Float's unit test. I also encountered this problem many times when writing unit tests, but I still couldn't understand why this error occurred. This test is driven by Vitest. I hope it can help you build a minimal example and solve this problem.

@ycs77
Copy link
Owner

ycs77 commented Sep 2, 2023

I found that this issue can only be solved by using await waitFor(), because I also wrote the unit test in the package in the same way:

it('should to render <Float> with <Menu>', async () => {
render(
<Menu>
<Float placement="bottom-start" offset={4}>
<Menu.Button>Options</Menu.Button>
<Menu.Items>
<Menu.Item><button type="button">Account settings</button></Menu.Item>
<Menu.Item><button type="button">Documentation</button></Menu.Item>
<Menu.Item disabled><span>Invite a friend (coming soon!)</span></Menu.Item>
</Menu.Items>
</Float>
</Menu>
)
await waitFor()
const button = screen.getByText('Options')
await waitFor()
expect(button).toBeInTheDocument()
expect(screen.queryByRole('menu')).toBeNull()
await userEvent.click(button)
await waitFor()
expect(screen.queryByRole('menu')).toHaveAttribute('data-headlessui-state', 'open')
const menuItems = screen.queryAllByRole('menuitem')
expect(menuItems).toHaveLength(3)
await userEvent.click(button)
await waitFor()
expect(screen.queryByRole('menu')).toBeNull()
})

However, I created a util function based on the usage of Floating UI, which can help your code look more concise:

const promisedWaitFor = () => new Promise<void>(resolve => waitFor(resolve))

I hope this can help you.

However, I think this issue cannot be solved in the package, so I will close this issue for now. If you have a better solution, please send a PR.

@ycs77 ycs77 closed this as completed Sep 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants