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({