Skip to content

Commit

Permalink
fix: findAll root nodes when using render function (#1227)
Browse files Browse the repository at this point in the history
  • Loading branch information
freakzlike committed Jan 17, 2022
1 parent 12334f7 commit 77994a0
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 33 deletions.
53 changes: 20 additions & 33 deletions src/baseWrapper.ts
@@ -1,4 +1,4 @@
import { isNotNullOrUndefined, textContent } from './utils'
import { textContent } from './utils'
import type { TriggerOptions } from './createDomEvent'
import {
ComponentInternalInstance,
Expand Down Expand Up @@ -41,6 +41,21 @@ export default abstract class BaseWrapper<ElementType extends Node>
this.wrapperElement = element
}

protected findAllDOMElements(selector: string): Element[] {
const elementRootNodes = this.getRootNodes().filter(isElement)
if (elementRootNodes.length === 0) return []

const result: Element[] = [
...elementRootNodes.filter((node) => node.matches(selector))
]

elementRootNodes.forEach((rootNode) => {
result.push(...Array.from(rootNode.querySelectorAll(selector)))
})

return result
}

find<K extends keyof HTMLElementTagNameMap>(
selector: K
): DOMWrapper<HTMLElementTagNameMap[K]>
Expand All @@ -65,24 +80,9 @@ export default abstract class BaseWrapper<ElementType extends Node>
}
}

const elementRootNodes = this.getRootNodes().filter(
(node): node is Element => node instanceof Element
)
if (elementRootNodes.length === 0) {
return createWrapperError('DOMWrapper')
}
const matchingRootNode = elementRootNodes.find((node) =>
node.matches(selector)
)
if (matchingRootNode) {
return createDOMWrapper(matchingRootNode)
}

const result = elementRootNodes
.map((node) => node.querySelector(selector))
.filter(isNotNullOrUndefined)
if (result.length > 0) {
return createDOMWrapper(result[0])
const elements = this.findAllDOMElements(selector)
if (elements.length > 0) {
return createDOMWrapper(elements[0])
}

return createWrapperError('DOMWrapper')
Expand All @@ -96,20 +96,7 @@ export default abstract class BaseWrapper<ElementType extends Node>
): DOMWrapper<SVGElementTagNameMap[K]>[]
findAll<T extends Element>(selector: string): DOMWrapper<T>[]
findAll(selector: string): DOMWrapper<Element>[] {
if (!isElement(this.element)) {
return []
}

const result = this.element.matches(selector)
? [createDOMWrapper(this.element)]
: []

return [
...result,
...Array.from(this.element.querySelectorAll(selector)).map((x) =>
createDOMWrapper(x)
)
]
return this.findAllDOMElements(selector).map(createDOMWrapper)
}

// searching by string without specifying component results in WrapperLike object
Expand Down
14 changes: 14 additions & 0 deletions tests/components/MultipleRootRender.vue
@@ -0,0 +1,14 @@
<template>
<render></render>
</template>

<script setup lang="ts">
import { h } from 'vue'
const render = () => [
h('a', {}, 'first'),
h('a', {}, 'second'),
h('a', {}, 'third'),
h('span', {}, 'other span')
]
</script>
11 changes: 11 additions & 0 deletions tests/find.spec.ts
Expand Up @@ -2,6 +2,7 @@ import { defineComponent, h, nextTick, Fragment } from 'vue'

import { mount, VueWrapper } from '../src'
import SuspenseComponent from './components/Suspense.vue'
import MultipleRootRender from './components/MultipleRootRender.vue'

describe('find', () => {
it('find using single root node', () => {
Expand Down Expand Up @@ -156,6 +157,11 @@ describe('find', () => {
const etc = wrapper.findComponent({ name: 'EmptyTestComponent' })
expect(etc.find('p').exists()).toBe(false)
})

it('finds root node with SFC render function', () => {
const wrapper = mount(MultipleRootRender)
expect(wrapper.find('a').exists()).toBe(true)
})
})

describe('findAll', () => {
Expand Down Expand Up @@ -335,5 +341,10 @@ describe('findAll', () => {
.exists()
).toBe(true)
})

it('finds all root nodes with SFC render function', () => {
const wrapper = mount(MultipleRootRender)
expect(wrapper.findAll('a')).toHaveLength(3)
})
})
})

0 comments on commit 77994a0

Please sign in to comment.