Skip to content

Commit

Permalink
feat: add switch role to toBeChecked (#228)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonrimmer committed Apr 8, 2020
1 parent 69681df commit 144c647
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 10 deletions.
18 changes: 13 additions & 5 deletions README.md
Expand Up @@ -46,7 +46,6 @@ clear to read and to maintain.
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->


- [Installation](#installation)
- [Usage](#usage)
- [Custom matchers](#custom-matchers)
Expand Down Expand Up @@ -776,8 +775,9 @@ toBeChecked()
```

This allows you to check whether the given element is checked. It accepts an
`input` of type `checkbox` or `radio` and elements with a `role` of `checkbox`
or `radio` with a valid `aria-checked` attribute of `"true"` or `"false"`.
`input` of type `checkbox` or `radio` and elements with a `role` of `checkbox`,
`radio` or `switch` with a valid `aria-checked` attribute of `"true"` or
`"false"`.

#### Examples

Expand All @@ -795,6 +795,8 @@ or `radio` with a valid `aria-checked` attribute of `"true"` or `"false"`.
<input type="radio" value="foo" data-testid="input-radio-unchecked" />
<div role="radio" aria-checked="true" data-testid="aria-radio-checked" />
<div role="radio" aria-checked="false" data-testid="aria-radio-unchecked" />
<div role="switch" aria-checked="true" data-testid="aria-switch-checked" />
<div role="switch" aria-checked="false" data-testid="aria-switch-unchecked" />
```

```javascript
Expand All @@ -815,6 +817,11 @@ expect(inputRadioChecked).toBeChecked()
expect(inputRadioUnchecked).not.toBeChecked()
expect(ariaRadioChecked).toBeChecked()
expect(ariaRadioUnchecked).not.toBeChecked()

const ariaSwitchChecked = getByTestId('aria-switch-checked')
const ariaSwitchUnchecked = getByTestId('aria-switch-unchecked')
expect(ariaSwitchChecked).toBeChecked()
expect(ariaSwitchUnchecked).not.toBeChecked()
```

## Deprecated matchers
Expand Down Expand Up @@ -867,8 +874,8 @@ I'm not aware of any, if you are please [make a pull request][prs] and add it
here!

If you would like to further test the accessibility and validity of the DOM
consider [`jest-axe`](https://github.com/nickcolley/jest-axe). It doesn't
overlap with `jest-dom` but can complement it for more in-depth accessibility
consider [`jest-axe`](https://github.com/nickcolley/jest-axe). It doesn't
overlap with `jest-dom` but can complement it for more in-depth accessibility
checking (eg: validating `aria` attributes or ensuring unique id attributes).

## Guiding Principles
Expand Down Expand Up @@ -951,6 +958,7 @@ Thanks goes to these people ([emoji key][emojis]):

<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors][all-contributors] specification.
Expand Down
48 changes: 45 additions & 3 deletions src/__tests__/to-be-checked.js
Expand Up @@ -41,6 +41,16 @@ describe('.toBeChecked', () => {
expect(queryByTestId('aria-radio-unchecked')).not.toBeChecked()
})

test('handles element with role="switch"', () => {
const {queryByTestId} = render(`
<div role="switch" aria-checked="true" data-testid="aria-switch-checked" />
<div role="switch" aria-checked="false" data-testid="aria-switch-unchecked" />
`)

expect(queryByTestId('aria-switch-checked')).toBeChecked()
expect(queryByTestId('aria-switch-unchecked')).not.toBeChecked()
})

test('throws when checkbox input is checked but expected not to be', () => {
const {queryByTestId} = render(
`<input type="checkbox" checked data-testid="input-checked" />`,
Expand Down Expand Up @@ -121,6 +131,26 @@ describe('.toBeChecked', () => {
).toThrowError()
})

test('throws when element with role="switch" is checked but expected not to be', () => {
const {queryByTestId} = render(
`<div role="switch" aria-checked="true" data-testid="aria-switch-checked" />`,
)

expect(() =>
expect(queryByTestId('aria-switch-checked')).not.toBeChecked(),
).toThrowError()
})

test('throws when element with role="switch" is not checked but expected to be', () => {
const {queryByTestId} = render(
`<div role="switch" aria-checked="false" data-testid="aria-switch-unchecked" />`,
)

expect(() =>
expect(queryByTestId('aria-switch-unchecked')).toBeChecked(),
).toThrowError()
})

test('throws when element with role="checkbox" has an invalid aria-checked attribute', () => {
const {queryByTestId} = render(
`<div role="checkbox" aria-checked="something" data-testid="aria-checkbox-invalid" />`,
Expand All @@ -129,7 +159,7 @@ describe('.toBeChecked', () => {
expect(() =>
expect(queryByTestId('aria-checkbox-invalid')).toBeChecked(),
).toThrowError(
'only inputs with type="checkbox" or type="radio" or elements with role="checkbox" or role="radio" and a valid aria-checked attribute can be used with .toBeChecked(). Use .toHaveValue() instead',
'only inputs with type="checkbox" or type="radio" or elements with role="checkbox", role="radio" or role="switch" and a valid aria-checked attribute can be used with .toBeChecked(). Use .toHaveValue() instead',
)
})

Expand All @@ -141,14 +171,26 @@ describe('.toBeChecked', () => {
expect(() =>
expect(queryByTestId('aria-radio-invalid')).toBeChecked(),
).toThrowError(
'only inputs with type="checkbox" or type="radio" or elements with role="checkbox" or role="radio" and a valid aria-checked attribute can be used with .toBeChecked(). Use .toHaveValue() instead',
'only inputs with type="checkbox" or type="radio" or elements with role="checkbox", role="radio" or role="switch" and a valid aria-checked attribute can be used with .toBeChecked(). Use .toHaveValue() instead',
)
})

test('throws when element with role="switch" has an invalid aria-checked attribute', () => {
const {queryByTestId} = render(
`<div role="switch" aria-checked="something" data-testid="aria-switch-invalid" />`,
)

expect(() =>
expect(queryByTestId('aria-switch-invalid')).toBeChecked(),
).toThrowError(
'only inputs with type="checkbox" or type="radio" or elements with role="checkbox", role="radio" or role="switch" and a valid aria-checked attribute can be used with .toBeChecked(). Use .toHaveValue() instead',
)
})

test('throws when the element is not an input', () => {
const {queryByTestId} = render(`<select data-testid="select"></select>`)
expect(() => expect(queryByTestId('select')).toBeChecked()).toThrowError(
'only inputs with type="checkbox" or type="radio" or elements with role="checkbox" or role="radio" and a valid aria-checked attribute can be used with .toBeChecked(). Use .toHaveValue() instead',
'only inputs with type="checkbox" or type="radio" or elements with role="checkbox", role="radio" or role="switch" and a valid aria-checked attribute can be used with .toBeChecked(). Use .toHaveValue() instead',
)
})
})
Expand Down
4 changes: 2 additions & 2 deletions src/to-be-checked.js
Expand Up @@ -13,7 +13,7 @@ export function toBeChecked(element) {

const isValidAriaElement = () => {
return (
['checkbox', 'radio'].includes(element.getAttribute('role')) &&
['checkbox', 'radio', 'switch'].includes(element.getAttribute('role')) &&
['true', 'false'].includes(element.getAttribute('aria-checked'))
)
}
Expand All @@ -22,7 +22,7 @@ export function toBeChecked(element) {
return {
pass: false,
message: () =>
'only inputs with type="checkbox" or type="radio" or elements with role="checkbox" or role="radio" and a valid aria-checked attribute can be used with .toBeChecked(). Use .toHaveValue() instead',
'only inputs with type="checkbox" or type="radio" or elements with role="checkbox", role="radio" or role="switch" and a valid aria-checked attribute can be used with .toBeChecked(). Use .toHaveValue() instead',
}
}

Expand Down

0 comments on commit 144c647

Please sign in to comment.