Skip to content

Commit

Permalink
feat: include component and wrapper in return type for vue mount adap…
Browse files Browse the repository at this point in the history
…ter (#24479)

BREAKING CHANGE: Vue mount returns wrapper and component rather than wrapper only
  • Loading branch information
lmiller1990 committed Nov 2, 2022
1 parent 6c1cedf commit 33875d7
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 16 deletions.
8 changes: 8 additions & 0 deletions npm/vue/cypress/component/test-utils-api/TestUtilsApi.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,12 @@ describe('VueTestUtils API', () => {

cy.get('h1').contains(greeting)
})

it('accesses wrapper and component', () => {
mount(TestUtilsApi, { props: { msg: 'Hello world!' } }).then(({ component, wrapper }) => {
expect(wrapper.find('h2').text()).to.eq('Hello world!')
expect(component.msg).to.eq('Hello world!')
expect(component.$data.foo).to.eq('bar')
})
})
})
14 changes: 14 additions & 0 deletions npm/vue/cypress/component/test-utils-api/TestUtilsApi.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
<template>
<globally-registered-component />
<h2>{{ msg }}</h2>
</template>

<script>
export default {
props: {
msg: String,
},
data () {
return {
foo: 'bar',
}
},
}
</script>
85 changes: 70 additions & 15 deletions npm/vue/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,10 @@ export function mount<V extends {}>(
__vccOpts: any
},
options?: MountingOptions<any> & Record<string, any>
): Cypress.Chainable<VueWrapper<ComponentPublicInstance<V>>>
): Cypress.Chainable<{
wrapper: VueWrapper<ComponentPublicInstance<V>>
component: VueWrapper<ComponentPublicInstance<V>>['vm']
}>

// Class component (without vue-class-component) - props
export function mount<V extends {}, P>(
Expand All @@ -139,7 +142,10 @@ export function mount<V extends {}, P>(
defaultProps?: Record<string, Prop<any>> | string[]
},
options?: MountingOptions<P & PublicProps> & Record<string, any>
): Cypress.Chainable<VueWrapper<ComponentPublicInstance<V>>>
): Cypress.Chainable<{
wrapper: VueWrapper<ComponentPublicInstance<V>>
component: VueWrapper<ComponentPublicInstance<V>>['vm']
}>

// Class component - no props
export function mount<V extends {}>(
Expand All @@ -148,7 +154,10 @@ export function mount<V extends {}>(
registerHooks(keys: string[]): void
},
options?: MountingOptions<any> & Record<string, any>
): Cypress.Chainable<VueWrapper<ComponentPublicInstance<V>>>
): Cypress.Chainable<{
wrapper: VueWrapper<ComponentPublicInstance<V>>
component: VueWrapper<ComponentPublicInstance<V>>['vm']
}>

// Class component - props
export function mount<V extends {}, P>(
Expand All @@ -158,13 +167,19 @@ export function mount<V extends {}, P>(
registerHooks(keys: string[]): void
},
options?: MountingOptions<P & PublicProps> & Record<string, any>
): Cypress.Chainable<VueWrapper<ComponentPublicInstance<V>>>
): Cypress.Chainable<{
wrapper: VueWrapper<ComponentPublicInstance<V>>
component: VueWrapper<ComponentPublicInstance<V>>['vm']
}>

// Functional component with emits
export function mount<Props extends {}, E extends EmitsOptions = {}>(
originalComponent: FunctionalComponent<Props, E>,
options?: MountingOptions<Props & PublicProps> & Record<string, any>
): Cypress.Chainable<VueWrapper<ComponentPublicInstance<Props>>>
): Cypress.Chainable<{
wrapper: VueWrapper<ComponentPublicInstance<Props>>
component: VueWrapper<ComponentPublicInstance<Props>>['vm']
}>

// Component declared with defineComponent
export function mount<
Expand Down Expand Up @@ -200,8 +215,8 @@ export function mount<
D
> &
Record<string, any>
): Cypress.Chainable<
VueWrapper<
): Cypress.Chainable<{
wrapper: VueWrapper<
InstanceType<
DefineComponent<
PropsOrPropOptions,
Expand All @@ -219,13 +234,34 @@ export function mount<
>
>
>
component: VueWrapper<
InstanceType<
DefineComponent<
PropsOrPropOptions,
RawBindings,
D,
C,
M,
Mixin,
Extends,
E,
EE,
PP,
Props,
Defaults
>
>
>['vm']}
>

// component declared by vue-tsc ScriptSetup
export function mount<T extends DefineComponent<any, any, any, any>>(
component: T,
options?: ComponentMountingOptions<T>
): Cypress.Chainable<VueWrapper<InstanceType<T>>>
): Cypress.Chainable<{
wrapper: VueWrapper<InstanceType<T>>
component: VueWrapper<InstanceType<T>>['vm']
}>

// Component declared with no props
export function mount<
Expand All @@ -251,7 +287,10 @@ export function mount<
EE
>,
options?: MountingOptions<Props & PublicProps, D>
): Cypress.Chainable<VueWrapper<ComponentPublicInstance<Props, RawBindings, D, C, M, E, VNodeProps & Props>>> & Record<string, any>
): Cypress.Chainable<{
wrapper: VueWrapper<ComponentPublicInstance<Props, RawBindings, D, C, M, E, VNodeProps & Props>>
component: VueWrapper<ComponentPublicInstance<Props, RawBindings, D, C, M, E, VNodeProps & Props>>['vm']
}> & Record<string, any>

// Component declared with { props: [] }
export function mount<
Expand Down Expand Up @@ -281,7 +320,10 @@ export function mount<
Props
>,
options?: MountingOptions<Props & PublicProps, D>
): Cypress.Chainable<VueWrapper<ComponentPublicInstance<Props, RawBindings, D, C, M, E>>>
): Cypress.Chainable<{
wrapper: VueWrapper<ComponentPublicInstance<Props, RawBindings, D, C, M, E>>
component: VueWrapper<ComponentPublicInstance<Props, RawBindings, D, C, M, E>>['vm']
}>

// Component declared with { props: { ... } }
export function mount<
Expand Down Expand Up @@ -309,8 +351,8 @@ export function mount<
EE
>,
options?: MountingOptions<ExtractPropTypes<PropsOptions> & PublicProps, D>
): Cypress.Chainable<
VueWrapper<
): Cypress.Chainable<{
wrapper: VueWrapper<
ComponentPublicInstance<
ExtractPropTypes<PropsOptions>,
RawBindings,
Expand All @@ -321,7 +363,18 @@ export function mount<
VNodeProps & ExtractPropTypes<PropsOptions>
>
>
>
component: VueWrapper<
ComponentPublicInstance<
ExtractPropTypes<PropsOptions>,
RawBindings,
D,
C,
M,
E,
VNodeProps & ExtractPropTypes<PropsOptions>
>
>['vm']
}>

// implementation
export function mount (componentOptions: any, options: any = {}) {
Expand Down Expand Up @@ -367,7 +420,6 @@ export function mount (componentOptions: any, options: any = {}) {
Cypress.vue = wrapper.vm as ComponentPublicInstance

return cy
.wrap(wrapper, { log: false })
.wait(1, { log: false })
.then(() => {
if (logInstance) {
Expand All @@ -377,7 +429,10 @@ export function mount (componentOptions: any, options: any = {}) {

// by returning undefined we keep the previous subject
// which is the mounted component
return undefined
return {
wrapper,
component: wrapper.vm,
}
})
})
}
Expand Down
10 changes: 9 additions & 1 deletion npm/vue2/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,10 @@ function getComponentDisplayName (componentOptions: any): string {
export const mount = (
component: VueComponent,
optionsOrProps: MountOptionsArgument = {},
) => {
): Cypress.Chainable<{
wrapper: Wrapper<Vue, Element>
component: Wrapper<Vue, Element>['vm']
}> => {
const options: Partial<MountOptions> = Cypress._.pick(
optionsOrProps,
defaultOptions,
Expand Down Expand Up @@ -410,6 +413,11 @@ export const mount = (

Cypress.vue = VTUWrapper.vm
Cypress.vueWrapper = VTUWrapper

return {
wrapper: VTUWrapper,
component: VTUWrapper.vm,
}
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ describe('<Logo />', () => {
propsData: {
msg: slotContent,
},
data () {
return {
foo: 'bar'
}
}
})
.then(({ wrapper, component }) => {
expect(wrapper.find('.hello').text()).to.contain(slotContent)
expect(component.$data.foo).to.eq('bar')
})

cy.contains('h1', slotContent)
Expand Down

0 comments on commit 33875d7

Please sign in to comment.