Skip to content

Commit c4eacd2

Browse files
authored
feat: Bound DTL queries to the base element (#100)
Closes #98 BREAKING CHANGE: baseElement is no longer tied to the document body, and container is no longer the parent node of the element wrapper, but a wrapper div. These changes shouldn't affect you if you weren't relying on either `baseElement` or `container`.
1 parent 787a34a commit c4eacd2

File tree

6 files changed

+155
-9
lines changed

6 files changed

+155
-9
lines changed

package-lock.json

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
"vue-jest": "^3.0.4",
5757
"vue-router": "^3.1.2",
5858
"vue-template-compiler": "^2.6.10",
59+
"vuetify": "^2.0.19",
5960
"vuex": "^3.1.1"
6061
},
6162
"peerDependencies": {

src/__tests__/components/Vuetify.vue

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<template>
2+
<v-app>
3+
<v-btn @click="show = true">open</v-btn>
4+
<v-dialog v-model="show">
5+
<v-card>
6+
<v-card-title class="headline green lighten-3">Lorem</v-card-title>
7+
<v-card-text>Lorem ipsum dolor sit amet.</v-card-text>
8+
</v-card>
9+
</v-dialog>
10+
</v-app>
11+
</template>
12+
13+
<script>
14+
export default {
15+
name: 'VuetifyDemoComponent',
16+
data() {
17+
return {
18+
show: false,
19+
}
20+
},
21+
}
22+
</script>

src/__tests__/render.js

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import {render} from '@testing-library/vue'
2+
import '@testing-library/jest-dom/extend-expect'
3+
4+
test('baseElement defaults to document.body', () => {
5+
const {baseElement} = render({template: '<div />'})
6+
expect(baseElement).toBe(document.body)
7+
})
8+
9+
test('renders custom baseElement', () => {
10+
const Component = {template: '<span />'}
11+
12+
const {baseElement, container} = render(Component, {
13+
baseElement: document.createElement('blink'),
14+
})
15+
16+
expect(baseElement).toMatchInlineSnapshot(`
17+
<blink>
18+
<div>
19+
<span />
20+
</div>
21+
</blink>
22+
`)
23+
24+
expect(container).toMatchInlineSnapshot(`
25+
<div>
26+
<span />
27+
</div>
28+
`)
29+
})
30+
31+
test('renders container', () => {
32+
const {container, getByTestId} = render({
33+
template: '<div data-testid="myDiv">my content</div>',
34+
})
35+
36+
expect(container.firstChild).toHaveTextContent(
37+
getByTestId('myDiv').textContent,
38+
)
39+
})
40+
41+
test('container defaults to div', () => {
42+
const {container} = render({template: '<div />'})
43+
44+
expect(container.tagName).toBe('DIV')
45+
})
46+
47+
test('renders custom container', () => {
48+
const blink = document.createElement('blink')
49+
const Component = {template: '<div />'}
50+
51+
const {container} = render(Component, {
52+
container: document.body.appendChild(blink),
53+
})
54+
55+
expect(container).toBe(blink)
56+
})
57+
58+
test('baseElement matches container if not custom baseElement is provided', () => {
59+
const blink = document.createElement('blink')
60+
const Component = {template: '<div />'}
61+
62+
const {container, baseElement} = render(Component, {
63+
container: document.body.appendChild(blink),
64+
})
65+
66+
expect(container).toMatchInlineSnapshot(`
67+
<blink>
68+
<div />
69+
</blink>
70+
`)
71+
72+
expect(baseElement).toMatchInlineSnapshot(`
73+
<blink>
74+
<div />
75+
</blink>
76+
`)
77+
})

src/__tests__/vuetify.js

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import Vue from 'vue'
2+
import {render, fireEvent} from '@testing-library/vue'
3+
import Vuetify from 'vuetify'
4+
import VuetifyDemoComponent from './components/Vuetify'
5+
6+
// We need to use a global Vue instance, otherwise Vuetify will complain about
7+
// read-only attributes.
8+
// More info: https://github.com/vuetifyjs/vuetify/issues/4068
9+
// https://vuetifyjs.com/en/getting-started/unit-testing
10+
Vue.use(Vuetify)
11+
12+
// Vuetify requires you to wrap you app with a v-app component that provides
13+
// a <div data-app="true"> node. So you can do that, or you can also set the
14+
// attribute to the DOM.
15+
document.body.setAttribute('data-app', true)
16+
// Another solution is to create a custom renderer that provides all the
17+
// environment required by Vuetify.
18+
19+
test('renders a Vuetify-powered component', async () => {
20+
const {getByText} = render(VuetifyDemoComponent, {
21+
vuetify: new Vuetify(),
22+
})
23+
24+
await fireEvent.click(getByText('open'))
25+
26+
expect(getByText('Lorem ipsum dolor sit amet.')).toMatchInlineSnapshot(`
27+
<div
28+
class="v-card__text"
29+
>
30+
Lorem ipsum dolor sit amet.
31+
</div>
32+
`)
33+
})

src/vue-testing-library.js

+16-9
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,19 @@ const mountedWrappers = new Set()
1111

1212
function render(
1313
TestComponent,
14-
{store = null, routes = null, ...mountOptions} = {},
14+
{
15+
store = null,
16+
routes = null,
17+
container: customContainer,
18+
baseElement: customBaseElement,
19+
...mountOptions
20+
} = {},
1521
configurationCb,
1622
) {
23+
const div = document.createElement('div')
24+
const baseElement = customBaseElement || customContainer || document.body
25+
const container = customContainer || baseElement.appendChild(div)
26+
1727
const localVue = createLocalVue()
1828
let vuexStore = null
1929
let router = null
@@ -53,15 +63,12 @@ function render(
5363
})
5464

5565
mountedWrappers.add(wrapper)
56-
57-
const div = document.createElement('div')
58-
wrapper.element.parentNode.insertBefore(div, wrapper.element)
59-
div.appendChild(wrapper.element)
66+
container.appendChild(wrapper.element)
6067

6168
return {
62-
container: wrapper.element.parentNode,
63-
baseElement: document.body,
64-
debug: (el = wrapper.element) => logDOM(el),
69+
container,
70+
baseElement,
71+
debug: (el = baseElement) => logDOM(el),
6572
unmount: () => wrapper.destroy(),
6673
isUnmounted: () => wrapper.vm._isDestroyed,
6774
html: () => wrapper.html(),
@@ -70,7 +77,7 @@ function render(
7077
wrapper.setProps(_)
7178
return wait()
7279
},
73-
...getQueriesForElement(wrapper.element.parentNode),
80+
...getQueriesForElement(baseElement),
7481
}
7582
}
7683

0 commit comments

Comments
 (0)