Skip to content

Commit 27c9ddd

Browse files
author
Kent C. Dodds
committed
feat(logDOM): add logDOM export
1 parent 6b504ad commit 27c9ddd

File tree

6 files changed

+108
-67
lines changed

6 files changed

+108
-67
lines changed

src/__tests__/pretty-dom.js

+52-16
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,63 @@
1-
import {prettyDOM} from '../pretty-dom'
2-
import {render} from './helpers/test-utils'
1+
import {prettyDOM, logDOM} from '../pretty-dom'
2+
import {render, renderIntoDocument, cleanup} from './helpers/test-utils'
33

4-
test('prints out the given DOM element tree', () => {
4+
afterEach(cleanup)
5+
6+
beforeEach(() => {
7+
jest.spyOn(console, 'log').mockImplementation(() => {})
8+
})
9+
10+
afterEach(() => {
11+
console.log.mockRestore()
12+
})
13+
14+
test('prettyDOM prints out the given DOM element tree', () => {
515
const {container} = render('<div>Hello World!</div>')
616
expect(prettyDOM(container)).toMatchInlineSnapshot(`
7-
"<div>
8-
<div>
9-
Hello World!
10-
</div>
11-
</div>"
12-
`)
17+
"<div>
18+
<div>
19+
Hello World!
20+
</div>
21+
</div>"
22+
`)
1323
})
1424

15-
test('supports truncating the output length', () => {
25+
test('prettyDOM supports truncating the output length', () => {
1626
const {container} = render('<div>Hello World!</div>')
1727
expect(prettyDOM(container, 5)).toMatch(/\.\.\./)
1828
})
1929

20-
test('supports receiving the document element', () => {
30+
test('prettyDOM defaults to document.body', () => {
31+
renderIntoDocument('<div>Hello World!</div>')
32+
expect(prettyDOM()).toMatchInlineSnapshot(`
33+
"<body>
34+
<div>
35+
Hello World!
36+
</div>
37+
</body>"
38+
`)
39+
})
40+
41+
test('prettyDOM supports receiving the document element', () => {
2142
expect(prettyDOM(document)).toMatchInlineSnapshot(`
22-
"<html>
23-
<head />
24-
<body />
25-
</html>"
26-
`)
43+
"<html>
44+
<head />
45+
<body />
46+
</html>"
47+
`)
2748
})
49+
50+
test('logDOM logs prettyDOM to the console', () => {
51+
const {container} = render('<div>Hello World!</div>')
52+
logDOM(container)
53+
expect(console.log).toHaveBeenCalledTimes(1)
54+
expect(console.log.mock.calls[0][0]).toMatchInlineSnapshot(`
55+
"<div>
56+
<div>
57+
Hello World!
58+
</div>
59+
</div>"
60+
`)
61+
})
62+
63+
/* eslint no-console:0 */

src/__tests__/role-helpers.js

+10-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
import {getRoles, logRoles, getImplicitAriaRoles} from '../role-helpers'
22
import {render} from './helpers/test-utils'
33

4+
beforeEach(() => {
5+
jest.spyOn(console, 'log').mockImplementation(() => {})
6+
})
7+
8+
afterEach(() => {
9+
console.log.mockRestore()
10+
})
11+
412
function setup() {
513
const {getByTestId} = render(`
614
<section data-testid='a-section'>
@@ -137,16 +145,9 @@ test('getRoles returns expected roles for various dom nodes', () => {
137145

138146
test('logRoles calls console.log with output from prettyRoles', () => {
139147
const {section} = setup()
140-
141-
jest.spyOn(console, 'log').mockImplementationOnce(() => {})
142-
143148
logRoles(section)
144-
// eslint-disable-next-line no-console
145149
expect(console.log).toHaveBeenCalledTimes(1)
146-
// eslint-disable-next-line no-console
147150
expect(console.log.mock.calls[0][0]).toMatchSnapshot()
148-
// eslint-disable-next-line no-console
149-
console.log.mockRestore()
150151
})
151152

152153
test('getImplicitAriaRoles returns expected roles for various dom nodes', () => {
@@ -158,3 +159,5 @@ test('getImplicitAriaRoles returns expected roles for various dom nodes', () =>
158159
expect(getImplicitAriaRoles(radio)).toEqual(['radio'])
159160
expect(getImplicitAriaRoles(input)).toEqual(['textbox'])
160161
})
162+
163+
/* eslint no-console:0 */

src/pretty-dom.js

+36-7
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,50 @@
11
import prettyFormat from 'pretty-format'
2+
import {getDocument} from './helpers'
3+
4+
function inCypress(dom) {
5+
const window =
6+
(dom.ownerDocument && dom.ownerDocument.defaultView) || undefined
7+
return (
8+
(typeof global !== 'undefined' && global.Cypress) ||
9+
(typeof window !== 'undefined' && window.Cypress)
10+
)
11+
}
12+
13+
const inNode = () =>
14+
typeof process !== 'undefined' &&
15+
process.versions !== undefined &&
16+
process.versions.node !== undefined
17+
18+
const getMaxLength = dom =>
19+
inCypress(dom) ? 0 : process.env.DEBUG_PRINT_LIMIT || 7000
220

321
const {DOMElement, DOMCollection} = prettyFormat.plugins
422

5-
function prettyDOM(htmlElement, maxLength, options) {
6-
if (htmlElement.documentElement) {
7-
htmlElement = htmlElement.documentElement
23+
function prettyDOM(
24+
dom = getDocument().body,
25+
maxLength = getMaxLength(dom),
26+
options,
27+
) {
28+
if (maxLength === 0) {
29+
return ''
30+
}
31+
if (dom.documentElement) {
32+
dom = dom.documentElement
833
}
934

10-
const debugContent = prettyFormat(htmlElement, {
35+
const debugContent = prettyFormat(dom, {
1136
plugins: [DOMElement, DOMCollection],
1237
printFunctionName: false,
13-
highlight: true,
38+
highlight: inNode(),
1439
...options,
1540
})
16-
return maxLength !== undefined && htmlElement.outerHTML.length > maxLength
41+
return maxLength !== undefined && dom.outerHTML.length > maxLength
1742
? `${debugContent.slice(0, maxLength)}...`
1843
: debugContent
1944
}
2045

21-
export {prettyDOM}
46+
const logDOM = (...args) => console.log(prettyDOM(...args))
47+
48+
export {prettyDOM, logDOM}
49+
50+
/* eslint no-console:0 */

src/query-helpers.js

+1-27
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,8 @@ import {prettyDOM} from './pretty-dom'
22
import {fuzzyMatches, matches, makeNormalizer} from './matches'
33
import {waitForElement} from './wait-for-element'
44

5-
/* eslint-disable complexity */
6-
function debugDOM(htmlElement) {
7-
const limit = process.env.DEBUG_PRINT_LIMIT || 7000
8-
const inNode =
9-
typeof process !== 'undefined' &&
10-
process.versions !== undefined &&
11-
process.versions.node !== undefined
12-
/* istanbul ignore next */
13-
const window =
14-
(htmlElement.ownerDocument && htmlElement.ownerDocument.defaultView) ||
15-
undefined
16-
const inCypress =
17-
(typeof global !== 'undefined' && global.Cypress) ||
18-
(typeof window !== 'undefined' && window.Cypress)
19-
/* istanbul ignore else */
20-
if (inCypress) {
21-
return ''
22-
} else if (inNode) {
23-
return prettyDOM(htmlElement, limit)
24-
} else {
25-
return prettyDOM(htmlElement, limit, {highlight: false})
26-
}
27-
}
28-
/* eslint-enable complexity */
29-
305
function getElementError(message, container) {
31-
return new Error([message, debugDOM(container)].filter(Boolean).join('\n\n'))
6+
return new Error([message, prettyDOM(container)].filter(Boolean).join('\n\n'))
327
}
338

349
function getMultipleElementsFoundError(message, container) {
@@ -111,7 +86,6 @@ function buildQueries(queryAllBy, getMultipleError, getMissingError) {
11186
}
11287

11388
export {
114-
debugDOM,
11589
getElementError,
11690
getMultipleElementsFoundError,
11791
queryAllByAttribute,

src/role-helpers.js

+7-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {elementRoles} from 'aria-query'
2-
import {debugDOM} from './query-helpers'
2+
import {prettyDOM} from './pretty-dom'
33

44
const elementRoleList = buildElementRoleList(elementRoles)
55

@@ -73,24 +73,23 @@ function getRoles(container) {
7373
}, {})
7474
}
7575

76-
function prettyRoles(container) {
77-
const roles = getRoles(container)
76+
function prettyRoles(dom) {
77+
const roles = getRoles(dom)
7878

7979
return Object.entries(roles)
8080
.map(([role, elements]) => {
8181
const delimiterBar = '-'.repeat(50)
8282
const elementsString = elements
83-
.map(el => debugDOM(el.cloneNode(false)))
83+
.map(el => prettyDOM(el.cloneNode(false)))
8484
.join('\n\n')
8585

8686
return `${role}:\n\n${elementsString}\n\n${delimiterBar}`
8787
})
8888
.join('\n')
8989
}
9090

91-
function logRoles(container) {
92-
// eslint-disable-next-line no-console
93-
console.log(prettyRoles(container))
94-
}
91+
const logRoles = dom => console.log(prettyRoles(dom))
9592

9693
export {getRoles, logRoles, getImplicitAriaRoles, prettyRoles}
94+
95+
/* eslint no-console:0 */

typings/query-helpers.d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export type AllByAttribute = (
2020

2121
export const queryByAttribute: QueryByAttribute
2222
export const queryAllByAttribute: AllByAttribute
23-
export const debugDOM: (htmlElement: HTMLElement) => string
23+
export const logDOM: (htmlElement: HTMLElement) => void
2424
export const getElementError: (message: string, container: HTMLElement) => Error
2525

2626
/**
@@ -53,7 +53,7 @@ export type BuiltQueryMethods<Arguments extends any[]> = [
5353
GetAllBy<Arguments>,
5454
GetBy<Arguments>,
5555
FindAllBy<Arguments>,
56-
FindBy<Arguments>
56+
FindBy<Arguments>,
5757
]
5858
export const buildQueries: <Arguments extends any[]>(
5959
queryByAll: GetAllBy<Arguments>,

0 commit comments

Comments
 (0)