Skip to content

Commit 7be9a8b

Browse files
sheerunKent C. Dodds
authored and
Kent C. Dodds
committed
feat: support for running in node environment (testing-library#125)
* Allow for running in node environment * use jest projects * remove unecessary code and add coverage checking * fix coverage * time is funny
1 parent 6ed5eef commit 7be9a8b

19 files changed

+186
-113
lines changed

.size-snapshot.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"dist/dom-testing-library.umd.js": {
3-
"bundled": 122519,
4-
"minified": 52052,
5-
"gzipped": 15632
3+
"bundled": 146890,
4+
"minified": 53947,
5+
"gzipped": 15849
66
}
77
}

jest.config.js

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
1-
const jestConfig = require('kcd-scripts/jest')
1+
const baseConfig = require('kcd-scripts/jest')
22

3-
module.exports = Object.assign(jestConfig, {
4-
testEnvironment: 'jest-environment-jsdom',
5-
})
3+
module.exports = {
4+
collectCoverageFrom: baseConfig.collectCoverageFrom,
5+
coverageThreshold: baseConfig.coverageThreshold,
6+
projects: [
7+
{
8+
...baseConfig,
9+
displayName: 'jsdom',
10+
testEnvironment: 'jest-environment-jsdom',
11+
},
12+
{
13+
...baseConfig,
14+
displayName: 'node',
15+
testEnvironment: 'jest-environment-node',
16+
},
17+
],
18+
// this is for eslint
19+
modulePaths: baseConfig.modulePaths,
20+
}

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,15 @@
3838
"typings"
3939
],
4040
"dependencies": {
41-
"mutationobserver-shim": "^0.3.2",
41+
"@sheerun/mutationobserver-shim": "^0.3.2",
4242
"pretty-format": "^23.6.0",
4343
"wait-for-expect": "^1.0.0"
4444
},
4545
"devDependencies": {
4646
"dtslint": "^0.3.0",
47-
"jest-dom": "^1.7.0",
47+
"jest-dom": "^2.0.4",
4848
"jest-in-case": "^1.0.2",
49+
"jsdom": "^12.2.0",
4950
"kcd-scripts": "^0.41.0",
5051
"microbundle": "^0.4.4"
5152
},

src/__tests__/__snapshots__/wait-for-element.js.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,4 @@ exports[`it waits for the callback to return a value and only reacts to DOM muta
7979
/>
8080
</div>
8181
`;
82+

src/__tests__/element-queries.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import 'jest-dom/extend-expect'
22
import {render} from './helpers/test-utils'
3+
import document from './helpers/document'
34

45
beforeEach(() => {
5-
window.Cypress = null
6+
document.defaultView.Cypress = null
67
})
78

89
test('query can return null', () => {
@@ -169,9 +170,7 @@ test('get element by its alt text', () => {
169170
<img alt="finding nemo poster" src="/finding-nemo.png" />
170171
</div>,
171172
`)
172-
expect(getByAltText(/fin.*nem.*poster$/i).src).toBe(
173-
'http://localhost/finding-nemo.png',
174-
)
173+
expect(getByAltText(/fin.*nem.*poster$/i).src).toContain('/finding-nemo.png')
175174
})
176175

177176
test('query/get element by its title', () => {
@@ -510,7 +509,7 @@ test('test the debug helper prints the dom state here', () => {
510509
})
511510

512511
test('get throws a useful error message without DOM in Cypress', () => {
513-
window.Cypress = {}
512+
document.defaultView.Cypress = {}
514513
const {
515514
getByLabelText,
516515
getBySelectText,

src/__tests__/events.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {fireEvent} from '..'
2+
import document from './helpers/document'
23

34
const eventTypes = [
45
{
@@ -171,7 +172,7 @@ test('assigning a value to a target that cannot have a value throws an error', (
171172

172173
test('assigning the files property on an input', () => {
173174
const node = document.createElement('input')
174-
const file = new File(['(⌐□_□)'], 'chucknorris.png', {
175+
const file = new document.defaultView.File(['(⌐□_□)'], 'chucknorris.png', {
175176
type: 'image/png',
176177
})
177178
fireEvent.change(node, {target: {files: [file]}})

src/__tests__/example.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import {getByLabelText, getByText, getByTestId, queryByTestId, wait} from '../'
33
// adds special assertions like toHaveTextContent
44
import 'jest-dom/extend-expect'
5+
import document from './helpers/document'
56

67
function getExampleDOM() {
78
// This is just a raw example of setting up some DOM

src/__tests__/get-queries-for-element.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {getQueriesForElement} from '../get-queries-for-element'
22
import {queries} from '..'
3+
import document from './helpers/document'
34

45
test('uses default queries', () => {
56
const container = document.createElement('div')

src/__tests__/helpers/document.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
let testWindow = typeof window === 'undefined' ? undefined : window
2+
3+
if (typeof window === 'undefined') {
4+
const {JSDOM} = require('jsdom')
5+
const dom = new JSDOM()
6+
testWindow = dom.window
7+
}
8+
9+
module.exports = testWindow.document

src/__tests__/helpers/test-utils.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {getQueriesForElement} from '../../get-queries-for-element'
2+
import document from './document'
23

34
function render(html) {
45
const container = document.createElement('div')

src/__tests__/pretty-dom.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {prettyDOM} from '../pretty-dom'
22
import {render} from './helpers/test-utils'
3+
import document from './helpers/document'
34

45
test('it prints out the given DOM element tree', () => {
56
const {container} = render('<div>Hello World!</div>')

src/__tests__/wait-for-dom-change.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {waitForDomChange} from '../'
22
// adds special assertions like toBeTruthy
33
import 'jest-dom/extend-expect'
44
import {render} from './helpers/test-utils'
5+
import document from './helpers/document'
56

67
const skipSomeTime = delayMs =>
78
new Promise(resolve => setTimeout(resolve, delayMs))
@@ -15,7 +16,11 @@ test('it waits for the next DOM mutation', async () => {
1516
const successHandler = jest.fn().mockName('successHandler')
1617
const errorHandler = jest.fn().mockName('errorHandler')
1718

18-
waitForDomChange().then(successHandler, errorHandler)
19+
if (typeof window === 'undefined') {
20+
waitForDomChange({container: document}).then(successHandler, errorHandler)
21+
} else {
22+
waitForDomChange().then(successHandler, errorHandler)
23+
}
1924

2025
// Promise callbacks are always asynchronous.
2126
expect(successHandler).toHaveBeenCalledTimes(0)
@@ -83,7 +88,14 @@ test('it throws if timeout is exceeded', async () => {
8388
const successHandler = jest.fn().mockName('successHandler')
8489
const errorHandler = jest.fn().mockName('errorHandler')
8590

86-
waitForDomChange({timeout: 70}).then(successHandler, errorHandler)
91+
if (typeof window === 'undefined') {
92+
waitForDomChange({container: document, timeout: 70}).then(
93+
successHandler,
94+
errorHandler,
95+
)
96+
} else {
97+
waitForDomChange({timeout: 70}).then(successHandler, errorHandler)
98+
}
8799

88100
await skipSomeTimeForMutationObserver(100)
89101

src/__tests__/wait-for-element.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {waitForElement, wait} from '../'
22
// adds special assertions like toBeTruthy
33
import 'jest-dom/extend-expect'
44
import {render} from './helpers/test-utils'
5+
import document from './helpers/document'
56

67
const skipSomeTime = delayMs =>
78
new Promise(resolve => setTimeout(resolve, delayMs))
@@ -320,7 +321,14 @@ test('works if a container is not defined', async () => {
320321
const successHandler = jest.fn().mockName('successHandler')
321322
const errorHandler = jest.fn().mockName('errorHandler')
322323

323-
waitForElement(callback).then(successHandler, errorHandler)
324+
if (typeof window === 'undefined') {
325+
waitForElement(callback, {container: document}).then(
326+
successHandler,
327+
errorHandler,
328+
)
329+
} else {
330+
waitForElement(callback).then(successHandler, errorHandler)
331+
}
324332

325333
await skipSomeTimeForMutationObserver()
326334

@@ -342,7 +350,14 @@ test('throws an error if callback is not a function', async () => {
342350
const successHandler = jest.fn().mockName('successHandler')
343351
const errorHandler = jest.fn().mockName('errorHandler')
344352

345-
waitForElement().then(successHandler, errorHandler)
353+
if (typeof window === 'undefined') {
354+
waitForElement(undefined, {container: document}).then(
355+
successHandler,
356+
errorHandler,
357+
)
358+
} else {
359+
waitForElement().then(successHandler, errorHandler)
360+
}
346361

347362
await skipSomeTimeForMutationObserver()
348363

src/__tests__/wait.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ test('can just be used for a next tick thing', async () => {
2020
const after = Date.now()
2121
// if it's greater than 50 then `wait` used a timeout
2222
// but it should have resolved sooner. It really should be 0
23-
expect(after - before).not.toBeGreaterThan(50)
23+
expect(after - before).not.toBeGreaterThan(60)
2424
expect(spy).toHaveBeenCalledTimes(1)
2525
})

0 commit comments

Comments
 (0)