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

Refactor Tab view, point ROOT to tab content, add support for dropdown tabs #49

Open
abalakh opened this issue Mar 13, 2018 · 6 comments

Comments

@abalakh
Copy link

abalakh commented Mar 13, 2018

Currently Tab's ROOT points to tab link, not to tab content, making it impossible to use relative locators for tab content:

ROOT = ParametrizedLocator(
        './/ul[contains(@class, "nav-tabs")]/li[normalize-space(.)={@tab_name|quote}]')

image

Also in foreman there're tabs which are included in some parent dropdown menu:
image

@abalakh
Copy link
Author

abalakh commented Mar 13, 2018

I've fixed it in following way for foreman, but can't guarantee it won't introduce any regressions to cfme

class Tab(View):
    """Represents the Tab view.

    Selects itself automatically when any child widget gets accessed, ensuring
    that the widget is visible.
    """
    TAB_NAME = None
    PARENT_TAB_NAME = None

    ROOT = ParametrizedLocator('.//div[contains(@class, "page-content")]')
    TAB = ParametrizedLocator(
        './../preceding-sibling::div//ul[contains(@class, "nav-tabs")]'
        '/li[a[normalize-space(.)={@tab_name|quote}]]')
    PARENT_TAB = ParametrizedLocator(
        './..//preceding-sibling::div//ul[contains(@class, "nav-tabs")]'
        '/li[a[normalize-space(.)={@parent_tab_name|quote}]]')
    CHILD_TAB = ParametrizedLocator(
        './../preceding-sibling::div//ul[contains(@class, "nav-tabs")]'
        '/li/a[normalize-space(.)={@parent_tab_name|quote}]/ul'
        '/li[normalize-space(.)={@tab_name|quote}]')

    @property
    def tab_name(self):
        return self.TAB_NAME or type(self).__name__.capitalize()

    def is_active(self):
        return 'active' in self.browser.classes(self.TAB)

    def is_disabled(self):
        return 'disabled' in self.browser.classes(self.TAB)

    def select(self):
        if not self.is_active():
            if self.is_disabled():
                raise ValueError(
                    'The tab {} you are trying to select is disabled'
                    .format(self.tab_name)
                )
            self.logger.info('Opening the tab %s', self.tab_name)
            if not self.PARENT_TAB_NAME:
                self.browser.click(self.TAB)
            else:
                self.browser.click(self.PARENT_TAB)
                self.browser.click(self.CHILD_TAB)

    def child_widget_accessed(self, widget):
        # Select the tab
        self.select()

    def __repr__(self):
        return '<Tab {!r}>'.format(self.tab_name)

@psav
Copy link
Member

psav commented Mar 14, 2018

So we can definitely take a look if Tab can be used generically, alternatively we can have a separate widget for tab with dropdown. @mfalesni can you please take a look at this.

@mfalesni
Copy link
Contributor

This solution is quite specific. I want to try and remove ROOT from the Tab, then you can import Tab and subclass it and add the modifications in your project.

@mfalesni
Copy link
Contributor

I created #50 where I am trying to remove the ROOT from the Tab so teams can specify their own.

@abalakh
Copy link
Author

abalakh commented Mar 15, 2018

@mfalesni and what about dropdowns support? That's not something specific to foreman/katello, they are officially supported by patternfly: https://www.patternfly.org/pattern-library/widgets/#tabs

@mfalesni
Copy link
Contributor

I think I will make that an inherited widget.

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

3 participants