Skip to content

Commit f09cc09

Browse files
committed
fix: remove ability to use findComponent with DOM selector
1 parent df43338 commit f09cc09

File tree

8 files changed

+27
-37
lines changed

8 files changed

+27
-37
lines changed

docs/api/index.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ test('mounts a component', () => {
4242
})
4343
```
4444

45-
Notice that `mount` accepts a second parameter to define the component's state configuration.
45+
Notice that `mount` accepts a second parameter to define the component's state configuration.
4646

4747
**Example: mounting with component props and a Vue App plugin**
4848
```js
@@ -58,7 +58,7 @@ const wrapper = mount(Component, {
5858

5959
#### options.global
6060

61-
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.
61+
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.
6262

6363
::: tip
6464
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<T extends ComponentPublicInstance>(selector: FindComponentSelector
11031103
11041104
| syntax | example | details |
11051105
| -------------- | ----------------------------- | ------------------------------------------------------------ |
1106-
| querySelector | `findComponent('.component')` | Matches standard query selector. |
11071106
| Component name | `findComponent({name: 'a'})` | matches PascalCase, snake-case, camelCase |
11081107
| Component ref | `findComponent({ref: 'ref'})` | Can be used only on direct ref children of mounted component |
11091108
| SFC | `findComponent(Component)` | Pass an imported component directly |

src/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ interface NameSelector {
2626
name: string
2727
}
2828

29-
export type FindComponentSelector = RefSelector | NameSelector | string
30-
export type FindAllComponentsSelector = NameSelector | string
29+
export type FindComponentSelector = RefSelector | NameSelector
30+
export type FindAllComponentsSelector = NameSelector
3131

3232
export type Slot = VNode | string | { render: Function } | Function | Component
3333

src/vueWrapper.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,12 @@ export class VueWrapper<T extends ComponentPublicInstance>
151151
findComponent<T extends ComponentPublicInstance>(
152152
selector: FindComponentSelector | (new () => T)
153153
): VueWrapper<T> {
154+
if (typeof selector === 'string') {
155+
throw Error(
156+
'findComponent requires a Vue constructor or valid find object. If you are searching for DOM nodes, use `find` instead'
157+
)
158+
}
159+
154160
if (typeof selector === 'object' && 'ref' in selector) {
155161
const result = this.vm.$refs[selector.ref]
156162
if (result && !(result instanceof HTMLElement)) {
@@ -200,6 +206,12 @@ export class VueWrapper<T extends ComponentPublicInstance>
200206
}
201207

202208
findAllComponents(selector: FindAllComponentsSelector): VueWrapper<T>[] {
209+
if (typeof selector === 'string') {
210+
throw Error(
211+
'findAllComponents requires a Vue constructor or valid find object. If you are searching for DOM nodes, use `find` instead'
212+
)
213+
}
214+
203215
return find(this.vm.$.subTree, selector).map((c) => createWrapper(null, c))
204216
}
205217

test-dts/getComponent.d-test.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@ const componentByName = wrapper.getComponent({ name: 'ComponentToFind' })
2828
// returns a wrapper with a generic vm (any)
2929
expectType<ComponentPublicInstance>(componentByName.vm)
3030

31-
// get by string
32-
const componentByString = wrapper.getComponent('other')
33-
// returns a wrapper with a generic vm (any)
34-
expectType<ComponentPublicInstance>(componentByString.vm)
35-
3631
// get by ref
3732
const componentByRef = wrapper.getComponent({ ref: 'ref' })
3833
// returns a wrapper with a generic vm (any)

tests/attributes.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ describe('attributes', () => {
5858
}
5959
})
6060

61-
expect(wrapper.findComponent('.hello-outside').attributes()).toEqual({
61+
expect(wrapper.findComponent({ name: 'Hello' }).attributes()).toEqual({
6262
class: 'hello-outside',
6363
'data-testid': 'hello',
6464
disabled: ''

tests/findAllComponents.spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ const compA = defineComponent({
1818
describe('findAllComponents', () => {
1919
it('finds all deeply nested vue components', () => {
2020
const wrapper = mount(compA)
21-
// find by DOM selector
22-
expect(wrapper.findAllComponents('.C')).toHaveLength(2)
21+
expect(wrapper.findAllComponents(compC)).toHaveLength(2)
2322
expect(wrapper.findAllComponents({ name: 'Hello' })[0].text()).toBe(
2423
'Hello world'
2524
)

tests/findComponent.spec.ts

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ const compA = defineComponent({
4141
describe('findComponent', () => {
4242
it('does not find plain dom elements', () => {
4343
const wrapper = mount(compA)
44-
expect(wrapper.findComponent('.domElement').exists()).toBeFalsy()
44+
// @ts-expect-error
45+
expect(() => wrapper.findComponent('.domElement')).toThrowError()
4546
})
4647

4748
it('finds component by ref', () => {
@@ -59,23 +60,6 @@ describe('findComponent', () => {
5960
expect(wrapper.findComponent({ ref: 'hello' }).exists()).toBe(false)
6061
})
6162

62-
it('finds component by dom selector', () => {
63-
const wrapper = mount(compA)
64-
// find by DOM selector
65-
expect(wrapper.findComponent('.C').vm).toHaveProperty(
66-
'$options.name',
67-
'ComponentC'
68-
)
69-
})
70-
71-
it('does allows using complicated DOM selector query', () => {
72-
const wrapper = mount(compA)
73-
expect(wrapper.findComponent('.B > .C').vm).toHaveProperty(
74-
'$options.name',
75-
'ComponentC'
76-
)
77-
})
78-
7963
it('finds component by name', () => {
8064
const wrapper = mount(compA)
8165
expect(wrapper.findComponent({ name: 'Hello' }).text()).toBe('Hello world')

tests/getComponent.spec.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { defineComponent } from 'vue'
2-
import { mount, MountingOptions, RouterLinkStub, shallowMount } from '../src'
2+
import { mount, RouterLinkStub, shallowMount } from '../src'
33
import Issue425 from './components/Issue425.vue'
44

55
const compA = defineComponent({
@@ -15,14 +15,15 @@ describe('getComponent', () => {
1515
it('should delegate to findComponent', () => {
1616
const wrapper = mount(compA)
1717
jest.spyOn(wrapper, 'findComponent').mockReturnThis()
18-
wrapper.getComponent('.domElement')
19-
expect(wrapper.findComponent).toHaveBeenCalledWith('.domElement')
18+
wrapper.getComponent(compA)
19+
expect(wrapper.findComponent).toHaveBeenCalledWith(compA)
2020
})
2121

2222
it('should throw if not found with a string selector', () => {
2323
const wrapper = mount(compA)
24+
// @ts-expect-error
2425
expect(() => wrapper.getComponent('.domElement')).toThrowError(
25-
'Unable to get component with selector .domElement within: <div class="A"></div>'
26+
'findComponent requires a Vue constructor or valid find object. If you are searching for DOM nodes, use `find` instead'
2627
)
2728
})
2829

@@ -69,12 +70,12 @@ describe('getComponent', () => {
6970
// https://github.com/vuejs/vue-test-utils-next/issues/425
7071
it('works with router-link and mount', () => {
7172
const wrapper = mount(Issue425, options)
72-
expect(wrapper.getComponent('.link').props('to')).toEqual({ name })
73+
expect(wrapper.getComponent(RouterLinkStub).props('to')).toEqual({ name })
7374
})
7475

7576
// https://github.com/vuejs/vue-test-utils-next/issues/425
7677
it('works with router-link and shallowMount', () => {
7778
const wrapper = shallowMount(Issue425, options)
78-
expect(wrapper.getComponent('.link').props('to')).toEqual({ name })
79+
expect(wrapper.getComponent(RouterLinkStub).props('to')).toEqual({ name })
7980
})
8081
})

0 commit comments

Comments
 (0)