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

afterEnter and afterLeave are not being fired in React Transition component #2299

Closed
meruyert93 opened this issue Feb 21, 2023 · 2 comments
Closed

Comments

@meruyert93
Copy link

meruyert93 commented Feb 21, 2023

What package within Headless UI are you using?

@headlessui/react

What version of that package are you using?
v1.7.11

What browser are you using?

Node JS enviroment (tests)

Reproduction URL

Here is the minimal reproduction: https://codesandbox.io/s/transition-component-failing-mp8q7v?file=/src/Transition.test.tsx

Describe your issue

afterEnter and afterLeave are not being fired in React Transition component when we are testing our component in jest.

It is a bit frustrating because we cannot test our functions in the components, which are being called when afterEnter or afterLeave is fired. Therefore, we had to upgrade our @headlessui/react to the version 1.6.2 since it is working in this version. However, it seems that starting from the version 1.6.3 it stopped to work (based on changelog: https://github.com/tailwindlabs/headlessui/blob/main/packages/@headlessui-react/CHANGELOG.md#163---2022-05-25)

It seems like #1500 this PR could be reason.
Note: We found that you are also using jest and testing-library and in your case it is working. https://github.com/tailwindlabs/headlessui/blob/main/packages/%40headlessui-react/src/components/transitions/transition.test.tsx#L1356

However, in our case it is probably not working because we have to use act() to fireEvent based on https://reactjs.org/docs/test-utils.html#act otherwise, we are getting warning. However, it is just my assumptions.

I will be grateful to hear any feedback or see the fixed version🙂
Thanks a lot in advance.

@RobinMalfait
Copy link
Member

Hey! Thank you for your bug report!
Much appreciated! 🙏

This is a bit unfortunate and a limitation of jsdom. Right now the transition related events don't fire properly and therefore the afterEnter and afterLeave callbacks are never called.

The workaround in Headless UI is not clean at all, it basically bails on those native events and uses a setTimeout that is cancellable.

if (process.env.NODE_ENV === 'test') {
let dispose = d.setTimeout(() => {
done()
dispose()
}, totalDuration)
} else {
let dispose = d.addEventListener(node, 'transitionend', (event) => {
if (event.target !== event.currentTarget) return
done()
dispose()
})
}

Ideally you run this as integration tests in a real browser using Playwright or similar tools. We also have to do that but we didn't get to it yet (hence why a bunch of tests are skipped).

Hope this makes sense!

@oferrero
Copy link

Not ideal, but I was able to mock the Transition component and manually trigger the afterLeave callbacks instead.

jest.mock('@headlessui/react', () => {
  return {
    Transition: ({ show, afterLeave, children }) => {
      if (!show) {
        afterLeave();
        return null;
      }
      return children;
    },
  };
});

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

3 participants