diff --git a/packages/test-utils/src/wrapper.js b/packages/test-utils/src/wrapper.js index 91fd02406..3ae6a0e42 100644 --- a/packages/test-utils/src/wrapper.js +++ b/packages/test-utils/src/wrapper.js @@ -126,6 +126,7 @@ export default class Wrapper implements BaseWrapper { /** * Checks if wrapper contains provided selector. + * @deprecated */ contains(rawSelector: Selector): boolean { warnDeprecated( @@ -176,6 +177,7 @@ export default class Wrapper implements BaseWrapper { /** * Returns an Array containing custom events emitted by the Wrapper vm + * @deprecated */ emittedByOrder(): Array<{ name: string, args: Array }> { warnDeprecated('emittedByOrder', 'Use `wrapper.emitted` instead') @@ -225,41 +227,8 @@ export default class Wrapper implements BaseWrapper { 'Use `findComponent` instead' ) } - const node = find(this.rootNode, this.vm, selector)[0] - - if (!node) { - return new ErrorWrapper(rawSelector) - } - - const wrapper = createWrapper(node, this.options) - wrapper.selector = rawSelector - return wrapper - } - - /** - * Finds DOM elements in tree of the current wrapper that matches - * the provided selector. - */ - findAll(rawSelector: Selector): WrapperArray { - const selector = getSelector(rawSelector, 'findAll') - if (selector.type !== DOM_SELECTOR) { - warnDeprecated( - 'finding components with `findAll`', - 'Use `findAllComponents` instead' - ) - } - const nodes = find(this.rootNode, this.vm, selector) - const wrappers = nodes.map(node => { - // Using CSS Selector, returns a VueWrapper instance if the root element - // binds a Vue instance. - const wrapper = createWrapper(node, this.options) - wrapper.selector = rawSelector - return wrapper - }) - const wrapperArray = new WrapperArray(wrappers) - wrapperArray.selector = rawSelector - return wrapperArray + return this.__find(rawSelector, selector) } /** @@ -268,11 +237,22 @@ export default class Wrapper implements BaseWrapper { */ findComponent(rawSelector: Selector): Wrapper | ErrorWrapper { const selector = getSelector(rawSelector, 'findComponent') + if (!this.vm) { + throwError( + 'You cannot chain findComponent off a DOM element. It can only be used on Vue Components.' + ) + } + if (selector.type === DOM_SELECTOR) { throwError( 'findComponent requires a Vue constructor or valid find object. If you are searching for DOM nodes, use `find` instead' ) } + + return this.__find(rawSelector, selector) + } + + __find(rawSelector: Selector, selector: Object): Wrapper | ErrorWrapper { const node = find(this.rootNode, this.vm, selector)[0] if (!node) { @@ -284,17 +264,41 @@ export default class Wrapper implements BaseWrapper { return wrapper } + /** + * Finds DOM elements in tree of the current wrapper that matches + * the provided selector. + */ + findAll(rawSelector: Selector): WrapperArray { + const selector = getSelector(rawSelector, 'findAll') + if (selector.type !== DOM_SELECTOR) { + warnDeprecated( + 'finding components with `findAll`', + 'Use `findAllComponents` instead' + ) + } + return this.__findAll(rawSelector, selector) + } + /** * Finds components in tree of the current wrapper that matches * the provided selector. */ findAllComponents(rawSelector: Selector): WrapperArray { const selector = getSelector(rawSelector, 'findAll') + if (!this.vm) { + throwError( + 'You cannot chain findAllComponents off a DOM element. It can only be used on Vue Components.' + ) + } if (selector.type === DOM_SELECTOR) { throwError( - 'findAllComponent requires a Vue constructor or valid find object. If you are searching for DOM nodes, use `find` instead' + 'findAllComponents requires a Vue constructor or valid find object. If you are searching for DOM nodes, use `find` instead' ) } + return this.__findAll(rawSelector, selector) + } + + __findAll(rawSelector: Selector, selector: Object): WrapperArray { const nodes = find(this.rootNode, this.vm, selector) const wrappers = nodes.map(node => { // Using CSS Selector, returns a VueWrapper instance if the root element @@ -318,6 +322,7 @@ export default class Wrapper implements BaseWrapper { /** * Checks if node matches selector + * @deprecated */ is(rawSelector: Selector): boolean { warnDeprecated('is', 'Use element.tagName instead') @@ -332,6 +337,7 @@ export default class Wrapper implements BaseWrapper { /** * Checks if node is empty + * @deprecated */ isEmpty(): boolean { warnDeprecated( @@ -360,6 +366,7 @@ export default class Wrapper implements BaseWrapper { /** * Checks if node is visible + * @deprecated */ isVisible(): boolean { warnDeprecated( @@ -384,6 +391,7 @@ export default class Wrapper implements BaseWrapper { /** * Checks if wrapper is a vue instance + * @deprecated */ isVueInstance(): boolean { warnDeprecated(`isVueInstance`) @@ -392,6 +400,7 @@ export default class Wrapper implements BaseWrapper { /** * Returns name of component, or tag name if node is not a Vue component + * @deprecated */ name(): string { warnDeprecated(`name`) @@ -414,6 +423,7 @@ export default class Wrapper implements BaseWrapper { /** * Prints a simple overview of the wrapper current state * with useful information for debugging + * @deprecated */ overview(): void { warnDeprecated(`overview`) @@ -517,6 +527,7 @@ export default class Wrapper implements BaseWrapper { /** * Checks radio button or checkbox element + * @deprecated */ setChecked(checked: boolean = true): Promise<*> { warnDeprecated( @@ -568,6 +579,7 @@ export default class Wrapper implements BaseWrapper { /** * Selects element + * @deprecated */ setSelected(): Promise { warnDeprecated( @@ -625,6 +637,7 @@ export default class Wrapper implements BaseWrapper { /** * Sets vm methods + * @deprecated */ setMethods(methods: Object): void { warnDeprecated(`setMethods`) diff --git a/test/specs/wrapper/find.spec.js b/test/specs/wrapper/find.spec.js index 19e748f58..ed3a306f4 100644 --- a/test/specs/wrapper/find.spec.js +++ b/test/specs/wrapper/find.spec.js @@ -152,6 +152,16 @@ describeWithShallowAndMount('find', mountingMethod => { .with.property('message', message) }) + it('throws an error if findComponent is chained off a DOM element', () => { + const wrapper = mountingMethod(ComponentWithChild) + const message = + '[vue-test-utils]: You cannot chain findComponent off a DOM element. It can only be used on Vue Components.' + const fn = () => wrapper.find('span').findComponent('#foo') + expect(fn) + .to.throw() + .with.property('message', message) + }) + itSkipIf(isRunningPhantomJS, 'returns Wrapper of class component', () => { const TestComponent = { template: ` diff --git a/test/specs/wrapper/findAll.spec.js b/test/specs/wrapper/findAll.spec.js index 2839b0bd1..515ff0bbf 100644 --- a/test/specs/wrapper/findAll.spec.js +++ b/test/specs/wrapper/findAll.spec.js @@ -145,22 +145,32 @@ describeWithShallowAndMount('findAll', mountingMethod => { expect(componentArr.length).to.equal(1) }) - it('returns an array of VueWrappers of Vue Components matching componentusing findAllComponents', () => { + it('returns an array of VueWrappers of Vue Components matching components using findAllComponents', () => { const wrapper = mountingMethod(ComponentWithChild) const componentArr = wrapper.findAllComponents(Component) expect(componentArr.length).to.equal(1) }) - it('throws an error if findComponent selector is a CSS selector', () => { + it('throws an error if findAllComponents selector is a CSS selector', () => { const wrapper = mountingMethod(Component) const message = - '[vue-test-utils]: findAllComponent requires a Vue constructor or valid find object. If you are searching for DOM nodes, use `find` instead' + '[vue-test-utils]: findAllComponents requires a Vue constructor or valid find object. If you are searching for DOM nodes, use `find` instead' const fn = () => wrapper.findAllComponents('#foo') expect(fn) .to.throw() .with.property('message', message) }) + it('throws an error if chaining findAllComponents off a DOM element', () => { + const wrapper = mountingMethod(ComponentWithChild) + const message = + '[vue-test-utils]: You cannot chain findAllComponents off a DOM element. It can only be used on Vue Components.' + const fn = () => wrapper.find('span').findAllComponents('#foo') + expect(fn) + .to.throw() + .with.property('message', message) + }) + it('returns correct number of Vue Wrapper when component has a v-for', () => { const items = [{ id: 1 }, { id: 2 }, { id: 3 }] const wrapper = mountingMethod(ComponentWithVFor, { propsData: { items } })