diff --git a/.all-contributorsrc b/.all-contributorsrc
index 3b25725b..fc50632f 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -419,6 +419,18 @@
"contributions": [
"code"
]
+ },
+ {
+ "login": "RoystonS",
+ "name": "Royston Shufflebotham",
+ "avatar_url": "https://avatars0.githubusercontent.com/u/19773?v=4",
+ "profile": "https://github.com/RoystonS",
+ "contributions": [
+ "bug",
+ "code",
+ "doc",
+ "test"
+ ]
}
]
}
diff --git a/README.md b/README.md
index 6bb9270d..65625191 100644
--- a/README.md
+++ b/README.md
@@ -10,19 +10,21 @@
+
[![Build Status][build-badge]][build]
[![Code Coverage][coverage-badge]][coverage]
[![version][version-badge]][package]
[![downloads][downloads-badge]][npmtrends]
[![MIT License][license-badge]][license]
-[](#contributors)
+[](#contributors)
[![PRs Welcome][prs-badge]][prs]
[![Code of Conduct][coc-badge]][coc]
[![Watch on GitHub][github-watch-badge]][github-watch]
[![Star on GitHub][github-star-badge]][github-star]
[![Tweet][twitter-badge]][twitter]
+
@@ -102,6 +104,7 @@ when a real user uses it.
- [`within` and `getQueriesForElement` APIs](#within-and-getqueriesforelement-apis)
- [Debugging](#debugging)
- [`prettyDOM`](#prettydom)
+- [Configuration](#configuration)
- [Implementations](#implementations)
- [Using Without Jest](#using-without-jest)
- [FAQ](#faq)
@@ -456,6 +459,17 @@ const usernameInputElement = getByTestId(container, 'username-input')
> `data-testid`s from the blog post
> ["Making your UI tests resilient to change"][data-testid-blog-post]
+#### Overriding `data-testid`
+
+The `...ByTestId` functions in `dom-testing-library` use the attribute `data-testid`
+by default, following the precedent set by
+[React Native Web](https://github.com/kentcdodds/react-testing-library/issues/1)
+which uses a `testID` prop to emit a `data-testid` attribute on the element,
+and we recommend you adopt that attribute where possible.
+But if you already have an existing codebase that uses a different attribute
+for this purpose, you can override this value via
+`configure({testIdAttribute: 'data-my-test-attribute'})`.
+
### `wait`
```typescript
@@ -928,6 +942,19 @@ console.log(prettyDOM(div))
This function is what also powers [the automatic debugging output described above](#debugging).
+## Configuration
+
+The library can be configured via the `configure` function, which accepts:
+
+- a plain JS object; this will be merged into the existing configuration. e.g. `configure({testIdAttribute: 'not-data-testid'})`
+- a function; the function will be given the existing configuration, and should return a plain JS object which will be merged as above, e.g.
+ `configure(existingConfig => ({something: [...existingConfig.something, 'extra value for the something array']}))`
+
+Configuration options:
+
+`testIdAttribute`: The attribute used by `getByTestId` and related queries.
+Defaults to `data-testid`. See [`getByTestId`](#getbytestid).
+
## Implementations
This library was not built to be used on its own. The original implementation
@@ -1115,6 +1142,7 @@ Thanks goes to these people ([emoji key][emojis]):
| [
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") | [
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") | [
Matan Kushner](http://matchai.me)
[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=matchai "Code") [📖](https://github.com/kentcdodds/dom-testing-library/commits?author=matchai "Documentation") [🤔](#ideas-matchai "Ideas, Planning, & Feedback") [⚠️](https://github.com/kentcdodds/dom-testing-library/commits?author=matchai "Tests") | [
Alex Wendte](http://www.wendtedesigns.com/)
[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=themostcolm "Code") [📖](https://github.com/kentcdodds/dom-testing-library/commits?author=themostcolm "Documentation") [⚠️](https://github.com/kentcdodds/dom-testing-library/commits?author=themostcolm "Tests") | [
Tamas Fodor](https://github.com/ruffle1986)
[📖](https://github.com/kentcdodds/dom-testing-library/commits?author=ruffle1986 "Documentation") |
| [
Benjamin Eckardt](https://github.com/BenjaminEckardt)
[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=BenjaminEckardt "Code") | [
Ryan Campbell](https://github.com/campbellr)
[📖](https://github.com/kentcdodds/dom-testing-library/commits?author=campbellr "Documentation") | [
Taylor Briggs](https://taylor-briggs.com)
[⚠️](https://github.com/kentcdodds/dom-testing-library/commits?author=TaylorBriggs "Tests") | [
John Gozde](https://github.com/jgoz)
[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=jgoz "Code") | [
C. T. Lin](https://github.com/chentsulin)
[📖](https://github.com/kentcdodds/dom-testing-library/commits?author=chentsulin "Documentation") | [
Terrence Wong](http://terrencewwong.com)
[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=terrencewwong "Code") | [
Soo Jae Hwang](https://www.ossfinder.com)
[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=misoguy "Code") |
+| [
Royston Shufflebotham](https://github.com/RoystonS)
[🐛](https://github.com/kentcdodds/dom-testing-library/issues?q=author%3ARoystonS "Bug reports") [💻](https://github.com/kentcdodds/dom-testing-library/commits?author=RoystonS "Code") [📖](https://github.com/kentcdodds/dom-testing-library/commits?author=RoystonS "Documentation") [⚠️](https://github.com/kentcdodds/dom-testing-library/commits?author=RoystonS "Tests") |
diff --git a/src/__tests__/config.js b/src/__tests__/config.js
new file mode 100644
index 00000000..40123a53
--- /dev/null
+++ b/src/__tests__/config.js
@@ -0,0 +1,55 @@
+import {configure, getConfig} from '../config'
+
+describe('configuration API', () => {
+ let originalConfig
+ beforeEach(() => {
+ // Grab the existing configuration so we can restore
+ // it at the end of the test
+ configure(existingConfig => {
+ originalConfig = existingConfig
+ // Don't change the existing config
+ return {}
+ })
+ })
+ afterEach(() => {
+ configure(originalConfig)
+ })
+
+ beforeEach(() => {
+ configure({other: 123})
+ })
+
+ describe('getConfig', () => {
+ test('returns existing configuration', () => {
+ const conf = getConfig()
+ expect(conf.testIdAttribute).toEqual('data-testid')
+ })
+ })
+
+ describe('configure', () => {
+ test('merges a delta rather than replacing the whole config', () => {
+ const conf = getConfig()
+ expect(conf).toMatchObject({testIdAttribute: 'data-testid'})
+ })
+
+ test('overrides existing values', () => {
+ configure({testIdAttribute: 'new-id'})
+ const conf = getConfig()
+ expect(conf.testIdAttribute).toEqual('new-id')
+ })
+
+ test('passes existing config out to config function', () => {
+ // Create a new config key based on the value of an existing one
+ configure(existingConfig => ({
+ testIdAttribute: `${existingConfig.testIdAttribute}-derived`,
+ }))
+ const conf = getConfig()
+
+ // The new value should be there, and existing values should be
+ // untouched
+ expect(conf).toMatchObject({
+ testIdAttribute: 'data-testid-derived',
+ })
+ })
+ })
+})
diff --git a/src/__tests__/element-queries.js b/src/__tests__/element-queries.js
index 6f1a1f92..af5e7a10 100644
--- a/src/__tests__/element-queries.js
+++ b/src/__tests__/element-queries.js
@@ -1,4 +1,5 @@
import 'jest-dom/extend-expect'
+import {configure} from '../config'
import {render, renderIntoDocument} from './helpers/test-utils'
import document from './helpers/document'
@@ -258,16 +259,34 @@ test('query/get select by text with multiple options selected', () => {
expect(queryBySelectText('Alaska').id).toEqual('state-select')
})
-test('can get elements by data-testid attribute', () => {
- const {queryByTestId} = render(``)
- expect(queryByTestId('firstName')).toBeTruthy()
- expect(queryByTestId(/first/)).toBeTruthy()
- expect(queryByTestId(testid => testid === 'firstName')).toBeTruthy()
- // match should be exact, case-sensitive
- expect(queryByTestId('firstname')).not.toBeTruthy()
- expect(queryByTestId('first')).not.toBeTruthy()
- expect(queryByTestId('firstNamePlusMore')).not.toBeTruthy()
- expect(queryByTestId('first-name')).not.toBeTruthy()
+describe('query by test id', () => {
+ test('can get elements by test id', () => {
+ const {queryByTestId} = render(``)
+ expect(queryByTestId('firstName')).toBeTruthy()
+ expect(queryByTestId(/first/)).toBeTruthy()
+ expect(queryByTestId(testid => testid === 'firstName')).toBeTruthy()
+ // match should be exact, case-sensitive
+ expect(queryByTestId('firstname')).not.toBeTruthy()
+ expect(queryByTestId('first')).not.toBeTruthy()
+ expect(queryByTestId('firstNamePlusMore')).not.toBeTruthy()
+ expect(queryByTestId('first-name')).not.toBeTruthy()
+ })
+
+ test('can override test id attribute', () => {
+ const {queryByTestId} = render(``)
+
+ configure({testIdAttribute: 'data-my-test-id'})
+ expect(queryByTestId('theTestId')).toBeTruthy()
+
+ configure({testIdAttribute: 'something-else'})
+ expect(queryByTestId('theTestId')).toBeFalsy()
+ })
+
+ afterEach(() => {
+ // Restore the default test id attribute
+ // even if these tests failed
+ configure({testIdAttribute: 'data-testid'})
+ })
})
test('getAll* matchers return an array', () => {
diff --git a/src/config.js b/src/config.js
new file mode 100644
index 00000000..5be8381d
--- /dev/null
+++ b/src/config.js
@@ -0,0 +1,24 @@
+// It would be cleaner for this to live inside './queries', but
+// other parts of the code assume that all exports from
+// './queries' are query functions.
+let config = {
+ testIdAttribute: 'data-testid',
+}
+
+export function configure(newConfig) {
+ if (typeof newConfig === 'function') {
+ // Pass the existing config out to the provided function
+ // and accept a delta in return
+ newConfig = newConfig(config)
+ }
+
+ // Merge the incoming config delta
+ config = {
+ ...config,
+ ...newConfig,
+ }
+}
+
+export function getConfig() {
+ return config
+}
diff --git a/src/index.js b/src/index.js
index 1be99df6..5b9dbefa 100644
--- a/src/index.js
+++ b/src/index.js
@@ -12,6 +12,7 @@ export * from './events'
export * from './get-queries-for-element'
export * from './query-helpers'
export * from './pretty-dom'
+export {configure} from './config'
export {
// The original name of bindElementToQueries was weird
diff --git a/src/queries.js b/src/queries.js
index e75819fe..c0d738a3 100644
--- a/src/queries.js
+++ b/src/queries.js
@@ -6,6 +6,7 @@ import {
queryAllByAttribute,
queryByAttribute,
} from './query-helpers'
+import {getConfig} from './config'
// Here are the queries for the library.
// The queries here should only be things that are accessible to both users who are using a screen reader
@@ -148,10 +149,16 @@ function queryBySelectText(...args) {
return firstResultOrNull(queryAllBySelectText, ...args)
}
+function getTestIdAttribute() {
+ return getConfig().testIdAttribute
+}
+
const queryByPlaceholderText = queryByAttribute.bind(null, 'placeholder')
const queryAllByPlaceholderText = queryAllByAttribute.bind(null, 'placeholder')
-const queryByTestId = queryByAttribute.bind(null, 'data-testid')
-const queryAllByTestId = queryAllByAttribute.bind(null, 'data-testid')
+const queryByTestId = (...args) =>
+ queryByAttribute(getTestIdAttribute(), ...args)
+const queryAllByTestId = (...args) =>
+ queryAllByAttribute(getTestIdAttribute(), ...args)
const queryByValue = queryByAttribute.bind(null, 'value')
const queryAllByValue = queryAllByAttribute.bind(null, 'value')
const queryByRole = queryByAttribute.bind(null, 'role')
@@ -182,7 +189,7 @@ function getAllByTestId(container, id, ...rest) {
const els = queryAllByTestId(container, id, ...rest)
if (!els.length) {
throw getElementError(
- `Unable to find an element by: [data-testid="${id}"]`,
+ `Unable to find an element by: [${getTestIdAttribute()}="${id}"]`,
container,
)
}
diff --git a/typings/config.d.ts b/typings/config.d.ts
new file mode 100644
index 00000000..6bb7c538
--- /dev/null
+++ b/typings/config.d.ts
@@ -0,0 +1,9 @@
+export interface IConfig {
+ testIdAttribute: string
+}
+
+export interface IConfigFn {
+ (existingConfig: IConfig): Partial
+}
+
+export function configure(configDelta: Partial | IConfigFn): void
diff --git a/typings/index.d.ts b/typings/index.d.ts
index 86064792..e6cf904a 100644
--- a/typings/index.d.ts
+++ b/typings/index.d.ts
@@ -15,3 +15,4 @@ export * from './get-node-text'
export * from './events'
export * from './get-queries-for-element'
export * from './pretty-dom'
+export * from './config'