Skip to content

Commit c6eedfa

Browse files
authored
Update views and entities for new inventory ui (#2258)
1 parent 712e87c commit c6eedfa

2 files changed

Lines changed: 55 additions & 64 deletions

File tree

airgun/entities/cloud_inventory.py

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ def get_displayed_buttons(self):
5656
),
5757
'sync_status': view.sync_status.is_displayed,
5858
'sync_status_text': view.sync_status.read() if view.sync_status.is_displayed else None,
59+
'generate_and_upload': view.inventory_list.generate_and_upload.is_displayed,
60+
'generate_and_upload_enabled': (
61+
view.inventory_list.generate_and_upload.disabled is False
62+
),
63+
'generate_report': view.inventory_list.generate_report.is_displayed,
64+
'generate_report_enabled': view.inventory_list.generate_report.disabled is False,
5965
}
6066
return result
6167

@@ -70,17 +76,6 @@ def get_displayed_descriptions(self):
7076
}
7177
return result
7278

73-
def get_displayed_inventory_tabs(self):
74-
"""Get displayed inventory tabs on Red Hat Inventory page"""
75-
view = self.navigate_to(self, 'All')
76-
self.browser.plugin.ensure_page_safe(timeout='5s')
77-
view.wait_displayed()
78-
result = {
79-
'generating': view.inventory_list.generating.is_displayed,
80-
'uploading': view.inventory_list.uploading.is_displayed,
81-
}
82-
return result
83-
8479
def configure_cloud_connector(self):
8580
"""Configure Cloud Connector"""
8681
view = self.navigate_to(self, 'All')
@@ -97,15 +92,31 @@ def sync_inventory_status(self):
9792
view = self.navigate_to(self, 'All')
9893
view.sync_status.click()
9994

100-
def generate_report(self, entity_name):
95+
def generate_and_upload_report(self, entity_name):
96+
"""
97+
Generate and upload inventory report for a specific organization.
98+
"""
10199
view = self.navigate_to(self, 'All')
102100
view.inventory_list.toggle(entity_name)
103-
view.browser.click(view.inventory_list.generating.generate, ignore_ajax=True)
101+
view.inventory_list.generate_and_upload.click()
102+
# self.browser.plugin.ensure_page_safe(timeout='10s')
104103

105-
def download_report(self, entity_name):
104+
def generate_report_only(self, entity_name):
105+
"""
106+
Generate inventory report (without upload) for a specific organization.
107+
"""
106108
view = self.navigate_to(self, 'All')
107109
view.inventory_list.toggle(entity_name)
108-
view.browser.click(view.inventory_list.generating.download_report, ignore_ajax=True)
110+
view.inventory_list.generate_report.click()
111+
# self.browser.plugin.ensure_page_safe(timeout='10s')
112+
113+
def download_report_only(self, org_name):
114+
"""
115+
Download inventory report for a specific organization.
116+
"""
117+
view = self.navigate_to(self, 'All')
118+
view.inventory_list.toggle(org_name)
119+
view.inventory_list.download_report.click()
109120
time.sleep(3)
110121
return self.browser.save_downloaded_file()
111122

airgun/views/cloud_inventory.py

Lines changed: 29 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
from selenium.common.exceptions import NoSuchElementException
21
from wait_for import wait_for
32
from widgetastic.utils import ParametrizedLocator
43
from widgetastic.widget import Text, View
5-
from widgetastic_patternfly import Button, Tab
4+
from widgetastic_patternfly import Tab
65
from widgetastic_patternfly4.switch import Switch
76
from widgetastic_patternfly5 import Button as PF5Button, Menu
87
from widgetastic_patternfly5.ouia import Text as PF5OUIAText
@@ -44,73 +43,54 @@ class InventoryItemsView(Accordion):
4443
DESCRIPTION_LOCATOR = (
4544
'.//span[contains(@class, "pf-v5-c-label pf-m-blue pf-m-outline account-icon")]'
4645
)
47-
STATUS_ELEMENTS = './/div[contains(@class, "status")]/div[contains(@class, "item")]'
48-
49-
@View.nested
50-
class generating(InventoryTab):
51-
process = Text('.//div[contains(@class, "tab-header")]/div[1]')
52-
generate = Button('contains', 'Generate')
53-
download_report = Button('Download Report')
54-
terminal = Text(
55-
'.//div[contains(@class, "report-generate")]//div[contains(@class, "terminal")]'
56-
)
57-
scheduled_run = Text('.//div[contains(@class, "scheduled_run")]')
58-
59-
@View.nested
60-
class uploading(InventoryTab):
61-
process = Text('.//div[contains(@class, "tab-header")]/div[1]')
62-
terminal = Text(
63-
'.//div[contains(@class, "report-upload")]//div[contains(@class, "terminal")]'
64-
)
6546

66-
@property
67-
def is_generating(self):
68-
try:
69-
self.parent_browser.element(f'{self.STATUS_ELEMENTS}[1]')
70-
return True
71-
except NoSuchElementException:
72-
return False
47+
# Task action buttons
48+
generate_and_upload = PF5Button('Generate and upload report')
49+
generate_report = PF5Button('Generate report')
50+
download_report = PF5Button('Download report')
7351

74-
@property
75-
def is_uploading(self):
76-
try:
77-
self.parent_browser.element(f'{self.STATUS_ELEMENTS}[2]')
78-
return True
79-
except NoSuchElementException:
80-
return False
81-
82-
@property
83-
def status(self):
84-
if self.is_generating:
85-
return 'generating'
86-
if self.is_uploading:
87-
return 'uploading'
88-
return 'idle'
52+
task_status = Text(locator='.//div[contains(@class, "pf-v5-c-progress__description")]')
53+
report_saved_to = Text(
54+
locator=(
55+
'.//dt[.//span[contains(text(), "Report saved to")]]/following-sibling::dd[1]'
56+
'//div[contains(@class, "pf-v5-c-description-list__text")]'
57+
)
58+
)
8959

9060
@property
9161
def is_active(self):
62+
"""Check if this accordion item is expanded."""
9263
classes = self.browser.classes(self)
9364
return any('expand-active' in class_ for class_ in classes)
9465

9566
def child_widget_accessed(self, widget):
67+
"""Automatically expand the accordion when accessing child widgets."""
9668
if not self.is_active:
9769
self.click()
9870

9971
def read(self, widget_names=None):
100-
final_dict = {
101-
'generating': self.generating.read(),
102-
'status': self.status,
72+
"""Read the current state of the view including all settings."""
73+
result = {
74+
'generate_and_upload_displayed': self.generate_and_upload.is_displayed,
75+
'generate_report_displayed': self.generate_report.is_displayed,
76+
'download_report_displayed': self.download_report.is_displayed,
10377
'obfuscate_hostnames': self.parent.obfuscate_hostnames.read(),
10478
'obfuscate_ips': self.parent.obfuscate_ips.read(),
10579
'exclude_packages': self.parent.exclude_packages.read(),
10680
}
107-
if self.uploading.is_displayed:
108-
final_dict['uploading'] = self.uploading.read()
81+
82+
# Include auto_update if it's displayed
10983
if self.parent.auto_update.is_displayed:
110-
final_dict['auto_update'] = self.parent.auto_update.read()
111-
return final_dict
84+
result['auto_update'] = self.parent.auto_update.read()
85+
86+
if self.report_saved_to.is_displayed:
87+
result['report_saved_to'] = self.report_saved_to.read()
88+
result['task_status'] = self.task_status.read()
89+
90+
return result
11291

11392
def fill(self, values):
93+
"""This view is read-only."""
11494
raise ReadOnlyWidgetError('View is read only, fill is prohibited')
11595

11696

0 commit comments

Comments
 (0)