Skip to content

Allow find to work with component tag #897

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
wants to merge 4 commits into from
Closed

Allow find to work with component tag #897

wants to merge 4 commits into from

Conversation

lmiller1990
Copy link
Member

Working on #695

Will most likely need some more test cases, but working nicely.

const pseudoSelectors = ['.', '#', '[', ':', '>', ' ']
if (htmlTags.includes(selector) ||
svgElements.includes(selector) ||
selector.split('').some(char => pseudoSelectors.includes(char))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should throw an error if the user is using a component selector with a pseudo selector, because they might expect this to work and be confused by find returning false.

Copy link
Member

@eddyerburgh eddyerburgh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good :)

Can you add test cases for the following component types:

  • functional components
  • sub class components (Vue.extend(options))
  • extended components ({ extends: AnotherCmp })

Also, as I commented I think we should throw a selector if tag selectors are mixed with pseudo selectors. Could you also write a test for this.

@lmiller1990
Copy link
Member Author

lmiller1990 commented Aug 4, 2018

Wow, fast review, thanks! Going to work on this comments now.

PS I saw you were coming to Vuefest in Tokyo in November, hopefully we can catch up then 👍

@lmiller1990
Copy link
Member Author

All cases are working except for functional components. Functional components don't seem to get tag or $options._componentTag assigned - maybe this feature cannot support functional components? (not that familiar with the main differences, other than the fact they are stateless).

Just fixing a few things and I'll push the updated tests (with failing functional one for now).

@eddyerburgh
Copy link
Member

Yes you're correct, I overlooked functional components. This is problematic, because it means we won't be able to replace the Constructor selector with the tag selector 😕

I've also thought of another potential problem: render functions that use the constructor ({ render: h => h(TestComponent)}).

The reason I was keen to go ahead with this feature was because I thought we could replace constructor selectors, but I hadn't considered functional components or render functions that use component constructors.

Sorry about this, but we need to put the brakes on this PR to figure out a solution. I'd like to get this feature added, but I'm concerned about the discrepancy between functional and normal components

@lmiller1990
Copy link
Member Author

lmiller1990 commented Aug 4, 2018

Functional components are tricky. I agree... the API should not require users to know about specifics, like the difference between functional and regular components. I will think about this more.

Throwing an error for cases like find("a > my-component") is also very tricky. There are so many cases to consider, such as:

  1. hierarchical selectors: a > my-component
  2. id/classes: my-component#some-id

But I think I this is not too difficult to solve, just more tricky than I originally expected.

Another thing I am sure will lead to confusion is even though you search with for a tag, say my-component, if you inspect the markup using wrapper.html you will use <mycomponent-stub>. I think that is a bit unintuitive (although using a constructor or name also has this problem).

I haven't done much React, but I wonder how Enzyme handles find.

@eddyerburgh
Copy link
Member

Enzyme parse string selectors, which we could do. There's not much need right now since we require a DOM environment, and have the Element.matches method which does the work for us (for DOM elements).

For components, enzyme uses the constructor/ function. The React render tree node has a reference to the constructor for class components, or function, for functional components. This means matching components is a case of selector === node.type (not sure on exact prop).

@eddyerburgh
Copy link
Member

I think this feature would be too complex to implement, so we'll continue with the current selector API instead

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 this pull request may close these issues.

2 participants