From d20089c8bbd8d88d2f4556cf7fa48fe69a8c8285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Fontcuberta?= Date: Sun, 29 Sep 2019 19:53:55 +0200 Subject: [PATCH 1/2] Bound queries to base element --- package-lock.json | 6 +++++ package.json | 1 + src/__tests__/components/Vuetify.vue | 22 +++++++++++++++++ src/__tests__/render.js | 36 ++++++++++++++++++++++++++++ src/__tests__/vuetify.js | 33 +++++++++++++++++++++++++ src/vue-testing-library.js | 17 ++++++------- 6 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 src/__tests__/components/Vuetify.vue create mode 100644 src/__tests__/render.js create mode 100644 src/__tests__/vuetify.js diff --git a/package-lock.json b/package-lock.json index db128a05..ba279c77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11690,6 +11690,12 @@ "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", "dev": true }, + "vuetify": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-2.0.19.tgz", + "integrity": "sha512-zBskf77Z+RH8+Qs1q0NIDv/1enVkOoVH2dcdjcs+ZUNOhnlG0IkDedmqE2+PNm0JvJdgpOaV8wq+Pl69TGD2Hg==", + "dev": true + }, "vuex": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.1.1.tgz", diff --git a/package.json b/package.json index 1a15eba0..cde5f72d 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "vue-jest": "^3.0.4", "vue-router": "^3.1.2", "vue-template-compiler": "^2.6.10", + "vuetify": "^2.0.19", "vuex": "^3.1.1" }, "peerDependencies": { diff --git a/src/__tests__/components/Vuetify.vue b/src/__tests__/components/Vuetify.vue new file mode 100644 index 00000000..3add64fa --- /dev/null +++ b/src/__tests__/components/Vuetify.vue @@ -0,0 +1,22 @@ + + + diff --git a/src/__tests__/render.js b/src/__tests__/render.js new file mode 100644 index 00000000..4c0f4c37 --- /dev/null +++ b/src/__tests__/render.js @@ -0,0 +1,36 @@ +import {render} from '@testing-library/vue' +import '@testing-library/jest-dom/extend-expect' + +test('returns baseElement which defaults to document.body', () => { + const {baseElement} = render({template: '
'}) + expect(baseElement).toBe(document.body) +}) + +test('returns custom baseElement', () => { + const {baseElement} = render( + { + template: '
', + }, + { + baseElement: document.createElement('blink'), + }, + ) + + expect(baseElement).toMatchInlineSnapshot(` + +
+
+
+ + `) +}) + +test('renders container', () => { + const {container, getByTestId} = render({ + template: '
my content
', + }) + + expect(container.firstChild).toHaveTextContent( + getByTestId('myDiv').textContent, + ) +}) diff --git a/src/__tests__/vuetify.js b/src/__tests__/vuetify.js new file mode 100644 index 00000000..17d30e86 --- /dev/null +++ b/src/__tests__/vuetify.js @@ -0,0 +1,33 @@ +import Vue from 'vue' +import {render, fireEvent} from '@testing-library/vue' +import Vuetify from 'vuetify' +import VuetifyDemoComponent from './components/Vuetify' + +// We need to use a global Vue instance, otherwise Vuetify will complain about +// read-only attributes. +// More info: https://github.com/vuetifyjs/vuetify/issues/4068 +// https://vuetifyjs.com/en/getting-started/unit-testing +Vue.use(Vuetify) + +// Vuetify requires you to wrap you app with a v-app component that provides +// a
node. So you can do that, or you can also set the +// attribute to the DOM. +document.body.setAttribute('data-app', true) +// Another solution is to create a custom renderer that provides all the +// environment required by Vuetify. + +test('renders a Vuetify-powered component', async () => { + const {getByText} = render(VuetifyDemoComponent, { + vuetify: new Vuetify(), + }) + + await fireEvent.click(getByText('open')) + + expect(getByText('Lorem ipsum dolor sit amet.')).toMatchInlineSnapshot(` +
+ Lorem ipsum dolor sit amet. +
+ `) +}) diff --git a/src/vue-testing-library.js b/src/vue-testing-library.js index ed072556..ec1d40de 100644 --- a/src/vue-testing-library.js +++ b/src/vue-testing-library.js @@ -14,6 +14,10 @@ function render( {store = null, routes = null, ...mountOptions} = {}, configurationCb, ) { + const div = document.createElement('div') + const baseElement = mountOptions.baseElement || document.body + const container = baseElement.appendChild(div) + const localVue = createLocalVue() let vuexStore = null let router = null @@ -53,15 +57,12 @@ function render( }) mountedWrappers.add(wrapper) - - const div = document.createElement('div') - wrapper.element.parentNode.insertBefore(div, wrapper.element) - div.appendChild(wrapper.element) + container.appendChild(wrapper.element) return { - container: wrapper.element.parentNode, - baseElement: document.body, - debug: (el = wrapper.element) => logDOM(el), + container, + baseElement, + debug: (el = baseElement) => logDOM(el), unmount: () => wrapper.destroy(), isUnmounted: () => wrapper.vm._isDestroyed, html: () => wrapper.html(), @@ -70,7 +71,7 @@ function render( wrapper.setProps(_) return wait() }, - ...getQueriesForElement(wrapper.element.parentNode), + ...getQueriesForElement(baseElement), } } From 049db94b59c30bf0ea4690dac92ee9bc78e9fa59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Fontcuberta?= Date: Wed, 2 Oct 2019 08:15:03 +0200 Subject: [PATCH 2/2] Update public API to match RTL's --- src/__tests__/render.js | 63 +++++++++++++++++++++++++++++++------- src/vue-testing-library.js | 12 ++++++-- 2 files changed, 61 insertions(+), 14 deletions(-) diff --git a/src/__tests__/render.js b/src/__tests__/render.js index 4c0f4c37..4a48772a 100644 --- a/src/__tests__/render.js +++ b/src/__tests__/render.js @@ -1,28 +1,31 @@ import {render} from '@testing-library/vue' import '@testing-library/jest-dom/extend-expect' -test('returns baseElement which defaults to document.body', () => { +test('baseElement defaults to document.body', () => { const {baseElement} = render({template: '
'}) expect(baseElement).toBe(document.body) }) -test('returns custom baseElement', () => { - const {baseElement} = render( - { - template: '
', - }, - { - baseElement: document.createElement('blink'), - }, - ) +test('renders custom baseElement', () => { + const Component = {template: ''} + + const {baseElement, container} = render(Component, { + baseElement: document.createElement('blink'), + }) expect(baseElement).toMatchInlineSnapshot(`
-
+
`) + + expect(container).toMatchInlineSnapshot(` +
+ +
+ `) }) test('renders container', () => { @@ -34,3 +37,41 @@ test('renders container', () => { getByTestId('myDiv').textContent, ) }) + +test('container defaults to div', () => { + const {container} = render({template: '
'}) + + expect(container.tagName).toBe('DIV') +}) + +test('renders custom container', () => { + const blink = document.createElement('blink') + const Component = {template: '
'} + + const {container} = render(Component, { + container: document.body.appendChild(blink), + }) + + expect(container).toBe(blink) +}) + +test('baseElement matches container if not custom baseElement is provided', () => { + const blink = document.createElement('blink') + const Component = {template: '
'} + + const {container, baseElement} = render(Component, { + container: document.body.appendChild(blink), + }) + + expect(container).toMatchInlineSnapshot(` + +
+ + `) + + expect(baseElement).toMatchInlineSnapshot(` + +
+ + `) +}) diff --git a/src/vue-testing-library.js b/src/vue-testing-library.js index ec1d40de..acfb1176 100644 --- a/src/vue-testing-library.js +++ b/src/vue-testing-library.js @@ -11,12 +11,18 @@ const mountedWrappers = new Set() function render( TestComponent, - {store = null, routes = null, ...mountOptions} = {}, + { + store = null, + routes = null, + container: customContainer, + baseElement: customBaseElement, + ...mountOptions + } = {}, configurationCb, ) { const div = document.createElement('div') - const baseElement = mountOptions.baseElement || document.body - const container = baseElement.appendChild(div) + const baseElement = customBaseElement || customContainer || document.body + const container = customContainer || baseElement.appendChild(div) const localVue = createLocalVue() let vuexStore = null