-
Notifications
You must be signed in to change notification settings - Fork 215
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(switch): Redo switch tests in react-testing-library (#386)
Co-authored-by: Alex Nicholls <anicholls3@gmail.com>
- Loading branch information
Showing
6 changed files
with
224 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import * as h from '../helpers'; | ||
|
||
const getSwitch = () => { | ||
return cy.get(`[type="checkbox"]`); | ||
}; | ||
|
||
describe('Switch', () => { | ||
before(() => { | ||
h.stories.visit(); | ||
}); | ||
['Default', 'Alert', 'Error'].forEach(story => { | ||
context(`given the '${story}' story is rendered`, () => { | ||
beforeEach(() => { | ||
h.stories.load('Components|Inputs/Switch/React/Top Label', story); | ||
}); | ||
|
||
it('should pass accessibility checks', () => { | ||
cy.checkA11y(); | ||
}); | ||
|
||
context('when clicked', () => { | ||
beforeEach(() => { | ||
getSwitch().click(); | ||
}); | ||
|
||
it('should be checked', () => { | ||
getSwitch().should('be.checked'); | ||
}); | ||
}); | ||
}); | ||
}); | ||
|
||
context(`given the 'Disabled' story is rendered`, () => { | ||
beforeEach(() => { | ||
h.stories.load('Components|Inputs/Switch/React/Top Label', 'Disabled'); | ||
}); | ||
|
||
it('should pass accessibility checks', () => { | ||
cy.checkA11y(); | ||
}); | ||
|
||
it('should be disabled', () => { | ||
getSwitch().should('be.disabled'); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
import Adapter from 'enzyme-adapter-react-16'; | ||
import {configure} from 'enzyme'; | ||
import {toHaveNoViolations} from 'jest-axe'; | ||
import serializer from 'jest-emotion'; | ||
import serializer, {matchers} from 'jest-emotion'; | ||
import '@testing-library/jest-dom/extend-expect'; | ||
|
||
expect.addSnapshotSerializer(serializer); | ||
expect.extend(toHaveNoViolations); | ||
expect.extend(matchers); | ||
configure({adapter: new Adapter()}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,124 @@ | ||
import * as React from 'react'; | ||
import {mount} from 'enzyme'; | ||
import {render, fireEvent} from '@testing-library/react'; | ||
import Switch from '../lib/Switch'; | ||
|
||
describe('Switch', () => { | ||
const cb = jest.fn(); | ||
|
||
/** | ||
* Today, this is hardcoded but this could possibly be | ||
* configurable in the future (e.g. role='switch'). | ||
* In fact, 'checkbox' probably isn't the correct role | ||
* according to MDN and ARIA | ||
* https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Switch_role | ||
* https://www.w3.org/TR/wai-aria-1.1/#switch | ||
*/ | ||
const role = 'checkbox'; | ||
|
||
afterEach(() => { | ||
cb.mockReset(); | ||
}); | ||
|
||
test('Switch should spread extra props', () => { | ||
const component = mount(<Switch data-propspread="test" onChange={cb} />); | ||
const input = component | ||
.find('input') | ||
// TODO: Standardize on prop spread location (see #150) | ||
.getDOMNode(); | ||
expect(input.getAttribute('data-propspread')).toBe('test'); | ||
component.unmount(); | ||
}); | ||
|
||
test('Switch creates a unique id for each instance', async () => { | ||
const fragment = mount( | ||
<form> | ||
<Switch checked={true} onChange={jest.fn()} disabled={false} />; | ||
<Switch onChange={jest.fn()} disabled={false} />; | ||
</form> | ||
); | ||
|
||
const id1 = fragment | ||
.find('input') | ||
.at(0) | ||
.getDOMNode() | ||
.getAttribute('id'); | ||
|
||
const id2 = fragment | ||
.find('input') | ||
.at(1) | ||
.getDOMNode() | ||
.getAttribute('id'); | ||
|
||
expect(id1).not.toEqual(id2); | ||
fragment.unmount(); | ||
cb.mockClear(); | ||
}); | ||
|
||
describe('when rendered', () => { | ||
it('should render an input element with `type=checkbox`', () => { | ||
const {getByRole} = render(<Switch onChange={cb} />); | ||
expect(getByRole(role)).toHaveProperty('type', 'checkbox'); | ||
}); | ||
|
||
it('should be unchecked by default', () => { | ||
const {getByRole} = render(<Switch onChange={cb} />); | ||
expect(getByRole(role)).toHaveProperty('checked', false); | ||
}); | ||
|
||
test('should have a "pointer" cursor', () => { | ||
const {getByRole} = render(<Switch onChange={cb} />); | ||
expect(getByRole(role)).toHaveStyleRule('cursor', 'pointer'); | ||
}); | ||
}); | ||
|
||
describe('when rendered with checked=true', () => { | ||
it('should render a checked checkbox input', () => { | ||
const {getByRole} = render(<Switch checked={true} onChange={cb} />); | ||
expect(getByRole(role)).toHaveProperty('checked', true); | ||
}); | ||
}); | ||
|
||
describe('when rendered with an id', () => { | ||
it('should render a checkbox input with that id', () => { | ||
const id = 'switchy'; | ||
const {getByRole} = render(<Switch id={id} onChange={cb} />); | ||
|
||
expect(getByRole(role)).toHaveAttribute('id', id); | ||
}); | ||
}); | ||
|
||
describe('when rendered without an id', () => { | ||
it('should create a unique id for each instance', () => { | ||
const testIds = ['test1', 'test2']; | ||
const {getByTestId} = render( | ||
<> | ||
<Switch data-testid={testIds[0]} onChange={cb} /> | ||
<Switch data-testid={testIds[1]} onChange={cb} /> | ||
</> | ||
); | ||
|
||
const id1 = getByTestId(testIds[0]).getAttribute('id'); | ||
const id2 = getByTestId(testIds[1]).getAttribute('id'); | ||
|
||
expect(id1).not.toEqual(id2); | ||
}); | ||
|
||
it('should keep the same unique id if re-rendered', () => { | ||
const {getByRole, rerender} = render(<Switch checked={false} onChange={cb} />); | ||
|
||
const uniqueId = getByRole(role).getAttribute('id'); | ||
expect(getByRole(role)).toHaveProperty('id', uniqueId); | ||
|
||
rerender(<Switch checked={true} onChange={cb} />); | ||
|
||
expect(getByRole(role)).toHaveProperty('checked'); | ||
expect(getByRole(role)).toHaveProperty('id', uniqueId); | ||
}); | ||
}); | ||
|
||
describe('when rendered with the disabled prop', () => { | ||
it('should render a disabled checkbox input', () => { | ||
const {getByRole} = render(<Switch disabled={true} onChange={cb} />); | ||
expect(getByRole(role)).toHaveProperty('disabled', true); | ||
}); | ||
it('should have a "not-allowed" cursor', () => { | ||
const {getByRole} = render(<Switch disabled={true} onChange={cb} />); | ||
expect(getByRole(role)).toHaveStyleRule('cursor', 'not-allowed'); | ||
}); | ||
}); | ||
|
||
describe('when rendered with extra, arbitrary props', () => { | ||
it('should apply those extra props to the checkbox input', () => { | ||
const testValue = 'test'; | ||
|
||
const {getByRole} = render(<Switch data-propspread={testValue} onChange={cb} />); | ||
expect(getByRole(role)).toHaveAttribute('data-propspread', testValue); | ||
}); | ||
}); | ||
|
||
describe('when rendered with an input ref', () => { | ||
it("should set the ref's current property to the checkbox input element", () => { | ||
const ref = React.createRef<HTMLInputElement>(); | ||
|
||
render(<Switch inputRef={ref} onChange={cb} />); | ||
|
||
expect(ref.current).not.toBeNull(); | ||
expect(ref.current).toHaveAttribute('role', role); | ||
}); | ||
}); | ||
|
||
describe('when clicked', () => { | ||
it('should call the onChange callback', () => { | ||
const {getByRole} = render(<Switch onChange={cb} />); | ||
|
||
fireEvent.click(getByRole(role)); | ||
|
||
expect(cb).toHaveBeenCalledTimes(1); | ||
}); | ||
}); | ||
}); |