')
expect(() => getByLabelText('LucyRicardo'))
.toThrowErrorMatchingInlineSnapshot(`
-"Unable to find a label with the text of: LucyRicardo
+ "Unable to find a label with the text of: LucyRicardo
-
-
-
"
-`)
+
+
+
"
+ `)
expect(() => getByPlaceholderText('LucyRicardo'))
.toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an element with the placeholder text of: LucyRicardo
+ "Unable to find an element with the placeholder text of: LucyRicardo
-
-
-
"
-`)
+
+
+
"
+ `)
expect(() => getByText('LucyRicardo')).toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an element with the text: LucyRicardo. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
+ "Unable to find an element with the text: LucyRicardo. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
-
-
-
"
-`)
+
+
+
"
+ `)
expect(() => getByTestId('LucyRicardo')).toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an element by: [data-testid="LucyRicardo"]
+ "Unable to find an element by: [data-testid="LucyRicardo"]
-
-
-
"
-`)
+
+
+
"
+ `)
expect(() => getByAltText('LucyRicardo')).toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an element with the alt text: LucyRicardo
+ "Unable to find an element with the alt text: LucyRicardo
-
-
-
"
-`)
+
+
+
"
+ `)
expect(() => getByTitle('LucyRicardo')).toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an element with the title: LucyRicardo.
+ "Unable to find an element with the title: LucyRicardo.
-
-
-
"
-`)
+
+
+
"
+ `)
expect(() => getByDisplayValue('LucyRicardo'))
.toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an element with the display value: LucyRicardo.
+ "Unable to find an element with the display value: LucyRicardo.
-
-
-
"
-`)
+
+
+
"
+ `)
expect(() => getByRole('LucyRicardo')).toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an accessible element with the role "LucyRicardo"
+ "Unable to find an accessible element with the role "LucyRicardo"
-There are no accessible roles. But there might be some inaccessible roles. If you wish to access them, then set the \`hidden\` option to \`true\`. Learn more about this here: https://testing-library.com/docs/dom-testing-library/api-queries#byrole
+ There are no accessible roles. But there might be some inaccessible roles. If you wish to access them, then set the \`hidden\` option to \`true\`. Learn more about this here: https://testing-library.com/docs/dom-testing-library/api-queries#byrole
-
-
-
"
-`)
+
+
+
"
+ `)
})
test('can get elements by matching their text content', () => {
@@ -352,14 +353,14 @@ test('label with no form control', () => {
const {getByLabelText, queryByLabelText} = render(``)
expect(queryByLabelText(/alone/)).toBeNull()
expect(() => getByLabelText(/alone/)).toThrowErrorMatchingInlineSnapshot(`
-"Found a label with the text of: /alone/, however no form control was found associated to that label. Make sure you're using the "for" attribute or "aria-labelledby" attribute correctly.
+ "Found a label with the text of: /alone/, however no form control was found associated to that label. Make sure you're using the "for" attribute or "aria-labelledby" attribute correctly.
-
-
-
"
-`)
+
+
+
"
+ `)
})
test('label with "for" attribute but no form control and fuzzy matcher', () => {
@@ -369,16 +370,16 @@ test('label with "for" attribute but no form control and fuzzy matcher', () => {
expect(queryByLabelText('alone', {exact: false})).toBeNull()
expect(() => getByLabelText('alone', {exact: false}))
.toThrowErrorMatchingInlineSnapshot(`
-"Found a label with the text of: alone, however no form control was found associated to that label. Make sure you're using the "for" attribute or "aria-labelledby" attribute correctly.
-
-
-
-
"
-`)
+ "Found a label with the text of: alone, however no form control was found associated to that label. Make sure you're using the "for" attribute or "aria-labelledby" attribute correctly.
+
+
+
+
"
+ `)
})
test('label with children with no form control', () => {
@@ -391,32 +392,32 @@ test('label with children with no form control', () => {
expect(queryByLabelText(/alone/, {selector: 'input'})).toBeNull()
expect(() => getByLabelText(/alone/, {selector: 'input'}))
.toThrowErrorMatchingInlineSnapshot(`
-"Found a label with the text of: /alone/, however no form control was found associated to that label. Make sure you're using the "for" attribute or "aria-labelledby" attribute correctly.
+ "Found a label with the text of: /alone/, however no form control was found associated to that label. Make sure you're using the "for" attribute or "aria-labelledby" attribute correctly.
-
-
-
-
-
"
-`)
+
+
+
+
+
"
+ `)
})
test('label with non-labellable element', () => {
@@ -431,35 +432,35 @@ test('label with non-labellable element', () => {
expect(queryByLabelText(/Label/)).toBeNull()
expect(() => getByLabelText(/Label/)).toThrowErrorMatchingInlineSnapshot(`
-"Found a label with the text of: /Label/, however the element associated with this label () is non-labellable [https://html.spec.whatwg.org/multipage/forms.html#category-label]. If you really need to label a , you can use aria-label or aria-labelledby instead.
+ "Found a label with the text of: /Label/, however the element associated with this label () is non-labellable [https://html.spec.whatwg.org/multipage/forms.html#category-label]. If you really need to label a , you can use aria-label or aria-labelledby instead.
-
-
-
-
-
-
-
-
-
-
+
- Hello
-
-
-
-
-
-
-
-
"
-`)
+
+
+
+
+
+
+
+
+
+ Hello
+
+
+
+
+
+
+
+
"
+ `)
})
test('multiple labels with non-labellable elements', () => {
@@ -478,65 +479,65 @@ test('multiple labels with non-labellable elements', () => {
expect(queryAllByLabelText(/Label/)).toEqual([])
expect(() => getAllByLabelText(/Label/)).toThrowErrorMatchingInlineSnapshot(`
-"Found a label with the text of: /Label/, however the element associated with this label () is non-labellable [https://html.spec.whatwg.org/multipage/forms.html#category-label]. If you really need to label a , you can use aria-label or aria-labelledby instead.
+ "Found a label with the text of: /Label/, however the element associated with this label () is non-labellable [https://html.spec.whatwg.org/multipage/forms.html#category-label]. If you really need to label a , you can use aria-label or aria-labelledby instead.
-Found a label with the text of: /Label/, however the element associated with this label () is non-labellable [https://html.spec.whatwg.org/multipage/forms.html#category-label]. If you really need to label a , you can use aria-label or aria-labelledby instead.
+ Found a label with the text of: /Label/, however the element associated with this label () is non-labellable [https://html.spec.whatwg.org/multipage/forms.html#category-label]. If you really need to label a , you can use aria-label or aria-labelledby instead.
-
-
-
-
-
-
-
-
-
-
+
- Hello
-
-
-
-
-
-
-
-
- World
-
-
-
-
-
-
-
-
"
-`)
+
+
+
+
+
+
+
+
+ Hello
+
+
+
+
+
+
+
+
+
+ World
+
+
+
+
+
+
+
+
"
+ `)
})
test('totally empty label', () => {
const {getByLabelText, queryByLabelText} = render(``)
expect(queryByLabelText('')).toBeNull()
expect(() => getByLabelText('')).toThrowErrorMatchingInlineSnapshot(`
-"Found a label with the text of: , however no form control was found associated to that label. Make sure you're using the "for" attribute or "aria-labelledby" attribute correctly.
+ "Found a label with the text of: , however no form control was found associated to that label. Make sure you're using the "for" attribute or "aria-labelledby" attribute correctly.
-
-
-
"
-`)
+
+
+
"
+ `)
})
test('getByLabelText with aria-label', () => {
@@ -1031,7 +1032,7 @@ test('the debug helper prints the dom state here', () => {
const {getByTestId} = renderIntoDocument(Hello)
process.env.DEBUG_PRINT_LIMIT = 5 // user should see `...`
expect(() => expect(getByTestId('not present')).toBeTruthy()).toThrowError(
- /\.\.\.$/,
+ /\.\.\./,
)
const {getByLabelText} = renderIntoDocument(Hello)
@@ -1219,14 +1220,14 @@ test('return a proper error message when no label is found and there is an aria-
expect(() => getByLabelText('LucyRicardo'))
.toThrowErrorMatchingInlineSnapshot(`
-"Unable to find a label with the text of: LucyRicardo
-
-
-
-
"
-`)
+ "Unable to find a label with the text of: LucyRicardo
+
+
+
+
"
+ `)
})
// https://github.com/testing-library/dom-testing-library/issues/723
diff --git a/src/__tests__/get-by-errors.js b/src/__tests__/get-by-errors.js
index c7e8cadf0..936cc51dd 100644
--- a/src/__tests__/get-by-errors.js
+++ b/src/__tests__/get-by-errors.js
@@ -97,6 +97,33 @@ cases(
},
)
+test.each([['getByText'], ['getByLabelText']])(
+ '%s query will print the playground link when enabled in the config',
+ query => {
+ configure({printPlaygroundLink: true})
+ document.body.innerHTML = '
Hello
'
+ expect(() => screen[query]('TEST QUERY')).toThrow(/playground/i)
+ },
+)
+
+test.each([['getByText'], ['getByLabelText']])(
+ '%s query will NOT print the playground link when disabled in the config',
+ query => {
+ configure({printPlaygroundLink: false})
+ document.body.innerHTML = '
Hello
'
+ expect(() => screen[query]('TEST QUERY')).not.toThrowError(/playground/i)
+ },
+)
+
+test.each([['getByText'], ['getByLabelText']])(
+ '%s query will NOT print the playground link when element has no children',
+ query => {
+ configure({printPlaygroundLink: true})
+ document.body.innerHTML = ''
+ expect(() => screen[query]('TEST QUERY')).not.toThrowError(/playground/i)
+ },
+)
+
describe('*ByDisplayValue queries throw an error when there are multiple elements returned', () => {
test('getByDisplayValue', () => {
const {getByDisplayValue} = render(
diff --git a/src/__tests__/role.js b/src/__tests__/role.js
index 109d2e627..be545ac56 100644
--- a/src/__tests__/role.js
+++ b/src/__tests__/role.js
@@ -2,98 +2,102 @@ import {configure, getConfig} from '../config'
import {getQueriesForElement} from '../get-queries-for-element'
import {render, renderIntoDocument} from './helpers/test-utils'
+beforeAll(() => {
+ configure({printPlaygroundLink: false})
+})
+
test('by default logs accessible roles when it fails', () => {
const {getByRole} = render(`
Hi
`)
expect(() => getByRole('article')).toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an accessible element with the role "article"
+ "Unable to find an accessible element with the role "article"
-Here are the accessible roles:
+ Here are the accessible roles:
- heading:
+ heading:
- Name "Hi":
-
+ Name "Hi":
+
- --------------------------------------------------
+ --------------------------------------------------
-
-
- Hi
-
-
"
-`)
+
+
+ Hi
+
+
"
+ `)
})
test('when hidden: true logs available roles when it fails', () => {
const {getByRole} = render(`
Hi
`)
expect(() => getByRole('article', {hidden: true}))
.toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an element with the role "article"
+ "Unable to find an element with the role "article"
-Here are the available roles:
+ Here are the available roles:
- heading:
+ heading:
- Name "Hi":
-
+ Name "Hi":
+
- --------------------------------------------------
+ --------------------------------------------------
-
-
-
- Hi
-
-
-
"
-`)
+
+
+
+ Hi
+
+
+
"
+ `)
})
test('logs error when there are no accessible roles', () => {
const {getByRole} = render('')
expect(() => getByRole('article')).toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an accessible element with the role "article"
+ "Unable to find an accessible element with the role "article"
-There are no accessible roles. But there might be some inaccessible roles. If you wish to access them, then set the \`hidden\` option to \`true\`. Learn more about this here: https://testing-library.com/docs/dom-testing-library/api-queries#byrole
+ There are no accessible roles. But there might be some inaccessible roles. If you wish to access them, then set the \`hidden\` option to \`true\`. Learn more about this here: https://testing-library.com/docs/dom-testing-library/api-queries#byrole
-
-
-
"
-`)
+
+
+
"
+ `)
})
test('logs a different error if inaccessible roles should be included', () => {
const {getByRole} = render('')
expect(() => getByRole('article', {hidden: true}))
.toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an element with the role "article"
+ "Unable to find an element with the role "article"
-There are no available roles.
+ There are no available roles.
-
-
-
"
-`)
+
+
+
"
+ `)
})
test('by default excludes elements that have the html hidden attribute or any of their parents', () => {
const {getByRole} = render('
')
expect(() => getByRole('list')).toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an accessible element with the role "list"
-
-There are no accessible roles. But there might be some inaccessible roles. If you wish to access them, then set the \`hidden\` option to \`true\`. Learn more about this here: https://testing-library.com/docs/dom-testing-library/api-queries#byrole
-
-
-
-
-
-
"
-`)
+ "Unable to find an accessible element with the role "list"
+
+ There are no accessible roles. But there might be some inaccessible roles. If you wish to access them, then set the \`hidden\` option to \`true\`. Learn more about this here: https://testing-library.com/docs/dom-testing-library/api-queries#byrole
+
+
+
+
+
+
"
+ `)
})
test('by default excludes elements which have display: none or any of their parents', () => {
@@ -102,20 +106,20 @@ test('by default excludes elements which have display: none or any of their pare
)
expect(() => getByRole('list')).toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an accessible element with the role "list"
-
-There are no accessible roles. But there might be some inaccessible roles. If you wish to access them, then set the \`hidden\` option to \`true\`. Learn more about this here: https://testing-library.com/docs/dom-testing-library/api-queries#byrole
-
-
-
-
-
-
"
-`)
+ "Unable to find an accessible element with the role "list"
+
+ There are no accessible roles. But there might be some inaccessible roles. If you wish to access them, then set the \`hidden\` option to \`true\`. Learn more about this here: https://testing-library.com/docs/dom-testing-library/api-queries#byrole
+
+
+
+
+
+
"
+ `)
})
test('by default excludes elements which have visibility hidden', () => {
@@ -124,18 +128,18 @@ test('by default excludes elements which have visibility hidden', () => {
const {getByRole} = render('
')
expect(() => getByRole('list')).toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an accessible element with the role "list"
-
-There are no accessible roles. But there might be some inaccessible roles. If you wish to access them, then set the \`hidden\` option to \`true\`. Learn more about this here: https://testing-library.com/docs/dom-testing-library/api-queries#byrole
-
-
-
-
-
-
"
-`)
+ "Unable to find an accessible element with the role "list"
+
+ There are no accessible roles. But there might be some inaccessible roles. If you wish to access them, then set the \`hidden\` option to \`true\`. Learn more about this here: https://testing-library.com/docs/dom-testing-library/api-queries#byrole
+
+
+
+
+
+
"
+ `)
})
test('by default excludes elements which have aria-hidden="true" or any of their parents', () => {
@@ -148,20 +152,20 @@ test('by default excludes elements which have aria-hidden="true" or any of their
)
expect(() => getByRole('list')).toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an accessible element with the role "list"
-
-There are no accessible roles. But there might be some inaccessible roles. If you wish to access them, then set the \`hidden\` option to \`true\`. Learn more about this here: https://testing-library.com/docs/dom-testing-library/api-queries#byrole
-
-
-
-
-
-
"
-`)
+ "Unable to find an accessible element with the role "list"
+
+ There are no accessible roles. But there might be some inaccessible roles. If you wish to access them, then set the \`hidden\` option to \`true\`. Learn more about this here: https://testing-library.com/docs/dom-testing-library/api-queries#byrole
+
+
+
+
+
+
"
+ `)
})
test('considers the computed visibility style not the parent', () => {
@@ -230,26 +234,26 @@ test('accessible name comparison is case sensitive', () => {
expect(() => getByRole('heading', {name: 'something that does not match'}))
.toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an accessible element with the role "heading" and name "something that does not match"
+ "Unable to find an accessible element with the role "heading" and name "something that does not match"
-Here are the accessible roles:
+ Here are the accessible roles:
- heading:
+ heading:
- Name "Sign up":
-
+ Name "Sign up":
+
- --------------------------------------------------
+ --------------------------------------------------
-
-
- Sign
-
- up
-
-
-
"
-`)
+
+
+ Sign
+
+ up
+
+
+
"
+ `)
})
test('accessible name filter implements TextMatch', () => {
@@ -276,49 +280,49 @@ test('TextMatch serialization in error message', () => {
expect(() => getByRole('heading', {name: /something that does not match/}))
.toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an accessible element with the role "heading" and name \`/something that does not match/\`
+ "Unable to find an accessible element with the role "heading" and name \`/something that does not match/\`
-Here are the accessible roles:
+ Here are the accessible roles:
- heading:
+ heading:
- Name "Sign up":
-
+ Name "Sign up":
+
- --------------------------------------------------
+ --------------------------------------------------
-
-
- Sign
-
- up
-
-
-
"
-`)
+
+
+ Sign
+
+ up
+
+
+
"
+ `)
expect(() => getByRole('heading', {name: () => false}))
.toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an accessible element with the role "heading" and name \`() => false\`
+ "Unable to find an accessible element with the role "heading" and name \`() => false\`
-Here are the accessible roles:
+ Here are the accessible roles:
- heading:
+ heading:
- Name "Sign up":
-
+ Name "Sign up":
+
- --------------------------------------------------
+ --------------------------------------------------
-
-
- Sign
-
- up
-
-
-
"
-`)
+
+
+ Sign
+
+ up
+
+
+
"
+ `)
})
test('does not include the container in the queryable roles', () => {
@@ -326,21 +330,21 @@ test('does not include the container in the queryable roles', () => {
container: document.createElement('ul'),
})
expect(() => getByRole('list')).toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an accessible element with the role "list"
+ "Unable to find an accessible element with the role "list"
-Here are the accessible roles:
+ Here are the accessible roles:
- listitem:
+ listitem:
- Name "":
-
+ Name "":
+
- --------------------------------------------------
+ --------------------------------------------------
-
-
-
"
-`)
+
+
+
"
+ `)
})
test('has no useful error message in findBy', async () => {
@@ -357,27 +361,27 @@ test('explicit role is most specific', () => {
)
expect(() => getByRole('button')).toThrowErrorMatchingInlineSnapshot(`
-"Unable to find an accessible element with the role "button"
+ "Unable to find an accessible element with the role "button"
-Here are the accessible roles:
+ Here are the accessible roles:
- tab:
+ tab:
- Name "my-tab":
-
+ Name "my-tab":
+
- --------------------------------------------------
+ --------------------------------------------------
-
-
-"
-`)
+
+
+ "
+ `)
})
test('accessible regex name in error message for multiple found', () => {
@@ -390,36 +394,36 @@ test('accessible regex name in error message for multiple found', () => {
expect(() => getByRole('button', {name: /value/i}))
.toThrowErrorMatchingInlineSnapshot(`
-"Found multiple elements with the role "button" and name \`/value/i\`
-
-Here are the matching elements:
-
-
-
-
-
-
-
-(If this is intentional, then use the \`*AllBy*\` variant of the query (like \`queryAllByText\`, \`getAllByText\`, or \`findAllByText\`)).
-
-
-
-
-
-
"
-`)
+ "Found multiple elements with the role "button" and name \`/value/i\`
+
+ Here are the matching elements:
+
+
+
+
+
+
+
+ (If this is intentional, then use the \`*AllBy*\` variant of the query (like \`queryAllByText\`, \`getAllByText\`, or \`findAllByText\`)).
+
+
+
+
+
+
"
+ `)
})
test('accessible string name in error message for multiple found', () => {
@@ -432,36 +436,36 @@ test('accessible string name in error message for multiple found', () => {
expect(() => getByRole('button', {name: 'Submit'}))
.toThrowErrorMatchingInlineSnapshot(`
-"Found multiple elements with the role "button" and name "Submit"
-
-Here are the matching elements:
-
-
-
-
-
-
-
-(If this is intentional, then use the \`*AllBy*\` variant of the query (like \`queryAllByText\`, \`getAllByText\`, or \`findAllByText\`)).
-
-
-
-
-
-
"
-`)
+ "Found multiple elements with the role "button" and name "Submit"
+
+ Here are the matching elements:
+
+
+
+
+
+
+
+ (If this is intentional, then use the \`*AllBy*\` variant of the query (like \`queryAllByText\`, \`getAllByText\`, or \`findAllByText\`)).
+
+
+
+
+
+
"
+ `)
})
test('matching elements in error for multiple found', () => {
@@ -475,35 +479,35 @@ test('matching elements in error for multiple found', () => {
expect(() => getByRole('button', {name: /value/i}))
.toThrowErrorMatchingInlineSnapshot(`
-"Found multiple elements with the role "button" and name \`/value/i\`
-
-Here are the matching elements:
-
-
-
-
-
-(If this is intentional, then use the \`*AllBy*\` variant of the query (like \`queryAllByText\`, \`getAllByText\`, or \`findAllByText\`)).
-
-
-
-
-
- Wrong role
-
-
-
"
-`)
+ "Found multiple elements with the role "button" and name \`/value/i\`
+
+ Here are the matching elements:
+
+
+
+
+
+ (If this is intentional, then use the \`*AllBy*\` variant of the query (like \`queryAllByText\`, \`getAllByText\`, or \`findAllByText\`)).
+
+
+
+
+
+ Wrong role
+
+
+
"
+ `)
})
describe('configuration', () => {
diff --git a/src/__tests__/suggestions.js b/src/__tests__/suggestions.js
index 3bb5364d9..3de58869e 100644
--- a/src/__tests__/suggestions.js
+++ b/src/__tests__/suggestions.js
@@ -3,7 +3,7 @@ import {screen, getSuggestedQuery} from '..'
import {renderIntoDocument, render} from './helpers/test-utils'
beforeAll(() => {
- configure({throwSuggestions: true})
+ configure({throwSuggestions: true, printPlaygroundLink: false})
})
afterEach(() => {
@@ -107,18 +107,18 @@ test('should suggest getByRole when used with getBy', () => {
renderIntoDocument(``)
expect(() => screen.getByTestId('foo')).toThrowErrorMatchingInlineSnapshot(`
-"A better query is available, try this:
-getByRole('button', { name: /submit/i })
+ "A better query is available, try this:
+ getByRole('button', { name: /submit/i })
-
-
-"
-`)
+
+
+ "
+ `)
})
test('should suggest getAllByRole when used with getAllByTestId', () => {
@@ -128,27 +128,27 @@ test('should suggest getAllByRole when used with getAllByTestId', () => {
expect(() => screen.getAllByTestId('foo'))
.toThrowErrorMatchingInlineSnapshot(`
-"A better query is available, try this:
-getAllByRole('button', { name: /submit/i })
-
-
-
-
-
-
-
-
-
-"
-`)
+ "A better query is available, try this:
+ getAllByRole('button', { name: /submit/i })
+
+
+
+
+
+
+
+
+
+ "
+ `)
})
test('should suggest findByRole when used with findByTestId', async () => {
renderIntoDocument(`
diff --git a/src/__tests__/wait-for.js b/src/__tests__/wait-for.js
index 7235f6a56..e099ca964 100644
--- a/src/__tests__/wait-for.js
+++ b/src/__tests__/wait-for.js
@@ -11,6 +11,10 @@ function deferred() {
return {promise, resolve, reject}
}
+beforeAll(() => {
+ configure({printPlaygroundLink: false})
+})
+
test('waits callback to not throw an error', async () => {
const spy = jest.fn()
// we are using random timeout here to simulate a real-time example
diff --git a/src/config.ts b/src/config.ts
index d37e46d01..201dfc4d3 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -1,4 +1,5 @@
import {Config, ConfigFn} from '../types/config'
+import {getPlaygroundUrl} from './playground-helper'
import {prettyDOM} from './pretty-dom'
type Callback = () => T
@@ -31,14 +32,30 @@ let config: InternalConfig = {
// called when getBy* queries fail. (message, container) => Error
getElementError(message, container) {
+ const playgroundUrl =
+ message &&
+ getConfig().printPlaygroundLink &&
+ getPlaygroundUrl(container, false)
+
const error = new Error(
- [message, prettyDOM(container)].filter(Boolean).join('\n\n'),
+ [
+ message,
+ prettyDOM(container),
+ playgroundUrl &&
+ `Open this DOM in the Testing-Library Playground:\n${playgroundUrl}`,
+ ]
+ .filter(Boolean)
+ .join('\n\n'),
)
+
error.name = 'TestingLibraryElementError'
return error
},
_disableExpensiveErrorDiagnostics: false,
computedStyleSupportsPseudoElements: false,
+
+ // print a link to the playground when queries fail
+ printPlaygroundLink: true,
}
export const DEFAULT_IGNORE_TAGS = 'script, style'
diff --git a/src/playground-helper.ts b/src/playground-helper.ts
new file mode 100644
index 000000000..f932a29b3
--- /dev/null
+++ b/src/playground-helper.ts
@@ -0,0 +1,31 @@
+import {compressToEncodedURIComponent} from 'lz-string'
+
+function unindent(value: string) {
+ // remove white spaces first, to save a few bytes.
+ // testing-playground will reformat on load any ways.
+ return value.replace(/[ \t]*[\n][ \t]*/g, '\n')
+}
+
+function encode(value: string) {
+ return compressToEncodedURIComponent(unindent(value))
+}
+
+function getPlaygroundUrl(element: Element | null, logErrors = true) {
+ if (!element || !('innerHTML' in element)) {
+ if (logErrors) {
+ console.log(`The element you're providing isn't a valid DOM element.`)
+ }
+ return null
+ }
+
+ if (!element.innerHTML) {
+ if (logErrors) {
+ console.log(`The provided element doesn't have any children.`)
+ }
+ return null
+ }
+
+ return `https://testing-playground.com/#markup=${encode(element.innerHTML)}`
+}
+
+export {getPlaygroundUrl}
diff --git a/src/screen.js b/src/screen.js
index 5cbdd2ded..3553e159c 100644
--- a/src/screen.js
+++ b/src/screen.js
@@ -1,40 +1,19 @@
-import {compressToEncodedURIComponent} from 'lz-string'
+import {getPlaygroundUrl} from './playground-helper'
import * as queries from './queries'
import {getQueriesForElement} from './get-queries-for-element'
import {logDOM} from './pretty-dom'
import {getDocument} from './helpers'
-function unindent(string) {
- // remove white spaces first, to save a few bytes.
- // testing-playground will reformat on load any ways.
- return string.replace(/[ \t]*[\n][ \t]*/g, '\n')
-}
-
-function encode(value) {
- return compressToEncodedURIComponent(unindent(value))
-}
-
-function getPlaygroundUrl(markup) {
- return `https://testing-playground.com/#markup=${encode(markup)}`
-}
-
const debug = (element, maxLength, options) =>
Array.isArray(element)
? element.forEach(el => logDOM(el, maxLength, options))
: logDOM(element, maxLength, options)
const logTestingPlaygroundURL = (element = getDocument().body) => {
- if (!element || !('innerHTML' in element)) {
- console.log(`The element you're providing isn't a valid DOM element.`)
- return
- }
- if (!element.innerHTML) {
- console.log(`The provided element doesn't have any children.`)
- return
+ const url = getPlaygroundUrl(element)
+ if (url) {
+ console.log(`Open this URL in your browser\n\n${url}`)
}
- console.log(
- `Open this URL in your browser\n\n${getPlaygroundUrl(element.innerHTML)}`,
- )
}
const initialValue = {debug, logTestingPlaygroundURL}
diff --git a/types/config.d.ts b/types/config.d.ts
index c8e239b65..f85362cff 100644
--- a/types/config.d.ts
+++ b/types/config.d.ts
@@ -10,6 +10,7 @@ export interface Config {
showOriginalStackTrace: boolean
throwSuggestions: boolean
getElementError: (message: string | null, container: Element) => Error
+ printPlaygroundLink: boolean
}
export interface ConfigFn {