Skip to content

Commit b03d208

Browse files
committed
fix: text() misses content for array functional component
1 parent 44f9a6f commit b03d208

File tree

5 files changed

+55
-9
lines changed

5 files changed

+55
-9
lines changed

src/baseWrapper.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { VNode } from 'vue'
12
import { textContent } from './utils'
23
import type { TriggerOptions } from './createDomEvent'
34
import {
@@ -217,7 +218,7 @@ export default abstract class BaseWrapper<ElementType extends Node>
217218
return results.map((c) =>
218219
c.proxy
219220
? createVueWrapper(null, c.proxy)
220-
: createDOMWrapper(c.vnode.el as Element)
221+
: createDOMWrapper(c.vnode.el as Element, c.subTree as VNode)
221222
)
222223
}
223224
abstract setValue(value?: any): Promise<void>

src/domWrapper.ts

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { VNode } from 'vue'
12
import { config } from './config'
23
import BaseWrapper from './baseWrapper'
34
import WrapperLike from './interfaces/wrapperLike'
@@ -11,16 +12,24 @@ import { isRefSelector } from './utils'
1112
import { createWrapperError } from './errorWrapper'
1213

1314
export class DOMWrapper<NodeType extends Node> extends BaseWrapper<NodeType> {
14-
constructor(element: NodeType | null | undefined) {
15+
protected readonly subTree: VNode | null | undefined = null
16+
17+
constructor(element: NodeType | null | undefined, subTree?: VNode | null) {
1518
if (!element) {
1619
return createWrapperError('DOMWrapper')
1720
}
1821
super(element)
22+
this.subTree = subTree
23+
1924
// plugins hook
2025
config.plugins.DOMWrapper.extend(this)
2126
}
2227

2328
getRootNodes() {
29+
if (Array.isArray(this.subTree?.children)) {
30+
// Any type should be fixed
31+
return this.subTree.children.map((node) => (node as any)?.el)
32+
}
2433
return [this.wrapperElement]
2534
}
2635

@@ -64,7 +73,7 @@ export class DOMWrapper<NodeType extends Node> extends BaseWrapper<NodeType> {
6473
}
6574
return Array.from(
6675
this.wrapperElement.querySelectorAll(selector),
67-
createDOMWrapper
76+
(element) => createDOMWrapper(element)
6877
)
6978
}
7079

@@ -155,4 +164,7 @@ export class DOMWrapper<NodeType extends Node> extends BaseWrapper<NodeType> {
155164
}
156165
}
157166

158-
registerFactory(WrapperType.DOMWrapper, (element) => new DOMWrapper(element))
167+
registerFactory(
168+
WrapperType.DOMWrapper,
169+
(element, subTree) => new DOMWrapper(element, subTree)
170+
)

src/vueWrapper.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,9 @@ export class VueWrapper<
173173
): DOMWrapper<SVGElementTagNameMap[K]>[]
174174
findAll<T extends Element>(selector: string): DOMWrapper<T>[]
175175
findAll(selector: string): DOMWrapper<Element>[] {
176-
return this.findAllDOMElements(selector).map(createDOMWrapper)
176+
return this.findAllDOMElements(selector).map((e) =>
177+
createDOMWrapper(e)
178+
)
177179
}
178180

179181
private attachNativeEventListener(): void {

src/wrapperFactory.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ComponentPublicInstance, App } from 'vue'
1+
import { ComponentPublicInstance, App, VNode } from 'vue'
22
import type { DOMWrapper as DOMWrapperType } from './domWrapper'
33
import type { VueWrapper as VueWrapperType } from './vueWrapper'
44

@@ -8,7 +8,8 @@ export enum WrapperType {
88
}
99

1010
type DOMWrapperFactory = <T extends Node>(
11-
element: T | null | undefined
11+
element: T | null | undefined,
12+
subTree?: VNode
1213
) => DOMWrapperType<T>
1314
type VueWrapperFactory = <T extends ComponentPublicInstance>(
1415
app: App | null,
@@ -36,7 +37,7 @@ export function registerFactory(
3637
factories[type] = fn
3738
}
3839

39-
export const createDOMWrapper: DOMWrapperFactory = (element) =>
40-
factories[WrapperType.DOMWrapper]!(element)
40+
export const createDOMWrapper: DOMWrapperFactory = (element, subTree) =>
41+
factories[WrapperType.DOMWrapper]!(element, subTree)
4142
export const createVueWrapper: VueWrapperFactory = (app, vm, setProps) =>
4243
factories[WrapperType.VueWrapper]!(app, vm, setProps)

tests/element.spec.ts

+30
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,36 @@ describe('element', () => {
6060
expect(wrapper.text()).toBe('foobarbaz')
6161
})
6262

63+
it('returns correct element for functional component with multiple roots', () => {
64+
const Func = () => ['foo', 'bar']
65+
66+
const Parent = defineComponent({
67+
name: 'Parent',
68+
components: { Func },
69+
template: '<div><Func/></div>'
70+
})
71+
const wrapper = mount(Parent)
72+
73+
expect(wrapper.findComponent(Func).html()).toBe('foo\nbar')
74+
expect(wrapper.findComponent(Func).text()).toBe('foobar')
75+
})
76+
77+
it('returns correct element for functional component with multiple roots', () => {
78+
const Func = () => [h('div', {}, 'foo'), h('div', {}, 'bar')]
79+
80+
const Parent = defineComponent({
81+
name: 'Parent',
82+
components: { Func },
83+
template: '<div><Func/></div>'
84+
})
85+
const wrapper = mount(Parent)
86+
87+
expect(wrapper.findComponent(Func).html()).toBe(
88+
'<div>foo</div>\n<div>bar</div>'
89+
)
90+
expect(wrapper.findComponent(Func).text()).toBe('foobar')
91+
})
92+
6393
it('returns correct element for root slot', () => {
6494
const Parent = defineComponent({
6595
components: { ReturnSlot },

0 commit comments

Comments
 (0)