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.

Layer component stays rendered in test suites

See original GitHub issue

Expected Behavior

When testing the Layer component with React-Testing-Library each instance of test should render a new component.

Actual Behavior

The Layer component remains rendered to the testing DOM despite providing a cleanup function afterEach(cleanup). This causes tests to fail as duplicates of the component are found.

URL, screen shot, or Codepen exhibiting the issue

https://codesandbox.io/s/grommet-v2-template-forked-66prc?file=/modal.test.js

CodeSandbox is having issues running tests but this is an example.

Steps to Reproduce

Create a component utilizing Grommet’s Layer component, run test with React-Testing-Library, notice the Layer remains rendered across multiple tests.

Your Environment

Only noticed after bumping to Grommet 2.17.2

  • Grommet version: 2.17.2

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
tayseacommented, May 10, 2021

Hey Andrew! Thanks so much for putting the repo together and documenting this so clearly. @jcfilben, @britt6612, and I have been looking into this today, and I wanted to summarize our findings for you here:

  1. Since portals (which Layer is built using) render outside of the root div , we need to explicitly clear them beforeEach test involving them because the react testing library cleanup function doesn’t handle it (https://stackoverflow.com/questions/67298821/jest-react-testing-library-portals-are-not-being-cleaned-up). Grommet does this in a function called createPortal which ensures that the DOM is cleared out before the test: https://github.com/grommet/grommet/blob/master/src/js/utils/portal.js#L4

Within our Layer-test file, we call beforeEach(createPortal) Because your testing setup doesn’t include this beforeEach function, the portal is not being cleared out between tests. This is unrelated to grommet 2.17.2. I cloned your repo and reverted the dependency versions to match the react, react-dom, testing-library, and grommet versions that we used at grommet v2.16.3 and saw the tests failing with the same errors as you’re experiencing here. However, once I added the beforeEach everything is working as expected.

Screen Shot 2021-05-10 at 3 22 49 PM

WITH beforeEach: Screen Shot 2021-05-10 at 3 38 43 PM

It seems like the reason your project was passing prior but not with grommet v2.17.1 or 2.17.2 is because React 16 and lower treated useEffect differently (synchronously) than useEffect is treated in React 17 (asynchronously). Given this, we made an adjustment in grommet v2.17.1 to Layer to use useLayoutEffect (which runs synchronously like useEffect had in older versions of React).

Recommendation: Add the following to your jest

beforeEach(() => {
  // make sure to remove all body children
  document.body.innerHTML = '';
  document.body.appendChild(document.createElement('div'));
})
1reaction
jcfilbencommented, May 5, 2021

In react-dom v17 useEffect is changed to run asynchronously, so we switched Layer to use useLayoutEffect which runs synchronously which is the old behavior of useEffect. This change fixed an issue with the Layer animation but it don’t think it would be related to the tests and I don’t think it would cause the Layer to persist between tests.

I did notice in the codesandbox that was shared above the versions for the react and react-dom are v16 instead of v17 so I think this is likely the cause of the problem

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to fire events on multiple layers of custom components ...
So most tests should look something like this. const user = userEvent.setup() render(<MyComponent/>) await ...
Read more >
React Testing Techniques. This blog focuses on the 'how' of…
Continuing to build upon the idea of “Test your components as a user would”, a key strategy is to prefer integration testing over...
Read more >
Testing a simple component with React Testing Library
First I will render the component and see that it's actually on screen. I will create a new test file called: AddWord.test.js and...
Read more >
React Component Tests for Humans - CSS-Tricks
Component tests flow through three phases: Arrange: The component props are prepared. Act: The component needs to render its DOM to the UI...
Read more >
Testing React Components With Enzyme
I'll cover a few cases where mount is the better choice later. Simulating Change Events With Enzyme. Rendering a component with Enzyme's shallow ......
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