def __init__(self, driver, base_url): super().__init__(driver, base_url, "/host") self.header = PageHeader(self.driver, self.base_url) self.footer = PageFooter(self.driver, self.base_url) self.table = CommonTableObj(self.driver, self.base_url, HostListLocators.HostTable) self.host_popup = HostCreatePopupObj(self.driver, self.base_url)
def __init__(self, driver, base_url): if self.MENU_SUFFIX is None: raise AttributeError('You should explicitly set MENU_SUFFIX in class definition') super().__init__(driver, base_url, "/admin/" + self.MENU_SUFFIX) self.header = PageHeader(self.driver, self.base_url) self.footer = PageFooter(self.driver, self.base_url) self.config = CommonConfigMenuObj(self.driver, self.base_url) self.table = CommonTableObj(self.driver, self.base_url) self.toolbar = CommonToolbar(self.driver, self.base_url)
def __init__(self, driver, base_url, provider_id: int): if self.MENU_SUFFIX is None: raise AttributeError('You should explicitly set MENU_SUFFIX in class definition') super().__init__(driver, base_url, "/provider/{provider_id}/" + self.MENU_SUFFIX, provider_id=provider_id) self.header = PageHeader(self.driver, self.base_url) self.footer = PageFooter(self.driver, self.base_url) self.config = CommonConfigMenuObj(self.driver, self.base_url) self.provider_id = provider_id self.toolbar = CommonToolbar(self.driver, self.base_url) self.table = CommonTableObj(self.driver, self.base_url) self.group_config = GroupConfigList(self.driver, self.base_url)
def __init__(self, driver, base_url, cluster_id: int, service_id: int, component_id: int): if self.MENU_SUFFIX is None: raise AttributeError( 'You should explicitly set MENU_SUFFIX in class definition') super().__init__( driver, base_url, "/cluster/{cluster_id}/service/{service_id}/component/{component_id}/" + self.MENU_SUFFIX, cluster_id=cluster_id, service_id=service_id, component_id=component_id, ) self.cluster_id = cluster_id self.service_id = service_id self.component_id = component_id self.header = PageHeader(self.driver, self.base_url) self.footer = PageFooter(self.driver, self.base_url) self.config = CommonConfigMenuObj(self.driver, self.base_url) self.toolbar = CommonToolbar(self.driver, self.base_url) self.table = CommonTableObj(self.driver, self.base_url) self.group_config = GroupConfigList(self.driver, self.base_url)
class HostListPage(BasePageObject): """Host List Page class""" def __init__(self, driver, base_url): super().__init__(driver, base_url, "/host") self.header = PageHeader(self.driver, self.base_url) self.footer = PageFooter(self.driver, self.base_url) self.table = CommonTableObj(self.driver, self.base_url, HostListLocators.HostTable) self.host_popup = HostCreatePopupObj(self.driver, self.base_url) @allure.step('Get host information from row #{row_num}') def get_host_row(self, row_num: int = 0) -> WebElement: """Get host information from row""" def _table_has_enough_rows(): assert_enough_rows(row_num, self.table.row_count) wait_until_step_succeeds(_table_has_enough_rows, timeout=5, period=0.1) rows = self.table.get_all_rows() assert_enough_rows(row_num, len(rows)) return rows[row_num] @allure.step('Get host information from table row #{row_num}') def get_host_info_from_row(self, row_num: int = 0) -> HostRowInfo: """Get host information from table row""" row = self.table.get_row(row_num) row_elements = HostListLocators.HostTable.HostRow cluster_value = self.find_child(row, row_elements.cluster).text return HostRowInfo( fqdn=self.find_child(row, row_elements.fqdn).text, provider=self.find_child(row, row_elements.provider).text, cluster=cluster_value if cluster_value != HostRowInfo.UNASSIGNED_CLUSTER_VALUE else None, state=self.find_child(row, row_elements.state).text, ) @allure.step('Click on cell {child_locator} (row #{row_num})') def click_on_row_child(self, row_num: int, child_locator: Locator): """Click on row child""" row = self.table.get_row(row_num) self.find_child(row, child_locator).click() @allure.step("Create new host") def create_host( self, fqdn: str, cluster: Optional[str] = None, ): """Create host in popup""" self.open_host_creation_popup() self._insert_new_host_info(fqdn, cluster) self.click_create_host_in_popup() self.close_host_creation_popup() @allure.step("Upload bundle from host creation popup") def upload_bundle_from_host_create_popup(self, bundle_path: str): """Upload bundle in host creation popup and close popup""" self.open_host_creation_popup() self._upload_bundle(bundle_path) self.close_host_creation_popup() @allure.step("Create new provider and host") def create_provider_and_host( self, bundle_path: str, fqdn: str, cluster: Optional[str] = None, ) -> str: """ Open host creation popup Upload bundle and create provider Fill in information about new host Create host Close popup :returns: Name of created provider """ self.open_host_creation_popup() self._upload_bundle(bundle_path) provider_name = self._get_hostprovider_name() self._insert_new_host_info(fqdn, cluster) self.click_create_host_in_popup() self.close_host_creation_popup() # because we don't pass provider name return provider_name @allure.step( 'Run action "{action_display_name}" on host in row {host_row_num}') def run_action(self, host_row_num: int, action_display_name: str): """Run action from Host row""" host_row = HostListLocators.HostTable.HostRow self.click_on_row_child(host_row_num, host_row.actions) init_action = self.wait_element_visible( host_row.action_option(action_display_name)) init_action.click() self.wait_element_visible(ActionDialog.body) self.find_and_click(ActionDialog.run) self.wait_element_hide(ActionDialog.body) @allure.step('Delete host in row {host_row_num}') def delete_host(self, host_row_num: int): """Delete host from table row""" self.click_on_row_child(host_row_num, HostListLocators.HostTable.HostRow.delete_btn) self.wait_element_visible(DeleteDialog.body) self.find_and_click(DeleteDialog.yes) self.wait_element_hide(DeleteDialog.body) @allure.step('Bind host in row {host_row_num} to cluster "{cluster_name}"') def bind_host_to_cluster(self, host_row_num: int, cluster_name: str): """Assign host to cluster in host list table""" self.click_on_row_child(host_row_num, HostListLocators.HostTable.HostRow.cluster) self.host_popup.wait_and_click_on_cluster_option( cluster_name, HostListLocators.HostTable.cluster_option) @allure.step( 'Assert host in row {row_num} is assigned to cluster {cluster_name}') def assert_host_bonded_to_cluster(self, row_num: int, cluster_name: str): """Assert host in row is assigned to cluster""" def _check_host_cluster(page: HostListPage, row: WebElement): real_cluster = page.find_child( row, HostListLocators.HostTable.HostRow.cluster).text assert real_cluster == cluster_name host_row = self.table.get_row(row_num) wait_until_step_succeeds(_check_host_cluster, timeout=5, period=0.1, page=self, row=host_row) @allure.step('Assert host in row {row_num} has state "{state}"') def assert_host_state(self, row_num: int, state: str): """Assert host in row has state given state""" def _check_host_state(page: HostListPage, row: WebElement): real_state = page.find_child( row, HostListLocators.HostTable.HostRow.state).text assert real_state == state host_row = self.table.get_row(row_num) wait_until_step_succeeds(_check_host_state, timeout=10, period=0.5, page=self, row=host_row) @allure.step('Open host creation popup') def open_host_creation_popup(self): """Open host creation popup""" self.find_and_click(HostListLocators.Tooltip.host_add_btn) self.wait_element_visible(HostCreationLocators.block) @allure.step('Close host creation popup') def close_host_creation_popup(self): """Close popup with `Cancel` button""" self.find_and_click(HostCreationLocators.cancel_btn) @allure.step('Click "Create host" in popup') def click_create_host_in_popup(self): """Click create host button in popup""" self.find_and_click(HostCreationLocators.create_btn) def _insert_new_host_info(self, fqdn: str, cluster: Optional[str] = None): """Insert new host info in fields of opened popup""" self.wait_element_visible(HostCreationLocators.fqdn_input) self.send_text_to_element(HostCreationLocators.fqdn_input, fqdn) if cluster: self._choose_cluster_in_popup(cluster) def _upload_bundle(self, bundle_path: str): """ Add new host provider Popup should be opened Popup is not closed at the end """ provider_section = HostCreationLocators.Provider self.find_and_click(provider_section.add_btn) self.wait_element_visible(provider_section.new_provider_block) self.find_element( provider_section.upload_bundle_btn).send_keys(bundle_path) self.find_and_click(provider_section.new_provider_add_btn) self.wait_element_hide(provider_section.new_provider_block) def _get_hostprovider_name(self) -> str: """Get chosen provider from opened new host popup""" return self.find_element( HostCreationLocators.Provider.chosen_provider).text def _choose_cluster_in_popup(self, cluster_name: str): self.find_and_click(HostCreationLocators.Cluster.cluster_select) option = HostCreationLocators.Cluster.cluster_option self._wait_and_click_on_cluster_option(cluster_name, option) self.wait_element_hide(option) def _wait_and_click_on_cluster_option(self, cluster_name: str, option_locator: Locator): WDW(self.driver, self.default_loc_timeout).until( EC.presence_of_element_located( [option_locator.by, option_locator.value.format(cluster_name)]), message=f"Can't find cluster with name {cluster_name} " f"in dropdown on page {self.driver.current_url} " f"for {self.default_loc_timeout} seconds", ).click()
def __init__(self, driver, base_url): super().__init__(driver, base_url, "/task") self.header = PageHeader(self.driver, self.base_url) self.footer = PageFooter(self.driver, self.base_url) self.table = CommonTableObj(self.driver, self.base_url, TaskListLocators.Table)
class JobListPage(BasePageObject): """Job List Page class""" def __init__(self, driver, base_url): super().__init__(driver, base_url, "/task") self.header = PageHeader(self.driver, self.base_url) self.footer = PageFooter(self.driver, self.base_url) self.table = CommonTableObj(self.driver, self.base_url, TaskListLocators.Table) def get_task_info_from_table( self, row_num: int = 0, *, full_invoker_objects_link: bool = False) -> TableTaskInfo: """ Get job information from row :param row_num: Index of row in table :param full_invoker_objects_link: Use it to get full object link (with "parent" objects) or just object which invoked the action """ row = self.table.get_row(row_num) row_locators = TaskListLocators.Table.Row if full_invoker_objects_link: invoker_objects = self.find_children(row, row_locators.invoker_objects) object_link = '/'.join(obj.text.strip() for obj in invoker_objects) else: object_link = self.find_child( row, row_locators.invoker_objects).text.strip() return TableTaskInfo( action_name=self.find_child(row, row_locators.action_name).text, invoker_objects=object_link, start_date=self.find_child(row, row_locators.start_date).text, finish_date=self.find_child(row, row_locators.finish_date).text, status=self._get_status_from_class_string( self.find_child(row, row_locators.status)), ) def get_task_info_from_popup(self, row_num: int = 0) -> PopupTaskInfo: """Get job information from list in popup""" job = self.header.get_single_job_row_from_popup(row_num) popup_locators = AuthorizedHeaderLocators.JobPopup return PopupTaskInfo( action_name=self.find_child(job, popup_locators.JobRow.job_name).text, status=self._get_status_from_class_string( self.find_child(job, popup_locators.JobRow.job_status)), ) def get_all_jobs_info(self) -> List[SubTaskJobInfo]: """ Returns information about all jobs from expanded first task's jobs list """ expand_task_locators = TaskListLocators.Table.ExpandedTask job_rows = self.find_elements(expand_task_locators.row) return [ SubTaskJobInfo( name=self.find_child(job, expand_task_locators.Row.job_name).text, status=self._get_status_from_class_string( self.find_child(job, expand_task_locators.Row.job_status)), ) for job in job_rows ] @allure.step('Expand task in row {row_num}') def expand_task_in_row(self, row_num: int = 0): """Click on expand jobs button""" table_locators = TaskListLocators.Table row = self.table.get_row(row_num) self.find_child(row, table_locators.Row.expand_task).click() self.wait_element_visible(table_locators.ExpandedTask.block) @allure.step("Click on job in task's job list") def click_on_job(self, job_num: int = 0): """Click on job in expanded first task's job list""" expand_task_locators = TaskListLocators.Table.ExpandedTask job_rows = self.find_elements(expand_task_locators.row) assert job_num < len(job_rows), 'Not enough jobs in this task' self.find_child(job_rows[job_num], expand_task_locators.Row.job_name).click() @allure.step('Click on action name') def click_on_action_name_in_row(self, row: WebElement): """Click on action name in row""" locator = TaskListLocators.Table.Row.action_name row.find_element(locator.by, locator.value).click() @allure.step('Select the "All" filter tab') def select_filter_all_tab(self): """Show all tasks""" self._select_filter(TaskListLocators.Filter.all) @allure.step('Select the "Running" filter tab') def select_filter_running_tab(self): """Show only running tasks""" self._select_filter(TaskListLocators.Filter.running) @allure.step('Select the "Success" filter tab') def select_filter_success_tab(self): """Show only success tasks""" self._select_filter(TaskListLocators.Filter.success) @allure.step('Select the "Failed" filter tab') def select_filter_failed_tab(self): """Show only failed tasks""" self._select_filter(TaskListLocators.Filter.failed) def _select_filter(self, filter_locator: Locator): """Click on filter tab and wait it is pressed""" self.find_and_click(filter_locator) self.wait_element_attribute(filter_locator, 'aria-pressed', "true") self.wait_element_hide(CommonToolbarLocators.progress_bar) @staticmethod def _get_status_from_class_string(status_element: WebElement) -> JobStatus: """Get JobStatus from @class string""" class_string = status_element.get_attribute('class') for status in JobStatus: if status.value in class_string: return status raise KeyError('Job status not found in class string: %s' % str(class_string)) def get_selected_filter(self): """Get selected filter text""" for filter_element in self.find_elements( TaskListLocators.Filter.filter_btn): if filter_element.get_attribute("aria-pressed") == "true": return filter_element.text
class BundleListPage(BasePageObject): """Bundle List Page class""" def __init__(self, driver, base_url): super().__init__(driver, base_url, "/bundle") self.header = PageHeader(self.driver, self.base_url) self.footer = PageFooter(self.driver, self.base_url) self.table = CommonTableObj(self.driver, self.base_url, BundleListLocators.Table) @allure.step('Get bundle information from row #{row_num}') def get_bundle_info(self, row_num: int = 0) -> BundleInfo: """Get information about bundle from row""" row = self.table.get_row(row_num) row_elements = BundleListLocators.Table.Row return BundleInfo( name=self.find_child(row, row_elements.name).text, version=self.find_child(row, row_elements.version).text, edition=self.find_child(row, row_elements.edition).text, description=self.find_child(row, row_elements.description).text, ) @allure.step('Upload bundle from {bundle_path}') def upload_bundle(self, bundle_path: str): """Upload bundle with 'Upload bundles' button""" self.find_element( BundleListLocators.Toolbar.upload_btn).send_keys(bundle_path) @allure.step('Upload bundles from {bundle_paths}') def upload_bundles(self, bundle_paths: list): """Upload multiple bundles at once with 'Upload bundles' button""" self.find_element(BundleListLocators.Toolbar.upload_btn).send_keys( "\n".join(bundle_paths)) @allure.step('Remove bundle') def delete_bundle(self, row_num: int = 0): """Remove bundle by clicking on trash icon in row""" row = self.table.get_row(row_num) self.find_child(row, BundleListLocators.Table.Row.delete_btn).click() self.wait_element_visible(DeleteDialog.body) self.find_and_click(DeleteDialog.yes) self.wait_element_hide(DeleteDialog.body) @allure.step('Accept licence agreement') def accept_licence(self, row_num: int = 0): """Accept license""" row = self.table.get_row(row_num) row_elements = BundleListLocators.Table.Row self.find_child(row, row_elements.license_btn).click() self.wait_element_visible(BundleListLocators.LicensePopup.block) self.find_and_click(BundleListLocators.LicensePopup.agree_btn) self.wait_element_hide(BundleListLocators.LicensePopup.block) @allure.step('Click bundle name in row') def click_bundle_in_row(self, row: WebElement): """Click on bundle name""" bundle_name = self.find_child(row, BundleListLocators.Table.Row.name) bundle_name.click() @allure.step('Click on "home" button on toolbar') def click_on_home_button_on_toolbar(self): """Click on home button (a.k.a. "apps") in toolbar to open into page""" self.find_and_click(BundleListLocators.Toolbar.apps_btn) @allure.step('Check bundle is visible') def check_at_least_one_bundle_is_presented(self): """Check that at least one row is visible in table""" self.check_element_should_be_visible(BundleListLocators.Table.row)
def __init__(self, driver, base_url): super().__init__(driver, base_url, "/cluster") self.header = PageHeader(self.driver, self.base_url) self.footer = PageFooter(self.driver, self.base_url) self.table = CommonTableObj(self.driver, self.base_url, ClusterListLocators.ClusterTable)
class ClusterListPage(BasePageObject): """Cluster List Page class""" def __init__(self, driver, base_url): super().__init__(driver, base_url, "/cluster") self.header = PageHeader(self.driver, self.base_url) self.footer = PageFooter(self.driver, self.base_url) self.table = CommonTableObj(self.driver, self.base_url, ClusterListLocators.ClusterTable) @allure.step("Create cluster") def create_cluster(self, bundle: str, description: str = None, is_license: bool = False): """Create cluster""" self.find_and_click(ClusterListLocators.Tooltip.cluster_add_btn) popup = ClusterListLocators.CreateClusterPopup self.wait_element_visible(popup.block) self.find_element(popup.upload_bundle_btn).send_keys(bundle) if description: self.send_text_to_element(popup.description_input, description) self.find_and_click(popup.create_btn) if is_license: self.wait_element_visible(ClusterListLocators.LicensePopup.block) self.find_and_click(ClusterListLocators.LicensePopup.agree_btn) @allure.step("Upload bundle without creating a cluster") def upload_bundle_from_cluster_create_popup(self, bundle: str): """Upload bundle from cluster list page without creating a cluster""" self.find_and_click(ClusterListLocators.Tooltip.cluster_add_btn) popup = ClusterListLocators.CreateClusterPopup self.wait_element_visible(popup.block) self.find_element(popup.upload_bundle_btn).send_keys(bundle) self.find_and_click(popup.cancel_btn) self.wait_element_hide(popup.block) def get_cluster_info_from_row(self, row: int) -> dict: """Get Cluster info from Cluster List row""" row_elements = ClusterListLocators.ClusterTable.ClusterRow cluster_row = self.table.get_all_rows()[row] return { "name": self.find_child(cluster_row, row_elements.name).text, "bundle": self.find_child(cluster_row, row_elements.bundle).text, "description": self.find_child(cluster_row, row_elements.description).text, "state": self.find_child(cluster_row, row_elements.state).text, } @allure.step("Click on action button from row") def click_action_btn_in_row(self, row: WebElement): """Click on Action button from Cluster List row""" self.find_child(row, self.table.locators.ClusterRow.actions).click() @allure.step("Click on import button from row") def click_import_btn_in_row(self, row: WebElement): """Click on Import button from Cluster List row""" self.find_child(row, self.table.locators.ClusterRow.imports).click() @allure.step("Run action {action_name} for cluster from row") def run_action_in_cluster_row(self, row: WebElement, action_name: str): """Run action for cluster from row""" self.click_action_btn_in_row(row) self.wait_element_visible(self.table.locators.ActionPopup.block) self.find_and_click( self.table.locators.ActionPopup.button(action_name)) self.wait_element_visible(ActionDialog.body) self.find_and_click(ActionDialog.run) self.wait_element_hide(ActionDialog.body) @contextmanager def wait_cluster_state_change(self, row: WebElement): """Wait for cluster state to change""" state_before = self.get_cluster_state_from_row(row) yield def _wait_state(): state_after = self.get_cluster_state_from_row(row) assert state_after != state_before assert state_after != self.table.LOADING_STATE_TEXT wait_until_step_succeeds(_wait_state, period=1, timeout=self.default_loc_timeout) def get_cluster_state_from_row(self, row: WebElement): """Get Cluster state from row""" return self.find_child(row, self.table.locators.ClusterRow.state).text @allure.step("Get row by cluster name '{cluster_name}'") def get_row_by_cluster_name(self, cluster_name: str) -> WebElement: """Get Cluster row by cluster name""" rows = self.table.get_all_rows() for row in rows: if self.find_child( row, self.table.locators.ClusterRow.name).text == cluster_name: return row raise AssertionError( f"Cluster '{cluster_name}' not found in table rows") @allure.step("Click on config button from the row") def click_config_button_in_row(self, row: WebElement): """Click on Config button from the row""" self.find_child(row, self.table.locators.ClusterRow.config).click() @allure.step("Click on cluster name from the row") def click_cluster_name_in_row(self, row: WebElement): """Click on Cluster name from the row""" self.find_child(row, self.table.locators.ClusterRow.name).click() @allure.step("Delete cluster by button from the row") def delete_cluster_by_row(self, row: WebElement): """Delete Cluster by button from the row""" self.find_child(row, self.table.locators.ClusterRow.delete_btn).click() self.wait_element_visible(DeleteDialog.body) self.find_and_click(DeleteDialog.yes) self.wait_element_hide(DeleteDialog.body) @allure.step("Click on cluster concern object name from the row") def click_on_concern_by_object_name(self, row: WebElement, concern_object_name: str): """Click on Cluster Concern object name from the row""" self.hover_element( self.find_child(row, self.table.locators.ClusterRow.actions)) self.wait_element_visible(ListConcernPopupLocators.block) for issue in self.find_elements( ListConcernPopupLocators.link_to_concern_object): if concern_object_name in issue.text: issue.click() return raise AssertionError( f"Issue name '{concern_object_name}' not found in row issues")