Skip to content

Commit 673c5e9

Browse files
feat(queryconfig): create a test showing shadow dom implementation
1 parent fe05919 commit 673c5e9

File tree

1 file changed

+78
-34
lines changed

1 file changed

+78
-34
lines changed

src/__node_tests__/index.js

Lines changed: 78 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
1-
import {configure} from '../config'
21
import {JSDOM} from 'jsdom'
2+
import {configure} from '../config'
33
import * as dtl from '../'
44

5+
beforeEach(() => {
6+
// reset back to original config
7+
configure({
8+
queryAllElements: (element, query) => element.querySelectorAll(query),
9+
})
10+
})
11+
512
test('works without a global dom', async () => {
613
const container = new JSDOM(`
714
<html>
@@ -78,50 +85,87 @@ test('works without a browser context on a dom node (JSDOM Fragment)', () => {
7885
`)
7986
})
8087

81-
test('works with a custom configured element query', () => {
82-
const container = JSDOM.fragment(`
88+
test('works with a custom configured element query for shadow dom elements', async () => {
89+
const window = new JSDOM(`
8390
<html>
8491
<body>
85-
<form id="login-form">
86-
<label for="username">Username</label>
87-
<input id="username" />
88-
<label for="password">Password</label>
89-
<input id="password" type="password" />
90-
<button type="submit">Submit</button>
91-
<div id="data-container"></div>
92-
</form>
93-
<form id="other">
94-
<label for="user_other">Username</label>
95-
<input id="user_other" />
96-
<label for="pass_other">Password</label>
97-
<input id="pass_other" type="password" />
98-
<button type="submit">Submit</button>
99-
<div id="data-container"></div>
100-
</form>
92+
<example-input></example-input>
10193
</body>
10294
</html>
103-
`)
95+
`).window
96+
const document = window.document
97+
const container = document.body
98+
99+
// create custom element as system under test
100+
window.customElements.define(
101+
'example-input',
102+
class extends window.HTMLElement {
103+
constructor() {
104+
super()
105+
const shadow = this.attachShadow({mode: 'open'})
106+
107+
const div = document.createElement('div')
108+
const label = document.createElement('label')
109+
label.setAttribute('for', 'invisible-from-outer-dom')
110+
label.innerHTML =
111+
'Visible in browser, invisible for traditional queries'
112+
const input = document.createElement('input')
113+
input.setAttribute('id', 'invisible-from-outer-dom')
114+
div.appendChild(label)
115+
div.appendChild(input)
116+
shadow.appendChild(div)
117+
}
118+
},
119+
)
104120

121+
// Given the default configuration is used
122+
123+
// When querying for the label
124+
// Then it is not in the document
125+
expect(
126+
dtl.queryByLabelText(
127+
container,
128+
/Visible in browser, invisible for traditional queries/i,
129+
),
130+
).not.toBeInTheDocument()
131+
132+
// Given I have a naive query that allows searching shadow dom
133+
const queryMeAndChildrenAndShadow = (element, query) => [
134+
...element.querySelectorAll(query),
135+
...[...element.children].reduce(
136+
(result, child) => [
137+
...result,
138+
...queryMeAndChildrenAndShadow(child, query),
139+
],
140+
[],
141+
),
142+
...(element.shadowRoot?.querySelectorAll(query) ?? []),
143+
]
144+
145+
// When I configure the testing tools to use it
105146
configure({
106-
queryAllElements: (element, query) =>
107-
element.querySelectorAll(`#other ${query}`),
147+
queryAllElements: queryMeAndChildrenAndShadow,
108148
})
109149

110-
expect(dtl.getByLabelText(container, /username/i)).toMatchInlineSnapshot(`
111-
<input
112-
id=user_other
113-
/>
114-
`)
115-
expect(dtl.getByLabelText(container, /password/i)).toMatchInlineSnapshot(`
150+
// Then it is part of the document
151+
expect(
152+
dtl.queryByLabelText(
153+
container,
154+
/Visible in browser, invisible for traditional queries/i,
155+
),
156+
).toBeInTheDocument()
157+
158+
// And it returns the expected item
159+
expect(
160+
dtl.getByLabelText(
161+
container,
162+
/Visible in browser, invisible for traditional queries/i,
163+
),
164+
).toMatchInlineSnapshot(`
116165
<input
117-
id=pass_other
118-
type=password
166+
id=invisible-from-outer-dom
119167
/>
120168
`)
121-
// reset back to original config
122-
configure({
123-
queryAllElements: (element, query) => element.querySelectorAll(query),
124-
})
125169
})
126170

127171
test('byRole works without a global DOM', () => {

0 commit comments

Comments
 (0)