Skip to content

Get deprecated notification while using findAll() on html/css selector (no Vue component) #1703

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
kuehnleon opened this issue Oct 1, 2020 · 5 comments

Comments

@kuehnleon
Copy link

Subject of the issue

It is not possible to run findAll() without getting the deprecation notice:

finding components with `findAll` is deprecated and will be removed in the next major version. Use `findAllComponents` instead.

But it is not possible to use findAllComponents() if the wrapper is a non-vue component.

You will receive the following error:

Error: [vue-test-utils]: You cannot chain findAllComponents off a DOM element. It can only be used on Vue Components.
    at throwError (dist/js/webpack:/node_modules/@vue/test-utils/dist/vue-test-utils.js:1700:1)
    at Wrapper.findAllComponents (dist/js/webpack:/node_modules/@vue/test-utils/dist/vue-test-utils.js:10529:1)
    at Context.<anonymous> (dist/js/webpack:/tests/unit/tenant/tests/migration-job-list.spec.js:87:1)
    at processImmediate (internal/timers.js:456:21)

Steps to reproduce

notice: I'm using mocha and chai-should

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

let localVue;
localVue = createLocalVue();

it("test rows of table", () => {
  wrapper = shallowMount(MyComponent, {
      localVue
  });

  const table = cardBody.find("table");
  table.exists().should.equal(true);

  const rows = table.findAllComponents(TableRow);
  rows.length.should.equal(3);
});

Expected behaviour

const rows = table.findAllComponents(TableRow) should return a WrapperArray containing all TableRow components.

OR

const rows = table.findAll(TableRow) should return a WrapperArray containing all TableRow components without display a deprecation notice.

Actual behaviour

receiving an error:

Error: [vue-test-utils]: You cannot chain findAllComponents off a DOM element. It can only be used on Vue Components.
    at throwError (dist/js/webpack:/node_modules/@vue/test-utils/dist/vue-test-utils.js:1700:1)
    at Wrapper.findAllComponents (dist/js/webpack:/node_modules/@vue/test-utils/dist/vue-test-utils.js:10529:1)
    at Context.<anonymous> (dist/js/webpack:/tests/unit/tenant/tests/migration-job-list.spec.js:87:1)
    at processImmediate (internal/timers.js:456:21)

Possible Solution

Don't show deprecation notice if you're using findAll() on non-vue component.

@lmiller1990
Copy link
Member

lmiller1990 commented Oct 7, 2020

You cannot chain findComponent on a DOM node, since findComponent works with the virtual DOM (vdom) but find on the real DOM (two separate concepts). This is intentional.

Why not just do const rows = wrapper.findAllComponents(TableRow)? Or wrapper.findAll('tr')?

@xanf
Copy link
Contributor

xanf commented Oct 12, 2020

@lmiller1990 Since our components are rendering VNodes, I do not feel like these are two are separate concepts.
Especially there is no difference when we shallowMount - this usually means we intentionally want to stay within VNode concepts

Let me explain my point via real world example - sometimes we want in GitLab to use DOM element VNode as root of our search. Something like "Find gl-widget component in panel with specific title", where we are looking for panel (which is just <div>) having specific attribute and after that looking for specific widget via .find. Since panels are added dynamically there is no easy & clean way to add "data-test-id" and I really have a feeling that by using "data-test-id" my test will not capture original intent "widget inside specific panel"

@xanf
Copy link
Contributor

xanf commented Oct 12, 2020

As a potential solution, WDYT of adding to findComponent, findAllComponents selector second argument, context (absolutely similar to jquery approach where you can write $('tr', '.panel')) which will allow us to filter components located under specific DOM vnode

@lmiller1990
Copy link
Member

lmiller1990 commented Oct 12, 2020

This API is not forward compatible with Vue 3 + VTU v2 iirc - thus the deprecation. You cannot find a vnode from a DOM component, according to this comment. findComponent(Foo).find('#dom-el') is trivial to implement, but not the opposite way, since find returns a DOMWrapper (no vnode). From there is no way back to the VDOM (apparently, I didn't implement this part of the code-base).

I am not exactly why this isn't forward compatible with Vue 3, since obviously it does work here. The VDOM implementation changed a lot in Vue 2 -> Vue 3, maybe that is why? I have not personally looked into it, since I am a fan of making the separation between testing the DOM output (via find) and implementation details (via findComponent) clear.

If we can support chaining both ways in V2, it would be fine to allow chaining both find and findComponent (in both orders, I think it would feel a bit dirty if we only supported one way chaining and not the other).

You could try implementing this in V2, to see if it's really not forward compatible. The relevant file is here, it is pretty confusing, though 😅 WDYT?

@xanf
Copy link
Contributor

xanf commented Oct 12, 2020

@lmiller1990 will be happy to try 👍

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

No branches or pull requests

4 participants