Skip to content

Commit d158033

Browse files
rmynarpondrejk
authored andcommitted
pf5 on job_invocation wizard
1 parent 5b86882 commit d158033

7 files changed

Lines changed: 293 additions & 70 deletions

File tree

airgun/entities/host_new.py

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,19 @@
33
from navmazing import NavigateToSibling
44
from wait_for import wait_for
55

6+
from airgun.entities.all_hosts import AllHostsEntity
67
from airgun.entities.host import HostEntity
78
from airgun.navigation import NavigateStepWithWait as NavigateStep, navigator
9+
from airgun.views.all_hosts import AllHostsTableView
810
from airgun.views.cloud_insights import RemediateSummary
911
from airgun.views.fact import HostFactView
10-
from airgun.views.host import HostsView as LegacyHostsView
12+
from airgun.views.host import HostsJobInvocationStatusView, HostsView as LegacyHostsView
1113
from airgun.views.host_new import (
1214
AllAssignedRolesView,
1315
ContainerfileInstallCommandView,
1416
EditAnsibleRolesView,
1517
EditSystemPurposeView,
1618
EnableTracerView,
17-
HostsView,
1819
InstallPackagesView,
1920
ManageHostCollectionModal,
2021
ManageHostStatusesView,
@@ -349,6 +350,57 @@ def schedule_job(self, entity_name, values):
349350
view.fill(values)
350351
view.submit.click()
351352

353+
def schedule_remote_job(self, entities_list, values, timeout=60, wait_for_results=True):
354+
"""Apply Schedule Remote Job action to the hosts names in entities_list using PF5 UI.
355+
356+
For multiple hosts, uses AllHostsEntity helper to select checkboxes, then clicks
357+
"Schedule a job" button which opens the wizard with hosts pre-selected.
358+
359+
:param entities_list: The host names to apply the remote job.
360+
:param values: the values to fill The Job invocation view.
361+
:param timeout: The time to wait for the job to finish.
362+
:param wait_for_results: Whether to wait for the job to finish execution.
363+
364+
:returns: The job invocation status view values
365+
"""
366+
if len(entities_list) == 1:
367+
entity_name = entities_list[0]
368+
details_view = self.navigate_to(self, 'NewDetails', entity_name=entity_name)
369+
self.browser.plugin.ensure_page_safe()
370+
details_view.wait_displayed()
371+
self.browser.wait_for_element(details_view.schedule_job, exception=False)
372+
details_view.schedule_job.fill('Schedule a job')
373+
view = JobInvocationCreateView(self.browser)
374+
self.browser.plugin.ensure_page_safe()
375+
else:
376+
hosts_view = AllHostsEntity.all_hosts_navigate_and_select_hosts_helper(
377+
self, host_names=entities_list
378+
)
379+
schedule_button_locator = ".//button[contains(., 'Schedule a job') or @data-ouia-component-id='schedule-a-job-dropdown']"
380+
wait_for(
381+
lambda: hosts_view.browser.element(schedule_button_locator, check_visibility=True),
382+
timeout=10,
383+
delay=0.5,
384+
handle_exception=True,
385+
)
386+
schedule_button = hosts_view.browser.element(schedule_button_locator)
387+
hosts_view.browser.click(schedule_button)
388+
view = JobInvocationCreateView(self.browser)
389+
self.browser.plugin.ensure_page_safe()
390+
view.wait_displayed()
391+
392+
view.fill(values)
393+
self.browser.plugin.ensure_page_safe()
394+
view.submit.click()
395+
view.flash.assert_no_error()
396+
view.flash.dismiss()
397+
status_view = HostsJobInvocationStatusView(self.browser)
398+
self.browser.plugin.ensure_page_safe()
399+
status_view.wait_displayed()
400+
if wait_for_results:
401+
status_view.wait_for_result(timeout=timeout)
402+
return status_view.read()
403+
352404
def run_job(self, entity_name):
353405
"""Run a job on selected host"""
354406
view = self.navigate_to(self, 'NewDetails', entity_name=entity_name)
@@ -1231,7 +1283,7 @@ def get_content_view_envs(self, entity_name):
12311283
class ShowAllHosts(NavigateStep):
12321284
"""Navigate to new UI All Hosts page"""
12331285

1234-
VIEW = HostsView
1286+
VIEW = AllHostsTableView
12351287

12361288
def step(self, *args, **kwargs):
12371289
self.view.menu.select('Hosts', 'All Hosts')
@@ -1252,6 +1304,7 @@ def prerequisite(self, *args, **kwargs):
12521304

12531305
def step(self, *args, **kwargs):
12541306
entity_name = kwargs.get('entity_name')
1307+
12551308
self.parent.search(entity_name)
12561309
self.parent.table.row(name=entity_name)['Name'].widget.click()
12571310

airgun/entities/job_invocation.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ def run(self, values):
2222
"""Run specific job"""
2323
view = self.navigate_to(self, 'Run')
2424
view.fill(values)
25-
view.submit.expander.click()
26-
self.browser.wait_for_element(view.submit.submit, exception=False)
27-
view.submit.click()
25+
view.submit.click() # PF5 wizard: submit.click() handles everything
2826

2927
def search(self, value):
3028
"""Search for specific job invocation"""
@@ -40,6 +38,7 @@ def wait_job_invocation_state(self, entity_name, host_name, expected_state='succ
4038
"""Check job invocation state from table view"""
4139
view = self.navigate_to(self, 'All')
4240
view.search(f'host = {host_name}')
41+
4342
wait_for(
4443
lambda: view.table.row(description=entity_name)['Status'].read() == expected_state,
4544
timeout=300,

airgun/views/all_hosts.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ class AllHostsTableView(BaseLoggedInView, SearchableViewMixinPF4):
106106
locator='//li[contains(@class, "pf-v5-c-menu__list-item")]//button[span/span[text()="Change associations"]]/following-sibling::div[contains(@class, "pf-v5-c-menu")]'
107107
)
108108

109+
# Additional action buttons
110+
schedule_a_job = PF5OUIADropdown('schedule-a-job-dropdown')
111+
109112
table_loading = Text('//h5[normalize-space(.)="Loading"]')
110113
no_results = Text('//h5[normalize-space(.)="No Results"]')
111114
manage_columns = PF5Button('Manage columns')

airgun/views/common.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,3 +772,18 @@ def __init__(self, parent, logger=None):
772772
"""Expand the selected wizard step"""
773773
View.__init__(self, parent, logger=logger)
774774
self.expander.click()
775+
776+
777+
class PF5WizardStepView(View):
778+
"""PF5 Wizard step - doesn't use expanders, uses wizard navigation instead.
779+
780+
The PF5 wizard pattern navigates between steps using Next/Back buttons
781+
in the footer, not by clicking expander buttons. Steps are already visible
782+
when you're on that step.
783+
"""
784+
785+
def __init__(self, parent, logger=None):
786+
"""Initialize PF5 wizard step without clicking expander."""
787+
View.__init__(self, parent, logger=logger)
788+
# PF5 wizards don't have expanders - steps are navigated via Next/Back buttons
789+
# The step is already visible when active

airgun/views/host_new.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ class HostsView(BaseLoggedInView, SearchableViewMixinPF4):
268268

269269
@property
270270
def is_displayed(self):
271-
return self.title.is_displayed
271+
return self.browser.wait_for_element(self.title, exception=False) is not None
272272

273273

274274
class BreadcrumbSwitcher(Widget):

0 commit comments

Comments
 (0)