diff --git a/src/baseWrapper.ts b/src/baseWrapper.ts index f7745ce16..89785870e 100644 --- a/src/baseWrapper.ts +++ b/src/baseWrapper.ts @@ -191,11 +191,17 @@ export default abstract class BaseWrapper< matches(currentComponent.vnode, selector) && this.element.contains(currentComponent.vnode.el as Node) ) { + const rootComponent = currentComponent.subTree.component + // a functional root component has no proxy, wrap it like findAllComponents does + if (rootComponent && !rootComponent.proxy) { + return createDOMWrapper( + rootComponent.vnode.el as Element, + rootComponent.subTree + ) + } return createVueWrapper( null, - currentComponent.subTree.component - ? currentComponent.subTree.component.proxy! - : currentComponent.proxy! + rootComponent ? rootComponent.proxy! : currentComponent.proxy! ) } diff --git a/tests/findComponent.spec.ts b/tests/findComponent.spec.ts index 2882ce5f9..7e84ebf5e 100644 --- a/tests/findComponent.spec.ts +++ b/tests/findComponent.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' import { defineComponent, h, nextTick } from 'vue' -import { mount } from '../src' +import { DOMWrapper, mount } from '../src' import Hello from './components/Hello.vue' import ComponentWithoutName from './components/ComponentWithoutName.vue' import ScriptSetupWithChildren from './components/ScriptSetupWithChildren.vue' @@ -427,6 +427,36 @@ describe('findComponent', () => { expect(wrapper.findComponent(Func).exists()).toBe(true) }) + it('finds a functional root component by dom selector', () => { + const Func = (_: unknown, { slots }: any) => + h('div', { class: 'card' }, slots.default?.()) + const Comp = defineComponent({ + components: { Func }, + template: 'content' + }) + const wrapper = mount(Comp) + expect(wrapper.findComponent('.card')).toBeInstanceOf(DOMWrapper) + expect(wrapper.findComponent('.card').text()).toBe('content') + expect(wrapper.getComponent('.card').text()).toBe('content') + expect(mount(Func).findComponent('.card').exists()).toBe(true) + + const Outer = defineComponent({ + components: { Comp }, + template: '
' + }) + expect(mount(Outer).find('.card').findComponent('.card').exists()).toBe( + true + ) + }) + + it('finds the root element of a transition by dom selector', () => { + const Comp = defineComponent({ + template: '
content
' + }) + const wrapper = mount(Comp, { global: { stubs: { transition: false } } }) + expect(wrapper.findComponent('.panel').text()).toBe('content') + }) + describe('chaining from dom wrapper', () => { it('finds a component nested inside a node', () => { const Comp = defineComponent({