Skip to content

refactor: cleanup find methods and tests #1525

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 48 additions & 35 deletions packages/test-utils/src/wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ export default class Wrapper implements BaseWrapper {

/**
* Checks if wrapper contains provided selector.
* @deprecated
*/
contains(rawSelector: Selector): boolean {
warnDeprecated(
Expand Down Expand Up @@ -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<any> }> {
warnDeprecated('emittedByOrder', 'Use `wrapper.emitted` instead')
Expand Down Expand Up @@ -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)
}

/**
Expand All @@ -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) {
Expand All @@ -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
Expand All @@ -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')
Expand All @@ -332,6 +337,7 @@ export default class Wrapper implements BaseWrapper {

/**
* Checks if node is empty
* @deprecated
*/
isEmpty(): boolean {
warnDeprecated(
Expand Down Expand Up @@ -360,6 +366,7 @@ export default class Wrapper implements BaseWrapper {

/**
* Checks if node is visible
* @deprecated
*/
isVisible(): boolean {
warnDeprecated(
Expand All @@ -384,6 +391,7 @@ export default class Wrapper implements BaseWrapper {

/**
* Checks if wrapper is a vue instance
* @deprecated
*/
isVueInstance(): boolean {
warnDeprecated(`isVueInstance`)
Expand All @@ -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`)
Expand All @@ -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`)
Expand Down Expand Up @@ -517,6 +527,7 @@ export default class Wrapper implements BaseWrapper {

/**
* Checks radio button or checkbox element
* @deprecated
*/
setChecked(checked: boolean = true): Promise<*> {
warnDeprecated(
Expand Down Expand Up @@ -568,6 +579,7 @@ export default class Wrapper implements BaseWrapper {

/**
* Selects <option></option> element
* @deprecated
*/
setSelected(): Promise<void> {
warnDeprecated(
Expand Down Expand Up @@ -625,6 +637,7 @@ export default class Wrapper implements BaseWrapper {

/**
* Sets vm methods
* @deprecated
*/
setMethods(methods: Object): void {
warnDeprecated(`setMethods`)
Expand Down
10 changes: 10 additions & 0 deletions test/specs/wrapper/find.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: `
Expand Down
16 changes: 13 additions & 3 deletions test/specs/wrapper/findAll.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 } })
Expand Down