Skip to content

Commit 1a5251c

Browse files
michaellaskyKent C. Dodds
authored and
Kent C. Dodds
committed
feat: add getRoles and logRoles utilities (#285)
* Added npm package lodash.merge Added lodash.merge to handle deep merging in role-helpers. * Add `getRoles` and `logRoles` utilities #282 Implements requirements of #282 Added getRoles and logRoles to a new file, role-helpers.js. Moved buildElementRoleList from src/queries/role.js to src/role-helpers.js This function was also needed in role-helpers, and it didn't seem proper to to expert it from queries/role with a bunch of queries. Makes more sense to be in the helper file i think. * Updated logRole test to not rely on snapshot Thinking it over, using the snapshot didn't make much sense either. So Now this test just checks loosely that the output has the expected labels followed by expected element names * Added role-helpers export to index.js * Changed formatting of logRoles No longer shows child nodes in output cleaerer distinction between groups * Removed some tests that weren't needed * Refactored getRoles and updated related tests Fixed bug in getRoles where deeply nested children could overwrtie each other getRoles is now simlper The tests for getRoles and logRoles now use a more realistic DOM tree * Removed export of buildElementRoleList buildElementRoleList doesn't need to be exported at this time. Previously, src/queries/roles used that function to create elementRoleList variable, but since role-helpers needed that as well it's just created in there and only elementRoleList is exported * Removed lodash.merge dependency Lodash.merge is no longer required with the getRoles refactor * Minor: removed a useless -1 There was a leftover -1 on a calculation that calculates the number of '#'s for the role title in logRoles * Minor: statement no longer had to be temp literal * Reasability / sanity pass * Initial value for reducer switched to array * Fixed bug with node selectors on specificity > 0 nodes Nodes that required greater specificity (ie input[type="radio"] is role radio, not the default textbox) where not getting their roles set correctly. Moved getImplicitAriaRole from src/queries/role to src/role-helpers * Added the role-helpers snapshot * Added basic test coverage for getImplicitAriaRole * Removed un-needed branch Also gives 100% branch coverage * Minor: Added a cleanup afterEach test * Removed unneeded elementRoleMap elementRoleMap was useful before getRoles was refactored, but is no longer being used. * getRoles now handles muultiple implicit roles getRoles no longer assumes one implicit role for a given tag. getImplicitAriaRole was renamed to getImplicitAriaRoles Added a tag (menuitem) that has multiple imlicit roles to test case. * Added npm package jest-serializer-ansi * Snapshot now uses jest-serilizer-ansi Allows us to strip the control characters that debugDOM embeds to change text colors on the console. * Tests now use jest-serilizer-ansi These tests had control characters embedded into their inline snapshots to match output of debugDOM. Now they're stripped out and the tests won't fail if the colors debugDOM embeds changes. * Switched '#' to '-' in the output of logRoles * role-helpers test minor change to reduce LOC * Removed elementRoleList from role-helpers export elementRoleList was previously used by src/queries/role, but is not longer needed since moving getImplicitAriaRoles to src/role-helpers * Made public-api exports from role-helpers spcific Only getRoles and logRoles are exported to the public api * Minor: made testids more consistent * Minor: '\n' handling is more consistent in logRoles * Added TS definitions for getRoles, logRoles * Changed logRoles formatting Switched formatting back to initial proposal to avoid potential problems. * Fixed spelling error Closes #282
1 parent 349f497 commit 1a5251c

File tree

9 files changed

+463
-92
lines changed

9 files changed

+463
-92
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"dtslint": "^0.7.7",
5454
"jest-dom": "^3.4.0",
5555
"jest-in-case": "^1.0.2",
56+
"jest-serializer-ansi": "^1.0.3",
5657
"jest-watch-select-projects": "^0.1.1",
5758
"jsdom": "^15.1.1",
5859
"kcd-scripts": "^1.4.0"
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`logRoles logs expected roles for various dom nodes 1`] = `
4+
"region:
5+
6+
<section
7+
data-testid="a-section"
8+
/>
9+
10+
--------------------------------------------------
11+
navigation:
12+
13+
<nav
14+
data-testid="a-nav"
15+
/>
16+
17+
--------------------------------------------------
18+
heading:
19+
20+
<h1
21+
data-testid="a-h1"
22+
/>
23+
24+
<h2
25+
data-testid="a-h2"
26+
/>
27+
28+
<h3
29+
data-testid="a-h3"
30+
/>
31+
32+
--------------------------------------------------
33+
article:
34+
35+
<article
36+
data-testid="a-article"
37+
/>
38+
39+
--------------------------------------------------
40+
command:
41+
42+
<menuitem
43+
data-testid="a-menuitem-1"
44+
/>
45+
46+
<menuitem
47+
data-testid="a-menuitem-2"
48+
/>
49+
50+
--------------------------------------------------
51+
menuitem:
52+
53+
<menuitem
54+
data-testid="a-menuitem-1"
55+
/>
56+
57+
<menuitem
58+
data-testid="a-menuitem-2"
59+
/>
60+
61+
--------------------------------------------------
62+
list:
63+
64+
<ul
65+
data-testid="a-list"
66+
/>
67+
68+
<ul
69+
data-testid="b-list"
70+
/>
71+
72+
--------------------------------------------------
73+
listitem:
74+
75+
<li
76+
data-testid="a-list-item-1"
77+
/>
78+
79+
<li
80+
data-testid="a-list-item-2"
81+
/>
82+
83+
<li
84+
data-testid="b-list-item-1"
85+
/>
86+
87+
<li
88+
data-testid="b-list-item-2"
89+
/>
90+
91+
--------------------------------------------------
92+
table:
93+
94+
<table
95+
data-testid="a-table"
96+
/>
97+
98+
--------------------------------------------------
99+
rowgroup:
100+
101+
<tbody
102+
data-testid="a-tbody"
103+
/>
104+
105+
--------------------------------------------------
106+
row:
107+
108+
<tr
109+
data-testid="a-row"
110+
/>
111+
112+
--------------------------------------------------
113+
cell:
114+
115+
<td
116+
data-testid="a-cell-1"
117+
/>
118+
119+
<td
120+
data-testid="a-cell-2"
121+
/>
122+
123+
<td
124+
data-testid="a-cell-3"
125+
/>
126+
127+
--------------------------------------------------
128+
form:
129+
130+
<form
131+
data-testid="a-form"
132+
/>
133+
134+
--------------------------------------------------
135+
radio:
136+
137+
<input
138+
data-testid="a-radio-1"
139+
type="radio"
140+
/>
141+
142+
<input
143+
data-testid="a-radio-2"
144+
type="radio"
145+
/>
146+
147+
--------------------------------------------------
148+
textbox:
149+
150+
<input
151+
data-testid="a-input-1"
152+
type="text"
153+
/>
154+
155+
<input
156+
data-testid="a-input-2"
157+
type="text"
158+
/>
159+
160+
<textarea
161+
data-testid="a-textarea"
162+
/>
163+
164+
--------------------------------------------------"
165+
`;

src/__tests__/element-queries.js

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import jestSerializerAnsi from 'jest-serializer-ansi'
12
import {configure} from '../config'
23
import {render, renderIntoDocument} from './helpers/test-utils'
34

5+
expect.addSnapshotSerializer(jestSerializerAnsi)
46
beforeEach(() => {
57
document.defaultView.Cypress = null
68
})
@@ -37,60 +39,60 @@ test('get throws a useful error message', () => {
3739
.toThrowErrorMatchingInlineSnapshot(`
3840
"Unable to find a label with the text of: LucyRicardo
3941
40-
[36m<div>[39m
41-
[36m<div />[39m
42-
[36m</div>[39m"
42+
<div>
43+
<div />
44+
</div>"
4345
`)
4446
expect(() => getByPlaceholderText('LucyRicardo'))
4547
.toThrowErrorMatchingInlineSnapshot(`
4648
"Unable to find an element with the placeholder text of: LucyRicardo
4749
48-
[36m<div>[39m
49-
[36m<div />[39m
50-
[36m</div>[39m"
50+
<div>
51+
<div />
52+
</div>"
5153
`)
5254
expect(() => getByText('LucyRicardo')).toThrowErrorMatchingInlineSnapshot(`
5355
"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.
5456
55-
[36m<div>[39m
56-
[36m<div />[39m
57-
[36m</div>[39m"
57+
<div>
58+
<div />
59+
</div>"
5860
`)
5961
expect(() => getByTestId('LucyRicardo')).toThrowErrorMatchingInlineSnapshot(`
60-
"Unable to find an element by: [data-testid=\\"LucyRicardo\\"]
62+
"Unable to find an element by: [data-testid="LucyRicardo"]
6163
62-
[36m<div>[39m
63-
[36m<div />[39m
64-
[36m</div>[39m"
64+
<div>
65+
<div />
66+
</div>"
6567
`)
6668
expect(() => getByAltText('LucyRicardo')).toThrowErrorMatchingInlineSnapshot(`
6769
"Unable to find an element with the alt text: LucyRicardo
6870
69-
[36m<div>[39m
70-
[36m<div />[39m
71-
[36m</div>[39m"
71+
<div>
72+
<div />
73+
</div>"
7274
`)
7375
expect(() => getByTitle('LucyRicardo')).toThrowErrorMatchingInlineSnapshot(`
7476
"Unable to find an element with the title: LucyRicardo.
7577
76-
[36m<div>[39m
77-
[36m<div />[39m
78-
[36m</div>[39m"
78+
<div>
79+
<div />
80+
</div>"
7981
`)
8082
expect(() => getByDisplayValue('LucyRicardo'))
8183
.toThrowErrorMatchingInlineSnapshot(`
8284
"Unable to find an element with the value: LucyRicardo.
8385
84-
[36m<div>[39m
85-
[36m<div />[39m
86-
[36m</div>[39m"
86+
<div>
87+
<div />
88+
</div>"
8789
`)
8890
expect(() => getByRole('LucyRicardo')).toThrowErrorMatchingInlineSnapshot(`
8991
"Unable to find an element by [role=LucyRicardo]
9092
91-
[36m<div>[39m
92-
[36m<div />[39m
93-
[36m</div>[39m"
93+
<div>
94+
<div />
95+
</div>"
9496
`)
9597
})
9698

@@ -221,25 +223,25 @@ test('label with no form control', () => {
221223
const {getByLabelText, queryByLabelText} = render(`<label>All alone</label>`)
222224
expect(queryByLabelText(/alone/)).toBeNull()
223225
expect(() => getByLabelText(/alone/)).toThrowErrorMatchingInlineSnapshot(`
224-
"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.
226+
"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.
225227
226-
[36m<div>[39m
227-
[36m<label>[39m
228-
[0mAll alone[0m
229-
[36m</label>[39m
230-
[36m</div>[39m"
228+
<div>
229+
<label>
230+
All alone
231+
</label>
232+
</div>"
231233
`)
232234
})
233235

234236
test('totally empty label', () => {
235237
const {getByLabelText, queryByLabelText} = render(`<label />`)
236238
expect(queryByLabelText('')).toBeNull()
237239
expect(() => getByLabelText('')).toThrowErrorMatchingInlineSnapshot(`
238-
"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.
240+
"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.
239241
240-
[36m<div>[39m
241-
[36m<label />[39m
242-
[36m</div>[39m"
242+
<div>
243+
<label />
244+
</div>"
243245
`)
244246
})
245247

src/__tests__/pretty-dom.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1+
import jestSerializerAnsi from 'jest-serializer-ansi'
12
import {prettyDOM} from '../pretty-dom'
23
import {render} from './helpers/test-utils'
34

5+
expect.addSnapshotSerializer(jestSerializerAnsi)
6+
47
test('it prints out the given DOM element tree', () => {
58
const {container} = render('<div>Hello World!</div>')
69
expect(prettyDOM(container)).toMatchInlineSnapshot(`
7-
"[36m<div>[39m
8-
[36m<div>[39m
9-
[0mHello World![0m
10-
[36m</div>[39m
11-
[36m</div>[39m"
10+
"<div>
11+
<div>
12+
Hello World!
13+
</div>
14+
</div>"
1215
`)
1316
})
1417

@@ -19,9 +22,9 @@ test('it supports truncating the output length', () => {
1922

2023
test('it supports receiving the document element', () => {
2124
expect(prettyDOM(document)).toMatchInlineSnapshot(`
22-
"[36m<html>[39m
23-
[36m<head />[39m
24-
[36m<body />[39m
25-
[36m</html>[39m"
25+
"<html>
26+
<head />
27+
<body />
28+
</html>"
2629
`)
2730
})

0 commit comments

Comments
 (0)