Skip to content

Commit 56cf2e4

Browse files
author
Ali Nasserzadeh
committed
2 parents 82edc36 + 5dd0737 commit 56cf2e4

File tree

11 files changed

+120
-20
lines changed

11 files changed

+120
-20
lines changed

.all-contributorsrc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,25 @@
870870
"code",
871871
"test"
872872
]
873+
},
874+
{
875+
"login": "kwboyd",
876+
"name": "Kate W. Boyd",
877+
"avatar_url": "https://avatars0.githubusercontent.com/u/13855750?v=4",
878+
"profile": "http://kwboyd.com",
879+
"contributions": [
880+
"code"
881+
]
882+
},
883+
{
884+
"login": "rahulchavan30",
885+
"name": "Rahul Suryakanth",
886+
"avatar_url": "https://avatars2.githubusercontent.com/u/5296464?v=4",
887+
"profile": "https://github.com/rahulchavan30",
888+
"contributions": [
889+
"code",
890+
"test"
891+
]
873892
}
874893
],
875894
"repoHost": "https://github.com"

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ Thanks goes to these people ([emoji key][emojis]):
244244
<td align="center"><a href="https://github.com/apalaniuk"><img src="https://avatars1.githubusercontent.com/u/17710124?v=4" width="100px;" alt=""/><br /><sub><b>Adam Palaniuk</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/commits?author=apalaniuk" title="Code">💻</a> <a href="https://github.com/testing-library/dom-testing-library/commits?author=apalaniuk" title="Tests">⚠️</a></td>
245245
<td align="center"><a href="https://github.com/Yama-Tomo"><img src="https://avatars0.githubusercontent.com/u/4970917?v=4" width="100px;" alt=""/><br /><sub><b>Yama-Tomo</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/commits?author=Yama-Tomo" title="Code">💻</a> <a href="https://github.com/testing-library/dom-testing-library/commits?author=Yama-Tomo" title="Tests">⚠️</a></td>
246246
<td align="center"><a href="https://github.com/airjp73"><img src="https://avatars2.githubusercontent.com/u/25882770?v=4" width="100px;" alt=""/><br /><sub><b>Aaron Pettengill</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/commits?author=airjp73" title="Code">💻</a> <a href="https://github.com/testing-library/dom-testing-library/commits?author=airjp73" title="Tests">⚠️</a></td>
247+
<td align="center"><a href="http://kwboyd.com"><img src="https://avatars0.githubusercontent.com/u/13855750?v=4" width="100px;" alt=""/><br /><sub><b>Kate W. Boyd</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/commits?author=kwboyd" title="Code">💻</a></td>
248+
<td align="center"><a href="https://github.com/rahulchavan30"><img src="https://avatars2.githubusercontent.com/u/5296464?v=4" width="100px;" alt=""/><br /><sub><b>Rahul Suryakanth</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/commits?author=rahulchavan30" title="Code">💻</a> <a href="https://github.com/testing-library/dom-testing-library/commits?author=rahulchavan30" title="Tests">⚠️</a></td>
247249
</tr>
248250
</table>
249251

package.json

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,27 +30,26 @@
3030
"test": "kcd-scripts test",
3131
"test:debug": "node --inspect-brk ./node_modules/.bin/jest --watch --runInBand",
3232
"test:update": "npm test -- --updateSnapshot --coverage",
33-
"validate": "npm run typecheck && kcd-scripts validate",
33+
"validate": "kcd-scripts validate",
3434
"typecheck": "dtslint ./types/"
3535
},
3636
"files": [
3737
"dist",
3838
"types"
3939
],
4040
"dependencies": {
41-
"@babel/runtime": "^7.9.2",
41+
"@babel/runtime": "^7.9.6",
4242
"aria-query": "^4.0.2",
43-
"dom-accessibility-api": "^0.4.2",
44-
"pretty-format": "^25.1.0"
43+
"dom-accessibility-api": "^0.4.3",
44+
"pretty-format": "^26.0.1"
4545
},
4646
"devDependencies": {
47-
"@testing-library/jest-dom": "^5.1.1",
4847
"dtslint": "^3.4.2",
48+
"@testing-library/jest-dom": "^5.5.0",
4949
"jest-in-case": "^1.0.2",
5050
"jest-serializer-ansi": "^1.0.3",
5151
"jest-watch-select-projects": "^2.0.0",
52-
"jsdom": "^16.2.1",
53-
"kcd-scripts": "^5.6.0"
52+
"kcd-scripts": "^6.0.0"
5453
},
5554
"eslintConfig": {
5655
"extends": "./node_modules/kcd-scripts/eslint.js",

src/__tests__/misc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import {render} from './helpers/test-utils'
21
import {queryByAttribute} from '..'
2+
import {render} from './helpers/test-utils'
33

44
// we used to use queryByAttribute internally, but we don't anymore. Some people
55
// use it as an undocumented part of the API, so we'll keep it around.

src/__tests__/role-helpers.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ test.each([
176176
['<div style="visibility: visible" />', false],
177177
['<div hidden />', true],
178178
['<div style="display: none;"/>', true],
179-
['<div style="visibility: hidden;"/>', false], // bug in jsdom < 15.2
179+
['<div style="visibility: hidden;"/>', true],
180180
['<div aria-hidden="true" />', true],
181181
])('shouldExcludeFromA11yTree for %s returns %p', (html, expected) => {
182182
const {container} = render(html)

src/__tests__/screen.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import {renderIntoDocument} from './helpers/test-utils'
21
import {screen} from '..'
2+
import {renderIntoDocument} from './helpers/test-utils'
33

44
beforeEach(() => {
55
jest.spyOn(console, 'log').mockImplementation(() => {})

src/__tests__/wait-for-element.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ test('waits for element to appear in the document', async () => {
2222
expect(console.warn.mock.calls).toMatchInlineSnapshot(`
2323
Array [
2424
Array [
25-
"\`waitForElement\` has been deprecated. Use a \`find*\` query (preferred: https://testing-library.com/docs/dom-testing-library/api-queries#findby) or use \`wait\` instead (it's the same API, so you can find/replace): https://testing-library.com/docs/dom-testing-library/api-async#waitfor",
25+
"\`waitForElement\` has been deprecated. Use a \`find*\` query (preferred: https://testing-library.com/docs/dom-testing-library/api-queries#findby) or use \`waitFor\` instead (it's the same API, so you can find/replace): https://testing-library.com/docs/dom-testing-library/api-async#waitfor",
2626
],
2727
]
2828
`)

src/__tests__/wait-for.js

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import {renderIntoDocument} from './helpers/test-utils'
21
import {waitFor} from '../'
2+
import {renderIntoDocument} from './helpers/test-utils'
33

44
test('waits callback to not throw an error', async () => {
55
const spy = jest.fn()
@@ -23,7 +23,7 @@ test('can timeout after the given timeout time', async () => {
2323
expect(result).toBe(error)
2424
})
2525

26-
test('uses generic error if there was no last error', async () => {
26+
test('if no error is thrown then throws a timeout error', async () => {
2727
const result = await waitFor(
2828
() => {
2929
// eslint-disable-next-line no-throw-literal
@@ -34,6 +34,58 @@ test('uses generic error if there was no last error', async () => {
3434
expect(result).toMatchInlineSnapshot(`[Error: Timed out in waitFor.]`)
3535
})
3636

37+
test('if showOriginalStackTrace on a timeout error then the stack trace does not include this file', async () => {
38+
const result = await waitFor(
39+
() => {
40+
// eslint-disable-next-line no-throw-literal
41+
throw undefined
42+
},
43+
{timeout: 8, interval: 5, showOriginalStackTrace: true},
44+
).catch(e => e)
45+
expect(result.stack).not.toMatch(__dirname)
46+
})
47+
48+
test('uses full stack error trace when showOriginalStackTrace present', async () => {
49+
const error = new Error('Throws the full stack trace')
50+
// even if the error is a TestingLibraryElementError
51+
error.name = 'TestingLibraryElementError'
52+
const originalStackTrace = error.stack
53+
const result = await waitFor(
54+
() => {
55+
throw error
56+
},
57+
{timeout: 8, interval: 5, showOriginalStackTrace: true},
58+
).catch(e => e)
59+
expect(result.stack).toBe(originalStackTrace)
60+
})
61+
62+
test('does not change the stack trace if the thrown error is not a TestingLibraryElementError', async () => {
63+
const error = new Error('Throws the full stack trace')
64+
const originalStackTrace = error.stack
65+
const result = await waitFor(
66+
() => {
67+
throw error
68+
},
69+
{timeout: 8, interval: 5},
70+
).catch(e => e)
71+
expect(result.stack).toBe(originalStackTrace)
72+
})
73+
74+
test('provides an improved stack trace if the thrown error is a TestingLibraryElementError', async () => {
75+
const error = new Error('Throws the full stack trace')
76+
error.name = 'TestingLibraryElementError'
77+
const originalStackTrace = error.stack
78+
const result = await waitFor(
79+
() => {
80+
throw error
81+
},
82+
{timeout: 8, interval: 5},
83+
).catch(e => e)
84+
// too hard to test that the stack trace is what we want it to be
85+
// so we'll just make sure that it's not the same as the origianl
86+
expect(result.stack).not.toBe(originalStackTrace)
87+
})
88+
3789
test('throws nice error if provided callback is not a function', () => {
3890
const {queryByTestId} = renderIntoDocument(`
3991
<div data-testid="div"></div>

src/config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ let config = {
1616
asyncWrapper: cb => cb(),
1717
// default value for the `hidden` option in `ByRole` queries
1818
defaultHidden: false,
19+
//showOriginalStackTrace flag to show the full error stack traces for async errors
20+
showOriginalStackTrace: false,
1921

2022
// called when getBy* queries fail. (message, container) => Error
2123
getElementError(message, container) {

src/wait-for-element.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ async function waitForElement(callback, options) {
99
if (!hasWarned) {
1010
hasWarned = true
1111
console.warn(
12-
`\`waitForElement\` has been deprecated. Use a \`find*\` query (preferred: https://testing-library.com/docs/dom-testing-library/api-queries#findby) or use \`wait\` instead (it's the same API, so you can find/replace): https://testing-library.com/docs/dom-testing-library/api-async#waitfor`,
12+
`\`waitForElement\` has been deprecated. Use a \`find*\` query (preferred: https://testing-library.com/docs/dom-testing-library/api-queries#findby) or use \`waitFor\` instead (it's the same API, so you can find/replace): https://testing-library.com/docs/dom-testing-library/api-async#waitfor`,
1313
)
1414
}
1515
if (!callback) {

src/wait-for.js

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,32 @@ import {
88
} from './helpers'
99
import {getConfig} from './config'
1010

11+
// This is so the stack trace the developer sees is one that's
12+
// closer to their code (because async stack traces are hard to follow).
13+
function copyStackTrace(target, source) {
14+
target.stack = source.stack.replace(source.message, target.message)
15+
}
16+
1117
function waitFor(
1218
callback,
1319
{
1420
container = getDocument(),
1521
timeout = getConfig().asyncUtilTimeout,
22+
showOriginalStackTrace = getConfig().showOriginalStackTrace,
23+
stackTraceError,
1624
interval = 50,
1725
mutationObserverOptions = {
1826
subtree: true,
1927
childList: true,
2028
attributes: true,
2129
characterData: true,
2230
},
23-
} = {},
31+
},
2432
) {
2533
if (typeof callback !== 'function') {
2634
throw new TypeError('Received `callback` arg must be a function')
2735
}
2836

29-
// created here so we get a nice stacktrace
30-
const timedOutError = new Error('Timed out in waitFor.')
3137
if (interval < 1) interval = 1
3238
return new Promise((resolve, reject) => {
3339
let lastError
@@ -63,13 +69,33 @@ function waitFor(
6369
}
6470

6571
function onTimeout() {
66-
onDone(lastError || timedOutError, null)
72+
let error
73+
if (lastError) {
74+
error = lastError
75+
if (
76+
!showOriginalStackTrace &&
77+
error.name === 'TestingLibraryElementError'
78+
) {
79+
copyStackTrace(error, stackTraceError)
80+
}
81+
} else {
82+
error = new Error('Timed out in waitFor.')
83+
if (!showOriginalStackTrace) {
84+
copyStackTrace(error, stackTraceError)
85+
}
86+
}
87+
onDone(error, null)
6788
}
6889
})
6990
}
7091

71-
function waitForWrapper(...args) {
72-
return getConfig().asyncWrapper(() => waitFor(...args))
92+
function waitForWrapper(callback, options) {
93+
// create the error here so its stack trace is as close to the
94+
// calling code as possible
95+
const stackTraceError = new Error('STACK_TRACE_MESSAGE')
96+
return getConfig().asyncWrapper(() =>
97+
waitFor(callback, {stackTraceError, ...options}),
98+
)
7399
}
74100

75101
let hasWarned = false

0 commit comments

Comments
 (0)