rjurado01
rjurado01

Reputation: 5535

Vue test utils: extend VueWrapper to add plugin method

I am using Vue test utils and Typescript. I have added Data Test ID Plugin.

How can I extend VueWrapper interface to avoid this error:

Property 'findByTestId' does not exist on type 'VueWrapper<{ $: ComponentInternalInstance; $data: { showUserMenu: boolean ...

Upvotes: 0

Views: 1197

Answers (2)

Marco Weber
Marco Weber

Reputation: 839

Another option is to create a .d.ts file e.g. vue-test-utils.d.ts with the following content:

import { DOMWrapper } from '@vue/test-utils';

declare module '@vue/test-utils' {
  export class VueWrapper {
    findByTestId(selector: string): DOMWrapper[];
  }
}

And include it in your tsconfig.json

  "include": [
     //...
     "./vue-test-utils.d.ts"
     //...
  ]

So you're able to extend the existing definition of the VueWrapper class.

Upvotes: 1

tony19
tony19

Reputation: 138246

One solution is to export a type that adds findByTestId:

// my-vue-test-utils-plugin.ts
import { config, DOMWrapper, createWrapperError, type VueWrapper } from '@vue/test-utils'
               👇
export type TestWrapper = VueWrapper<any> & {
  findByTestId: (selector: string) => DOMWrapper<HTMLElement>
}

const DataTestIdPlugin = (wrapper: VueWrapper<any>) => {
  function findByTestId(selector: string) {
    const dataSelector = `[data-testid='${selector}']`
    const element = wrapper.element.querySelector(dataSelector)
    if (element) {
      return new DOMWrapper(element)
    }

    return createWrapperError('DOMWrapper')
  }

  return {
    findByTestId
  }
}

config.plugins.VueWrapper.install(DataTestIdPlugin as any)

Then, use type assertion (as keyword followed by the exported type above) on the mount() result:

// MyComponent.spec.ts
import type { TestWrapper } from './my-vue-test-utils-plugin.ts'

describe('MyComponent', () => {
  it('renders properly', () => {        👇
    const wrapper = mount(MyComponent) as TestWrapper
    expect(wrapper.findByTestId('my-component').text()).toBe('Hello World')
  })
})

Upvotes: 1

Related Questions