diff --git a/src/vue-wrapper.ts b/src/vue-wrapper.ts index d80ed8712..cd0b9ae12 100644 --- a/src/vue-wrapper.ts +++ b/src/vue-wrapper.ts @@ -110,13 +110,21 @@ export class VueWrapper get(selector: string): DOMWrapper { const result = this.find(selector) if (result instanceof ErrorWrapper) { - throw new Error(`Unable to find ${selector} within: ${this.html()}`) + throw new Error(`Unable to get ${selector} within: ${this.html()}`) } return result } - findComponent(selector: FindComponentSelector): VueWrapper | ErrorWrapper { + findComponent( + selector: new () => T + ): VueWrapper | ErrorWrapper + findComponent( + selector: FindComponentSelector + ): VueWrapper | ErrorWrapper + findComponent( + selector: any + ): VueWrapper | ErrorWrapper { if (typeof selector === 'object' && 'ref' in selector) { const result = this.vm.$refs[selector.ref] return result @@ -129,6 +137,25 @@ export class VueWrapper return createWrapper(null, result[0]) } + getComponent( + selector: new () => T + ): VueWrapper + getComponent( + selector: FindComponentSelector + ): VueWrapper + getComponent( + selector: any + ): VueWrapper { + const result = this.findComponent(selector) + if (result instanceof ErrorWrapper) { + throw new Error( + `Unable to get component with selector ${selector} within: ${this.html()}` + ) + } + + return result as VueWrapper + } + findAllComponents(selector: FindAllComponentsSelector): VueWrapper[] { return find(this.vm.$.subTree, selector).map((c) => createWrapper(null, c)) } diff --git a/test-dts/getComponent.d-test.ts b/test-dts/getComponent.d-test.ts new file mode 100644 index 000000000..ce59a6342 --- /dev/null +++ b/test-dts/getComponent.d-test.ts @@ -0,0 +1,39 @@ +import { expectType } from 'tsd' +import { defineComponent, ComponentPublicInstance } from 'vue' +import { mount } from '../src' + +const ComponentToFind = defineComponent({ + props: { + a: { + type: String, + required: true + } + }, + template: '' +}) + +const AppWithDefine = defineComponent({ + template: '' +}) + +const wrapper = mount(AppWithDefine) + +// get by type +const componentByType = wrapper.getComponent(ComponentToFind) +// returns a wrapper with properly typed vm +expectType(componentByType.vm.a) + +// get by name +const componentByName = wrapper.getComponent({ name: 'ComponentToFind' }) +// returns a wrapper with a generic vm (any) +expectType(componentByName.vm) + +// get by string +const componentByString = wrapper.getComponent('other') +// returns a wrapper with a generic vm (any) +expectType(componentByString.vm) + +// get by ref +const componentByRef = wrapper.getComponent({ ref: 'ref' }) +// returns a wrapper with a generic vm (any) +expectType(componentByRef.vm) diff --git a/tests/get.spec.ts b/tests/get.spec.ts index 806ffe9bd..a9ac12285 100644 --- a/tests/get.spec.ts +++ b/tests/get.spec.ts @@ -23,7 +23,7 @@ describe('get', () => { const wrapper = mount(Component) expect(() => wrapper.get('#other-span')).toThrowError( - 'Unable to find #other-span within:
' + 'Unable to get #other-span within:
' ) }) }) diff --git a/tests/getComponent.spec.ts b/tests/getComponent.spec.ts new file mode 100644 index 000000000..f64b0c124 --- /dev/null +++ b/tests/getComponent.spec.ts @@ -0,0 +1,23 @@ +import { defineComponent } from 'vue' +import { mount } from '../src' +import { VueWrapper } from '../src/vue-wrapper' + +const compA = defineComponent({ + template: `
` +}) + +describe('getComponent', () => { + it('should delegate to findComponent', () => { + const wrapper = mount(compA) + jest.spyOn(wrapper, 'findComponent').mockReturnThis() + wrapper.getComponent('.domElement') + expect(wrapper.findComponent).toHaveBeenCalledWith('.domElement') + }) + + it('should throw if not found', () => { + const wrapper = mount(compA) + expect(() => wrapper.getComponent('.domElement')).toThrowError( + 'Unable to get component with selector .domElement within:
' + ) + }) +})