Skip to content
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

Should component scope inside a collection preserve parent selector? #63

Closed
leonardocsouza opened this issue Oct 8, 2015 · 6 comments
Closed
Labels

Comments

@leonardocsouza
Copy link

Hi there!

I've just recently started using this awesome addon (thank you so much!) and noticed what seems to be an issue, but I wanted to confirm if it's indeed one.

I have a situation where I have a tree of nested elements and all the scoping for each collection of items within another collection works great, with exception of a case where I'm trying to use a component as an attribute of an item in a collection, but I can't find a way to find this component inside the item without manually appending an extra class on each property for the component.

Consider this HTML below as the leaf node of my tree:

... lines omitted for brevity
<li class="topic">
    <div class="flagging-menu is-open">
        <div class="mark urgent">Urgent</div>
        <div class="mark current">Current</div>
        <div class="mark past">Past</div>
    </div>
</li>
... lines omitted for brevity

Then what I'm trying to do is to define a component for the flagging-menu within thetopic item so that I can simply access the properties of the component without having to pass the component selector every time.

My first attempt was this:

topics:  collection({
  itemScope: '.topic',
  item: {
    title:      text('.title'),    

    flaggingMenu: {
      scope: '.flagging-menu',
      isOpen: hasClass('is-open'),

      selectCurrent: clickable('.mark.current'),
      selectPast: clickable('.mark.past'),
      selectUrgent: clickable('.mark.urgent')
    }
  }
})

The issue I ran into was that by setting scope: '.flagging-menu', the selector for the component dropped the parent scope (.topic) and matched any item on the page matching the broader .flagging-menu selector, when what I would have liked it to do was to append the component scope to the parent selector (i.e. .topic .flagging-menu).

The only way I found to get what I was trying to accomplish was to pretend I had a collection of flagging-menu, since by using itemScope I am able to preserve the parent scope while also narrowing down to the specific element I'm interested in.

topics:  collection({
  itemScope: '.topic',
  item: {
    title:      text('.title'),    

    // Hackish way to be able to have flaggingMenu preserve scope
    // of parent item. Using scope: attribute replaces parent scope.
    flaggingMenu: collection({
      itemScope: '.flagging-menu',

      item: { 
        isOpen: hasClass('is-open'),

        selectCurrent: clickable('.mark.current'),
        selectPast: clickable('.mark.past'),
        selectUrgent: clickable('.mark.urgent')
      }
    })
  }
})

This works, but seems a bit hackish to me. Is this behavior of not preserving a parent's scope when you have a component inside a collection's item the expected one?

Thank you so much for looking into this.

Best,
Leo

@san650
Copy link
Owner

san650 commented Oct 8, 2015

Hi @leonardocsouza, this is an issue indeed!

We detected this issue some days ago but I forgot to open an issue to let everyone else to be aware of it, thanks for reporting the issue.

We're working on a fix for it, see #62 specially the commit b09dd00

For now, another workaround is to wrap the component in a customHelper, for example

let flaggingMenu = customHelper(function(selector) {
  return {
    scope: `${selector} .flagging-menu`,
    isOpen: hasClass('is-open'),

    selectCurrent: clickable('.mark.current'),
    selectPast: clickable('.mark.past'),
    selectUrgent: clickable('.mark.urgent')
  };
});

let topics = collection({
  itemScope: '.topic',
  item: {
    title: text('.title'),
    flaggingMenu
  }
});

Please, let me know if this works for you.

@san650 san650 added the bug label Oct 8, 2015
@leonardocsouza
Copy link
Author

Thank you SO much for the quick and detailed reply!

I thought a customHelper could be a good solution, but had not tried that yet. I've just tested it now with the info you shared above and it seems like I may be missing some step to get it to work because it just comes back as a plain javascript Object as if it didn't get initialized or something like that.

image

In any case, we have a workaround that solves the problem for now, and I have it wrapped in a test helper so that whenever the fix for this is released I can just replace it in one place.

Thank you again!

Best,
Leo

@san650
Copy link
Owner

san650 commented Oct 9, 2015

Yes, you are right, let me fix the example so others can use it.

let menu = customHelper(function(selector) {
  return {
    scope: selector,
    isOpen: hasClass('is-open'),

    selectCurrent: clickable('.mark.current'),
    selectPast: clickable('.mark.past'),
    selectUrgent: clickable('.mark.urgent')
  };
});

let topics = collection({
  itemScope: '.topic',
  item: {
    title: text('.title'),
    flaggingMenu: menu('.flagging-menu')
  }
});

customHelper always returns a function, and the selector you pass to it will be scoped to the item level.

Although this is just a workaround for the issue you posted, it's a nice example of the power of the customHelper.

Cheers

@san650
Copy link
Owner

san650 commented Oct 10, 2015

Fixed by #62

@san650 san650 closed this as completed Oct 10, 2015
@san650
Copy link
Owner

san650 commented Oct 10, 2015

@leonardocsouza the fix is included on version 0.8.1. Thanks again for your report!

https://github.com/san650/ember-cli-page-object/releases/tag/v0.8.1

@leonardocsouza
Copy link
Author

Awesome! Thank you for the update and for the fix! :) 👍

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

No branches or pull requests

2 participants