diff --git a/docs/api/index.md b/docs/api/index.md index 4e5b2a12c..c5549bda9 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -42,7 +42,7 @@ test('mounts a component', () => { }) ``` -Notice that `mount` accepts a second parameter to define the component's state configuration. +Notice that `mount` accepts a second parameter to define the component's state configuration. **Example: mounting with component props and a Vue App plugin** ```js @@ -58,7 +58,7 @@ const wrapper = mount(Component, { #### options.global -Among component state, you can configure the aformentioned Vue 3 app by the [`MountingOptions.global` config property.](#global) This would be useful for providing mocked values which your components expect to have available. +Among component state, you can configure the aformentioned Vue 3 app by the [`MountingOptions.global` config property.](#global) This would be useful for providing mocked values which your components expect to have available. ::: tip If you find yourself having to set common App configuration for many of your tests, then you can set configuration for your entire test suite using the exported [`config` object.](#config) @@ -1103,7 +1103,6 @@ findComponent(selector: FindComponentSelector | syntax | example | details | | -------------- | ----------------------------- | ------------------------------------------------------------ | -| querySelector | `findComponent('.component')` | Matches standard query selector. | | Component name | `findComponent({name: 'a'})` | matches PascalCase, snake-case, camelCase | | Component ref | `findComponent({ref: 'ref'})` | Can be used only on direct ref children of mounted component | | SFC | `findComponent(Component)` | Pass an imported component directly | diff --git a/src/types.ts b/src/types.ts index 9a6f473cd..375793348 100644 --- a/src/types.ts +++ b/src/types.ts @@ -26,8 +26,8 @@ interface NameSelector { name: string } -export type FindComponentSelector = RefSelector | NameSelector | string -export type FindAllComponentsSelector = NameSelector | string +export type FindComponentSelector = RefSelector | NameSelector +export type FindAllComponentsSelector = NameSelector export type Slot = VNode | string | { render: Function } | Function | Component diff --git a/src/vueWrapper.ts b/src/vueWrapper.ts index 941302c30..89a9b361f 100644 --- a/src/vueWrapper.ts +++ b/src/vueWrapper.ts @@ -151,6 +151,12 @@ export class VueWrapper findComponent( selector: FindComponentSelector | (new () => T) ): VueWrapper { + if (typeof selector === 'string') { + throw Error( + 'findComponent requires a Vue constructor or valid find object. If you are searching for DOM nodes, use `find` instead' + ) + } + if (typeof selector === 'object' && 'ref' in selector) { const result = this.vm.$refs[selector.ref] if (result && !(result instanceof HTMLElement)) { @@ -200,6 +206,12 @@ export class VueWrapper } findAllComponents(selector: FindAllComponentsSelector): VueWrapper[] { + if (typeof selector === 'string') { + throw Error( + 'findAllComponents requires a Vue constructor or valid find object. If you are searching for DOM nodes, use `find` instead' + ) + } + 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 index 5914c9566..c5bbb5429 100644 --- a/test-dts/getComponent.d-test.ts +++ b/test-dts/getComponent.d-test.ts @@ -28,11 +28,6 @@ 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) diff --git a/tests/attributes.spec.ts b/tests/attributes.spec.ts index 412edbfa5..98fed7d88 100644 --- a/tests/attributes.spec.ts +++ b/tests/attributes.spec.ts @@ -58,7 +58,7 @@ describe('attributes', () => { } }) - expect(wrapper.findComponent('.hello-outside').attributes()).toEqual({ + expect(wrapper.findComponent({ name: 'Hello' }).attributes()).toEqual({ class: 'hello-outside', 'data-testid': 'hello', disabled: '' diff --git a/tests/findAllComponents.spec.ts b/tests/findAllComponents.spec.ts index b13e65460..f4d14069d 100644 --- a/tests/findAllComponents.spec.ts +++ b/tests/findAllComponents.spec.ts @@ -18,8 +18,7 @@ const compA = defineComponent({ describe('findAllComponents', () => { it('finds all deeply nested vue components', () => { const wrapper = mount(compA) - // find by DOM selector - expect(wrapper.findAllComponents('.C')).toHaveLength(2) + expect(wrapper.findAllComponents(compC)).toHaveLength(2) expect(wrapper.findAllComponents({ name: 'Hello' })[0].text()).toBe( 'Hello world' ) diff --git a/tests/findComponent.spec.ts b/tests/findComponent.spec.ts index d212ecfaf..971636bcc 100644 --- a/tests/findComponent.spec.ts +++ b/tests/findComponent.spec.ts @@ -41,7 +41,8 @@ const compA = defineComponent({ describe('findComponent', () => { it('does not find plain dom elements', () => { const wrapper = mount(compA) - expect(wrapper.findComponent('.domElement').exists()).toBeFalsy() + // @ts-expect-error + expect(() => wrapper.findComponent('.domElement')).toThrowError() }) it('finds component by ref', () => { @@ -59,23 +60,6 @@ describe('findComponent', () => { expect(wrapper.findComponent({ ref: 'hello' }).exists()).toBe(false) }) - it('finds component by dom selector', () => { - const wrapper = mount(compA) - // find by DOM selector - expect(wrapper.findComponent('.C').vm).toHaveProperty( - '$options.name', - 'ComponentC' - ) - }) - - it('does allows using complicated DOM selector query', () => { - const wrapper = mount(compA) - expect(wrapper.findComponent('.B > .C').vm).toHaveProperty( - '$options.name', - 'ComponentC' - ) - }) - it('finds component by name', () => { const wrapper = mount(compA) expect(wrapper.findComponent({ name: 'Hello' }).text()).toBe('Hello world') diff --git a/tests/getComponent.spec.ts b/tests/getComponent.spec.ts index 9f084f249..08facc54f 100644 --- a/tests/getComponent.spec.ts +++ b/tests/getComponent.spec.ts @@ -1,5 +1,5 @@ import { defineComponent } from 'vue' -import { mount, MountingOptions, RouterLinkStub, shallowMount } from '../src' +import { mount, RouterLinkStub, shallowMount } from '../src' import Issue425 from './components/Issue425.vue' const compA = defineComponent({ @@ -15,14 +15,15 @@ describe('getComponent', () => { it('should delegate to findComponent', () => { const wrapper = mount(compA) jest.spyOn(wrapper, 'findComponent').mockReturnThis() - wrapper.getComponent('.domElement') - expect(wrapper.findComponent).toHaveBeenCalledWith('.domElement') + wrapper.getComponent(compA) + expect(wrapper.findComponent).toHaveBeenCalledWith(compA) }) it('should throw if not found with a string selector', () => { const wrapper = mount(compA) + // @ts-expect-error expect(() => wrapper.getComponent('.domElement')).toThrowError( - 'Unable to get component with selector .domElement within:
' + 'findComponent requires a Vue constructor or valid find object. If you are searching for DOM nodes, use `find` instead' ) }) @@ -69,12 +70,12 @@ describe('getComponent', () => { // https://github.com/vuejs/vue-test-utils-next/issues/425 it('works with router-link and mount', () => { const wrapper = mount(Issue425, options) - expect(wrapper.getComponent('.link').props('to')).toEqual({ name }) + expect(wrapper.getComponent(RouterLinkStub).props('to')).toEqual({ name }) }) // https://github.com/vuejs/vue-test-utils-next/issues/425 it('works with router-link and shallowMount', () => { const wrapper = shallowMount(Issue425, options) - expect(wrapper.getComponent('.link').props('to')).toEqual({ name }) + expect(wrapper.getComponent(RouterLinkStub).props('to')).toEqual({ name }) }) })