-
Notifications
You must be signed in to change notification settings - Fork 244
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
How to test teleport, if subcomponents not a vue component #798
Comments
Good question, I posted some of my ideas on that SO thread: https://stackoverflow.com/questions/66923194/how-to-make-vue3-test-utils-work-with-teleport/68552979#68552979 I don't have a great solution right now. You could make an assertion against the I'll think about this a bit more and try to add something to Test Utils to handle this scenario. Do you have any ideas? |
I have a similar issue right now, I'm trying to test a component using headlessui's Dialog component which uses Teleport, but Dialog does not expose its target, so there is no way to manually create a target for it as suggested in the docs |
I tried to find a solution for teleport and headlessui. They hav some tests, which are kind of complex but worth looking at: https://github.com/tailwindlabs/headlessui/blob/d25f80ae9d896446c2b7119a70cfd5d99e250050/packages/%40headlessui-vue/src/components/dialog/dialog.ts#L98 Due to how they manage the Here's a quick example: it.only('works with headlessui', async () => {
// @ts-ignore
window.IntersectionObserver = class {
// @ts-ignore
observe () {}
}
const Comp = defineComponent({
components: { Dialog, DialogOverlay, DialogTitle, PortalGroup },
template: `
<button @click="isOpen = true">Open</button>
<Dialog :open="isOpen" @close="close" to="#id">
<DialogTitle>Dialog title</DialogTitle>
<DialogOverlay />
<input />
</Dialog>
`,
setup () {
const isOpen = ref(true)
return {
isOpen,
close: () => isOpen.value = false
}
}
})
const destination = document.createElement('div')
destination.id = 'somewhere'
document.body.appendChild(destination)
const wrapper = mount(Comp, {
attachTo: destination
})
console.log(wrapper.html())
console.log(document.body.outerHTML)
await wrapper.find('button').trigger('click')
}) This logs:
So the content is there. See this doc or this video for some ideas on how you can continue using the VTU wrapper API. This solution is kind of complex and hard to understand, I would like something a bit more ergonomic, but I'm not sure what. I think a utility function could probably abstract away a lot of this complexity. |
Hi! I'm writing a similar test to the one described in the teleport docs and the accompanying video, but with a slight variation. The child component which I need to test (and causing the issue) is a Dialog component from PrimeVue. <template>
<h5>Parent</h5>
<Dialog :visible="true">
...
</Dialog>
</template
... Looking at the Dialog's source code, I noticed that the component itself uses the built-in I'm able to correctly locate the Dialog component using const dialog = parent.getComponent(Dialog); but invoking e.g. const input = dialog.get('input'); fails. The reason seems to be that Running console.log('parent\n', parent.html());
console.log('dialog\n', dialog.html());
// ...
// console.log tests/unit/DialogTest.spec.ts:27
// parent
// <h5>Parent</h5>
// <!--teleport start-->
// <!--teleport end-->
//
// console.log tests/unit/DialogTest.spec.ts:28
// dialog
// <h5>Parent</h5>
// <!--teleport start-->
// <!--teleport end-->
// ... In the actual test, I have a button that opens the dialog and an input field I want to modify, but that should be irrelevant for this issue. I was able to replicate this with some minimal changes to Is there some concept I'm missing or some modifications I need to make to adapt to the child containing Hopefully, I came across somewhat clear! 😄 – Andreas |
Any comments on this @lmiller1990? |
I wonder if we could stub out the teleport all together? Would that be an option? |
We could definitely stub out We have that logic here, you'd just need to copy-paste it for mount(Foo, {
global: {
stubs: {
teleport: true
}
}
}) Which won't be a breaking change. Would someone like to make this PR? I could do it otherwise, but I'd really like to grow the contributors to this repo, since it's only a few people right now. This should be quite easy, since we have the concept already for transitions. |
I'll see if I can clone the repo and maybe PR this! Edit: it's not a simple copy/paste unfortunately, because Teleport doesn't have a compatible type with I'll keep plugging away, but TS is not my strong suit. |
I created a PR for this with some notes/questions: #1087 |
Added some review comments 👍 |
@AndreasNasman @Yijx we released rc.17, which has support for stubbing teleport: https://github.com/vuejs/vue-test-utils-next/releases/tag/v2.0.0-rc.17 mount(Comp, {
global: {
stubs: {
teleport: true
}
}
}) This might be useful? Just stub |
Thanks, great work! 🥳 |
Works perfectly for our needs, thank you! @TheDutchCoder @lmiller1990 🙏 |
This is a good solution, though I just wanted to chime in and say it doesn't work for headlessui. I suspect this is a headlessui problem though, not a VTU problem. For some reason the Dialog's FocusTrap can't find the contents of the Dialog when teleport is stubbed out causing an infinite loop? I don't really get it. Anyway, this is just for anyone else in the future running across this issue who's having the same issues with headlessui that I did. |
How to use same solution (stubs) if I have my teleport like this:
I must do teleport like this because of vite building issue: vuejs/core#2855 (comment) . When I'm doing like @lmiller1990 suggested I don't see content of mounted component: Plus I'm getting warn which I think might be because teleport actually worked (stub didn't replace in time) there is no target ( |
What is your testing stack? Is this Vitest specific? What is the goal - to avoid teleporting your content from your component? Eg, can you share your entire test and intention? |
Stubbing teleport works great - thanks so much! |
5 days in and I'm finding the stubbed teleport isn't reactive 😕 Maybe I'm missing something. |
I've not been able to access the contents of a stubbed teleport in my tests ever since 2.2.0. I keep intending to build a sample test case to demonstrate the bug, but it's quicker to just stay on 2.1.0 for now 😓 |
I'm not sure if the current state of this library lends itself well to testing teleport in general - I wonder if we need better docs, a better/new API for this, or something else. Can you share a minimal reproduction? I am not exactly what you mean, but I wouldn't expected a stubbed component to do much at all. |
I'm amazed at how much of a pain it is to just spin up a quick Vue project after Vite. I love Vite and think it was the right decision. However, I really miss the simplicity of Vue CLI and how quickly it set up a basic project with Jest testing. Anyways, I've got a repo up and get the expected bug behavior. |
Ah sorry, for reproductions, people often use https://stackblitz.com/edit/vitest-dev-vitest-2cimwj?file=test/basic.test.ts (ready to go). Or you can fork this repo and add a test case. I will make a new issue for this. |
@Made-of-Clay would you be interested in trying to fix this? You could add a test case to this test suite, and try to fix it. The stubbing stuff for Teleport is here: https://github.com/vuejs/test-utils/blob/main/src/vnodeTransformers/stubComponentsTransformer.ts#L123-L127 |
@lmiller1990 I'll take a look when I can make time for it 👍
If that's specified somewhere and I missed it, my bad. I admit I didn't look thru docs for contribution notes. Thanks for making the issue/bug for tracking. |
I had a quick look but I'm having trouble providing a custom stub for Teleport. It's been a while since I looked at this code, I don't have any ideas for a quick fix right now - might require some digging and exploration. |
Hi all. I was using the teleport stub solution mentioned above previously, with test utils version Could someone consider looking into this or re-opening this issue as a possible regression? I'm assuming since it's the same major version there wouldn't be any breaking changes with this particular functionality. |
Can you try previous versions (maybe 2.3.1, 2.3.0) and isolate the issue? How about making a new one describing the version with the breakage? I think it's better to track a new regression in a new issue. Thanks! |
This sounds like the same issue I'm facing, where the behaviour of subbing teleport broke in 2.2.0. |
Oh, so this one would be the issue to follow: #2033 |
I have a vue component like this
It is different from https://next.vue-test-utils.vuejs.org/guide/advanced/teleport.html
I can use document.body.querySelect('.hello'), it is work.
but wrapper.find or wrapper.findComponent, they are not work.
so, how can i test this component, it is a same question in stackoverflow https://stackoverflow.com/questions/66923194/how-to-make-vue3-test-utils-work-with-teleport
The text was updated successfully, but these errors were encountered: