-
Notifications
You must be signed in to change notification settings - Fork 111
Provide options to adapt the document before mount #98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi! Thanks for the detailed issue. We've got similar requests/issues through other channels regarding modals and, in general, elements that render outside of the parent component DOM node tree. I do believe there's a divergence between Vue Testing Lib and React Testing Lib, since their queries are bound to the whole document, not the wrapper of the rendered element. Bounding queries to the outermost element (the body, as to speak) would fix your issue, wouldn't it? It is something I plan on working soon, and I'll use your example to test it out. I'll keep you posted. For the time being, and from the top of my head, would creating a custom renderer solve your issue? import { render as VTLRender } from '@testing-library/vue'
const renderWithVuetify = (comp, options, cb) => {
return VTLRender({
// render function
render(h) {
// wrap your component with a <div data-app="true"> node
return h('div', { attrs: { 'data-app': true }}, comp)
},
options,
cb
})
}
// and then, somewhere else:
const { getByText } = renderWithVuetify(MyComp) (Can't test it right now, so syntax might be a bit off). |
Oh, by the way, const { getByText } = render(MyComp, {}, vue => {
vue.use(Vuetify)
}) this is something that could be done inside your custom renderer, too, so you don't have to repeat it every time. |
Thanks for your fast response!
Yes, this would work. 👍
I did it quite similar and it works. Just not sure on how to pass all events up, so import { render as VTLRender } from '@testing-library/vue'
function renderWithVuetify(component, options, callback) {
return VTLRender(
{
render(h) {
return h('div', { attrs: { 'data-app': true } }, [
h(component, {
props: options.props,
}),
])
},
},
options,
callback
)
}
Yeah, it should... But vuetify has an issue with multiple vue instances if it is initialized like that. This might be already fixed in the current version. In the meantime I use the jest setup file to set this once for every test. Here is the vuetify issue: vuetifyjs/vuetify#4068 |
Hi! Thanks for the detailed answer. I've set up a PR to try to bound queries to the parent node: #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`.
🎉 This issue has been resolved in version 4.0.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Thanks to this conversation I created a wrapper to use Vuetfiy, but there is one thing that I'm not sure about. I would like to eliminate the need of writing In the end it is another global Vue instance, so are there any downsides of doing it like that? export const renderWithVuetify = (component, options, callback) => {
Vue.use(Vuetify); // downsides?
return VTLRender(
{
render(h) {
// wrap the component with a <div data-app="true"> node
return h("div", { attrs: { "data-app": true } }, [h(component)]);
}
},
options,
callback
);
};
// in the test
// const { getByText } = renderWithVuetify(MyComponent); Or should the test pass its Vue instance via the wrapper function? export const renderWithVuetify = (component, vueInstance, options, callback) => {
vueInstance.use(Vuetify); // downsides?
return VTLRender(
....
// in the test
// const { getByText } = renderWithVuetify(MyComponent, Vue); |
Hi! I can't think of any downsides of the top of my head, as long as Vuetify issue with multiple Vue instances is still a thing (I guess it is!). This is something that should be fixed on their own, so I'd say having a comfortable workaround should do the trick 👍 |
The example above works only for Vuetify components that don't use the (e. g. You can bypass this by using For any future readers, here is the complete setup: Maybe interesting for the documentation/examples?
import Vue from "vue";
import Vuetify from "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);
import { render as VTLRender } from "@testing-library/vue";
import Vuetify from "vuetify";
/**
* Custom render wrapper to integrate Vuetify with Vue Testing Library.
*
* Vuetify requires you to wrap your app with a `v-app` component that provides
* a `<div data-app="true">` node.
*
* More info:
* https://github.com/vuetifyjs/vuetify/issues/4068
* https://vuetifyjs.com/en/getting-started/unit-testing
*
* @param {*} component Component from test to render
* @param {*} options Render options
* @param {() => void} callback Render callback
* @return {*} Render function of VTL including Vuetify `data-app`
*/
export const renderWithVuetify = (component, options, callback) => {
return VTLRender(
// anonymous component
{
// Vue's render function
render(createElement) {
// wrap the component with a <div data-app="true"> node and render the test component
return createElement("div", { attrs: { "data-app": true } }, [
createElement(component)
]);
}
},
{ vuetify: new Vuetify(), ...options },
callback
);
};
import { renderWithVuetify } from "../test-helper";
import MyComponent from "../../src/views/MyComponent.vue";
describe("MyComponent.vue", () => {
test("Some test...", () => {
const { getByText } = renderWithVuetify(MyComponent);
expect(getByText(/some text/));
});
}); |
Looks like a nice improvement for the Vuetify example. Fancy to open up a PR with the appropriate modifications? 🤗 |
Will do! Update: Done! #114 |
|
same things for |
Describe the feature
We are using Vuetify as component library in one of our projects. I would like to introduce vue-testing-library and came up with some setup troubles on the way. Vuetify requires a wrapper element containing the attribute
data-app
. This element is used to append components like dialog to the root DOM level. The required setup can be done using jest setup files. Thought, the dialog content can not be found when using the exposed queries of the vue-testing-librariesrender()
method.To Reproduce
Steps to reproduce the behavior:
<div data-app></div>
to your test DOM instance before mount=> queries like getByText will not query the dialog content
I tried to create a codesandbox, but failed. Is there a working example for vue-testing-library?
https://codesandbox.io/s/vuetify-with-vue-testing-library-bhu8f?previewwindow=tests
Expected behavior
I expect a configuration option like it exists for react:
Related information:
@testing-library/vue
version: 3.0.0Vue
version: 2.5.18node
version: 8.12.0yarn
version: 1.17.3Vuetify
version: 1.2.10Relevant code or config (if any)
The text was updated successfully, but these errors were encountered: