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

[code-infra] In react tests, clean up our act() #174

Open
oliviertassinari opened this issue Jul 12, 2024 · 2 comments
Open

[code-infra] In react tests, clean up our act() #174

oliviertassinari opened this issue Jul 12, 2024 · 2 comments
Labels
scope: code-infra Specific to the core-infra product test

Comments

@oliviertassinari
Copy link
Member

oliviertassinari commented Jul 12, 2024

1. Don't wrap fireEvent with act

Example: https://github.com/mui/material-ui/blob/0bddcac5beeb535c36fa2055082cc8324e59c282/packages/mui-material/src/Button/Button.test.js#L612-L615

     );
     const button = getByRole('button');
 
+    fireEvent.keyDown(document.body, { key: 'TAB' });
     act(() => {
-      fireEvent.keyDown(document.body, { key: 'TAB' });
       button.focus();
     });

2. act should be awaited

As per mui/material-ui#41061 (comment)

From the docs:

We recommend using act with await and an async function. Although the sync version works in many cases, it doesn’t work in all cases and due to the way React schedules updates internally, it’s difficult to predict when you can use the sync version.
We will deprecate and remove the sync version in the future.

This is causing hard to debug issues. We should make our tests more robust and remove all sync usage of act.

     const button = getByRole('button');
 
     fireEvent.keyDown(document.body, { key: 'TAB' });
-    act(() => {
+    await act(async () => {
       button.focus();
     });

Also investigate if we can leverage eslint to discourage sync usage of act, see testing-library/eslint-plugin-testing-library#915

Search keywords:

@oliviertassinari oliviertassinari added the scope: code-infra Specific to the core-infra product label Jul 12, 2024
@oliviertassinari oliviertassinari changed the title In react tests, clean up our act [code-infra] In react tests, clean up our act Jul 12, 2024
@oliviertassinari oliviertassinari changed the title [code-infra] In react tests, clean up our act [code-infra] In react tests, clean up our act() Sep 17, 2024
@oliviertassinari
Copy link
Member Author

oliviertassinari commented Oct 6, 2024

On point 2. I wonder how true "This is causing hard to debug issues." is. They seem to report errors when an await is missing: https://github.com/facebook/react/blob/1460d67c5b9a0d4498b4d22e1a5a6c0ccac85fdd/packages/react/src/ReactAct.js#L122

Edit: looks like it's not true, it's needed: testing-library/react-testing-library#1061 (comment).

@Janpot
Copy link
Member

Janpot commented Oct 8, 2024

From mui/material-ui#44028 (review), potential eslint rule to help use with 2:

'no-restricted-syntax': [
  'error',
  {
    selector: "CallExpression[callee.name='act'] > ArrowFunctionExpression:not([async=true])",
    message: 'Synchronous form of `act` is not allowed. Use `await act(async () => {...})` instead.',
  },
  {
    selector: "CallExpression[callee.name='act']:not(AwaitExpression > CallExpression[callee.name='act'])",
    message: '`act` must be awaited. Use `await act(async () => {...})` instead.',
  },
],

We could plan some time to do a full sweep of the codebase, in my limited experience the sync version doesn't always work as expected. I wouldn't be surprised if mui/mui-x#14668 magically starts working if we remove all sync act calls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
scope: code-infra Specific to the core-infra product test
Projects
None yet
Development

No branches or pull requests

2 participants