Skip to content

Commit

Permalink
Add PF4 versions of MultiSelect and FilteredDropdown. Use them in Fil…
Browse files Browse the repository at this point in the history
…ters.
  • Loading branch information
lhellebr committed Sep 21, 2023
1 parent 01ca4f2 commit 8a1e8db
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 4 deletions.
4 changes: 4 additions & 0 deletions airgun/entities/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ class FilterEntity(BaseEntity):
def create(self, role_name, values):
"""Create new filter for specific role"""
view = self.navigate_to(self, 'New', role_name=role_name)
view.wait_displayed()
# we need to wait explicitly for this element for some reason
view.resource_type.wait_displayed()
self.browser.plugin.ensure_page_safe()
view.fill(values)
view.submit.click()
view.flash.assert_no_error()
Expand Down
11 changes: 7 additions & 4 deletions airgun/views/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
from airgun.views.common import BaseLoggedInView, SatTab
from airgun.widgets import (
ActionsDropdown,
FilteredDropdown,
MultiSelect,
Pagination,
PF4FilteredDropdown,
PF4MultiSelect,
Search,
)

Expand Down Expand Up @@ -50,12 +51,14 @@ def search(self, query):

class FilterDetailsView(BaseLoggedInView):
breadcrumb = BreadCrumb()
resource_type = FilteredDropdown(id='filter_resource_type')
permission = MultiSelect(id='ms-filter_permission_ids')
resource_type = PF4FilteredDropdown(
locator='.//div[@data-ouia-component-id="resource-type-select"]'
)
permission = PF4MultiSelect('.//div[@id="permission-duel-select"]')
override = Checkbox(id='override_taxonomy_checkbox')
unlimited = Checkbox(id='filter_unlimited')
filter = TextInput(id='search')
submit = Text('//input[@name="commit"]')
submit = Text('//button[@data-ouia-component-id="filters-submit-button"]')

@property
def is_displayed(self):
Expand Down
76 changes: 76 additions & 0 deletions airgun/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,58 @@ def read(self):
}


class PF4MultiSelect(GenericLocatorWidget):
"""Typical two-pane multiselect widget. Allows to move items from
list of ``unassigned`` entities to list of ``assigned`` ones and vice
versa. PF4 version.
"""

unassigned = ItemsList(".//ul[@aria-labelledby='permission-duel-select-available-pane-status']")
assigned = ItemsList(".//ul[@aria-labelledby='permission-duel-select-chosen-pane-status']")
move_to_assigned = Text(".//button[@aria-label='Add selected']")
move_to_unassigned = Text(".//button[@aria-label='Remove selected']")

def __init__(self, parent, locator=None, id=None, logger=None):
"""Supports initialization via ``locator=`` or ``id=``"""
if locator and id or not locator and not id:
raise TypeError('Please specify either locator or id')
locator = locator or f".//div[@id='{id}']"
super().__init__(parent, locator, logger)

def fill(self, values):
"""Read current values, find the difference between current and passed
ones and fills the widget accordingly.
:param values: dict with keys ``assigned`` and/or ``unassigned``,
containing list of strings, representing item names
"""
current = self.read()
to_add = [res for res in values.get('assigned', ()) if res not in current['assigned']]
to_remove = [
res for res in values.get('unassigned', ()) if res not in current['unassigned']
]
if not to_add and not to_remove:
return False
if to_add:
for value in to_add:
self.unassigned.fill(value)
self.move_to_assigned.click()
if to_remove:
for value in to_remove:
self.assigned.fill(value)
self.move_to_unassigned.click()
return True

def read(self):
"""Returns a dict with current lists values."""
unassigned = self.unassigned.read() if self.unassigned.is_displayed else []
assigned = self.assigned.read() if self.assigned.is_displayed else []
return {
'unassigned': unassigned,
'assigned': assigned,
}


class PuppetClassesMultiSelect(MultiSelect):
"""Widget has different appearance than MultiSelect, because there are no actual panes,
but logically it is the same. It looks like two lists of items and specific for puppet
Expand Down Expand Up @@ -1006,6 +1058,30 @@ def fill(self, value):
self.filter_content.fill(value)


class PF4FilteredDropdown(GenericLocatorWidget):
"""Drop-down element with filtering functionality - PatternFly 4 version"""

filter_criteria = TextInput(locator=".//input[@aria-label='Select a resource type']")
filter_content = ItemsList(".//ul")

def clear(self):
"""Clear currently selected value for drop-down"""
self.browser.clear(self.filter_criteria)

def fill(self, value):
"""Select specific item from the drop-down
:param value: string with item value
"""
self.clear()
self.filter_criteria.fill(value)
self.filter_content.fill(value)

def read(self):
"""Return drop-down selected item value"""
return self.browser.text(self.filter_criteria)


class CustomParameter(Table):
"""Name-Value paired input elements which can be added, edited or removed.
Expand Down

0 comments on commit 8a1e8db

Please sign in to comment.