diff --git a/airgun/entities/job_invocation.py b/airgun/entities/job_invocation.py index 4655609a8..2c12a827a 100644 --- a/airgun/entities/job_invocation.py +++ b/airgun/entities/job_invocation.py @@ -4,11 +4,13 @@ from airgun.entities.base import BaseEntity from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation +from airgun.views.dynflowconsole import DynflowConsoleView from airgun.views.job_invocation import ( JobInvocationCreateView, JobInvocationStatusView, JobInvocationsView, ) +from airgun.views.task import TaskDetailsView class JobInvocationEntity(BaseEntity): @@ -42,6 +44,22 @@ def wait_job_invocation_state(self, entity_name, host_name, expected_state='succ logger=view.logger, ) + def read_dynflow_output(self, entity_name, host_name): + """Read dynflow console output""" + view = self.navigate_to(self, 'Job Status', entity_name=entity_name, host_name=host_name) + wait_for(lambda: view.overview.hosts_table.is_displayed, timeout=10) + view.overview.hosts_table.row(host=host_name)['Actions'].widget.fill('Host task') + view = TaskDetailsView(self.browser) + wait_for(lambda: view.task.dynflow_console.is_displayed, timeout=10) + view.task.dynflow_console.click() + self.browser.switch_to_window(self.browser.window_handles[1]) + console = DynflowConsoleView(self.browser) + wait_for(lambda: console.is_displayed, timeout=100) + result = console.output.read() + self.browser.switch_to_window(self.browser.window_handles[0]) + self.browser.close_window(self.browser.window_handles[1]) + return result + @navigator.register(JobInvocationEntity, 'All') class ShowAllJobs(NavigateStep): diff --git a/airgun/views/dynflowconsole.py b/airgun/views/dynflowconsole.py new file mode 100644 index 000000000..307c545fe --- /dev/null +++ b/airgun/views/dynflowconsole.py @@ -0,0 +1,15 @@ +from widgetastic.widget import Text +from widgetastic_patternfly4 import Pagination as PF4Pagination + +from airgun.views.common import BaseLoggedInView + + +class DynflowConsoleView(BaseLoggedInView): + title = Text("//a[@class='navbar-brand']//img") + output = Text("//div[@class='action']/pre[2]") + + pagination = PF4Pagination() + + @property + def is_displayed(self): + return self.browser.wait_for_element(self.title, exception=False) is not None diff --git a/airgun/views/job_invocation.py b/airgun/views/job_invocation.py index 5f668dc79..43c8e9088 100644 --- a/airgun/views/job_invocation.py +++ b/airgun/views/job_invocation.py @@ -160,7 +160,7 @@ class overview(SatTab): './/table', column_widgets={ 'Host': Text('./a'), - 'Actions': ActionsDropdown("./div[contains(@class, 'btn-group')]"), + 'Actions': ActionsDropdown('.//div[contains(@class, "btn-group")]'), }, ) total_hosts = Text( diff --git a/airgun/views/task.py b/airgun/views/task.py index 6ceb35c43..925edfb83 100644 --- a/airgun/views/task.py +++ b/airgun/views/task.py @@ -1,6 +1,6 @@ from wait_for import wait_for from widgetastic.widget import Table, Text, View -from widgetastic_patternfly import BreadCrumb +from widgetastic_patternfly import BreadCrumb, Button from widgetastic_patternfly4 import Pagination as PF4Pagination from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixinPF4 @@ -97,6 +97,7 @@ class task(SatTab): progressbar = ProgressBar(locator='//div[contains(@class,"progress-bar")]') output = TaskReadOnlyEntry(name='Output') errors = TaskReadOnlyEntryError(name='Errors') + dynflow_console = Button('Dynflow console') def wait_for_result(self, timeout=60, delay=1): """Wait for invocation job to finish"""