-
Notifications
You must be signed in to change notification settings - Fork 1.2k
[Test Modernization] Switch to using mountWithApp on ResourceItem and ResourceList tests. #4362
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
Conversation
|
👋 Thanks for opening your first pull request. A contributor should give feedback soon. If you haven’t already, please check out the contributing guidelines. |
| it('does not call onClick when hitting keyUp on the item when no URL exists', () => { | ||
| const onClick = jest.fn(); | ||
| const wrapper = mountWithAppProvider( | ||
| const wrapper = mountWithApp( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it intentional to have this one test with mockSelectModeContext in the middle of all the other ones with mockDefaultContext?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so. Feel free to move it out of the default group
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if we should move it out of the default group or change it's context to the default one, since the test itself seems related to its neighbours, it's just the context that's different (which could have been some autocomplete mistake). What do you think?
|
|
||
| it('renders a checked Checkbox if the item is in the selectedItems context', () => { | ||
| const wrapper = mountWithAppProvider( | ||
| const wrapper = mountWithApp( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is in the "SelectMode" describe block, but uses mockSelectableContext. Is this intentional?
size-limit report
|
73d04ae to
2bf6d95
Compare
kyledurand
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job @lucabezerra 👏
| ); | ||
|
|
||
| expect(findByTestID(element, 'Item-Wrapper').prop('data-href')).toBe(url); | ||
| const div = element.find('div', {'data-href': url} as any); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should be able to use toContainReactComponent here
expect(element).toContainReactComponent('div', {'data-href': url});
| it('does not call onClick when hitting keyUp on the item when no URL exists', () => { | ||
| const onClick = jest.fn(); | ||
| const wrapper = mountWithAppProvider( | ||
| const wrapper = mountWithApp( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so. Feel free to move it out of the default group
| ); | ||
|
|
||
| expect(item.find('li').prop('data-href')).toBe('google.com'); | ||
| const li = item.find('li', {'data-href': 'google.com'} as any); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could probably use toContainReactComponent
| ); | ||
|
|
||
| expect(item.find('li').prop('data-href')).toBeUndefined(); | ||
| const li = item.find('li', {'data-href': undefined} as any); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here too
AndrewMusgrave
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a comment about filtering by class names, ideally we wouldn't import the css module & css utilities. We're relying on the implementation logic in the test, which isn't ideal. Other than that, LGTM! 🎉
| styles.ResourceItem, | ||
| styles.selectable, | ||
| styles.selectMode, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was there anything we could filter on, other than class names?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was going to comment on this as well. Importing css modules into our tests will slow them down. Unfortunately we're already doing that in other areas and it is a nicer way to remove findByTestID
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I don't like it either. On top of the reasons you've mentioned, it kinda looks brittle to me (and sometimes complex to figure out which classes are expected depending on which props were passed to the component). I was hoping you folks would be able to suggest me a better alternative. Should I leave it like that, then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Slow down will be negligible. The style file is already part of the module graph because ResourceItem itself imports it too. When Jest encounters .scss files it basically maps in identity-obj-proxy which is some very trivial JS that says "any key is valid, return that value as a string" - so styles.ResourceItem is 'ResourceItem', styles.selectable is 'selectable' etc.
Agree with Kyle, that the while not super great it's better than keeping using testID stuff, and I've got no better idea.
To reduce the need to play "guess all the classes' whachamole I think you might be able to use expect.stringContaining to reference just the one
wrapper .find('div', {
className: expect.stringContaining(styles.ResourceItem)
})!.trigger('onKeyUp', {key: 'Enter'})e.g.
polaris-react/src/components/Button/tests/Button.test.tsx
Lines 424 to 426 in 746d2db
| expect(button).toContainReactComponent(UnstyledButton, { | |
| className: expect.stringContaining('removeUnderline'), | |
| }); |
or use findWhere to write a filter function if that doesn't work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition to Ben's comment, here're a few ideas
find('div', {testID})// we're generally against testID's but thought id mention it still works- use the class names directly so we don't reply on implementation logic
find('div', {className: 'ResourceItem') - extract the logic so it's only in one location
const resourceItemSelector = {className: styles.ResourceItem'}
...
component.find('div', resourceItemSelector)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, everyone!
As @BPScott had anticipated, the expect.stringContaining only works within the context of jest matchers, but I was able to introduce it to a few places anyway. I've used the findWhere everywhere else.
I've also incorporated a bit of @AndrewMusgrave 's suggestion to extract the logic into a single place, hopefully it's looking better now.
Thanks @kyledurand for spotting the places I've missed!
There are now just these 2 points before I can consider this done. Github won't let me paste the direct links to the discussions no matter what I try (it keeps removing the anchor from the link), so please copy the following anchors and paste it at the end of this PR's URL to go straight to them: #discussion_r683666010 and #discussion_r686332281
Co-authored-by: Kyle Durand <kyledurand@users.noreply.github.com>
…pify/polaris-react into resourceitem-modernize-tests
| const ariaLabel = 'View Item'; | ||
|
|
||
| const resourceItemSelector = {className: styles.ResourceItem}; | ||
| const resourceItemFilter = (node: any) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having two ways of doing this feels a little strange. It seems like resourceItemFilter does everything resourceItemSelector can but can additional cases. what if we stick with just resourceItemFilter.
I think we can type this better too: node: Node<unknown> where you can do import {Node} from '@shopify/react-testing'. Rathe than import from @shopify/react-testing in this file though, it might be nicer to do import {Node} from 'test-utiilities', and have src/test-utilities/react-testing.tsx rexport the Node type.
|
This has been closed in favor of #4398, which uses the most recent implementation of |
WHY are these changes introduced?
Modernizes tests to use the new modern framework (
{mountWithApp}fromtest-utilities).WHAT is this pull request doing?
Updates tests using
{mountWithAppProvider}fromtest-utilities/legacyto use{mountWithApp}fromtest-utilities