Skip to content

Cannot call .findComponent() on wrapper of .find() result #1644

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

Closed
nwoltman opened this issue Aug 14, 2020 · 5 comments
Closed

Cannot call .findComponent() on wrapper of .find() result #1644

nwoltman opened this issue Aug 14, 2020 · 5 comments

Comments

@nwoltman
Copy link

Subject of the issue

I'm trying to use .find() then .findComponent() on the wrapper returned by .find() but I'm getting the error 'You cannot chain findComponent off a DOM element. It can only be used on Vue Components.'.

Steps to reproduce

import { shallowMount, createLocalVue } from '@vue/test-utils';
import MyComponent from './MyComponent.vue';
import MyButton from './MyButton.vue';

const wrapper = shallowMount(MyComponent, { localVue });
const sectionWrapper = wrapper.find('.section');
const button = wrapper.findComponent(MyButton);

Expected behaviour

wrapper.findComponent(MyButton) should find the MyButton component.

Actual behaviour

This error is thrown:

You cannot chain findComponent off a DOM element. It can only be used on Vue Components.

Possible Solution

I commented out these lines and it found the component just fine:

if (!this.vm && !this.isFunctionalComponent) {
throwError(
'You cannot chain findComponent off a DOM element. It can only be used on Vue Components.'
)
}

I'm not sure why this error exists, but it seems unnecessary in this case.

@lmiller1990
Copy link
Member

I can't remember exactly why but I think there is a architectural reason for why this doesn't work (difficult/impossible to implement without significant risk/breaking changes maybe? Could be wrong).

It was briefly discussed here but with no real conclusion. If you are extremely motivated, you can attempt to remove the warning and see what happens.

Most of the time, I just recommend people search for they want directly, by adding a data-testid or test-specific selector, rather than coupling your tests to a specific DOM structure.

@dobromir-hristov
Copy link
Contributor

I would encourage to make this work for VTU 2 first, before removing the warnings, they were added because the API is not backwards compatible. You cannot search for components from a dom node.

@nwoltman
Copy link
Author

@dobromir-hristov Where is VTU 2? I don't see any reference to it anywhere in this repo?

Regardless, I'll trust that it won't work in VTU 2. Is there any way to find a component that's below a DOM node that matches a particular CSS selector? The reason I'm trying to do wrapper.find('.class').findComponent(MyComponent) is because that seems less brittle than doing something like wrapper.findAllComponents(MyComponent)[someIndex].

@lmiller1990
Copy link
Member

lmiller1990 commented Aug 19, 2020

VTU next: https://github.com/vuejs/vue-test-utils-next
We should add a note to the README here.
The least brittle way would be to select the comoponent/DOM node directly, either via role or data-testid or something along those lines.

For reference, implementing findComponent is quite challenging in VTU 2 (as it was here). I do not see any way to find a component below a specific CSS selector, unfortunately, sorry about that. Any help with implementing this feature would be greatly appreciated!

@nwoltman
Copy link
Author

If it's that challenging to implement I'll just close this issue. I have yet to run into a scenario where finding a component below a specific DOM node is absolutely necessary, so I'm okay for now. Thanks for the help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants