Skip to content

Commit 93b374e

Browse files
author
Kent C. Dodds
authored
Merge branch 'beta' into pr/remove-default-wait-callback
2 parents f629b4c + b3487d0 commit 93b374e

15 files changed

+116
-62
lines changed

.all-contributorsrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,15 @@
804804
"code",
805805
"test"
806806
]
807+
},
808+
{
809+
"login": "MichaelDeBoey",
810+
"name": "Michaël De Boey",
811+
"avatar_url": "https://avatars3.githubusercontent.com/u/6643991?v=4",
812+
"profile": "https://michaeldeboey.be",
813+
"contributions": [
814+
"code"
815+
]
807816
}
808817
],
809818
"repoHost": "https://github.com"

.gitattributes

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
* text=auto
2-
*.js text eol=lf
1+
* text=auto eol=lf

.gitignore

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
node_modules
22
coverage
33
dist
4-
.opt-in
5-
.opt-out
64
.DS_Store
7-
.eslintcache
8-
yarn-error.log
9-
.idea/
105

116
# these cause more harm than good
127
# when working with contributors

.prettierignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
package.json
21
node_modules
3-
dist
42
coverage
3+
dist

.prettierrc

Lines changed: 0 additions & 11 deletions
This file was deleted.

.prettierrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('kcd-scripts/prettier')

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ cache: npm
33
notifications:
44
email: false
55
node_js:
6-
- 10.14
6+
- 10.0.0
77
- 12
88
- node
99
install: npm install
@@ -13,7 +13,6 @@ script:
1313
branches:
1414
only:
1515
- master
16-
- next
1716
- beta
1817

1918
jobs:

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ Thanks goes to these people ([emoji key][emojis]):
235235
<td align="center"><a href="https://www.linkedin.com/in/seetdev/"><img src="https://avatars2.githubusercontent.com/u/35116035?v=4" width="100px;" alt=""/><br /><sub><b>seetdev</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/commits?author=seetdev" title="Tests">⚠️</a> <a href="https://github.com/testing-library/dom-testing-library/commits?author=seetdev" title="Code">💻</a></td>
236236
<td align="center"><a href="https://twitter.com/xgbuils"><img src="https://avatars2.githubusercontent.com/u/6483614?v=4" width="100px;" alt=""/><br /><sub><b>Xavier Garcia Buils</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/commits?author=xgbuils" title="Code">💻</a> <a href="https://github.com/testing-library/dom-testing-library/commits?author=xgbuils" title="Tests">⚠️</a></td>
237237
<td align="center"><a href="https://github.com/aw-davidson"><img src="https://avatars2.githubusercontent.com/u/32170938?v=4" width="100px;" alt=""/><br /><sub><b>aw-davidson</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/commits?author=aw-davidson" title="Code">💻</a> <a href="https://github.com/testing-library/dom-testing-library/commits?author=aw-davidson" title="Tests">⚠️</a></td>
238+
<td align="center"><a href="https://michaeldeboey.be"><img src="https://avatars3.githubusercontent.com/u/6643991?v=4" width="100px;" alt=""/><br /><sub><b>Michaël De Boey</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/commits?author=MichaelDeBoey" title="Code">💻</a></td>
238239
</tr>
239240
</table>
240241

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,19 @@
1717
"end-to-end",
1818
"e2e"
1919
],
20-
"author": "Kent C. Dodds <kent@doddsfamily.us> (https://kentcdodds.com/)",
20+
"author": "Kent C. Dodds <me@kentcdodds.com> (https://kentcdodds.com)",
2121
"license": "MIT",
2222
"engines": {
23-
"node": ">=8"
23+
"node": ">=10"
2424
},
2525
"scripts": {
2626
"build": "kcd-scripts build --ignore \"**/__tests__/**,**/__node_tests__/**,**/__mocks__/**\" && kcd-scripts build --bundle --no-clean",
2727
"lint": "kcd-scripts lint",
28+
"setup": "npm install && npm run validate -s",
2829
"test": "kcd-scripts test",
29-
"test:update": "npm test -- --updateSnapshot --coverage",
3030
"test:debug": "node --inspect-brk ./node_modules/.bin/jest --watch --runInBand",
31-
"validate": "kcd-scripts validate",
32-
"setup": "npm install && npm run validate -s"
31+
"test:update": "npm test -- --updateSnapshot --coverage",
32+
"validate": "kcd-scripts validate"
3333
},
3434
"husky": {
3535
"hooks": {
@@ -70,7 +70,7 @@
7070
],
7171
"repository": {
7272
"type": "git",
73-
"url": "https://github.com/testing-library/dom-testing-library.git"
73+
"url": "https://github.com/testing-library/dom-testing-library"
7474
},
7575
"bugs": {
7676
"url": "https://github.com/testing-library/dom-testing-library/issues"

src/__tests__/wait-for-element-to-be-removed.js

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,27 +45,35 @@ test('resolves on mutation if callback throws an error', async () => {
4545
await waitForElementToBeRemoved(() => getByTestId('div'), {timeout: 100})
4646
})
4747

48-
test('requires a function as the first parameter', () => {
48+
test('requires an element to exist first', () => {
4949
return expect(
50-
waitForElementToBeRemoved(),
50+
waitForElementToBeRemoved(null),
5151
).rejects.toThrowErrorMatchingInlineSnapshot(
52-
`"waitForElementToBeRemoved requires a callback as the first parameter"`,
52+
`"The element(s) given to waitForElementToBeRemoved are already removed. waitForElementToBeRemoved requires that the element(s) exist(s) before waiting for removal."`,
5353
)
5454
})
5555

56-
test('requires an element to exist first', () => {
56+
test('requires an unempty array of elements to exist first', () => {
57+
return expect(
58+
waitForElementToBeRemoved([]),
59+
).rejects.toThrowErrorMatchingInlineSnapshot(
60+
`"The element(s) given to waitForElementToBeRemoved are already removed. waitForElementToBeRemoved requires that the element(s) exist(s) before waiting for removal."`,
61+
)
62+
})
63+
64+
test('requires an element to exist first (function form)', () => {
5765
return expect(
5866
waitForElementToBeRemoved(() => null),
5967
).rejects.toThrowErrorMatchingInlineSnapshot(
60-
`"The callback function which was passed did not return an element or non-empty array of elements. waitForElementToBeRemoved requires that the element(s) exist(s) before waiting for removal."`,
68+
`"The element(s) given to waitForElementToBeRemoved are already removed. waitForElementToBeRemoved requires that the element(s) exist(s) before waiting for removal."`,
6169
)
6270
})
6371

64-
test('requires an unempty array of elements to exist first', () => {
72+
test('requires an unempty array of elements to exist first (function form)', () => {
6573
return expect(
6674
waitForElementToBeRemoved(() => []),
6775
).rejects.toThrowErrorMatchingInlineSnapshot(
68-
`"The callback function which was passed did not return an element or non-empty array of elements. waitForElementToBeRemoved requires that the element(s) exist(s) before waiting for removal."`,
76+
`"The element(s) given to waitForElementToBeRemoved are already removed. waitForElementToBeRemoved requires that the element(s) exist(s) before waiting for removal."`,
6977
)
7078
})
7179

@@ -132,3 +140,37 @@ test('rethrows non-testing-lib errors', () => {
132140
}),
133141
).rejects.toBe(error)
134142
})
143+
144+
test('accepts an element as an argument and waits for it to be removed from its top-most parent', async () => {
145+
const {queryByTestId} = renderIntoDocument(`
146+
<div data-testid="div"></div>
147+
`)
148+
const div = queryByTestId('div')
149+
setTimeout(() => {
150+
div.parentElement.removeChild(div)
151+
}, 20)
152+
153+
await waitForElementToBeRemoved(div, {timeout: 200})
154+
})
155+
156+
test('accepts an array of elements as an argument and waits for those elements to be removed from their top-most parent', async () => {
157+
const {queryAllByTestId} = renderIntoDocument(`
158+
<div>
159+
<div>
160+
<div data-testid="div"></div>
161+
</div>
162+
<div>
163+
<div data-testid="div"></div>
164+
</div>
165+
</div>
166+
`)
167+
const [div1, div2] = queryAllByTestId('div')
168+
setTimeout(() => {
169+
div1.parentElement.removeChild(div1)
170+
}, 20)
171+
172+
setTimeout(() => {
173+
div2.parentElement.removeChild(div2)
174+
}, 50)
175+
await waitForElementToBeRemoved([div1, div2], {timeout: 200})
176+
})

src/__tests__/wait.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,14 @@ test('can timeout after the given timeout time', async () => {
2727
).catch(e => e)
2828
expect(result).toBe(error)
2929
})
30+
31+
test('can timeout after the given timeout time', async () => {
32+
const error = new Error('throws every time')
33+
const result = await wait(
34+
() => {
35+
throw error
36+
},
37+
{timeout: 8, interval: 5},
38+
).catch(e => e)
39+
expect(result).toBe(error)
40+
})

src/queries/label-text.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,19 @@ function queryAllByLabelText(
6464
}
6565
if (label.getAttribute('id')) {
6666
// <label id="someId">text</label><input aria-labelledby="someId" />
67-
container
68-
.querySelectorAll(`[aria-labelledby~="${label.getAttribute('id')}"]`)
69-
.forEach(element => elementsForLabel.push(element))
67+
Array.from(
68+
container.querySelectorAll(
69+
`[aria-labelledby~="${label.getAttribute('id')}"]`,
70+
),
71+
).forEach(element => elementsForLabel.push(element))
7072
}
7173
if (label.childNodes.length) {
7274
// <label>text: <input /></label>
7375
const formControlSelector =
7476
'button, input, meter, output, progress, select, textarea'
75-
label
76-
.querySelectorAll(formControlSelector)
77-
.forEach(element => elementsForLabel.push(element))
77+
Array.from(
78+
label.querySelectorAll(formControlSelector),
79+
).forEach(element => elementsForLabel.push(element))
7880
}
7981
return matchedElements.concat(elementsForLabel)
8082
}, [])

src/query-helpers.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {fuzzyMatches, matches, makeNormalizer} from './matches'
2-
import {waitForElement} from './wait-for-element'
2+
import {wait} from './wait'
33
import {getConfig} from './config'
44

55
function getMultipleElementsFoundError(message, container) {
@@ -65,13 +65,10 @@ function makeGetAllQuery(allQuery, getMissingError) {
6565
}
6666

6767
// this accepts a getter query function and returns a function which calls
68-
// waitForElement and passing a function which invokes the getter.
68+
// wait and passing a function which invokes the getter.
6969
function makeFindQuery(getter) {
70-
return (container, text, options, waitForElementOptions) =>
71-
waitForElement(
72-
() => getter(container, text, options),
73-
waitForElementOptions,
74-
)
70+
return (container, text, options, waitOptions) =>
71+
wait(() => getter(container, text, options), waitOptions)
7572
}
7673

7774
function buildQueries(queryAllBy, getMultipleError, getMissingError) {

src/role-helpers.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,10 @@ function getRoles(container, {hidden = false} = {}) {
149149
function prettyRoles(dom, {hidden}) {
150150
const roles = getRoles(dom, {hidden})
151151

152-
return Object.entries(roles)
153-
.map(([role, elements]) => {
152+
// Object.entries is not supported in older browsers
153+
return Object.keys(roles)
154+
.map(role => {
155+
const elements = roles[role]
154156
const delimiterBar = '-'.repeat(50)
155157
const elementsString = elements
156158
.map(el => {

src/wait-for-element-to-be-removed.js

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,31 @@ import {wait} from './wait'
22

33
const isRemoved = result => !result || (Array.isArray(result) && !result.length)
44

5-
async function waitForElementToBeRemoved(callback, options) {
6-
if (!callback) {
7-
return Promise.reject(
8-
new Error(
9-
'waitForElementToBeRemoved requires a callback as the first parameter',
10-
),
5+
// Check if the element is not present.
6+
// As the name implies, waitForElementToBeRemoved should check `present` --> `removed`
7+
function initialCheck(elements) {
8+
if (isRemoved(elements)) {
9+
throw new Error(
10+
'The element(s) given to waitForElementToBeRemoved are already removed. waitForElementToBeRemoved requires that the element(s) exist(s) before waiting for removal.',
1111
)
1212
}
13+
}
1314

14-
// Check if the element is not present synchronously,
15-
// As the name implies, waitForElementToBeRemoved should check `present` --> `removed`
16-
if (isRemoved(callback())) {
17-
throw new Error(
18-
'The callback function which was passed did not return an element or non-empty array of elements. waitForElementToBeRemoved requires that the element(s) exist(s) before waiting for removal.',
19-
)
15+
async function waitForElementToBeRemoved(callback, options) {
16+
if (typeof callback !== 'function') {
17+
// await waitForElementToBeRemoved(getAllByText('Hello'))
18+
initialCheck(callback)
19+
const elements = Array.isArray(callback) ? callback : [callback]
20+
const getRemainingElements = elements.map(element => {
21+
let parent = element.parentElement
22+
while (parent.parentElement) parent = parent.parentElement
23+
return () => (parent.contains(element) ? element : null)
24+
})
25+
callback = () => getRemainingElements.map(c => c()).filter(Boolean)
2026
}
2127

28+
initialCheck(callback())
29+
2230
return wait(() => {
2331
let result
2432
try {

0 commit comments

Comments
 (0)