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

test(checkbox): Change tests to react-testing-library and improve coverage #372

Merged
merged 41 commits into from
Jan 21, 2020

Conversation

anicholls
Copy link
Contributor

@anicholls anicholls commented Dec 13, 2019

Summary

Closes #363
Related to #286

Converts test to RTL, improves coverage, adds a static states story for visual regression testing, and uses a more BDD (behavioral-driven) approach for unit tests.

Checklist

  • branch has been rebased on the latest master commit
  • tests are changed or added
  • yarn test passes
  • all (dev)dependencies that the module needs is added to its package.json
  • code adheres to the API & Pattern guidelines

@lychyi lychyi added this to In progress in Current Sprint (7/20 - 8/9) via automation Dec 13, 2019
@cypress
Copy link

cypress bot commented Dec 13, 2019



Test summary

65 0 0 0


Run details

Project canvas-kit
Status Passed
Commit e37bd93
Started Jan 21, 2020 6:29 PM
Ended Jan 21, 2020 6:31 PM
Duration 01:24 💡
OS Linux Ubuntu Linux - 16.04
Browser Electron 61

View run in Cypress Dashboard ➡️


This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard

@lychyi lychyi mentioned this pull request Dec 28, 2019
31 tasks
@anicholls anicholls force-pushed the testing-checkbox branch 4 times, most recently from 27adf62 to 75035b8 Compare January 8, 2020 19:38
modules/checkbox/react/lib/Checkbox.tsx Outdated Show resolved Hide resolved
describe('with checked=true', () => {
test('should render a checked checkbox input', () => {
const {getByLabelText} = render(<Checkbox checked={true} onChange={cb} label={label} />);
expect(getByLabelText(label)).toHaveProperty('checked', true);
Copy link
Contributor Author

@anicholls anicholls Jan 8, 2020

Choose a reason for hiding this comment

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

Would love to use the new toBeChecked matcher from @testing-library/jest-dom, but there seem to be type issues within Emotion. We can update these when we update to Emotion 11 (see emotion-js/emotion#1689 for more info)

modules/checkbox/react/spec/Checkbox.spec.tsx Outdated Show resolved Hide resolved
@anicholls anicholls marked this pull request as ready for review January 8, 2020 19:44
@anicholls anicholls changed the title test(checkbox): Switch tests to RTL and improve coverage test(checkbox): Change tests to react-testing-library and improve coverage Jan 8, 2020
anicholls and others added 17 commits January 9, 2020 11:30
* feat(labs): Add bidirectionality support

feat(core): Experiment bidirectionality

feat(core): Rename DirectionProvider to useDirection

feat(core): Use Theming for Direction

feat(core): Add temporary wrapper in CanvasProvider

feat(core): Add more RTL defaults to try

feat(core): Use theming for Direction in more components

feat(core): Set default direction to LTR

feat(core): Knobs works for Direction

feat(labs): Use body dir attribute instead of div wrapper

feat(labs): Create overridden styled function to handle contexts

feat(labs): Use new styled function to replace useDirection

fix(labs): Handle undefined interpolations in styled function

fix(labs): Fix types for custom styled function

feat(labs): Direction from a prop in styled function

fix(labs): Fix operator for direction in styled function

fix(labs): Show how to use a CanvasProvider to use a different direction at a component level

fix(labs): Better example

fix(labs): More type fixes for custom styled function

feat(labs): Add a way to pass direction prop to all styled components

refactor(labs): Change extension of custom styled file to correct .ts

fix(labs): Don't clone all children if direction prop isn't defined

fix(labs): Follow documentation on how to create a theme

fix(labs): Remove testing on components

fix(labs): Code cleanup

fix(labs): Code cleanup

fix(labs): Update Theming Readme to include bidirectionality

docs(labs): Add a story for direction

feat(core): Experiment bidirectionality

feat(core): Experiment bidirectionality

feat(core): Rename DirectionProvider to useDirection

feat(core): Use Theming for Direction

feat(core): Add more RTL defaults to try

feat(core): Use theming for Direction in more components

feat(core): Set default direction to LTR

feat(core): Knobs works for Direction

feat(labs): Use body dir attribute instead of div wrapper

feat(labs): Create overridden styled function to handle contexts

feat(labs): Use new styled function to replace useDirection

fix(labs): Handle undefined interpolations in styled function

fix(labs): Fix types for custom styled function

feat(labs): Direction from a prop in styled function

fix(labs): Fix operator for direction in styled function

fix(labs): Show how to use a CanvasProvider to use a different direction at a component level

fix(labs): Better example

fix(labs): More type fixes for custom styled function

feat(labs): Add a way to pass direction prop to all styled components

refactor(labs): Change extension of custom styled file to correct .ts

fix(labs): Follow documentation on how to create a theme

fix(labs): Remove testing on components

fix(labs): Code cleanup

fix(labs): Code cleanup

fix(labs): Remove ThemeContext from popup

feat(labs): Merge from theming

fix(labs): Merge from theming

* refactor(labs): Remove global setting functionality (deferred)

* refactor(labs): Make sure props.theme is defined

* feat(banner): Add theming support to try bidirectionnality

* refactor(labs): Remove direction from Themeable interface

* refactor(labs): Remove dir from body

* fix(Labs): Prevent createCanvastheme from overriding defaultTheme

* docs(labs): fix typo

* docs(labs): Update README for bidirectionality

* refactor(labs): Remove applyDirection

* docs(Labs): Update direction story to show both directions

* refactor(labs): Use bdo element instead of div for dir container

* refactor(labs): Update readme and styled.ts based on PR review

* refactor(labs): Code clean up

* docs(labs): Fix typo

* refactor(labs): Update based on PR review

* chore(labs): Remove unused variable

* chore(labs): Formatting updates
lychyi added a commit to lychyi/canvas-kit that referenced this pull request Jan 14, 2020
lychyi added a commit to lychyi/canvas-kit that referenced this pull request Jan 14, 2020
@NicholasBoll
Copy link
Member

To make the visual work with the className trick would require changing the Checkbox.tsx file a bit to apply the className to both the wrapper and the container. My main question there is “should we really prevent the hover circle from showing if we are actively fighting a browser standard to do so?”

If yes, we could allow the hover circle when the label is hovered.

If no, maybe we should adjust the implementation of the Checkbox.tsx file slightly to allow the "hover" state to show correctly on our visual testing

@anicholls
Copy link
Contributor Author

@NicholasBoll I've addressed both of your comments and am waiting to hear back from the design team on whether tying the ripple to the label is okay 👍

Copy link
Contributor

@lychyi lychyi left a 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 any of these comments block merging, I just wanted to get some thoughts out there on how to make this more generic and re-usable. But in the context of form inputs, the new StaticStatesTable looks and works great

utils/storybook/StaticStatesTable.tsx Outdated Show resolved Hide resolved
* This uses our `StaticStates` system. Note: This system requires the use of Canvas'
* `styled` wrapper within the component, instead of the default emotion one.
*/
export interface StaticStatesTableProps {
Copy link
Contributor

Choose a reason for hiding this comment

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

I love the idea of this table and I think the rest of the comments in this file depend on what StaticStatesTable is intended to be, you can take these suggestions/comments with a grain of salt. Nothing blocks merging since this is only a test utility. It would be silly to be so picky for something we don't ship.

I'm approaching it as if this utility is supposed to be highly re-usable across all components in our library, not just form inputs and not just to render static states. If this wasn't the idea at all then you can probably ignore the rest of the comments or we can just simply think about this later.

To make it more generic, I would suggest that we decouple StaticStates and the table. Then you would simply compose the two and use the render prop accordingly.

// Instead of having the magic built within...
<StaticStatesTable ... />

// Compose them together instead
<StaticStates> {/* Sole job is to transform psuedo selectors to classes */}
  <ComponentTable {/* renders the component with a combination of props and states */}
    ...
   renderComponent={(...) => { return <SomeComponent ... />}}
  >
  </ComponentTable>
</StaticStates>

Copy link
Member

Choose a reason for hiding this comment

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

I think more generically it would be a matrix of x props and y props. As it is now, "Props" represent a row and "state" (the className for the psuedo-selector state) are the columns.

More generically it is a matrix of prop combinations since className is really a prop.

I'm not sure I like the implementation as a permutation of props that has to be filtered. What about this instead?

<ComponentPropsTable
  rowProps={[
    { label: 'Checked', checked: true, indeterminate: false },
    { label: 'Indeterminate', checked: false, indeterminate: true },
    // etc
  ]}
  columnProps={[
    { label: 'Focus', className: 'focus' },
    { label: 'Hover', className: 'hover' },
    // etc
  ]}
>
  (props) => <Checkbox {...props} />
</ComponentPropsTable>

You can always make some utility functions that will give you the rowProps array from permutations

* The render function called to render the component in each cell of the table. This gives you
* the ability to add extra styling or markup (a blue background for an inverse variant, for example).
*/
renderComponent(props: ComponentProps, disabled: boolean, className: string): React.ReactNode;
Copy link
Contributor

Choose a reason for hiding this comment

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

I would change the signature to (props: ComponentProps, state: string): React.ReactNode, getting rid of the disabled param and making the user take care of it in the render function itself. I would also rename className to state and handle that in the render function too.

This makes it a bit more generic and highly reusable for other components without a disabled state and ones that may not use StaticStates as a wrapper (we may also have other wrappers in the future) or choose to use the state for something other than a className.

Usage in https://github.com/Workday/canvas-kit/pull/372/files#diff-abfef4dc218304fbe5a1c9bb0fccb3d8R136 would look something like this:

      renderComponent={(props, state) => (
        <Checkbox
          checked={props.checked}
          disabled={state.includes('disabled')}
          indeterminate={props.indeterminate}
          error={props.error}
          className={state}
          onChange={() => {}} // eslint-disable-line no-empty-function
          label="Checkbox"
        />
      )}

export default class StaticStatesTable extends React.Component<StaticStatesTableProps> {
public static defaultProps = {
componentProps: {},
states: [
Copy link
Contributor

Choose a reason for hiding this comment

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

If this is supposed to be more generic, I would probably just make this a required prop and maybe provide an exported collection of states for form inputs (or even make it a static member that someone can just do states={[...StaticStatesTable.States.InputStates, 'custom state']}

utils/storybook/StaticStatesTable.tsx Outdated Show resolved Hide resolved
})}
</tr>
</thead>
<tbody>{this.mapProps()}</tbody>
Copy link
Contributor

Choose a reason for hiding this comment

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

We should think about testing mapProps() as we use this table more. It would suck to have a bug set a false visual baseline

@anicholls anicholls merged commit 858f061 into Workday:master Jan 21, 2020
Current Sprint (7/20 - 8/9) automation moved this from In progress (PRs) to Done Jan 21, 2020
@anicholls anicholls deleted the testing-checkbox branch January 21, 2020 18:34
@anicholls
Copy link
Contributor Author

Based on conversation, we're going to address the follow up changes to StaticStatesTable in another PR!

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

Successfully merging this pull request may close these issues.

Fix: a11y - Lack of association for left label and checkbox 544
6 participants