Skip to content

Commit a8368e7

Browse files
authored
Add support for CVE modal and PF4 version of LCE Selector (#1514)
1 parent 87b9fca commit a8368e7

File tree

4 files changed

+103
-3
lines changed

4 files changed

+103
-3
lines changed

airgun/entities/all_hosts.py

+19
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
BuildManagementDialog,
1010
BulkHostDeleteDialog,
1111
HostDeleteDialog,
12+
ManageCVEModal,
1213
ManagePackagesModal,
1314
)
1415
from airgun.views.job_invocation import JobInvocationCreateView
@@ -82,6 +83,24 @@ def build_management(self, reboot=False, rebuild=False):
8283
self.browser.wait_for_element(view.alert_message, exception=False)
8384
return view.alert_message.read()
8485

86+
def manage_cve(self, lce=None, cv=None):
87+
"""Bulk reassign Content View Environments through the All Hosts page
88+
args:
89+
lce (str): Lifecycle Environment to swap the hosts to.
90+
cv (str): CV within that LCE to assign the hosts to.
91+
"""
92+
view = self.navigate_to(self, 'All')
93+
self.browser.plugin.ensure_page_safe(timeout='5s')
94+
view.wait_displayed()
95+
view.select_all.fill(True)
96+
view.bulk_actions_kebab.click()
97+
self.browser.move_to_element(view.bulk_actions_menu.item_element('Manage content'))
98+
view.bulk_actions.item_select('Content view environments')
99+
view = ManageCVEModal(self.browser)
100+
view.lce_selector.fill({lce: True})
101+
view.content_source_select.item_select(cv)
102+
view.save_btn.click()
103+
85104
def manage_table_columns(self, values: dict):
86105
"""
87106
Select which columns should be displayed in the hosts table.

airgun/views/all_hosts.py

+42-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
1-
from widgetastic.widget import Checkbox, Text, View
2-
from widgetastic_patternfly4 import Button, Dropdown, Menu, Modal, Pagination, Radio
1+
from widgetastic.widget import Checkbox, ParametrizedView, Text, View
2+
from widgetastic_patternfly4 import (
3+
Button,
4+
Dropdown,
5+
Menu,
6+
Modal,
7+
Pagination,
8+
Radio,
9+
Select,
10+
)
311
from widgetastic_patternfly4.ouia import (
412
Alert as OUIAAlert,
513
PatternflyTable,
614
)
715

816
from airgun.views.common import (
917
BaseLoggedInView,
18+
PF4LCESelectorGroup,
1019
SearchableViewMixinPF4,
1120
WizardStepView,
1221
)
@@ -20,6 +29,19 @@ class AllHostsMenu(Menu):
2029
ROOT = f"{BUTTON_LOCATOR}/.."
2130

2231

32+
class AllHostsSelect(Select):
33+
BUTTON_LOCATOR = ".//button[@aria-label='Options menu']"
34+
ITEMS_LOCATOR = ".//ul[contains(@class, 'pf-c-select__menu')]/li"
35+
ITEM_LOCATOR = (
36+
"//*[contains(@class, 'pf-c-select__menu-item') and .//*[contains(normalize-space(.), {})]]"
37+
)
38+
SELECTED_ITEM_LOCATOR = ".//span[contains(@class, 'ins-c-conditional-filter')]"
39+
TEXT_LOCATOR = ".//div[contains(@class, 'pf-c-select') and child::button]"
40+
DEFAULT_LOCATOR = (
41+
'.//div[contains(@class, "pf-c-select") and @data-ouia-component-id="select-content-view"]'
42+
)
43+
44+
2345
class AllHostsTableView(BaseLoggedInView, SearchableViewMixinPF4):
2446
title = Text("//h1[normalize-space(.)='Hosts']")
2547
select_all = Checkbox(
@@ -130,6 +152,24 @@ def fill(self, values):
130152
self.checkbox_group.fill(values)
131153

132154

155+
class ManageCVEModal(Modal):
156+
"""
157+
This class represents the Manage Content View Environments modal that is used to update the CVE of hosts.
158+
"""
159+
160+
ROOT = './/div[@data-ouia-component-id="bulk-change-host-cv-modal"]'
161+
162+
title = Text("//span[normalize-space(.)='Edit content view environments']")
163+
save_btn = Button(locator='//button[normalize-space(.)="Save"]')
164+
cancel_btn = Button(locator='//button[normalize-space(.)="Cancel"]')
165+
content_source_select = AllHostsSelect()
166+
lce_selector = ParametrizedView.nested(PF4LCESelectorGroup)
167+
168+
@property
169+
def is_displayed(self):
170+
return self.browser.wait_for_element(self.title, exception=False) is not None
171+
172+
133173
class ManagePackagesModal(Modal):
134174
"""
135175
This class represents the Manage Packages modal that is used to install or update packages on hosts.

airgun/views/common.py

+14
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
ItemsList,
2626
LCESelector,
2727
Pf4ConfirmationDialog,
28+
PF4LCESelector,
2829
PF4NavSearch,
2930
PF4Search,
3031
ProgressBar,
@@ -264,6 +265,19 @@ def read(self):
264265
return self.lce.read()
265266

266267

268+
class PF4LCESelectorGroup(LCESelectorGroup):
269+
ROOT = './/div[./div[@class="env-path"]]'
270+
271+
PARAMETERS = ('lce_name',)
272+
273+
LAST_ENV = './/div[@class="env-path"][last()]'
274+
lce = PF4LCESelector(
275+
locator=ParametrizedLocator(
276+
'.//div[@class="env-path" and .//*[contains(normalize-space(.), "{lce_name}")]]'
277+
)
278+
)
279+
280+
267281
class ListRemoveTab(SatSecondaryTab):
268282
"""'List/Remove' tab, part of :class:`AddRemoveResourcesView`."""
269283

airgun/widgets.py

+28-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@
2626
Kebab,
2727
VerticalNavigation,
2828
)
29-
from widgetastic_patternfly4 import Button as PF4Button, Pagination as PF4Pagination
29+
from widgetastic_patternfly4 import (
30+
Button as PF4Button,
31+
Pagination as PF4Pagination,
32+
)
3033
from widgetastic_patternfly4.ouia import (
3134
BaseSelect,
3235
Button as OUIAButton,
@@ -1483,6 +1486,30 @@ def fill(self, value):
14831486
return self.select(checkbox_locator, checkbox_value)
14841487

14851488

1489+
class PF4LCESelector(LCESelector):
1490+
"""Group of checkboxes that goes in a line one after another. Usually used
1491+
to specify lifecycle environment, updated for PF4 pages
1492+
"""
1493+
1494+
LABELS = './/label[contains(@class, "pf-c-radio__label")]'
1495+
CHECKBOX = (
1496+
'.//input[contains(@class, "pf-c-radio__input") and ../label[.//*[contains(text(), "{}")]]]'
1497+
)
1498+
1499+
def __init__(self, parent, locator=None, logger=None):
1500+
"""Allow to specify ``locator`` if needed or use default one otherwise.
1501+
Locator is needed when multiple :class:`LCESelector` are present,
1502+
typically as a part of :class:`airgun.views.common.LCESelectorGroup`.
1503+
"""
1504+
if locator is None:
1505+
locator = './/div[contains(@class, "env-path")]'
1506+
super().__init__(parent, locator, logger=logger)
1507+
1508+
def checkbox_selected(self, locator):
1509+
"""Identify whether specific checkbox is selected or not"""
1510+
return self.browser.is_selected(locator)
1511+
1512+
14861513
class LimitInput(Widget):
14871514
"""Input for managing limits (e.g. Hosts limit). Consists of 'Unlimited'
14881515
checkbox and text input for specifying the limit, which is only visible if

0 commit comments

Comments
 (0)