diff --git a/src/dom-wrapper.ts b/src/dom-wrapper.ts index c7b6d22fb..683a4e94e 100644 --- a/src/dom-wrapper.ts +++ b/src/dom-wrapper.ts @@ -41,17 +41,31 @@ export class DOMWrapper implements WrapperAPI { return this.element.outerHTML } - find(selector: string): DOMWrapper | ErrorWrapper { - const result = this.element.querySelector(selector) + find( + selector: K + ): DOMWrapper | ErrorWrapper + find( + selector: K + ): DOMWrapper | ErrorWrapper + find(selector: string): DOMWrapper | ErrorWrapper + find(selector: string): DOMWrapper | ErrorWrapper { + const result = this.element.querySelector(selector) if (result) { - return new DOMWrapper(result) + return new DOMWrapper(result) } return new ErrorWrapper({ selector }) } - get(selector: string): DOMWrapper { - const result = this.find(selector) + get( + selector: K + ): DOMWrapper + get( + selector: K + ): DOMWrapper + get(selector: string): DOMWrapper + get(selector: string): DOMWrapper { + const result = this.find(selector) if (result instanceof ErrorWrapper) { throw new Error(`Unable to find ${selector} within: ${this.html()}`) } @@ -59,8 +73,15 @@ export class DOMWrapper implements WrapperAPI { return result } - findAll(selector: string): DOMWrapper[] { - return Array.from(this.element.querySelectorAll(selector)).map( + findAll( + selector: K + ): DOMWrapper[] + findAll( + selector: K + ): DOMWrapper[] + findAll(selector: string): DOMWrapper[] + findAll(selector: string): DOMWrapper[] { + return Array.from(this.element.querySelectorAll(selector)).map( (x) => new DOMWrapper(x) ) } diff --git a/src/error-wrapper.ts b/src/error-wrapper.ts index f16687ed0..ba7c00db0 100644 --- a/src/error-wrapper.ts +++ b/src/error-wrapper.ts @@ -36,6 +36,10 @@ export class ErrorWrapper { throw this.wrapperError('find') } + get(): never { + throw this.wrapperError('get') + } + findAll(): never { throw this.wrapperError('findAll') } diff --git a/src/types.ts b/src/types.ts index d49ee8b43..917982e97 100644 --- a/src/types.ts +++ b/src/types.ts @@ -8,6 +8,7 @@ export interface WrapperAPI { classes: (className?: string) => string[] | boolean | ErrorWrapper readonly element: Element exists: () => boolean + get(selector: string): DOMWrapper find(selector: string): DOMWrapper | ErrorWrapper findAll(selector: string): DOMWrapper[] html: () => string diff --git a/src/vue-wrapper.ts b/src/vue-wrapper.ts index 2538db53c..a016367d8 100644 --- a/src/vue-wrapper.ts +++ b/src/vue-wrapper.ts @@ -78,9 +78,16 @@ export class VueWrapper return this.element.textContent?.trim() } - find(selector: string): DOMWrapper | ErrorWrapper { + find( + selector: K + ): DOMWrapper | ErrorWrapper + find( + selector: K + ): DOMWrapper | ErrorWrapper + find(selector: string): DOMWrapper | ErrorWrapper + find(selector: string): DOMWrapper | ErrorWrapper { // force using the parentElement to allow finding the root element - const result = this.parentElement.querySelector(selector) as T + const result = this.parentElement.querySelector(selector) if (result) { return new DOMWrapper(result) } @@ -88,8 +95,15 @@ export class VueWrapper return new ErrorWrapper({ selector }) } - get(selector: string): DOMWrapper { - const result = this.find(selector) + get( + selector: K + ): DOMWrapper + get( + selector: K + ): DOMWrapper + get(selector: string): DOMWrapper + get(selector: string): DOMWrapper { + const result = this.find(selector) if (result instanceof ErrorWrapper) { throw new Error(`Unable to find ${selector} within: ${this.html()}`) } @@ -110,9 +124,16 @@ export class VueWrapper return find(this.vm.$.subTree, selector).map((c) => createWrapper(null, c)) } - findAll(selector: string): DOMWrapper[] { - const results = this.parentElement.querySelectorAll(selector) - return Array.from(results).map((x) => new DOMWrapper(x)) + findAll( + selector: K + ): DOMWrapper[] + findAll( + selector: K + ): DOMWrapper[] + findAll(selector: string): DOMWrapper[] + findAll(selector: string): DOMWrapper[] { + const results = this.parentElement.querySelectorAll(selector) + return Array.from(results).map((element) => new DOMWrapper(element)) } setProps(props: Record): Promise { diff --git a/test-dts/index.d-test.ts b/test-dts/mount.d-test.ts similarity index 100% rename from test-dts/index.d-test.ts rename to test-dts/mount.d-test.ts diff --git a/test-dts/wrapper.d-test.ts b/test-dts/wrapper.d-test.ts new file mode 100644 index 000000000..b71a50b68 --- /dev/null +++ b/test-dts/wrapper.d-test.ts @@ -0,0 +1,88 @@ +import { expectType } from 'tsd' +import { defineComponent } from 'vue' +import { mount } from '../src' + +const AppWithDefine = defineComponent({ + template: '' +}) + +const wrapper = mount(AppWithDefine) +const domWrapper = wrapper.find('#other') + +// find Vue wrapper +// HTML element selector +let inputMaybe = wrapper.find('input') +expectType(inputMaybe.element) + +// SVG element selector +let lineMaybe = wrapper.find('line') +expectType(lineMaybe.element) + +// string selector +let byClassMaybe = wrapper.find('.todo') +expectType(byClassMaybe.element) + +// find DOM wrapper +// HTML element selector +inputMaybe = domWrapper.find('input') +expectType(inputMaybe.element) + +// SVG element selector +lineMaybe = domWrapper.find('line') +expectType(lineMaybe.element) + +// string selector +byClassMaybe = domWrapper.find('.todo') +expectType(byClassMaybe.element) + +// findAll +// HTML element selector +let inputArray = wrapper.findAll('input') +expectType(inputArray[0].element) + +// SVG element selector +let lineArray = wrapper.findAll('line') +expectType(lineArray[0].element) + +// string selector +let byClassArray = wrapper.findAll('.todo') +expectType(byClassArray[0].element) + +// findAll DOM wrapper +// HTML element selector +inputArray = domWrapper.findAll('input') +expectType(inputArray[0].element) + +// SVG element selector +lineArray = domWrapper.findAll('line') +expectType(lineArray[0].element) + +// string selector +byClassArray = domWrapper.findAll('.todo') +expectType(byClassArray[0].element) + +// get +// HTML element selector +let input = wrapper.get('input') +expectType(input.element) + +// SVG element selector +let line = wrapper.get('line') +expectType(line.element) + +// string selector +let byClass = wrapper.get('.todo') +expectType(byClass.element) + +// get DOM wrapper +// HTML element selector +input = domWrapper.get('input') +expectType(input.element) + +// SVG element selector +line = domWrapper.get('line') +expectType(line.element) + +// string selector +byClass = domWrapper.get('.todo') +expectType(byClass.element)