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

Migrate enzyme to testing library #586

Merged
merged 64 commits into from
Sep 11, 2023
Merged

Conversation

josiasds
Copy link
Contributor

@josiasds josiasds commented Mar 15, 2023

This PR contains the migration from enzyme to react-testing-library, as requested in #567.

From the docs:

Testing Library has a different approach to testing when compared to Enzyme. What that means is there's not a one-to-one mapping of Enzyme features to React Testing Library features.

React Testing Library encourages you to avoid testing implementation details like the internals of a component you're testing (though it's still possible). The Guiding Principles of this library emphasize a focus on tests that closely resemble how your web pages are interacted by the users.

You may want to avoid the following implementation details:

  • Internal state of a component
  • Internal methods of a component
  • Lifecycle methods of a component
  • Child components

Release Notes

Author Checklist

  • Setup RTL side-by-side with Enzyme in order to migrate components progressively
  • Migrate ColorPicker (depends on Routine maintenance 2023-08 #596)
  • Incorporate code review feedback on feature branch
  • Merge PRs containing subsets of migrated tests
  • Remove Enzyme (and adapter) libs and setup

Components to migrate:
100%


  • Add unit test(s)
  • Update version in package.json (see the versioning guidelines)
  • Update documentation (if necessary)
  • Add story to storybook (if necessary)
  • Assign dev reviewer

@josiasds josiasds marked this pull request as draft March 15, 2023 20:19
Copy link
Contributor Author

@josiasds josiasds left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aojin Great work on this! 🎉
I left some comments as we discussed in the call.

test/forms/buttons/button-area.test.js Outdated Show resolved Hide resolved
test/forms/buttons/submit-button.test.js Outdated Show resolved Hide resolved
test/forms/buttons/submit-button.test.js Outdated Show resolved Hide resolved
test/forms/buttons/button.test.js Outdated Show resolved Hide resolved
test/forms/buttons/button.test.js Outdated Show resolved Hide resolved
test/forms/buttons/button.test.js Outdated Show resolved Hide resolved
test/forms/buttons/button.test.js Outdated Show resolved Hide resolved
test/forms/buttons/button.test.js Outdated Show resolved Hide resolved
test/forms/buttons/button.test.js Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
Copy link
Contributor

@chawes13 chawes13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Lots of questions – I'm sure that'll peter out as we all get more comfortable with the new library

package-lock.json Outdated Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
src/indicators/spinner.js Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
test/forms/inputs/checkbox.test.js Outdated Show resolved Hide resolved
test/forms/inputs/checkbox-group.test.js Outdated Show resolved Hide resolved
test/forms/inputs/checkbox-group.test.js Outdated Show resolved Hide resolved
test/forms/inputs/checkbox-group.test.js Outdated Show resolved Hide resolved
test/forms/inputs/checkbox-group.test.js Outdated Show resolved Hide resolved
chawes13 and others added 6 commits August 4, 2023 15:27
* Migrate paginator

* Add comment

* Remove unused import

* Migrate tab-bar
* Initial commit

* Clean up logs

* Add tests more default close interactions
* Migrate loading container

* Migrate flash message

* Migrate flash message container

* Upgdate assertion
Copy link
Contributor Author

@josiasds josiasds left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated a bunch of tests addressing comments here. There are a few more to update and then we can merge the pending PRs.

<button>Hi</button>
</ButtonArea>
)
expect(screen.getByRole('button').closest('div')).toHaveClass('extra classes')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

test/forms/buttons/button.test.js Outdated Show resolved Hide resolved
const wrapper = shallow(<Button submitting={true}> Hi</Button>)
expect(wrapper.hasClass('in-progress')).toBe(true)
render(<Button submitting={true}> Hi</Button>)
expect(screen.getByRole('button').getAttribute("class")).toContain("in-progress")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

test/forms/buttons/button.test.js Outdated Show resolved Hide resolved
test/forms/buttons/button.test.js Outdated Show resolved Hide resolved
test/forms/inputs/checkbox-group.test.js Outdated Show resolved Hide resolved
test/forms/inputs/checkbox-group.test.js Outdated Show resolved Hide resolved
test/forms/inputs/checkbox-group.test.js Outdated Show resolved Hide resolved
test/forms/inputs/checkbox.test.js Show resolved Hide resolved
test/forms/inputs/checkbox.test.js Outdated Show resolved Hide resolved
@@ -1,7 +1,7 @@
import { castArray, has } from '../../utils'

// Get column info from children via props
function getColumnData(children = [], doDisable) {
function getColumnData(children, doDisable) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was only called in sortable-table, whose prop types require children. We were getting a flag for missing a branch here, but in reality this isn't a valid use of this util.

@josiasds
Copy link
Contributor Author

josiasds commented Sep 5, 2023

@chawes13 I just reviewed your latest changes, looking good. Mocking isServer is the best approach in my opinion.

@@ -81,6 +88,7 @@ function getAdjacentControl(control, { previous = false } = {}) {

// Recursively searches for the closest parent tab list
function getClosestTabList(el) {
/* istanbul ignore next */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't possible to test without changing the markup of the component. If this situation does occur, we'll get an error on undefined.querySelectorAll('[role="tab"]')).

However, it still feels good to me to have this guard in a recursive function? Let me know if you think we should remove it outright

@chawes13
Copy link
Contributor

chawes13 commented Sep 6, 2023

@josiasds Ready for ya! We got to 100% coverage 😎

Copy link
Contributor

@chawes13 chawes13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@josiasds Looks good on my end, but let me know what you think about the commits increasing the coverage %!

render(<WrappedDropdownCheckboxGroup value={['1']} />)

const select = screen.getByRole('button')
await act(() => user.click(select))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is act necessary here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding is that any code that relies on asserting on state changes within a component should be wrapped in act. The button's nextSibling will only have the is-active class applied if the internal expanded state changes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, it looks like all events within React's callstack should be covered, so maybe I don't need it here!

https://kentcdodds.com/blog/fix-the-not-wrapped-in-act-warning

Additionally, it's possible that instead of calling act directly, I should be using waitFor (https://testing-library.com/docs/react-testing-library/cheatsheet/#async). What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, fixed it :)

@@ -1,5 +1,5 @@
import React from 'react'
import { render, screen } from '@testing-library/react'
import { render, screen, fireEvent } from '@testing-library/react'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to prefer fireEvent over the userEvent lib here?

Copy link
Contributor

@chawes13 chawes13 Sep 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, from what I could tell the keyboard command only works on focusable elements and there are none other than the tabs themselves. Most of the tests that use fireEvent needed an event to be targeted at an element that was not a tab (e.g., pressing directional key when not focused on a tab does not change focus). Lastly, one of the tests required key to be Unidentified, which I wasn't able to replicate with any known keyboard commands (so I used { code: 'Home' } with fireEvent instead).

It's a little bit of an escape hatch – I used keyboard when possible.

@chawes13 chawes13 merged commit c3bf628 into main Sep 11, 2023
1 check passed
@chawes13 chawes13 deleted the migrate-enzyme-to-testing-library branch September 11, 2023 20:16
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

Successfully merging this pull request may close these issues.

3 participants