diff --git a/README.md b/README.md
index 7a3e06f..c7df104 100644
--- a/README.md
+++ b/README.md
@@ -82,6 +82,7 @@ clear to read and to maintain.
- [`toHaveRole`](#tohaverole)
- [`toHaveErrorMessage`](#tohaveerrormessage)
- [`toHaveSelection`](#tohaveselection)
+ - [`toBePressed`](#tobepressed)
- [Deprecated matchers](#deprecated-matchers)
- [`toBeEmpty`](#tobeempty)
- [`toBeInTheDOM`](#tobeinthedom)
@@ -1306,6 +1307,44 @@ expect(timeInput).toHaveErrorMessage(expect.stringContaining('Invalid time')) //
expect(timeInput).not.toHaveErrorMessage('Pikachu!')
```
+
+
+### `toBePressed`
+
+This allows to check whether given element has been [pressed](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-pressed).
+
+It accepts elements with explicit or implicit `button` role and valid `aria-pressed` attribute of `"true"` or `"false"`.
+
+```typescript
+toBePressed()
+```
+
+#### Examples
+
+```html
+
+
+
+
+
+
+Pressed span
+Released span
+```
+
+##### Using DOM Testing Library
+
+```javascript
+screen.getByRole('button', { name: 'Pressed' }).toBePressed();
+screen.getByRole('button', { name: 'Released' }).not.toBePressed();
+
+screen.getByRole('button', { name: 'Pressed input button' }).toBePressed();
+screen.getByRole('button', { name: 'Released input button' }).not.toBePressed();
+
+screen.getByRole('button', { name: 'Pressed span' }).toBePressed();
+screen.getByRole('button', { name: 'Released span' }).not.toBePressed();
+```
+
## Deprecated matchers
### `toBeEmpty`
diff --git a/src/__tests__/to-be-pressed.js b/src/__tests__/to-be-pressed.js
new file mode 100644
index 0000000..3969fd8
--- /dev/null
+++ b/src/__tests__/to-be-pressed.js
@@ -0,0 +1,87 @@
+import {render} from './helpers/test-utils'
+
+describe('.toBePressed', () => {
+ test('handles button element', () => {
+ const {queryByTestId} = render(`
+
+
+ `)
+
+ expect(queryByTestId('button-pressed')).toBePressed()
+ expect(queryByTestId('button-not-pressed')).not.toBePressed()
+ })
+
+ test('handles element with role="button"', () => {
+ const {queryByTestId} = render(`
+
+
+ `)
+
+ expect(queryByTestId('button-pressed')).toBePressed()
+ expect(queryByTestId('button-not-pressed')).not.toBePressed()
+ })
+
+ test('handles input with button type', () => {
+ const {queryByTestId} = render(`
+
+
+ `)
+
+ expect(queryByTestId('button-pressed')).toBePressed()
+ expect(queryByTestId('button-not-pressed')).not.toBePressed()
+ })
+
+ test('throw an error when pressable element is not pressed but expected to be', () => {
+ const {queryByTestId} = render(`
+
+ `)
+
+ expect(() => expect(queryByTestId('button')).toBePressed())
+ .toThrowErrorMatchingInlineSnapshot(`
+ expect(>element>).toBePressed()>
+
+ Expected element to have:
+ aria-pressed="true">
+ Received:
+ aria-pressed="false">
+ `)
+ })
+
+ test('throw an error when pressable element is pressed but expected not to be', () => {
+ const {queryByTestId} = render(`
+
+ `)
+
+ expect(() => expect(queryByTestId('button')).not.toBePressed())
+ .toThrowErrorMatchingInlineSnapshot(`
+ expect(>element>).not.toBePressed()>
+
+ Expected element to have:
+ aria-pressed="false">
+ Received:
+ aria-pressed="true">
+ `)
+ })
+
+ test('throw an error when pressable element has invalid aria-pressed attribute', () => {
+ const {queryByTestId} = render(`
+
+ `)
+
+ expect(() =>
+ expect(queryByTestId('button')).toBePressed(),
+ ).toThrowErrorMatchingInlineSnapshot(
+ `Only button or input with type="button" or element with role="button" and a valid aria-pressed attribute can be used with .toBePressed()`,
+ )
+ })
+
+ test('throws when element do not have aria-pressed attribute', () => {
+ const {queryByTestId} = render(``)
+
+ expect(() =>
+ expect(queryByTestId('span')).toBePressed(),
+ ).toThrowErrorMatchingInlineSnapshot(
+ `Only button or input with type="button" or element with role="button" and a valid aria-pressed attribute can be used with .toBePressed()`,
+ )
+ })
+})
diff --git a/src/matchers.js b/src/matchers.js
index ed534e2..9f5a72d 100644
--- a/src/matchers.js
+++ b/src/matchers.js
@@ -25,3 +25,4 @@ export {toBePartiallyChecked} from './to-be-partially-checked'
export {toHaveDescription} from './to-have-description'
export {toHaveErrorMessage} from './to-have-errormessage'
export {toHaveSelection} from './to-have-selection'
+export {toBePressed} from './to-be-pressed'
diff --git a/src/to-be-pressed.js b/src/to-be-pressed.js
new file mode 100644
index 0000000..638b699
--- /dev/null
+++ b/src/to-be-pressed.js
@@ -0,0 +1,56 @@
+import {checkHtmlElement, getMessage} from './utils'
+
+export function toBePressed(element) {
+ checkHtmlElement(element, toBePressed, this)
+
+ const isButton = () => {
+ return (
+ element.tagName.toLowerCase() === 'button' ||
+ element.getAttribute('role') === 'button' ||
+ (element.tagName.toLowerCase() === 'input' && element.type === 'button')
+ )
+ }
+
+ const isValidAriaElement = () => {
+ const ariaPressed = element.getAttribute('aria-pressed')
+
+ if (ariaPressed === 'true' || ariaPressed === 'false') {
+ return true
+ }
+
+ return false
+ }
+
+ if (!isButton() || !isValidAriaElement()) {
+ return {
+ pass: false,
+ message: () =>
+ `Only button or input with type="button" or element with role="button" and a valid aria-pressed attribute can be used with .toBePressed()`,
+ }
+ }
+
+ const isPressed = () => {
+ return element.getAttribute('aria-pressed') === 'true'
+ }
+
+ return {
+ pass: isButton() && isPressed(),
+
+ message: () => {
+ const matcher = this.utils.matcherHint(
+ `${this.isNot ? '.not' : ''}.toBePressed`,
+ 'element',
+ '',
+ )
+
+ return getMessage(
+ this,
+ matcher,
+ `Expected element to have`,
+ `aria-pressed="${this.isNot ? 'false' : 'true'}"`,
+ `Received`,
+ `aria-pressed="${element.getAttribute('aria-pressed')}"`,
+ )
+ },
+ }
+}
diff --git a/types/matchers.d.ts b/types/matchers.d.ts
index 8bf2ad5..b7c7e6a 100755
--- a/types/matchers.d.ts
+++ b/types/matchers.d.ts
@@ -761,6 +761,36 @@ declare namespace matchers {
* [testing-library/jest-dom#tohaveselection](https://github.com/testing-library/jest-dom#tohaveselection)
*/
toHaveSelection(selection?: string): R
+ /*
+ * @description
+ * This allows to check whether given element has been [pressed](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-pressed)
+ *
+ * It accepts elements with explicit or implicit `button` role and valid `aria-pressed`
+ * attribute of `"true"` or `"false"`.
+ *
+ * @example
+ *
+ *
+ *
+ *
+ *
+ *
+ * Pressed span
+ * Released span
+ *
+ * screen.getByRole('button', { name: 'Pressed' }).toBePressed();
+ * screen.getByRole('button', { name: 'Released' }).not.toBePressed();
+ *
+ * screen.getByRole('button', { name: 'Pressed input button' }).toBePressed();
+ * screen.getByRole('button', { name: 'Released input button' }).not.toBePressed();
+ *
+ * screen.getByRole('button', { name: 'Pressed span' }).toBePressed();
+ * screen.getByRole('button', { name: 'Released span' }).not.toBePressed();
+ *
+ * @see
+ * [testing-library/jest-dom#tobepressed](https://github.com/testing-library/jest-dom#tobepressed)
+ */
+ toBePressed(): R
}
}