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

[ButtonBase] Improve test coverage #16361

Merged
merged 26 commits into from
Jun 27, 2019

Conversation

eps1lon
Copy link
Member

@eps1lon eps1lon commented Jun 25, 2019

  • improve type coverage by type checking the ButtonBase unit test (investigating viability of Migrate to TypeScript #15984)
  • improve a11y coverage by moving to rtl
  • use strict mode compatible test API (remove enzyme's simulate)
  • enables a previously skipped test

All these points are coupled together (rtl is a bit more type friendly to the new testing approach, rtl enables new test etc).

Enables thinking about when to test for DOM properties vs HTML attributes so that was good practice.

@@ -9,7 +9,7 @@ import {

export interface ButtonBaseTypeMap {
props: {
action?: (actions: ButtonBaseActions) => void;
action?: React.Ref<ButtonBaseActions>;
Copy link
Member Author

Choose a reason for hiding this comment

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

This is passed to useImperativeHandle.

@codecov

This comment has been minimized.

@eps1lon eps1lon force-pushed the test/ButtonBase/strict-mode-api branch from ed7b707 to f05ab36 Compare June 25, 2019 13:42
@eps1lon eps1lon force-pushed the test/ButtonBase/strict-mode-api branch from e08538a to 8f36d59 Compare June 26, 2019 11:34
@mui-pr-bot
Copy link

mui-pr-bot commented Jun 26, 2019

No bundle size changes comparing ed4a76c...cc69b86

Generated by 🚫 dangerJS against cc69b86

still requires enzyme. Should be TouchRippleProps={{ center: true }} instead
@eps1lon eps1lon marked this pull request as ready for review June 26, 2019 12:52
Copy link
Member

@oliviertassinari oliviertassinari left a comment

Choose a reason for hiding this comment

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

How was your experience moving the tests from enzyme to testing-library?

};
}

const fireEvent = Object.assign(rtlFireEvent, {
// polyfill event.key for chrome 49 (supported in Material-UI v4)
Copy link
Member

Choose a reason for hiding this comment

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

Would using react-dom/test-utils solve the issue?

Copy link
Member Author

@eps1lon eps1lon Jun 27, 2019

Choose a reason for hiding this comment

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

They don't create native events for you but dispatch a given one. I haven't looked for a package that creates "old events" ergonomically. I couldn't even find a way to create events in chrome 49 manually without react failing to identify the key.

It seems like key is the prioritized property by react to create the synthetic event which makes this the simplest solution.

Copy link
Member

Choose a reason for hiding this comment

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

So using react-dom/test-utils doesn't have an impact on how React polyfills the events.
What allowed the tests to pass previously in Chrome 49?

Copy link
Member Author

Choose a reason for hiding this comment

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

It wasn't an actual event just something that matched it structurally for the important parts. It works most of the time since we're not interested in the full event object but it makes the test a bit more robust against implementation changes while they are more brittle towards browser implementation.

I would definitely rethink this if we would support more older browsers but since it's only chrome 49 and we will likely phase that out in v5 I'm comfortable with that.

It also raises awareness about behavior that would require user/dev action in certain browsers like enabling touch events in edge.

@eps1lon
Copy link
Member Author

eps1lon commented Jun 27, 2019

How was your experience moving the tests from enzyme to testing-library?

Learned a bit about the DOM. Writing experience was pleasant since vscode works really well with typed libraries. Whenever I made a mistake refactoring the proper expect matchers helped identify the problem without me having to add another console.log. rtl also helps printing out the DOM tree when it can't find an element .e.g.

const button = getByRole('button'); will log

cannot find element with [role="button"] in 
<div>
  <button type="button">Hello</button>
</div>

so you immediately know you should've used getByText1 and don't have to debug manually.

Some things are obviously hard like the centerRipple but we don't have a test for that anyway.

Tests are now more descriptive and it's easier with them to explain to someone how something should behave i.e. every time you do something that nobody will ever do in their codebase/browser you leave some question marks. It's obviously easier in some cases like focus compared to an Enter keyDown which has like 1 or 2 pages of spec text.

All we can do is try to improve instead of giving up immediately because it won't be perfect.

@eps1lon
Copy link
Member Author

eps1lon commented Jun 27, 2019

Forgot to add the 1: Going back and forth whether role="button" should match <button /> as well but a native button has different behavior than just role="button" so I guess the current behavior is ok. I wish browsers would apply behavior based on roles as well.

Copy link
Member

@oliviertassinari oliviertassinari left a comment

Choose a reason for hiding this comment

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

Sweet, thanks for sharing the journey.

@eps1lon eps1lon merged commit c78b343 into mui:master Jun 27, 2019
@eps1lon eps1lon deleted the test/ButtonBase/strict-mode-api branch June 27, 2019 12:04
@eps1lon
Copy link
Member Author

eps1lon commented Jul 2, 2019

Forgot to add the 1: Going back and forth whether role="button" should match <button /> as well but a native button has different behavior than just role="button" so I guess the current behavior is ok. I wish browsers would apply behavior based on roles as well.

Turns out I was wrong about that. The documentation for getByRole was incomplete. expect(render(<button />).getByRole('button')).toBeInTheDocument() works perfectly fine since getByRole considers default roles.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants