Skip to content

Commit

Permalink
fix: text() misses content for array functional component
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelrincon committed Dec 31, 2024
1 parent 44f9a6f commit b03d208
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 9 deletions.
3 changes: 2 additions & 1 deletion src/baseWrapper.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { VNode } from 'vue'
import { textContent } from './utils'
import type { TriggerOptions } from './createDomEvent'
import {
Expand Down Expand Up @@ -217,7 +218,7 @@ export default abstract class BaseWrapper<ElementType extends Node>
return results.map((c) =>
c.proxy
? createVueWrapper(null, c.proxy)
: createDOMWrapper(c.vnode.el as Element)
: createDOMWrapper(c.vnode.el as Element, c.subTree as VNode)
)
}
abstract setValue(value?: any): Promise<void>
Expand Down
18 changes: 15 additions & 3 deletions src/domWrapper.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { VNode } from 'vue'
import { config } from './config'
import BaseWrapper from './baseWrapper'
import WrapperLike from './interfaces/wrapperLike'
Expand All @@ -11,16 +12,24 @@ import { isRefSelector } from './utils'
import { createWrapperError } from './errorWrapper'

export class DOMWrapper<NodeType extends Node> extends BaseWrapper<NodeType> {
constructor(element: NodeType | null | undefined) {
protected readonly subTree: VNode | null | undefined = null

constructor(element: NodeType | null | undefined, subTree?: VNode | null) {
if (!element) {
return createWrapperError('DOMWrapper')
}
super(element)
this.subTree = subTree

// plugins hook
config.plugins.DOMWrapper.extend(this)
}

getRootNodes() {
if (Array.isArray(this.subTree?.children)) {
// Any type should be fixed
return this.subTree.children.map((node) => (node as any)?.el)
}
return [this.wrapperElement]
}

Expand Down Expand Up @@ -64,7 +73,7 @@ export class DOMWrapper<NodeType extends Node> extends BaseWrapper<NodeType> {
}
return Array.from(
this.wrapperElement.querySelectorAll(selector),
createDOMWrapper
(element) => createDOMWrapper(element)
)
}

Expand Down Expand Up @@ -155,4 +164,7 @@ export class DOMWrapper<NodeType extends Node> extends BaseWrapper<NodeType> {
}
}

registerFactory(WrapperType.DOMWrapper, (element) => new DOMWrapper(element))
registerFactory(
WrapperType.DOMWrapper,
(element, subTree) => new DOMWrapper(element, subTree)
)
4 changes: 3 additions & 1 deletion src/vueWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,9 @@ export class VueWrapper<
): DOMWrapper<SVGElementTagNameMap[K]>[]
findAll<T extends Element>(selector: string): DOMWrapper<T>[]
findAll(selector: string): DOMWrapper<Element>[] {
return this.findAllDOMElements(selector).map(createDOMWrapper)
return this.findAllDOMElements(selector).map((e) =>
createDOMWrapper(e)
)
}

private attachNativeEventListener(): void {
Expand Down
9 changes: 5 additions & 4 deletions src/wrapperFactory.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ComponentPublicInstance, App } from 'vue'
import { ComponentPublicInstance, App, VNode } from 'vue'
import type { DOMWrapper as DOMWrapperType } from './domWrapper'
import type { VueWrapper as VueWrapperType } from './vueWrapper'

Expand All @@ -8,7 +8,8 @@ export enum WrapperType {
}

type DOMWrapperFactory = <T extends Node>(
element: T | null | undefined
element: T | null | undefined,
subTree?: VNode
) => DOMWrapperType<T>
type VueWrapperFactory = <T extends ComponentPublicInstance>(
app: App | null,
Expand Down Expand Up @@ -36,7 +37,7 @@ export function registerFactory(
factories[type] = fn
}

export const createDOMWrapper: DOMWrapperFactory = (element) =>
factories[WrapperType.DOMWrapper]!(element)
export const createDOMWrapper: DOMWrapperFactory = (element, subTree) =>
factories[WrapperType.DOMWrapper]!(element, subTree)
export const createVueWrapper: VueWrapperFactory = (app, vm, setProps) =>
factories[WrapperType.VueWrapper]!(app, vm, setProps)
30 changes: 30 additions & 0 deletions tests/element.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,36 @@ describe('element', () => {
expect(wrapper.text()).toBe('foobarbaz')
})

it('returns correct element for functional component with multiple roots', () => {
const Func = () => ['foo', 'bar']

const Parent = defineComponent({
name: 'Parent',
components: { Func },
template: '<div><Func/></div>'
})
const wrapper = mount(Parent)

expect(wrapper.findComponent(Func).html()).toBe('foo\nbar')
expect(wrapper.findComponent(Func).text()).toBe('foobar')
})

it('returns correct element for functional component with multiple roots', () => {
const Func = () => [h('div', {}, 'foo'), h('div', {}, 'bar')]

const Parent = defineComponent({
name: 'Parent',
components: { Func },
template: '<div><Func/></div>'
})
const wrapper = mount(Parent)

expect(wrapper.findComponent(Func).html()).toBe(
'<div>foo</div>\n<div>bar</div>'
)
expect(wrapper.findComponent(Func).text()).toBe('foobar')
})

it('returns correct element for root slot', () => {
const Parent = defineComponent({
components: { ReturnSlot },
Expand Down

0 comments on commit b03d208

Please sign in to comment.