diff --git a/.all-contributorsrc b/.all-contributorsrc index ac7bafbc..ebb53535 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -314,6 +314,16 @@ "contributions": [ "code" ] + }, + { + "login": "JeffBaumgardt", + "name": "Jeff Baumgardt", + "avatar_url": "https://avatars2.githubusercontent.com/u/777527?v=4", + "profile": "https://github.com/JeffBaumgardt", + "contributions": [ + "code", + "doc" + ] } ] } diff --git a/README.md b/README.md index 560d7831..a163be37 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ [![downloads][downloads-badge]][npmtrends] [![MIT License][license-badge]][license] -[![All Contributors](https://img.shields.io/badge/all_contributors-31-orange.svg?style=flat-square)](#contributors) +[![All Contributors](https://img.shields.io/badge/all_contributors-32-orange.svg?style=flat-square)](#contributors) [![PRs Welcome][prs-badge]][prs] [![Code of Conduct][coc-badge]][coc] @@ -351,6 +351,27 @@ Returns the element that has the matching value. const lastNameInput = getByValue('Norris') ``` +### `getByRole` + +```typescript +getByRole( + container: HTMLElement, + text: TextMatch, + options?: { + exact?: boolean = true, + collapseWhitespace?: boolean = false, + trim?: boolean = true, + }): HTMLElement` +``` + +A shortcut to `` container.querySelector(`[role="${yourRole}"]`) `` (and it +also accepts a [`TextMatch`](#textmatch)). + +```javascript +//
...
+const dialogContainer = getByTestrole(container, 'dialog') +``` + ### `getByTestId` ```typescript @@ -933,7 +954,7 @@ Thanks goes to these people ([emoji key][emojis]): | [
Anto Aravinth](https://github.com/antoaravinth)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=antoaravinth "Code") [⚠️](https://github.com/kentcdodds/dom-testing-library/commits?author=antoaravinth "Tests") [πŸ“–](https://github.com/kentcdodds/dom-testing-library/commits?author=antoaravinth "Documentation") | [
Jonah Moses](https://github.com/JonahMoses)
[πŸ“–](https://github.com/kentcdodds/dom-testing-library/commits?author=JonahMoses "Documentation") | [
Łukasz Gandecki](http://team.thebrain.pro)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=lgandecki "Code") [⚠️](https://github.com/kentcdodds/dom-testing-library/commits?author=lgandecki "Tests") [πŸ“–](https://github.com/kentcdodds/dom-testing-library/commits?author=lgandecki "Documentation") | [
Ivan Babak](https://sompylasar.github.io)
[πŸ›](https://github.com/kentcdodds/dom-testing-library/issues?q=author%3Asompylasar "Bug reports") [πŸ€”](#ideas-sompylasar "Ideas, Planning, & Feedback") [πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=sompylasar "Code") [πŸ“–](https://github.com/kentcdodds/dom-testing-library/commits?author=sompylasar "Documentation") | [
Jesse Day](https://github.com/jday3)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=jday3 "Code") | [
Ernesto GarcΓ­a](http://gnapse.github.io)
[πŸ’¬](#question-gnapse "Answering Questions") [πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=gnapse "Code") [πŸ“–](https://github.com/kentcdodds/dom-testing-library/commits?author=gnapse "Documentation") | [
Josef Maxx Blake](http://jomaxx.com)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=jomaxx "Code") [πŸ“–](https://github.com/kentcdodds/dom-testing-library/commits?author=jomaxx "Documentation") [⚠️](https://github.com/kentcdodds/dom-testing-library/commits?author=jomaxx "Tests") | | [
Alex Cook](https://github.com/alecook)
[πŸ“–](https://github.com/kentcdodds/dom-testing-library/commits?author=alecook "Documentation") [πŸ’‘](#example-alecook "Examples") | [
Daniel Cook](https://github.com/dfcook)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=dfcook "Code") [πŸ“–](https://github.com/kentcdodds/dom-testing-library/commits?author=dfcook "Documentation") [⚠️](https://github.com/kentcdodds/dom-testing-library/commits?author=dfcook "Tests") | [
Thomas Chia](https://github.com/thchia)
[πŸ›](https://github.com/kentcdodds/dom-testing-library/issues?q=author%3Athchia "Bug reports") [πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=thchia "Code") | [
Tim Deschryver](https://github.com/tdeschryver)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=tdeschryver "Code") [⚠️](https://github.com/kentcdodds/dom-testing-library/commits?author=tdeschryver "Tests") | [
Alex Krolick](https://alexkrolick.com)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=alexkrolick "Code") | [
Maddi Joyce](http://www.maddijoyce.com)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=maddijoyce "Code") | [
Peter Kamps](https://github.com/npeterkamps)
[πŸ›](https://github.com/kentcdodds/dom-testing-library/issues?q=author%3Anpeterkamps "Bug reports") [πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=npeterkamps "Code") [⚠️](https://github.com/kentcdodds/dom-testing-library/commits?author=npeterkamps "Tests") | | [
Jonathan Stoye](http://jonathanstoye.de)
[πŸ“–](https://github.com/kentcdodds/dom-testing-library/commits?author=JonathanStoye "Documentation") | [
Sanghyeon Lee](https://github.com/yongdamsh)
[πŸ’‘](#example-yongdamsh "Examples") | [
Justice Mba ](https://github.com/Dajust)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=Dajust "Code") [πŸ“–](https://github.com/kentcdodds/dom-testing-library/commits?author=Dajust "Documentation") [πŸ€”](#ideas-Dajust "Ideas, Planning, & Feedback") | [
Wayne Crouch](https://github.com/wgcrouch)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=wgcrouch "Code") | [
Ben Elliott](http://benjaminelliott.co.uk)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=benelliott "Code") | [
Ruben Costa](http://nuances.co)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=rubencosta "Code") | [
Robert Smith](http://rbrtsmith.com/)
[πŸ›](https://github.com/kentcdodds/dom-testing-library/issues?q=author%3Arbrtsmith "Bug reports") [πŸ€”](#ideas-rbrtsmith "Ideas, Planning, & Feedback") [πŸ“–](https://github.com/kentcdodds/dom-testing-library/commits?author=rbrtsmith "Documentation") | -| [
dadamssg](https://github.com/dadamssg)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=dadamssg "Code") | [
Neil Kistner](https://neilkistner.com/)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=wyze "Code") | [
Ben Chauvette](http://bdchauvette.net/)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=bdchauvette "Code") | +| [
dadamssg](https://github.com/dadamssg)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=dadamssg "Code") | [
Neil Kistner](https://neilkistner.com/)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=wyze "Code") | [
Ben Chauvette](http://bdchauvette.net/)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=bdchauvette "Code") | [
Jeff Baumgardt](https://github.com/JeffBaumgardt)
[πŸ’»](https://github.com/kentcdodds/dom-testing-library/commits?author=JeffBaumgardt "Code") [πŸ“–](https://github.com/kentcdodds/dom-testing-library/commits?author=JeffBaumgardt "Documentation") | diff --git a/src/__tests__/__snapshots__/element-queries.js.snap b/src/__tests__/__snapshots__/element-queries.js.snap index 0ff24479..08d5ca44 100644 --- a/src/__tests__/__snapshots__/element-queries.js.snap +++ b/src/__tests__/__snapshots__/element-queries.js.snap @@ -56,6 +56,14 @@ exports[`get throws a useful error message 7`] = ` " `; +exports[`get throws a useful error message 8`] = ` +"Unable to find an element by role=LucyRicardo + +
 + 
 +
" +`; + exports[`get throws a useful error message without DOM in Cypress 1`] = `"Unable to find a label with the text of: LucyRicardo"`; exports[`get throws a useful error message without DOM in Cypress 2`] = `"Unable to find an element with the placeholder text of: LucyRicardo"`; diff --git a/src/__tests__/element-queries.js b/src/__tests__/element-queries.js index f392741d..e1274e6e 100644 --- a/src/__tests__/element-queries.js +++ b/src/__tests__/element-queries.js @@ -29,6 +29,7 @@ test('get throws a useful error message', () => { getByAltText, getByTitle, getByValue, + getByRole, } = render('
') expect(() => getByLabelText('LucyRicardo')).toThrowErrorMatchingSnapshot() expect(() => @@ -39,6 +40,7 @@ test('get throws a useful error message', () => { expect(() => getByAltText('LucyRicardo')).toThrowErrorMatchingSnapshot() expect(() => getByTitle('LucyRicardo')).toThrowErrorMatchingSnapshot() expect(() => getByValue('LucyRicardo')).toThrowErrorMatchingSnapshot() + expect(() => getByRole('LucyRicardo')).toThrowErrorMatchingSnapshot() }) test('can get elements by matching their text content', () => { @@ -209,8 +211,9 @@ test('getAll* matchers return an array', () => { getAllByLabelText, getAllByPlaceholderText, getAllByText, + getAllByRole, } = render(` -
+
finding nemo poster { expect(getAllByPlaceholderText(/The Rock/)).toHaveLength(1) expect(getAllByLabelText('User Name')).toHaveLength(1) expect(getAllByText(/^where/i)).toHaveLength(1) + expect(getAllByRole(/container/i)).toHaveLength(1) }) test('getAll* matchers throw for 0 matches', () => { @@ -243,8 +247,9 @@ test('getAll* matchers throw for 0 matches', () => { getAllByLabelText, getAllByPlaceholderText, getAllByText, + getAllByRole, } = render(` -
+
, `) @@ -255,6 +260,7 @@ test('getAll* matchers throw for 0 matches', () => { expect(() => getAllByLabelText('no matches please')).toThrow() expect(() => getAllByPlaceholderText('nope')).toThrow() expect(() => getAllByText('nope')).toThrow() + expect(() => getAllByRole('nope')).toThrow() }) test('queryAll* matchers return an array for 0 matches', () => { @@ -264,6 +270,7 @@ test('queryAll* matchers return an array for 0 matches', () => { queryAllByLabelText, queryAllByPlaceholderText, queryAllByText, + queryAllByRole, } = render(`
, @@ -273,6 +280,7 @@ test('queryAll* matchers return an array for 0 matches', () => { expect(queryAllByLabelText('nope')).toHaveLength(0) expect(queryAllByPlaceholderText('nope')).toHaveLength(0) expect(queryAllByText('nope')).toHaveLength(0) + expect(queryAllByRole('nope')).toHaveLength(0) }) test('using jest helpers to assert element states', () => { @@ -375,6 +383,16 @@ test('using jest helpers to check element class names', () => { ).toThrowError() }) +test('using jest helpers to check element role', () => { + const {getByRole} = render(` +
+ Contents +
+ `) + + expect(getByRole('dialog')).toHaveTextContent('Contents') +}) + test('test the debug helper prints the dom state here', () => { const originalDebugPrintLimit = process.env.DEBUG_PRINT_LIMIT const Large = `
diff --git a/src/queries.js b/src/queries.js index 56e71401..86e31848 100644 --- a/src/queries.js +++ b/src/queries.js @@ -106,6 +106,8 @@ const queryByTestId = queryByAttribute.bind(null, 'data-testid') const queryAllByTestId = queryAllByAttribute.bind(null, 'data-testid') const queryByValue = queryByAttribute.bind(null, 'value') const queryAllByValue = queryAllByAttribute.bind(null, 'value') +const queryByRole = queryByAttribute.bind(null, 'role') +const queryAllByRole = queryAllByAttribute.bind(null, 'role') function queryAllByAltText( container, @@ -241,6 +243,18 @@ function getByAltText(...args) { return firstResultOrNull(getAllByAltText, ...args) } +function getAllByRole(container, id, ...rest) { + const els = queryAllByRole(container, id, ...rest) + if (!els.length) { + throw getElementError(`Unable to find an element by role=${id}`, container) + } + return els +} + +function getByRole(...args) { + return firstResultOrNull(getAllByRole, ...args) +} + export { queryByPlaceholderText, queryAllByPlaceholderText, @@ -270,6 +284,10 @@ export { queryAllByValue, getByValue, getAllByValue, + queryByRole, + queryAllByRole, + getAllByRole, + getByRole, } /* eslint complexity:["error", 14] */ diff --git a/typings/queries.d.ts b/typings/queries.d.ts index 01bcab45..a7d6882d 100644 --- a/typings/queries.d.ts +++ b/typings/queries.d.ts @@ -57,3 +57,7 @@ export const queryByValue: QueryByAttribute export const queryAllByValue: AllByAttribute export const getByValue: GetByAttribute export const getAllByValue: AllByAttribute +export const queryByTRole: QueryByAttribute +export const queryAllByTRole: AllByAttribute +export const getByTRole: GetByAttribute +export const getAllByTRole: AllByAttribute