Skip to content

Commit

Permalink
fix(find): find and findAll should not find itself on DOM wrappers (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
xanf committed Mar 28, 2022
1 parent cdf8e09 commit 1923223
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 22 deletions.
14 changes: 6 additions & 8 deletions src/baseWrapper.ts
Expand Up @@ -80,24 +80,22 @@ export default abstract class BaseWrapper<ElementType extends Node>
}
}

const elements = this.findAllDOMElements(selector)
const elements = this.findAll(selector)
if (elements.length > 0) {
return createDOMWrapper(elements[0])
return elements[0]
}

return createWrapperError('DOMWrapper')
}

findAll<K extends keyof HTMLElementTagNameMap>(
abstract findAll<K extends keyof HTMLElementTagNameMap>(
selector: K
): DOMWrapper<HTMLElementTagNameMap[K]>[]
findAll<K extends keyof SVGElementTagNameMap>(
abstract findAll<K extends keyof SVGElementTagNameMap>(
selector: K
): DOMWrapper<SVGElementTagNameMap[K]>[]
findAll<T extends Element>(selector: string): DOMWrapper<T>[]
findAll(selector: string): DOMWrapper<Element>[] {
return this.findAllDOMElements(selector).map(createDOMWrapper)
}
abstract findAll<T extends Element>(selector: string): DOMWrapper<T>[]
abstract findAll(selector: string): DOMWrapper<Element>[]

// searching by string without specifying component results in WrapperLike object
findComponent<T extends never>(selector: string): WrapperLike
Expand Down
23 changes: 22 additions & 1 deletion src/domWrapper.ts
@@ -1,7 +1,11 @@
import { config } from './config'
import BaseWrapper from './baseWrapper'
import WrapperLike from './interfaces/wrapperLike'
import { registerFactory, WrapperType } from './wrapperFactory'
import {
createDOMWrapper,
registerFactory,
WrapperType
} from './wrapperFactory'
import { RefSelector } from './types'
import { isRefSelector } from './utils'
import { createWrapperError } from './errorWrapper'
Expand Down Expand Up @@ -40,6 +44,23 @@ export class DOMWrapper<NodeType extends Node> extends BaseWrapper<NodeType> {
return result
}

findAll<K extends keyof HTMLElementTagNameMap>(
selector: K
): DOMWrapper<HTMLElementTagNameMap[K]>[]
findAll<K extends keyof SVGElementTagNameMap>(
selector: K
): DOMWrapper<SVGElementTagNameMap[K]>[]
findAll<T extends Element>(selector: string): DOMWrapper<T>[]
findAll(selector: string): DOMWrapper<Element>[] {
if (!(this.wrapperElement instanceof Element)) {
return []
}
return Array.from(
this.wrapperElement.querySelectorAll(selector),
createDOMWrapper
)
}

findAllComponents(selector: any): any {
const results = super.findAllComponents(selector)
return results.filter((r: WrapperLike) => this.element.contains(r.element))
Expand Down
12 changes: 12 additions & 0 deletions src/vueWrapper.ts
Expand Up @@ -15,6 +15,7 @@ import { mergeDeep } from './utils'
import { getRootNodes } from './utils/getRootNodes'
import { emitted, recordEvent } from './emit'
import BaseWrapper from './baseWrapper'
import type { DOMWrapper } from './domWrapper'
import {
createDOMWrapper,
registerFactory,
Expand Down Expand Up @@ -81,6 +82,17 @@ export class VueWrapper<
return this.vm.$
}

findAll<K extends keyof HTMLElementTagNameMap>(
selector: K
): DOMWrapper<HTMLElementTagNameMap[K]>[]
findAll<K extends keyof SVGElementTagNameMap>(
selector: K
): DOMWrapper<SVGElementTagNameMap[K]>[]
findAll<T extends Element>(selector: string): DOMWrapper<T>[]
findAll(selector: string): DOMWrapper<Element>[] {
return this.findAllDOMElements(selector).map(createDOMWrapper)
}

private attachNativeEventListener(): void {
const vm = this.vm
if (!vm) return
Expand Down
7 changes: 7 additions & 0 deletions tests/components/ParentComponent.vue
@@ -0,0 +1,7 @@
<template>
<div class="parent">
<div class="first">child</div>
<div>child</div>
<div>child</div>
</div>
</template>
46 changes: 33 additions & 13 deletions tests/find.spec.ts
@@ -1,7 +1,7 @@
import { defineComponent, h, nextTick, Fragment } from 'vue'

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

describe('find', () => {
Expand Down Expand Up @@ -93,18 +93,6 @@ describe('find', () => {
expect(wrapper.find('.foo').exists()).toBe(true)
})

it('returns the root element from dom wrapper if it matches', () => {
const Component = defineComponent({
render() {
return h('div', { class: 'foo' }, 'text')
}
})

const wrapper = mount(Component)
const domWrapper = wrapper.find('.foo')
expect(domWrapper.find('.foo').exists()).toBe(true)
})

it('can be chained', () => {
const Component = defineComponent({
render() {
Expand Down Expand Up @@ -347,4 +335,36 @@ describe('findAll', () => {
expect(wrapper.findAll('a')).toHaveLength(3)
})
})

// https://github.com/vuejs/test-utils/issues/1233
it('finds 3 children', () => {
const wrapper = mount(ParentComponent)

const parent = wrapper.get('.parent')

expect(parent.findAll('div').length).toBe(3)
})

it('finds itself on Vue wrapper', () => {
const wrapper = mount(ParentComponent)

const parent = wrapper.get('div')

expect(parent.classes()).toContain('parent')
})

it('does not find itself on DOM node', () => {
const wrapper = mount(ParentComponent)

const parent = wrapper.get('.parent')

expect(parent.find('div').classes()).toContain('first')
})

// https://github.com/vuejs/test-utils/issues/1233
it('finds all divs with findAll', () => {
const wrapper = mount(ParentComponent)

expect(wrapper.findAll('div').length).toBe(4)
})
})

0 comments on commit 1923223

Please sign in to comment.