Skip to content

Commit

Permalink
Merge pull request #1533 from pnovotny/cherry-pick-6.16.z-new-job-inv…
Browse files Browse the repository at this point in the history
…ocation-details-page

[6.16.z] New job invocation details page
  • Loading branch information
pnovotny committed Aug 27, 2024
2 parents b78106e + 75443b7 commit 147e3a7
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 4 deletions.
32 changes: 30 additions & 2 deletions airgun/entities/job_invocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
JobInvocationCreateView,
JobInvocationStatusView,
JobInvocationsView,
NewJobInvocationStatusView,
)


Expand All @@ -30,9 +31,10 @@ def search(self, value):
view = self.navigate_to(self, 'All')
return view.search(value)

def read(self, entity_name, host_name, widget_names=None):
def read(self, entity_name, host_name, widget_names=None, new_ui=False):
"""Read values for scheduled or already executed job"""
view = self.navigate_to(self, 'Job Status', entity_name=entity_name, host_name=host_name)
nav_step = 'Job Status' if not new_ui else 'Job Status New UI'
view = self.navigate_to(self, nav_step, entity_name=entity_name, host_name=host_name)
return view.read(widget_names=widget_names)

def wait_job_invocation_state(self, entity_name, host_name, expected_state='succeeded'):
Expand Down Expand Up @@ -124,3 +126,29 @@ def prerequisite(self, *args, **kwargs):
def step(self, *args, **kwargs):
self.parent.search(f'host = {kwargs.get("host_name")}')
self.parent.table.row(description=kwargs.get('entity_name'))['Description'].widget.click()


@navigator.register(JobInvocationEntity, 'Job Status New UI')
class NewJobStatus(NavigateStep):
"""Navigate to the new job invocation details page.
Note: `Show Experimental Labs` setting must be enabled.
Args:
entity_name: name of the job
host_name: name of the host to which job was applied
"""

VIEW = NewJobInvocationStatusView

def prerequisite(self, *args, **kwargs):
return self.navigate_to(
self.obj,
'Job Status',
entity_name=kwargs.get('entity_name'),
host_name=kwargs.get('host_name'),
)

def step(self, *args, **kwargs):
self.parent.new_ui.click()
self.view.browser.plugin.ensure_page_safe()
self.view.wait_displayed()
73 changes: 71 additions & 2 deletions airgun/views/job_invocation.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
from wait_for import wait_for
from widgetastic.widget import Text, TextInput, View
from widgetastic_patternfly import BreadCrumb
from widgetastic_patternfly4 import Button, ChipGroup, Radio, Select
from widgetastic_patternfly4.ouia import Select as OUIASelect
from widgetastic_patternfly4 import Button, ChipGroup, DescriptionList, Radio, Select
from widgetastic_patternfly4.donutchart import DonutCircle, DonutLegend
from widgetastic_patternfly4.ouia import (
Dropdown as OUIADropdown,
Select as OUIASelect,
Text as OUIAText,
)

from airgun.views.common import (
BaseLoggedInView,
Expand Down Expand Up @@ -152,6 +157,7 @@ def is_displayed(self):
job_task = Text("//a[normalize-space(.)='Job Task']")
cancel_job = Button(value='Cancel Job')
abort_job = Button(value='Abort Job')
new_ui = Text("//a[normalize-space(.)='New UI']")

@View.nested
class overview(SatTab):
Expand Down Expand Up @@ -196,3 +202,66 @@ def wait_for_result(self, timeout=600, delay=1):
delay=1,
logger=self.logger,
)


class NewJobInvocationStatusView(BaseLoggedInView):
breadcrumb = BreadCrumb()
title = OUIAText('breadcrumb_title')
create_report = Button(value='Create report')
actions = OUIADropdown('job-invocation-global-actions-dropdown')
BREADCRUMB_LENGTH = 2

@property
def is_displayed(self):
breadcrumb_loaded = self.breadcrumb.wait_displayed()
title_loaded = self.title.wait_displayed()
data_loaded, _ = wait_for(
func=lambda: self.status.is_displayed,
timeout=60,
delay=15,
fail_func=self.browser.refresh,
)
return (
breadcrumb_loaded
and title_loaded
and data_loaded
and self.breadcrumb.locations[0] == 'Jobs'
and len(self.breadcrumb.locations) == self.BREADCRUMB_LENGTH
)

@View.nested
class overall_status(DonutCircle):
"""The donut circle with the overall job status of '{succeeded hosts}/{total hosts}'"""

def read(self):
"""Return `dict` with the parsed overall status numbers, for example:
```{'succeeded_hosts': 2, 'total_hosts': 5}```
"""
succeeded_hosts, total_hosts = self.labels[0].split('/')
return {'succeeded_hosts': int(succeeded_hosts), 'total_hosts': int(total_hosts)}

@View.nested
class status(DonutLegend):
"""'System status' panel."""

ROOT = ".//div[contains(@class, 'chart-legend')]"
first_label = Text(locator="//*[@id='legend-labels-0']")

@property
def is_displayed(self):
"""Any status label is displayed after all data are loaded."""
return self.first_label.is_displayed

def read(self):
"""Return `dict` with the System status info.
Example: ```{'Succeeded': 2, 'Failed': 1, 'In Progress': 0, 'Canceled': 0}```
"""
return {item['label']: int(item['value']) for item in self.all_items}

@View.nested
class overview(DescriptionList):
ROOT = ".//div[contains(@class, 'job-overview')]"

def read(self):
"""Return `dict` without trailing ':' in the key names."""
return {key.replace(':', ''): val for key, val in super().read().items()}

0 comments on commit 147e3a7

Please sign in to comment.