Skip to content

Commit a0f87d6

Browse files
authored
Merge pull request #89 from cexbrayat/feat/get-component
feat: getComponent
2 parents 3c035d4 + e1ab0d8 commit a0f87d6

File tree

4 files changed

+92
-3
lines changed

4 files changed

+92
-3
lines changed

src/vue-wrapper.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,21 @@ export class VueWrapper<T extends ComponentPublicInstance>
110110
get(selector: string): DOMWrapper<Element> {
111111
const result = this.find(selector)
112112
if (result instanceof ErrorWrapper) {
113-
throw new Error(`Unable to find ${selector} within: ${this.html()}`)
113+
throw new Error(`Unable to get ${selector} within: ${this.html()}`)
114114
}
115115

116116
return result
117117
}
118118

119-
findComponent(selector: FindComponentSelector): VueWrapper<T> | ErrorWrapper {
119+
findComponent<T extends ComponentPublicInstance>(
120+
selector: new () => T
121+
): VueWrapper<T> | ErrorWrapper
122+
findComponent<T extends ComponentPublicInstance>(
123+
selector: FindComponentSelector
124+
): VueWrapper<T> | ErrorWrapper
125+
findComponent<T extends ComponentPublicInstance>(
126+
selector: any
127+
): VueWrapper<T> | ErrorWrapper {
120128
if (typeof selector === 'object' && 'ref' in selector) {
121129
const result = this.vm.$refs[selector.ref]
122130
return result
@@ -129,6 +137,25 @@ export class VueWrapper<T extends ComponentPublicInstance>
129137
return createWrapper(null, result[0])
130138
}
131139

140+
getComponent<T extends ComponentPublicInstance>(
141+
selector: new () => T
142+
): VueWrapper<T>
143+
getComponent<T extends ComponentPublicInstance>(
144+
selector: FindComponentSelector
145+
): VueWrapper<T>
146+
getComponent<T extends ComponentPublicInstance>(
147+
selector: any
148+
): VueWrapper<T> {
149+
const result = this.findComponent(selector)
150+
if (result instanceof ErrorWrapper) {
151+
throw new Error(
152+
`Unable to get component with selector ${selector} within: ${this.html()}`
153+
)
154+
}
155+
156+
return result as VueWrapper<T>
157+
}
158+
132159
findAllComponents(selector: FindAllComponentsSelector): VueWrapper<T>[] {
133160
return find(this.vm.$.subTree, selector).map((c) => createWrapper(null, c))
134161
}

test-dts/getComponent.d-test.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { expectType } from 'tsd'
2+
import { defineComponent, ComponentPublicInstance } from 'vue'
3+
import { mount } from '../src'
4+
5+
const ComponentToFind = defineComponent({
6+
props: {
7+
a: {
8+
type: String,
9+
required: true
10+
}
11+
},
12+
template: ''
13+
})
14+
15+
const AppWithDefine = defineComponent({
16+
template: ''
17+
})
18+
19+
const wrapper = mount(AppWithDefine)
20+
21+
// get by type
22+
const componentByType = wrapper.getComponent(ComponentToFind)
23+
// returns a wrapper with properly typed vm
24+
expectType<string>(componentByType.vm.a)
25+
26+
// get by name
27+
const componentByName = wrapper.getComponent({ name: 'ComponentToFind' })
28+
// returns a wrapper with a generic vm (any)
29+
expectType<ComponentPublicInstance>(componentByName.vm)
30+
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+
36+
// get by ref
37+
const componentByRef = wrapper.getComponent({ ref: 'ref' })
38+
// returns a wrapper with a generic vm (any)
39+
expectType<ComponentPublicInstance>(componentByRef.vm)

tests/get.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ describe('get', () => {
2323

2424
const wrapper = mount(Component)
2525
expect(() => wrapper.get('#other-span')).toThrowError(
26-
'Unable to find #other-span within: <div><span id="my-span"></span></div>'
26+
'Unable to get #other-span within: <div><span id="my-span"></span></div>'
2727
)
2828
})
2929
})

tests/getComponent.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { defineComponent } from 'vue'
2+
import { mount } from '../src'
3+
import { VueWrapper } from '../src/vue-wrapper'
4+
5+
const compA = defineComponent({
6+
template: `<div class="A"></div>`
7+
})
8+
9+
describe('getComponent', () => {
10+
it('should delegate to findComponent', () => {
11+
const wrapper = mount(compA)
12+
jest.spyOn(wrapper, 'findComponent').mockReturnThis()
13+
wrapper.getComponent('.domElement')
14+
expect(wrapper.findComponent).toHaveBeenCalledWith('.domElement')
15+
})
16+
17+
it('should throw if not found', () => {
18+
const wrapper = mount(compA)
19+
expect(() => wrapper.getComponent('.domElement')).toThrowError(
20+
'Unable to get component with selector .domElement within: <div class="A"></div>'
21+
)
22+
})
23+
})

0 commit comments

Comments
 (0)