diff --git a/src/baseWrapper.ts b/src/baseWrapper.ts index ffb68ec22..9ed34a1cb 100644 --- a/src/baseWrapper.ts +++ b/src/baseWrapper.ts @@ -45,9 +45,8 @@ export default abstract class BaseWrapper find( selector: K ): DOMWrapper - find(selector: string | RefSelector): DOMWrapper - find(selector: string): DOMWrapper - find(selector: RefSelector): DOMWrapper + find(selector: string): DOMWrapper + find(selector: string | RefSelector): DOMWrapper find(selector: string | RefSelector): DOMWrapper { // allow finding the root element if (!isElement(this.element)) { @@ -227,9 +226,13 @@ export default abstract class BaseWrapper get( selector: K ): Omit, 'exists'> - get(selector: string): Omit, 'exists'> - get(selector: RefSelector): Omit, 'exists'> - get(selector: string | RefSelector): Omit, 'exists'> { + get( + selector: string + ): Omit, 'exists'> + get( + selector: string | RefSelector + ): Omit, 'exists'> + get(selector: string | RefSelector): Omit, 'exists'> { const result = this.find(selector) if (result.exists()) { return result diff --git a/src/domWrapper.ts b/src/domWrapper.ts index 605f184bc..46a72b32d 100644 --- a/src/domWrapper.ts +++ b/src/domWrapper.ts @@ -3,6 +3,9 @@ import BaseWrapper from './baseWrapper' import WrapperLike from './interfaces/wrapperLike' import { isElement } from './utils/isElement' import { registerFactory, WrapperType } from './wrapperFactory' +import { RefSelector } from './types' +import { isRefSelector } from './utils' +import { createWrapperError } from './errorWrapper' export class DOMWrapper extends BaseWrapper { constructor(element: NodeType) { @@ -21,6 +24,17 @@ export class DOMWrapper extends BaseWrapper { : this.element.toString() } + find(selector: string | RefSelector): DOMWrapper { + const result = super.find(selector) + if (result.exists() && isRefSelector(selector)) { + return this.element.contains(result.element) + ? result + : createWrapperError('DOMWrapper') + } + + return result + } + findAllComponents(selector: any): any { const results = super.findAllComponents(selector) return results.filter((r: WrapperLike) => this.element.contains(r.element)) diff --git a/src/interfaces/wrapperLike.ts b/src/interfaces/wrapperLike.ts index 3ba2bc9ee..9d56bfba1 100644 --- a/src/interfaces/wrapperLike.ts +++ b/src/interfaces/wrapperLike.ts @@ -17,9 +17,8 @@ export default interface WrapperLike { find( selector: K ): DOMWrapper - find(selector: string | RefSelector): DOMWrapper - find(selector: string): DOMWrapper - find(selector: RefSelector): DOMWrapper + find(selector: string): DOMWrapper + find(selector: string | RefSelector): DOMWrapper findAll( selector: K @@ -68,9 +67,12 @@ export default interface WrapperLike { get( selector: K ): Omit, 'exists'> - get(selector: string): Omit, 'exists'> - get(selector: RefSelector): Omit, 'exists'> - get(selector: string): Omit, 'exists'> + get( + selector: string + ): Omit, 'exists'> + get( + selector: string | RefSelector + ): Omit, 'exists'> getComponent(selector: string): Omit getComponent( diff --git a/src/utils.ts b/src/utils.ts index 3ca2bc8ca..656f4f73a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,4 @@ -import { GlobalMountOptions } from './types' +import { GlobalMountOptions, RefSelector } from './types' import { ComponentOptions, ConcreteComponent, FunctionalComponent } from 'vue' import { config } from './config' @@ -107,3 +107,9 @@ export function hasOwnProperty( ): obj is O & Record { return obj.hasOwnProperty(prop) } + +export function isRefSelector( + selector: string | RefSelector +): selector is RefSelector { + return typeof selector === 'object' && 'ref' in selector +} diff --git a/tests/find.spec.ts b/tests/find.spec.ts index f165f6384..6235144e0 100644 --- a/tests/find.spec.ts +++ b/tests/find.spec.ts @@ -38,6 +38,21 @@ describe('find', () => { expect(wrapper.find({ ref: 'plain' }).exists()).toBe(true) expect(wrapper.find({ ref: 'plain' }).element).toBeInstanceOf(Text) }) + + it('does not find ref located in the same component but not in current DOM wrapper', () => { + const Component = defineComponent({ + render() { + return h('div', [ + h('span', { ref: 'span', id: 'my-span' }), + h('div', { class: 'search-target' }) + ]) + } + }) + const wrapper = mount(Component) + expect( + wrapper.find('.search-target').find({ ref: 'span' }).exists() + ).toBe(false) + }) }) it('find using multiple root nodes', () => {