diff --git a/.gitignore b/.gitignore index 9288b9e73..142f4a05b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,5 @@ settings.ini # common venv name .airgun/ +venv* + diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ed9dbb968..9a5de8f8c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,27 +1,17 @@ # configuration for pre-commit git hooks repos: -- repo: https://github.com/asottile/reorder_python_imports - rev: v3.0.1 - hooks: - - id: reorder-python-imports -- repo: https://github.com/asottile/pyupgrade - rev: v2.32.0 - hooks: - - id: pyupgrade - args: [--py36-plus] - repo: https://github.com/psf/black - rev: 22.3.0 + rev: 23.3.0 hooks: - id: black -- repo: https://github.com/pycqa/flake8 - rev: 3.9.2 +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.0.277 hooks: - - id: flake8 + - id: ruff + args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.2.0 hooks: - - id: trailing-whitespace - - id: end-of-file-fixer - id: check-yaml - id: debug-statements diff --git a/airgun/__init__.py b/airgun/__init__.py index d203d340e..16f9520e9 100644 --- a/airgun/__init__.py +++ b/airgun/__init__.py @@ -1,4 +1,3 @@ from airgun.settings import Settings - settings = Settings() diff --git a/airgun/browser.py b/airgun/browser.py index 127c2eba1..e80aa1175 100644 --- a/airgun/browser.py +++ b/airgun/browser.py @@ -2,28 +2,24 @@ tests. """ import base64 +from contextlib import contextmanager +from datetime import datetime import logging import os import time import urllib -from contextlib import contextmanager -from datetime import datetime from urllib.parse import unquote -import yaml from box import Box from selenium import webdriver -from wait_for import TimedOutError -from wait_for import wait_for +from wait_for import TimedOutError, wait_for from webdriver_kaifuku import BrowserManager -from widgetastic.browser import Browser -from widgetastic.browser import DefaultPlugin -from widgetastic.exceptions import NoAlertPresentException -from widgetastic.exceptions import NoSuchElementException +from widgetastic.browser import Browser, DefaultPlugin +from widgetastic.exceptions import NoAlertPresentException, NoSuchElementException +import yaml from airgun import settings -from airgun.widgets import ConfirmationDialog -from airgun.widgets import Pf4ConfirmationDialog +from airgun.widgets import ConfirmationDialog, Pf4ConfirmationDialog LOGGER = logging.getLogger(__name__) @@ -116,7 +112,7 @@ def finalize(self, passed=True): or not. Is only used for ``saucelabs`` provider. :return: None """ - if self.provider == 'selenium' or self.provider == 'remote': + if self.provider in ('selenium', 'remote'): self._webdriver.quit() return @@ -342,7 +338,7 @@ def get_downloads_list(self): '.filter(e => e.state === "COMPLETE")' '.map(e => e.file_url || e.fileUrl);' ) - if self.browser_type == 'chrome' and self.browser_version >= 79: + if self.browser_type == 'chrome': script = ( 'return document.querySelector("downloads-manager")' '.shadowRoot.querySelector("#downloadsList")' @@ -477,7 +473,7 @@ def handle_alert( ): """Extend the behaviour of widgetstatic.browser.handle_alert to handle PF4 alerts""" popup = self.get_alert(squash=squash) - if isinstance(popup, (Pf4ConfirmationDialog, ConfirmationDialog)): + if isinstance(popup, Pf4ConfirmationDialog | ConfirmationDialog): if cancel: self.logger.info(" dismissing") popup.cancel() diff --git a/airgun/entities/activationkey.py b/airgun/entities/activationkey.py index 3b0dbe515..aecdd3b23 100644 --- a/airgun/entities/activationkey.py +++ b/airgun/entities/activationkey.py @@ -1,12 +1,13 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.activationkey import ActivationKeyCreateView -from airgun.views.activationkey import ActivationKeyEditView -from airgun.views.activationkey import ActivationKeysView +from airgun.views.activationkey import ( + ActivationKeyCreateView, + ActivationKeyEditView, + ActivationKeysView, +) class ActivationKeyEntity(BaseEntity): diff --git a/airgun/entities/ansible_role.py b/airgun/entities/ansible_role.py index cc26f200d..ecf109cfc 100644 --- a/airgun/entities/ansible_role.py +++ b/airgun/entities/ansible_role.py @@ -1,10 +1,8 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator -from airgun.views.ansible_role import AnsibleRolesImportView -from airgun.views.ansible_role import AnsibleRolesView +from airgun.navigation import NavigateStep, navigator +from airgun.views.ansible_role import AnsibleRolesImportView, AnsibleRolesView class AnsibleRolesEntity(BaseEntity): diff --git a/airgun/entities/ansible_variable.py b/airgun/entities/ansible_variable.py index a508686b6..9838c3a03 100644 --- a/airgun/entities/ansible_variable.py +++ b/airgun/entities/ansible_variable.py @@ -1,10 +1,8 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator -from airgun.views.ansible_variable import AnsibleVariablesView -from airgun.views.ansible_variable import NewAnsibleVariableView +from airgun.navigation import NavigateStep, navigator +from airgun.views.ansible_variable import AnsibleVariablesView, NewAnsibleVariableView class AnsibleVariablesEntity(BaseEntity): diff --git a/airgun/entities/architecture.py b/airgun/entities/architecture.py index dd2f91da0..c8b903d70 100644 --- a/airgun/entities/architecture.py +++ b/airgun/entities/architecture.py @@ -1,12 +1,13 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.architecture import ArchitectureCreateView -from airgun.views.architecture import ArchitectureDetailsView -from airgun.views.architecture import ArchitecturesView +from airgun.views.architecture import ( + ArchitectureCreateView, + ArchitectureDetailsView, + ArchitecturesView, +) class ArchitectureEntity(BaseEntity): diff --git a/airgun/entities/audit.py b/airgun/entities/audit.py index 53b0e3a79..491d432c3 100644 --- a/airgun/entities/audit.py +++ b/airgun/entities/audit.py @@ -1,6 +1,5 @@ from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation from airgun.views.audit import AuditsView diff --git a/airgun/entities/base.py b/airgun/entities/base.py index 624c11466..27b6015e9 100644 --- a/airgun/entities/base.py +++ b/airgun/entities/base.py @@ -6,7 +6,6 @@ class BaseEntity: - HELPER_CLASS = BaseEntityHelper def __init__(self, browser): diff --git a/airgun/entities/bookmark.py b/airgun/entities/bookmark.py index b5729f3c0..34c83fb3a 100644 --- a/airgun/entities/bookmark.py +++ b/airgun/entities/bookmark.py @@ -1,9 +1,7 @@ from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.bookmark import BookmarkEditView -from airgun.views.bookmark import BookmarksView +from airgun.views.bookmark import BookmarkEditView, BookmarksView def _gen_queries(entity_name, controller=None): diff --git a/airgun/entities/cloud_insights.py b/airgun/entities/cloud_insights.py index 08ef2fd60..cb946c3f3 100644 --- a/airgun/entities/cloud_insights.py +++ b/airgun/entities/cloud_insights.py @@ -1,9 +1,7 @@ from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.cloud_insights import CloudInsightsView -from airgun.views.cloud_insights import CloudTokenView +from airgun.views.cloud_insights import CloudInsightsView, CloudTokenView class CloudInsightsEntity(BaseEntity): diff --git a/airgun/entities/cloud_inventory.py b/airgun/entities/cloud_inventory.py index ed21eb241..33bcaa4ad 100644 --- a/airgun/entities/cloud_inventory.py +++ b/airgun/entities/cloud_inventory.py @@ -1,6 +1,5 @@ from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation from airgun.views.cloud_inventory import CloudInventoryListView diff --git a/airgun/entities/computeprofile.py b/airgun/entities/computeprofile.py index c991e8778..2f3380e0e 100644 --- a/airgun/entities/computeprofile.py +++ b/airgun/entities/computeprofile.py @@ -1,13 +1,14 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.computeprofile import ComputeProfileCreateView -from airgun.views.computeprofile import ComputeProfileDetailView -from airgun.views.computeprofile import ComputeProfileRenameView -from airgun.views.computeprofile import ComputeProfilesView +from airgun.views.computeprofile import ( + ComputeProfileCreateView, + ComputeProfileDetailView, + ComputeProfileRenameView, + ComputeProfilesView, +) class ComputeProfileEntity(BaseEntity): diff --git a/airgun/entities/computeresource.py b/airgun/entities/computeresource.py index 231f4ea50..c366e62b7 100644 --- a/airgun/entities/computeresource.py +++ b/airgun/entities/computeresource.py @@ -1,19 +1,20 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.computeresource import ComputeResourceRHVImageCreateView -from airgun.views.computeresource import ComputeResourceRHVImageEditView -from airgun.views.computeresource import ComputeResourcesView -from airgun.views.computeresource import ComputeResourceVMwareImageCreateView -from airgun.views.computeresource import ComputeResourceVMwareImageEditView -from airgun.views.computeresource import ResourceProviderCreateView -from airgun.views.computeresource import ResourceProviderDetailView -from airgun.views.computeresource import ResourceProviderEditView -from airgun.views.computeresource import ResourceProviderProfileView -from airgun.views.computeresource import ResourceProviderVMImport +from airgun.views.computeresource import ( + ComputeResourceRHVImageCreateView, + ComputeResourceRHVImageEditView, + ComputeResourcesView, + ComputeResourceVMwareImageCreateView, + ComputeResourceVMwareImageEditView, + ResourceProviderCreateView, + ResourceProviderDetailView, + ResourceProviderEditView, + ResourceProviderProfileView, + ResourceProviderVMImport, +) class ComputeResourceEntity(BaseEntity): @@ -273,7 +274,7 @@ class ComputeResourceImageProvider(NavigateStep): (that depend from compute resource provider) before reaching navigation destination. """ - PROVIDER_VIEWS = dict() + PROVIDER_VIEWS = {} def prerequisite(self, *args, **kwargs): entity_name = kwargs.get('entity_name') @@ -293,11 +294,10 @@ def am_i_here(self, *args, **kwargs): @navigator.register(ComputeResourceEntity, 'Create Image') class ComputeResourceImageCreate(ComputeResourceImageProvider): - - PROVIDER_VIEWS = dict( - RHV=ComputeResourceRHVImageCreateView, - VMware=ComputeResourceVMwareImageCreateView, - ) + PROVIDER_VIEWS = { + 'RHV': ComputeResourceRHVImageCreateView, + 'VMware': ComputeResourceVMwareImageCreateView, + } def step(self, *args, **kwargs): self.parent.create_image.click() @@ -305,11 +305,10 @@ def step(self, *args, **kwargs): @navigator.register(ComputeResourceEntity, 'Edit Image') class ComputeResourceImageEdit(ComputeResourceImageProvider): - - PROVIDER_VIEWS = dict( - RHV=ComputeResourceRHVImageEditView, - VMware=ComputeResourceVMwareImageEditView, - ) + PROVIDER_VIEWS = { + 'RHV': ComputeResourceRHVImageEditView, + 'VMware': ComputeResourceVMwareImageEditView, + } def step(self, *args, **kwargs): image_name = kwargs.get('image_name') diff --git a/airgun/entities/config_report.py b/airgun/entities/config_report.py index 8cbcc191b..7c3520fb2 100644 --- a/airgun/entities/config_report.py +++ b/airgun/entities/config_report.py @@ -1,9 +1,7 @@ from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.config_report import ConfigReportDetailsView -from airgun.views.config_report import ConfigReportsView +from airgun.views.config_report import ConfigReportDetailsView, ConfigReportsView class ConfigReportEntity(BaseEntity): diff --git a/airgun/entities/configgroup.py b/airgun/entities/configgroup.py index 3b34e46d1..a11432ab9 100644 --- a/airgun/entities/configgroup.py +++ b/airgun/entities/configgroup.py @@ -1,12 +1,13 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.configgroup import ConfigGroupCreateView -from airgun.views.configgroup import ConfigGroupEditView -from airgun.views.configgroup import ConfigGroupsView +from airgun.views.configgroup import ( + ConfigGroupCreateView, + ConfigGroupEditView, + ConfigGroupsView, +) class ConfigGroupEntity(BaseEntity): diff --git a/airgun/entities/containerimagetag.py b/airgun/entities/containerimagetag.py index 877d51883..15dee1f74 100644 --- a/airgun/entities/containerimagetag.py +++ b/airgun/entities/containerimagetag.py @@ -1,9 +1,10 @@ from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.containerimagetag import ContainerImageTagDetailsView -from airgun.views.containerimagetag import ContainerImageTagsView +from airgun.views.containerimagetag import ( + ContainerImageTagDetailsView, + ContainerImageTagsView, +) class ContainerImageTagEntity(BaseEntity): diff --git a/airgun/entities/contentcredential.py b/airgun/entities/contentcredential.py index e17afe890..16de913ad 100644 --- a/airgun/entities/contentcredential.py +++ b/airgun/entities/contentcredential.py @@ -1,12 +1,13 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.contentcredential import ContentCredentialCreateView -from airgun.views.contentcredential import ContentCredentialEditView -from airgun.views.contentcredential import ContentCredentialsTableView +from airgun.views.contentcredential import ( + ContentCredentialCreateView, + ContentCredentialEditView, + ContentCredentialsTableView, +) from airgun.views.product import ProductEditView diff --git a/airgun/entities/contenthost.py b/airgun/entities/contenthost.py index 320a6c73d..e6ca54f56 100644 --- a/airgun/entities/contenthost.py +++ b/airgun/entities/contenthost.py @@ -1,15 +1,15 @@ from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.contenthost import ContentHostDetailsView -from airgun.views.contenthost import ContentHostsView -from airgun.views.contenthost import ContentHostTaskDetailsView -from airgun.views.contenthost import ErrataDetailsView -from airgun.views.contenthost import SyspurposeBulkActionView +from airgun.views.contenthost import ( + ContentHostDetailsView, + ContentHostsView, + ContentHostTaskDetailsView, + ErrataDetailsView, + SyspurposeBulkActionView, +) from airgun.views.host_new import NewHostDetailsView -from airgun.views.job_invocation import JobInvocationCreateView -from airgun.views.job_invocation import JobInvocationStatusView +from airgun.views.job_invocation import JobInvocationCreateView, JobInvocationStatusView class ContentHostEntity(BaseEntity): @@ -116,7 +116,7 @@ def execute_module_stream_action( customize_values = {} view = self.navigate_to(self, 'Edit', entity_name=entity_name) view.module_streams.search(f'name = {module_name} and stream = {stream_version}') - action_type = dict(is_customize=customize, action=action_type) + action_type = {'is_customize': customize, 'action': action_type} view.module_streams.table.row(name=module_name, stream=stream_version)['Actions'].fill( action_type ) diff --git a/airgun/entities/contentview.py b/airgun/entities/contentview.py index 75e3e54ad..57efda581 100644 --- a/airgun/entities/contentview.py +++ b/airgun/entities/contentview.py @@ -3,19 +3,20 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.contentview import ContentViewCopyView -from airgun.views.contentview import ContentViewCreateView -from airgun.views.contentview import ContentViewEditView -from airgun.views.contentview import ContentViewRemoveView -from airgun.views.contentview import ContentViewTableView -from airgun.views.contentview import ContentViewVersionDetailsView -from airgun.views.contentview import ContentViewVersionPromoteView -from airgun.views.contentview import ContentViewVersionPublishView -from airgun.views.contentview import ContentViewVersionRemoveConfirmationView -from airgun.views.contentview import ContentViewVersionRemoveView +from airgun.views.contentview import ( + ContentViewCopyView, + ContentViewCreateView, + ContentViewEditView, + ContentViewRemoveView, + ContentViewTableView, + ContentViewVersionDetailsView, + ContentViewVersionPromoteView, + ContentViewVersionPublishView, + ContentViewVersionRemoveConfirmationView, + ContentViewVersionRemoveView, +) class ContentViewEntity(BaseEntity): diff --git a/airgun/entities/contentview_new.py b/airgun/entities/contentview_new.py index 138ff313f..f73aaeefa 100644 --- a/airgun/entities/contentview_new.py +++ b/airgun/entities/contentview_new.py @@ -1,11 +1,12 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.contentview_new import NewContentViewCreateView -from airgun.views.contentview_new import NewContentViewTableView +from airgun.views.contentview_new import ( + NewContentViewCreateView, + NewContentViewTableView, +) class NewContentViewEntity(BaseEntity): diff --git a/airgun/entities/contentviewfilter.py b/airgun/entities/contentviewfilter.py index ce5efb750..f65e797f1 100644 --- a/airgun/entities/contentviewfilter.py +++ b/airgun/entities/contentviewfilter.py @@ -1,12 +1,13 @@ from airgun.entities.base import BaseEntity from airgun.entities.contentview import ContentViewEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.contentviewfilter import ACTIONS_COLUMN -from airgun.views.contentviewfilter import ContentViewFiltersView -from airgun.views.contentviewfilter import CreateYumFilterView -from airgun.views.contentviewfilter import EditYumFilterView +from airgun.views.contentviewfilter import ( + ACTIONS_COLUMN, + ContentViewFiltersView, + CreateYumFilterView, + EditYumFilterView, +) class ContentViewFilterEntity(BaseEntity): diff --git a/airgun/entities/dashboard.py b/airgun/entities/dashboard.py index 4291f4443..8684c38d0 100644 --- a/airgun/entities/dashboard.py +++ b/airgun/entities/dashboard.py @@ -1,6 +1,5 @@ from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation from airgun.views.dashboard import DashboardView diff --git a/airgun/entities/discoveredhosts.py b/airgun/entities/discoveredhosts.py index 804edcd08..5b7c3fa49 100644 --- a/airgun/entities/discoveredhosts.py +++ b/airgun/entities/discoveredhosts.py @@ -1,18 +1,19 @@ from wait_for import wait_for from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.discoveredhosts import DiscoveredHostDetailsView -from airgun.views.discoveredhosts import DiscoveredHostEditProvisioningView -from airgun.views.discoveredhosts import DiscoveredHostProvisionDialog -from airgun.views.discoveredhosts import DiscoveredHostsAssignLocationDialog -from airgun.views.discoveredhosts import DiscoveredHostsAssignOrganizationDialog -from airgun.views.discoveredhosts import DiscoveredHostsAutoProvisionDialog -from airgun.views.discoveredhosts import DiscoveredHostsDeleteDialog -from airgun.views.discoveredhosts import DiscoveredHostsRebootDialog -from airgun.views.discoveredhosts import DiscoveredHostsView +from airgun.views.discoveredhosts import ( + DiscoveredHostDetailsView, + DiscoveredHostEditProvisioningView, + DiscoveredHostProvisionDialog, + DiscoveredHostsAssignLocationDialog, + DiscoveredHostsAssignOrganizationDialog, + DiscoveredHostsAutoProvisionDialog, + DiscoveredHostsDeleteDialog, + DiscoveredHostsRebootDialog, + DiscoveredHostsView, +) class DiscoveredHostsEntity(BaseEntity): @@ -86,11 +87,11 @@ def provision( view = self.navigate_to(self, 'Provision', entity_name=entity_name) view.fill( - dict( - host_group=host_group, - organization=organization, - location=location, - ) + { + 'host_group': host_group, + 'organization': organization, + 'location': location, + } ) if quick: view.quick_create.click() @@ -186,7 +187,7 @@ def step(self, *args, **kwargs): f'Please provide a valid action name. action_name: "{action_name}" not found.' ) entities_list = kwargs.get('entities_list') - if not isinstance(entities_list, (list, tuple)): + if not isinstance(entities_list, list | tuple): entities_list = [entities_list] for entity_name in entities_list: self.parent.table.row_by_cell_or_widget_value('Name', entity_name)[0].widget.click() @@ -195,7 +196,6 @@ def step(self, *args, **kwargs): @navigator.register(DiscoveredHostsEntity, 'Provision') class DiscoveredHostProvisionActionNavigation(NavigateStep): - VIEW = DiscoveredHostProvisionDialog def prerequisite(self, *args, **kwargs): diff --git a/airgun/entities/discoveryrule.py b/airgun/entities/discoveryrule.py index b66758109..afcf95973 100644 --- a/airgun/entities/discoveryrule.py +++ b/airgun/entities/discoveryrule.py @@ -2,13 +2,14 @@ from widgetastic.exceptions import NoSuchElementException from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation from airgun.views.discoveredhosts import DiscoveredHostsView -from airgun.views.discoveryrule import DiscoveryRuleCreateView -from airgun.views.discoveryrule import DiscoveryRuleEditView -from airgun.views.discoveryrule import DiscoveryRulesView +from airgun.views.discoveryrule import ( + DiscoveryRuleCreateView, + DiscoveryRuleEditView, + DiscoveryRulesView, +) from airgun.views.host import HostsView diff --git a/airgun/entities/domain.py b/airgun/entities/domain.py index 8c8fd818d..10b1afeef 100644 --- a/airgun/entities/domain.py +++ b/airgun/entities/domain.py @@ -1,12 +1,9 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.domain import DomainCreateView -from airgun.views.domain import DomainEditView -from airgun.views.domain import DomainListView +from airgun.views.domain import DomainCreateView, DomainEditView, DomainListView class DomainEntity(BaseEntity): diff --git a/airgun/entities/errata.py b/airgun/entities/errata.py index 211df9668..da29261f3 100644 --- a/airgun/entities/errata.py +++ b/airgun/entities/errata.py @@ -1,13 +1,14 @@ import re from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.errata import ErrataDetailsView -from airgun.views.errata import ErrataInstallationConfirmationView -from airgun.views.errata import ErrataTaskDetailsView -from airgun.views.errata import ErratumView +from airgun.views.errata import ( + ErrataDetailsView, + ErrataInstallationConfirmationView, + ErrataTaskDetailsView, + ErratumView, +) class ErrataEntity(BaseEntity): diff --git a/airgun/entities/filter.py b/airgun/entities/filter.py index 731be299f..489f8bc9e 100644 --- a/airgun/entities/filter.py +++ b/airgun/entities/filter.py @@ -1,10 +1,7 @@ from airgun.entities.base import BaseEntity from airgun.entities.role import RoleEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator -from airgun.views.filter import FilterCreateView -from airgun.views.filter import FilterDetailsView -from airgun.views.filter import FiltersView +from airgun.navigation import NavigateStep, navigator +from airgun.views.filter import FilterCreateView, FilterDetailsView, FiltersView class FilterEntity(BaseEntity): diff --git a/airgun/entities/hardware_model.py b/airgun/entities/hardware_model.py index 1c152ee99..7d4601c2e 100644 --- a/airgun/entities/hardware_model.py +++ b/airgun/entities/hardware_model.py @@ -1,12 +1,13 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.hardware_model import HardwareModelCreateView -from airgun.views.hardware_model import HardwareModelEditView -from airgun.views.hardware_model import HardwareModelsView +from airgun.views.hardware_model import ( + HardwareModelCreateView, + HardwareModelEditView, + HardwareModelsView, +) class HardwareModelEntity(BaseEntity): diff --git a/airgun/entities/host.py b/airgun/entities/host.py index 02d4ba0ab..f5abeb3fb 100644 --- a/airgun/entities/host.py +++ b/airgun/entities/host.py @@ -5,29 +5,29 @@ from airgun.entities.base import BaseEntity from airgun.exceptions import DisabledWidgetError from airgun.helpers.host import HostHelper -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation from airgun.views.cloud_insights import CloudInsightsView -from airgun.views.host import HostCreateView -from airgun.views.host import HostDetailsView -from airgun.views.host import HostEditView -from airgun.views.host import HostRegisterView -from airgun.views.host import HostsAssignCompliancePolicy -from airgun.views.host import HostsAssignLocation -from airgun.views.host import HostsAssignOrganization -from airgun.views.host import HostsChangeEnvironment -from airgun.views.host import HostsChangeGroup -from airgun.views.host import HostsChangeOpenscapCapsule -from airgun.views.host import HostsDeleteActionDialog -from airgun.views.host import HostsDeleteTaskDetailsView -from airgun.views.host import HostsJobInvocationCreateView -from airgun.views.host import HostsJobInvocationStatusView -from airgun.views.host import HostsUnassignCompliancePolicy -from airgun.views.host import HostsView -from airgun.views.host import RecommendationListView -from airgun.views.host_new import ManageColumnsView -from airgun.views.host_new import NewHostDetailsView +from airgun.views.host import ( + HostCreateView, + HostDetailsView, + HostEditView, + HostRegisterView, + HostsAssignCompliancePolicy, + HostsAssignLocation, + HostsAssignOrganization, + HostsChangeEnvironment, + HostsChangeGroup, + HostsChangeOpenscapCapsule, + HostsDeleteActionDialog, + HostsDeleteTaskDetailsView, + HostsJobInvocationCreateView, + HostsJobInvocationStatusView, + HostsUnassignCompliancePolicy, + HostsView, + RecommendationListView, +) +from airgun.views.host_new import ManageColumnsView, NewHostDetailsView class HostEntity(BaseEntity): @@ -251,7 +251,7 @@ def get_webconsole_content(self, entity_name, rhel_version=7): view.validations.assert_no_errors() # set locators based on selected UI - if rhel_version > 7: + if rhel_version > 7: # noqa: PLR2004 - Context makes magic number clear hostname_element = 'span' hostname_id = 'system_information_hostname_text' else: diff --git a/airgun/entities/host_new.py b/airgun/entities/host_new.py index 00814b95b..2b4ad1d34 100644 --- a/airgun/entities/host_new.py +++ b/airgun/entities/host_new.py @@ -3,20 +3,20 @@ from navmazing import NavigateToSibling from airgun.entities.host import HostEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator -from airgun.views.host_new import AllAssignedRolesView -from airgun.views.host_new import EditSystemPurposeView -from airgun.views.host_new import EnableTracerView -from airgun.views.host_new import InstallPackagesView -from airgun.views.host_new import ManageHostCollectionModal -from airgun.views.host_new import ModuleStreamDialog -from airgun.views.host_new import NewHostDetailsView -from airgun.views.host_new import ParameterDeleteDialog -from airgun.views.host_new import RemediationView +from airgun.navigation import NavigateStep, navigator +from airgun.views.host_new import ( + AllAssignedRolesView, + EditSystemPurposeView, + EnableTracerView, + InstallPackagesView, + ManageHostCollectionModal, + ModuleStreamDialog, + NewHostDetailsView, + ParameterDeleteDialog, + RemediationView, +) from airgun.views.job_invocation import JobInvocationCreateView - global available_param_types available_param_types = ['string', 'boolean', 'integer', 'real', 'array', 'hash', 'yaml', 'json'] @@ -131,7 +131,7 @@ def add_host_to_host_collection( raise ValueError('No host collections found or left for addition!') if not add_to_all_collections: - if type(host_collection_name) is list: + if isinstance(host_collection_name, list): if not host_collection_name: raise ValueError('host_collection_name list is empty!') for host_col in host_collection_name: @@ -196,7 +196,7 @@ def remove_host_from_host_collection( self.browser.plugin.ensure_page_safe() if not remove_from_all_collections: - if type(host_collection_name) is list: + if isinstance(host_collection_name, list): if not host_collection_name: raise ValueError('host_collection_name list is empty!') for host_col in host_collection_name: @@ -436,13 +436,13 @@ def dict_val_gen(item_name): networking_interface_dict = {} tmp = { - 'fqdn': [i.text for i in list(dict_val_gen('FQDN'))[0]], - 'ipv4': [i.text for i in list(dict_val_gen('IPv4'))[0]], - 'ipv6': [i.text for i in list(dict_val_gen('IPv6'))[0]], - 'mac': [i.text for i in list(dict_val_gen('MAC'))[0]], + 'fqdn': [i.text for i in next(iter(dict_val_gen('FQDN')))], + 'ipv4': [i.text for i in next(iter(dict_val_gen('IPv4')))], + 'ipv6': [i.text for i in next(iter(dict_val_gen('IPv6')))], + 'mac': [i.text for i in next(iter(dict_val_gen('MAC')))], # TODO: After RFE BZ2183086 is resolved, uncomment line below # 'subnet': [i.text for i in list(dict_val_gen('Subnet'))[0]], - 'mtu': [i.text for i in list(dict_val_gen('MTU'))[0]], + 'mtu': [i.text for i in next(iter(dict_val_gen('MTU')))], } for i, dev in enumerate(net_devices): @@ -679,26 +679,26 @@ def remediate_with_insights( else: view.insights.recommendations_table.sort_by('Recommendation', 'ascending') - if type(recommendation_to_remediate) is list: + if isinstance(recommendation_to_remediate, list): if not recommendation_to_remediate: raise ValueError('List of recommendations cannot be empty!') for recommendation in recommendation_to_remediate: view.insights.click() # Excape double quotes in the recommendation - recommendation = recommendation.replace('"', '\\"') - recommendation = f'title = "{recommendation}"' - view.insights.search_bar.fill(recommendation, enter_timeout=3) + _rec = recommendation.replace('"', '\\"') + _rec = f'title = "{_rec}"' + view.insights.search_bar.fill(_rec, enter_timeout=3) view.wait_displayed() self.browser.plugin.ensure_page_safe() time.sleep(3) try: # Click the checkbox of the first recommendation view.insights.recommendations_table[0][0].widget.click() - except IndexError: + except IndexError as ie: raise IndexError( - f'Recommendation {recommendation} not found on {entity_name}, ' + f'Recommendation {_rec} not found on {entity_name}, ' 'thus cannot be remediated.' - ) + ) from ie else: # Excape double quotes in the recommendation recommendation_to_remediate = recommendation_to_remediate.replace('"', '\\"') @@ -710,11 +710,11 @@ def remediate_with_insights( try: # Click the checkbox of the first recommendation view.insights.recommendations_table[0][0].widget.click() - except IndexError: + except IndexError as ie: raise IndexError( f'Recommendation {recommendation_to_remediate} not found ' f'on {entity_name}, thus cannot be remediated.' - ) + ) from ie view.insights.remediate.click() view = RemediationView(self.browser) view.remediate.click() @@ -746,6 +746,3 @@ class ShowNewHostAnsible(NavigateStep): VIEW = NewHostDetailsView prerequisite = NavigateToSibling('NewDetails') - - def step(self, *args, **kwargs): - print(self.parent.rolesListTable) diff --git a/airgun/entities/hostcollection.py b/airgun/entities/hostcollection.py index 0263790c8..597056d07 100644 --- a/airgun/entities/hostcollection.py +++ b/airgun/entities/hostcollection.py @@ -2,20 +2,20 @@ from wait_for import wait_for from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.hostcollection import HostCollectionActionRemoteExecutionJobCreate -from airgun.views.hostcollection import HostCollectionActionTaskDetailsView -from airgun.views.hostcollection import HostCollectionChangeAssignedContentView -from airgun.views.hostcollection import HostCollectionCreateView -from airgun.views.hostcollection import HostCollectionEditView -from airgun.views.hostcollection import HostCollectionInstallErrataView -from airgun.views.hostcollection import HostCollectionManageModuleStreamsView -from airgun.views.hostcollection import HostCollectionManagePackagesView -from airgun.views.hostcollection import HostCollectionsView -from airgun.views.job_invocation import JobInvocationCreateView -from airgun.views.job_invocation import JobInvocationStatusView +from airgun.views.hostcollection import ( + HostCollectionActionRemoteExecutionJobCreate, + HostCollectionActionTaskDetailsView, + HostCollectionChangeAssignedContentView, + HostCollectionCreateView, + HostCollectionEditView, + HostCollectionInstallErrataView, + HostCollectionManageModuleStreamsView, + HostCollectionManagePackagesView, + HostCollectionsView, +) +from airgun.views.job_invocation import JobInvocationCreateView, JobInvocationStatusView class HostCollectionEntity(BaseEntity): @@ -222,7 +222,7 @@ def manage_module_streams( view.details.manage_module_streams.click() view = HostCollectionManageModuleStreamsView(view.browser) view.search(f'name = {module_name} and stream = {stream_version}') - action_type = dict(is_customize=customize, action=action_type) + action_type = {'is_customize': customize, 'action': action_type} view.table.row(name=module_name, stream=stream_version)['Actions'].fill(action_type) if customize: view = JobInvocationCreateView(view.browser) diff --git a/airgun/entities/hostgroup.py b/airgun/entities/hostgroup.py index 6bbcef9fd..d3311b44b 100644 --- a/airgun/entities/hostgroup.py +++ b/airgun/entities/hostgroup.py @@ -2,12 +2,13 @@ from widgetastic.exceptions import NoSuchElementException from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.hostgroup import HostGroupCreateView -from airgun.views.hostgroup import HostGroupEditView -from airgun.views.hostgroup import HostGroupsView +from airgun.views.hostgroup import ( + HostGroupCreateView, + HostGroupEditView, + HostGroupsView, +) class HostGroupEntity(BaseEntity): diff --git a/airgun/entities/http_proxy.py b/airgun/entities/http_proxy.py index fb7723a79..7c0ad5bbd 100644 --- a/airgun/entities/http_proxy.py +++ b/airgun/entities/http_proxy.py @@ -1,12 +1,13 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.http_proxy import HTTPProxyCreateView -from airgun.views.http_proxy import HTTPProxyEditView -from airgun.views.http_proxy import HTTPProxyView +from airgun.views.http_proxy import ( + HTTPProxyCreateView, + HTTPProxyEditView, + HTTPProxyView, +) class HTTPProxyEntity(BaseEntity): diff --git a/airgun/entities/job_invocation.py b/airgun/entities/job_invocation.py index a3a426e00..4655609a8 100644 --- a/airgun/entities/job_invocation.py +++ b/airgun/entities/job_invocation.py @@ -2,12 +2,13 @@ from wait_for import wait_for from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.job_invocation import JobInvocationCreateView -from airgun.views.job_invocation import JobInvocationStatusView -from airgun.views.job_invocation import JobInvocationsView +from airgun.views.job_invocation import ( + JobInvocationCreateView, + JobInvocationStatusView, + JobInvocationsView, +) class JobInvocationEntity(BaseEntity): diff --git a/airgun/entities/job_template.py b/airgun/entities/job_template.py index af8b1b112..7cead1b98 100644 --- a/airgun/entities/job_template.py +++ b/airgun/entities/job_template.py @@ -2,12 +2,13 @@ from wait_for import wait_for from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.job_template import JobTemplateCreateView -from airgun.views.job_template import JobTemplateEditView -from airgun.views.job_template import JobTemplatesView +from airgun.views.job_template import ( + JobTemplateCreateView, + JobTemplateEditView, + JobTemplatesView, +) class JobTemplateEntity(BaseEntity): diff --git a/airgun/entities/ldap_authentication.py b/airgun/entities/ldap_authentication.py index 8d670f7d7..6c8bf210c 100644 --- a/airgun/entities/ldap_authentication.py +++ b/airgun/entities/ldap_authentication.py @@ -1,14 +1,14 @@ from navmazing import NavigateToSibling -from widgetastic.exceptions import NoSuchElementException -from widgetastic.exceptions import RowNotFound +from widgetastic.exceptions import NoSuchElementException, RowNotFound from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.ldapauthentication import LDAPAuthenticationCreateView -from airgun.views.ldapauthentication import LDAPAuthenticationEditView -from airgun.views.ldapauthentication import LDAPAuthenticationsView +from airgun.views.ldapauthentication import ( + LDAPAuthenticationCreateView, + LDAPAuthenticationEditView, + LDAPAuthenticationsView, +) class LDAPAuthenticationEntity(BaseEntity): diff --git a/airgun/entities/lifecycleenvironment.py b/airgun/entities/lifecycleenvironment.py index fe6c4c9e8..10a88e076 100644 --- a/airgun/entities/lifecycleenvironment.py +++ b/airgun/entities/lifecycleenvironment.py @@ -1,12 +1,9 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.lifecycleenvironment import LCECreateView -from airgun.views.lifecycleenvironment import LCEEditView -from airgun.views.lifecycleenvironment import LCEView +from airgun.views.lifecycleenvironment import LCECreateView, LCEEditView, LCEView class LCEEntity(BaseEntity): diff --git a/airgun/entities/location.py b/airgun/entities/location.py index bd967c4f0..3aa6da849 100644 --- a/airgun/entities/location.py +++ b/airgun/entities/location.py @@ -1,13 +1,10 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation from airgun.views.common import BaseLoggedInView -from airgun.views.location import LocationCreateView -from airgun.views.location import LocationsEditView -from airgun.views.location import LocationsView +from airgun.views.location import LocationCreateView, LocationsEditView, LocationsView class LocationEntity(BaseEntity): @@ -104,11 +101,12 @@ class SelectLocationContext(NavigateStep): """ VIEW = BaseLoggedInView + ELLIPSIS_LENGTH = 30 def am_i_here(self, *args, **kwargs): loc_name = kwargs.get('loc_name') - if len(loc_name) > 30: - loc_name = loc_name[:27] + '...' + if len(loc_name) > self.ELLIPSIS_LENGTH: + loc_name = loc_name[: self.ELLIPSIS_LENGTH - 3] + '...' return loc_name == self.view.taxonomies.current_loc def step(self, *args, **kwargs): diff --git a/airgun/entities/login.py b/airgun/entities/login.py index a30ce6151..e8e90c61c 100644 --- a/airgun/entities/login.py +++ b/airgun/entities/login.py @@ -1,6 +1,5 @@ from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.views.common import BaseLoggedInView from airgun.views.login import LoginView diff --git a/airgun/entities/media.py b/airgun/entities/media.py index 174d4926d..ff0fd4a8f 100644 --- a/airgun/entities/media.py +++ b/airgun/entities/media.py @@ -1,12 +1,9 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.media import MediaCreateView -from airgun.views.media import MediaEditView -from airgun.views.media import MediumView +from airgun.views.media import MediaCreateView, MediaEditView, MediumView class MediaEntity(BaseEntity): diff --git a/airgun/entities/modulestream.py b/airgun/entities/modulestream.py index e386547b8..079b77157 100644 --- a/airgun/entities/modulestream.py +++ b/airgun/entities/modulestream.py @@ -1,11 +1,9 @@ from wait_for import wait_for from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.modulestream import ModuleStreamsDetailsView -from airgun.views.modulestream import ModuleStreamView +from airgun.views.modulestream import ModuleStreamsDetailsView, ModuleStreamView class ModuleStreamEntity(BaseEntity): diff --git a/airgun/entities/organization.py b/airgun/entities/organization.py index f4a1cd206..83ea804c7 100644 --- a/airgun/entities/organization.py +++ b/airgun/entities/organization.py @@ -1,14 +1,14 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.common import BaseLoggedInView -from airgun.views.common import WrongContextAlert -from airgun.views.organization import OrganizationCreateView -from airgun.views.organization import OrganizationEditView -from airgun.views.organization import OrganizationsView +from airgun.views.common import BaseLoggedInView, WrongContextAlert +from airgun.views.organization import ( + OrganizationCreateView, + OrganizationEditView, + OrganizationsView, +) class OrganizationEntity(BaseEntity): @@ -105,11 +105,12 @@ class SelectOrganizationContext(NavigateStep): """ VIEW = BaseLoggedInView + ELLIPSIS_LENGTH = 30 def am_i_here(self, *args, **kwargs): org_name = kwargs.get('org_name') - if len(org_name) > 30: - org_name = org_name[:27] + '...' + if len(org_name) > self.ELLIPSIS_LENGTH: + org_name = org_name[: self.ELLIPSIS_LENGTH - 3] + '...' return org_name == self.view.taxonomies.current_org def step(self, *args, **kwargs): diff --git a/airgun/entities/os.py b/airgun/entities/os.py index e765629f1..3b3b51416 100644 --- a/airgun/entities/os.py +++ b/airgun/entities/os.py @@ -1,12 +1,13 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.os import OperatingSystemCreateView -from airgun.views.os import OperatingSystemEditView -from airgun.views.os import OperatingSystemsView +from airgun.views.os import ( + OperatingSystemCreateView, + OperatingSystemEditView, + OperatingSystemsView, +) class OperatingSystemEntity(BaseEntity): diff --git a/airgun/entities/oscapcontent.py b/airgun/entities/oscapcontent.py index f0e090e7a..af4293dd7 100644 --- a/airgun/entities/oscapcontent.py +++ b/airgun/entities/oscapcontent.py @@ -1,12 +1,13 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.oscapcontent import SCAPContentCreateView -from airgun.views.oscapcontent import SCAPContentEditView -from airgun.views.oscapcontent import SCAPContentsView +from airgun.views.oscapcontent import ( + SCAPContentCreateView, + SCAPContentEditView, + SCAPContentsView, +) class OSCAPContentEntity(BaseEntity): diff --git a/airgun/entities/oscappolicy.py b/airgun/entities/oscappolicy.py index 738899562..7d1a77537 100644 --- a/airgun/entities/oscappolicy.py +++ b/airgun/entities/oscappolicy.py @@ -1,13 +1,14 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.oscappolicy import SCAPPoliciesView -from airgun.views.oscappolicy import SCAPPolicyCreateView -from airgun.views.oscappolicy import SCAPPolicyDetailsView -from airgun.views.oscappolicy import SCAPPolicyEditView +from airgun.views.oscappolicy import ( + SCAPPoliciesView, + SCAPPolicyCreateView, + SCAPPolicyDetailsView, + SCAPPolicyEditView, +) class OSCAPPolicyEntity(BaseEntity): diff --git a/airgun/entities/oscaptailoringfile.py b/airgun/entities/oscaptailoringfile.py index 38f3279b4..51c2c89f7 100644 --- a/airgun/entities/oscaptailoringfile.py +++ b/airgun/entities/oscaptailoringfile.py @@ -1,12 +1,13 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.oscaptailoringfile import SCAPTailoringFileCreateView -from airgun.views.oscaptailoringfile import SCAPTailoringFileEditView -from airgun.views.oscaptailoringfile import SCAPTailoringFilesView +from airgun.views.oscaptailoringfile import ( + SCAPTailoringFileCreateView, + SCAPTailoringFileEditView, + SCAPTailoringFilesView, +) class OSCAPTailoringFileEntity(BaseEntity): diff --git a/airgun/entities/package.py b/airgun/entities/package.py index 3853ac10d..723f6ea9a 100644 --- a/airgun/entities/package.py +++ b/airgun/entities/package.py @@ -1,9 +1,7 @@ from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.package import PackageDetailsView -from airgun.views.package import PackagesView +from airgun.views.package import PackageDetailsView, PackagesView class PackageEntity(BaseEntity): diff --git a/airgun/entities/partitiontable.py b/airgun/entities/partitiontable.py index b37b2a53b..2d18dce99 100644 --- a/airgun/entities/partitiontable.py +++ b/airgun/entities/partitiontable.py @@ -1,12 +1,13 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.partitiontable import PartitionTableCreateView -from airgun.views.partitiontable import PartitionTableEditView -from airgun.views.partitiontable import PartitionTablesView +from airgun.views.partitiontable import ( + PartitionTableCreateView, + PartitionTableEditView, + PartitionTablesView, +) class PartitionTableEntity(BaseEntity): diff --git a/airgun/entities/product.py b/airgun/entities/product.py index 449e7c4ba..e7a689301 100644 --- a/airgun/entities/product.py +++ b/airgun/entities/product.py @@ -1,18 +1,19 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.product import ProductAdvancedSync -from airgun.views.product import ProductCreateView -from airgun.views.product import ProductEditView -from airgun.views.product import ProductManageHttpProxy -from airgun.views.product import ProductRepoDiscoveryView -from airgun.views.product import ProductsTableView -from airgun.views.product import ProductSyncPlanView -from airgun.views.product import ProductTaskDetailsView -from airgun.views.product import ProductVerifyContentChecksum +from airgun.views.product import ( + ProductAdvancedSync, + ProductCreateView, + ProductEditView, + ProductManageHttpProxy, + ProductRepoDiscoveryView, + ProductsTableView, + ProductSyncPlanView, + ProductTaskDetailsView, + ProductVerifyContentChecksum, +) from airgun.views.task import TaskDetailsView diff --git a/airgun/entities/provisioning_template.py b/airgun/entities/provisioning_template.py index 619ef32e1..3cf03f7e1 100644 --- a/airgun/entities/provisioning_template.py +++ b/airgun/entities/provisioning_template.py @@ -1,12 +1,13 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.provisioning_template import ProvisioningTemplateCreateView -from airgun.views.provisioning_template import ProvisioningTemplateDetailsView -from airgun.views.provisioning_template import ProvisioningTemplatesView +from airgun.views.provisioning_template import ( + ProvisioningTemplateCreateView, + ProvisioningTemplateDetailsView, + ProvisioningTemplatesView, +) class ProvisioningTemplateEntity(BaseEntity): diff --git a/airgun/entities/puppet_class.py b/airgun/entities/puppet_class.py index 2e7a2313c..e70a3aeb7 100644 --- a/airgun/entities/puppet_class.py +++ b/airgun/entities/puppet_class.py @@ -1,9 +1,7 @@ from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.puppet_class import PuppetClassDetailsView -from airgun.views.puppet_class import PuppetClassesView +from airgun.views.puppet_class import PuppetClassDetailsView, PuppetClassesView class PuppetClassEntity(BaseEntity): diff --git a/airgun/entities/puppet_environment.py b/airgun/entities/puppet_environment.py index 0ca238537..f43005a56 100644 --- a/airgun/entities/puppet_environment.py +++ b/airgun/entities/puppet_environment.py @@ -1,12 +1,13 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.puppet_environment import PuppetEnvironmentCreateView -from airgun.views.puppet_environment import PuppetEnvironmentImportView -from airgun.views.puppet_environment import PuppetEnvironmentTableView +from airgun.views.puppet_environment import ( + PuppetEnvironmentCreateView, + PuppetEnvironmentImportView, + PuppetEnvironmentTableView, +) class PuppetEnvironmentEntity(BaseEntity): diff --git a/airgun/entities/redhat_repository.py b/airgun/entities/redhat_repository.py index 9e6483b47..edeee5abf 100644 --- a/airgun/entities/redhat_repository.py +++ b/airgun/entities/redhat_repository.py @@ -1,6 +1,5 @@ from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation from airgun.views.redhat_repository import RedHatRepositoriesView diff --git a/airgun/entities/report_template.py b/airgun/entities/report_template.py index 529cf1734..7aa812437 100644 --- a/airgun/entities/report_template.py +++ b/airgun/entities/report_template.py @@ -2,13 +2,14 @@ from wait_for import wait_for from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.report_template import ReportTemplateCreateView -from airgun.views.report_template import ReportTemplateDetailsView -from airgun.views.report_template import ReportTemplateGenerateView -from airgun.views.report_template import ReportTemplatesView +from airgun.views.report_template import ( + ReportTemplateCreateView, + ReportTemplateDetailsView, + ReportTemplateGenerateView, + ReportTemplatesView, +) class ReportTemplateEntity(BaseEntity): diff --git a/airgun/entities/repository.py b/airgun/entities/repository.py index 5817fab9b..cc71534ad 100644 --- a/airgun/entities/repository.py +++ b/airgun/entities/repository.py @@ -5,14 +5,15 @@ from airgun.entities.base import BaseEntity from airgun.entities.product import ProductEntity from airgun.entities.settings import SettingsEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation from airgun.views.product import ProductTaskDetailsView -from airgun.views.repository import RepositoriesView -from airgun.views.repository import RepositoryCreateView -from airgun.views.repository import RepositoryEditView -from airgun.views.repository import RepositoryPackagesView +from airgun.views.repository import ( + RepositoriesView, + RepositoryCreateView, + RepositoryEditView, + RepositoryPackagesView, +) class RepositoryEntity(BaseEntity): diff --git a/airgun/entities/rhai/inventory.py b/airgun/entities/rhai/inventory.py index 1bfe4e178..37c220c77 100644 --- a/airgun/entities/rhai/inventory.py +++ b/airgun/entities/rhai/inventory.py @@ -2,10 +2,8 @@ from airgun.entities.base import BaseEntity from airgun.entities.rhai.base import InsightsNavigateStep -from airgun.navigation import NavigateStep -from airgun.navigation import navigator -from airgun.views.rhai import InventoryAllHosts -from airgun.views.rhai import InventoryHostDetails +from airgun.navigation import NavigateStep, navigator +from airgun.views.rhai import InventoryAllHosts, InventoryHostDetails class InventoryHostEntity(BaseEntity): diff --git a/airgun/entities/rhai/plan.py b/airgun/entities/rhai/plan.py index 81c379df2..bc32b043a 100644 --- a/airgun/entities/rhai/plan.py +++ b/airgun/entities/rhai/plan.py @@ -3,14 +3,9 @@ from airgun.entities.base import BaseEntity from airgun.entities.rhai.base import InsightsNavigateStep -from airgun.navigation import NavigateStep -from airgun.navigation import navigator -from airgun.views.job_invocation import JobInvocationCreateView -from airgun.views.job_invocation import JobInvocationStatusView -from airgun.views.rhai import AddPlanView -from airgun.views.rhai import AllPlansView -from airgun.views.rhai import PlanEditView -from airgun.views.rhai import PlanModalWindow +from airgun.navigation import NavigateStep, navigator +from airgun.views.job_invocation import JobInvocationCreateView, JobInvocationStatusView +from airgun.views.rhai import AddPlanView, AllPlansView, PlanEditView, PlanModalWindow class PlanEntity(BaseEntity): diff --git a/airgun/entities/rhsso_login.py b/airgun/entities/rhsso_login.py index e235ec7c8..34debd383 100644 --- a/airgun/entities/rhsso_login.py +++ b/airgun/entities/rhsso_login.py @@ -1,16 +1,16 @@ from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.views.common import BaseLoggedInView -from airgun.views.rhsso_login import RhssoExternalLogoutView -from airgun.views.rhsso_login import RhssoLoginView -from airgun.views.rhsso_login import RhssoTotpView -from airgun.views.rhsso_login import RhssoTwoFactorSuccessView +from airgun.views.rhsso_login import ( + RhssoExternalLogoutView, + RhssoLoginView, + RhssoTotpView, + RhssoTwoFactorSuccessView, +) class RHSSOLoginEntity(BaseEntity): def login(self, values, external_login=False, totp=None): - if external_login: view = RhssoExternalLogoutView(self.browser) view.login_again.click() diff --git a/airgun/entities/role.py b/airgun/entities/role.py index 45b094d23..3411a9112 100644 --- a/airgun/entities/role.py +++ b/airgun/entities/role.py @@ -1,13 +1,9 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.role import RoleCloneView -from airgun.views.role import RoleCreateView -from airgun.views.role import RoleEditView -from airgun.views.role import RolesView +from airgun.views.role import RoleCloneView, RoleCreateView, RoleEditView, RolesView class RoleEntity(BaseEntity): diff --git a/airgun/entities/settings.py b/airgun/entities/settings.py index c8abbdb2c..86e9e8d50 100644 --- a/airgun/entities/settings.py +++ b/airgun/entities/settings.py @@ -1,6 +1,5 @@ from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation from airgun.views.common import BaseLoggedInView from airgun.views.settings import SettingsView diff --git a/airgun/entities/smart_class_parameter.py b/airgun/entities/smart_class_parameter.py index 563c3e924..292c75ec2 100644 --- a/airgun/entities/smart_class_parameter.py +++ b/airgun/entities/smart_class_parameter.py @@ -1,9 +1,10 @@ from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.smart_class_parameter import SmartClassParameterEditView -from airgun.views.smart_class_parameter import SmartClassParametersView +from airgun.views.smart_class_parameter import ( + SmartClassParameterEditView, + SmartClassParametersView, +) class SmartClassParameterEntity(BaseEntity): diff --git a/airgun/entities/subnet.py b/airgun/entities/subnet.py index 231679db4..79bb36358 100644 --- a/airgun/entities/subnet.py +++ b/airgun/entities/subnet.py @@ -1,12 +1,9 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.subnet import SubnetCreateView -from airgun.views.subnet import SubnetEditView -from airgun.views.subnet import SubnetsView +from airgun.views.subnet import SubnetCreateView, SubnetEditView, SubnetsView class SubnetEntity(BaseEntity): diff --git a/airgun/entities/subscription.py b/airgun/entities/subscription.py index d678bbf92..4173d37bb 100644 --- a/airgun/entities/subscription.py +++ b/airgun/entities/subscription.py @@ -1,16 +1,16 @@ from navmazing import NavigateToSibling -from wait_for import TimedOutError -from wait_for import wait_for +from wait_for import TimedOutError, wait_for from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.subscription import AddSubscriptionView -from airgun.views.subscription import DeleteManifestConfirmationView -from airgun.views.subscription import ManageManifestView -from airgun.views.subscription import SubscriptionDetailsView -from airgun.views.subscription import SubscriptionListView +from airgun.views.subscription import ( + AddSubscriptionView, + DeleteManifestConfirmationView, + ManageManifestView, + SubscriptionDetailsView, + SubscriptionListView, +) class SubscriptionEntity(BaseEntity): diff --git a/airgun/entities/sync_status.py b/airgun/entities/sync_status.py index 3c9d174b3..0c7862805 100644 --- a/airgun/entities/sync_status.py +++ b/airgun/entities/sync_status.py @@ -1,8 +1,7 @@ from wait_for import wait_for from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation from airgun.views.sync_status import SyncStatusView @@ -40,7 +39,7 @@ def synchronize(self, repository_paths, timeout=3600): repo_node.fill(True) view.synchronize_now.click() wait_for( - lambda: all([node.progress is None for node in repo_nodes]), + lambda: all(node.progress is None for node in repo_nodes), timeout=timeout, delay=5, logger=view.logger, diff --git a/airgun/entities/sync_templates.py b/airgun/entities/sync_templates.py index eaf2373f5..83a661cc7 100644 --- a/airgun/entities/sync_templates.py +++ b/airgun/entities/sync_templates.py @@ -1,11 +1,9 @@ from wait_for import wait_for from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.sync_templates import SyncTemplatesView -from airgun.views.sync_templates import TemplatesReportView +from airgun.views.sync_templates import SyncTemplatesView, TemplatesReportView class SyncTemplatesEntity(BaseEntity): diff --git a/airgun/entities/syncplan.py b/airgun/entities/syncplan.py index 776071da6..f34e42f1a 100644 --- a/airgun/entities/syncplan.py +++ b/airgun/entities/syncplan.py @@ -1,12 +1,9 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.syncplan import SyncPlanCreateView -from airgun.views.syncplan import SyncPlanEditView -from airgun.views.syncplan import SyncPlansView +from airgun.views.syncplan import SyncPlanCreateView, SyncPlanEditView, SyncPlansView class SyncPlanEntity(BaseEntity): diff --git a/airgun/entities/task.py b/airgun/entities/task.py index bf0c84786..03f101783 100644 --- a/airgun/entities/task.py +++ b/airgun/entities/task.py @@ -1,9 +1,7 @@ from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.task import TaskDetailsView -from airgun.views.task import TasksView +from airgun.views.task import TaskDetailsView, TasksView class TaskEntity(BaseEntity): diff --git a/airgun/entities/user.py b/airgun/entities/user.py index f24830dbc..178c982f7 100644 --- a/airgun/entities/user.py +++ b/airgun/entities/user.py @@ -2,12 +2,9 @@ from wait_for import wait_for from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.user import UserCreateView -from airgun.views.user import UserDetailsView -from airgun.views.user import UsersView +from airgun.views.user import UserCreateView, UserDetailsView, UsersView class UserEntity(BaseEntity): diff --git a/airgun/entities/usergroup.py b/airgun/entities/usergroup.py index a31db89f0..cdbe5bf79 100644 --- a/airgun/entities/usergroup.py +++ b/airgun/entities/usergroup.py @@ -2,12 +2,13 @@ from widgetastic.exceptions import NoSuchElementException from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.usergroup import UserGroupCreateView -from airgun.views.usergroup import UserGroupDetailsView -from airgun.views.usergroup import UserGroupsView +from airgun.views.usergroup import ( + UserGroupCreateView, + UserGroupDetailsView, + UserGroupsView, +) class UserGroupEntity(BaseEntity): diff --git a/airgun/entities/virtwho_configure.py b/airgun/entities/virtwho_configure.py index 82f483d70..e8f467ecf 100644 --- a/airgun/entities/virtwho_configure.py +++ b/airgun/entities/virtwho_configure.py @@ -1,13 +1,14 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.virtwho_configure import VirtwhoConfigureCreateView -from airgun.views.virtwho_configure import VirtwhoConfigureDetailsView -from airgun.views.virtwho_configure import VirtwhoConfigureEditView -from airgun.views.virtwho_configure import VirtwhoConfiguresView +from airgun.views.virtwho_configure import ( + VirtwhoConfigureCreateView, + VirtwhoConfigureDetailsView, + VirtwhoConfigureEditView, + VirtwhoConfiguresView, +) class VirtwhoConfigureEntity(BaseEntity): @@ -33,7 +34,7 @@ def check_create_permission(self): """Check if the config can be viewed/created""" try: view = self.navigate_to(self, 'All') - except Exception: + except Exception: # noqa: BLE001 - TODO: determine proper exception return {"can_view": False, "can_create": False} return {"can_view": True, "can_create": view.new.is_displayed} diff --git a/airgun/entities/webhook.py b/airgun/entities/webhook.py index 33280d2cc..ba3a9dc37 100644 --- a/airgun/entities/webhook.py +++ b/airgun/entities/webhook.py @@ -1,13 +1,14 @@ from navmazing import NavigateToSibling from airgun.entities.base import BaseEntity -from airgun.navigation import NavigateStep -from airgun.navigation import navigator +from airgun.navigation import NavigateStep, navigator from airgun.utils import retry_navigation -from airgun.views.webhook import DeleteWebhookConfirmationView -from airgun.views.webhook import WebhookCreateView -from airgun.views.webhook import WebhookEditView -from airgun.views.webhook import WebhooksView +from airgun.views.webhook import ( + DeleteWebhookConfirmationView, + WebhookCreateView, + WebhookEditView, + WebhooksView, +) class WebhookEntity(BaseEntity): diff --git a/airgun/exceptions.py b/airgun/exceptions.py index e974619fa..be67a7adc 100644 --- a/airgun/exceptions.py +++ b/airgun/exceptions.py @@ -1,6 +1,6 @@ """Exceptions raised by airgun""" from selenium.common.exceptions import InvalidElementStateException -from widgetastic.exceptions import * # noqa: F403, F401 +from widgetastic.exceptions import * # noqa: F403 class ReadOnlyWidgetError(Exception): diff --git a/airgun/helpers/base.py b/airgun/helpers/base.py index e3cffa7ce..e3ce6a73f 100644 --- a/airgun/helpers/base.py +++ b/airgun/helpers/base.py @@ -1,10 +1,7 @@ -from typing import Any -from typing import Dict -from typing import List from typing import TYPE_CHECKING if TYPE_CHECKING: - from airgun.entities.base import BaseEntity + pass class BaseEntityHelper: diff --git a/airgun/navigation.py b/airgun/navigation.py index d27269477..69466e32b 100644 --- a/airgun/navigation.py +++ b/airgun/navigation.py @@ -1,6 +1,6 @@ """AirGun's implementation of base navigation and navigate steps.""" -import navmazing from cached_property import cached_property +import navmazing from selenium.common.exceptions import NoSuchElementException @@ -82,7 +82,7 @@ def go(self, _tries=0, *args, **kwargs): :return: view instance if class attribute ``VIEW`` is set or ``None`` otherwise """ - super().go(_tries=_tries, *args, **kwargs) + super().go(*args, _tries=_tries, **kwargs) view = self.view if self.VIEW is not None else None return view diff --git a/airgun/session.py b/airgun/session.py index 30f1fe746..c87e4cb17 100644 --- a/airgun/session.py +++ b/airgun/session.py @@ -1,15 +1,14 @@ """Session controller which manages UI session""" +from datetime import datetime import logging import os import sys -from datetime import datetime from cached_property import cached_property from fauxfactory import gen_string from airgun import settings -from airgun.browser import AirgunBrowser -from airgun.browser import SeleniumBrowserFactory +from airgun.browser import AirgunBrowser, SeleniumBrowserFactory from airgun.entities.activationkey import ActivationKeyEntity from airgun.entities.ansible_role import AnsibleRolesEntity from airgun.entities.ansible_variable import AnsibleVariablesEntity @@ -82,8 +81,7 @@ from airgun.entities.usergroup import UserGroupEntity from airgun.entities.virtwho_configure import VirtwhoConfigureEntity from airgun.entities.webhook import WebhookEntity -from airgun.navigation import Navigate -from airgun.navigation import navigator +from airgun.navigation import Navigate, navigator LOGGER = logging.getLogger(__name__) @@ -235,7 +233,7 @@ def __exit__(self, exc_type, exc_value, traceback): try: if not passed: self.take_screenshot() - except Exception as err: + except Exception as err: # noqa: BLE001 - TODO: fix bare except LOGGER.exception(err) finally: self._factory.finalize(passed) diff --git a/airgun/settings.py b/airgun/settings.py index 537a04028..0c4f9f79b 100644 --- a/airgun/settings.py +++ b/airgun/settings.py @@ -1,7 +1,6 @@ +from configparser import ConfigParser import logging import os -from configparser import ConfigParser - SETTINGS_FILE_NAME = 'settings.ini' diff --git a/airgun/utils.py b/airgun/utils.py index 63d104b9d..05c2198f5 100644 --- a/airgun/utils.py +++ b/airgun/utils.py @@ -86,7 +86,7 @@ def retry_wrapper(*args, **kwargs): for i in range(attempts): try: return method(*args, **kwargs) - except (TimedOutError): + except TimedOutError: if i < attempts - 1: args[0].view.parent.browser.refresh() time.sleep(0.5) diff --git a/airgun/views/activationkey.py b/airgun/views/activationkey.py index eeeaa69e2..12af15a1b 100644 --- a/airgun/views/activationkey.py +++ b/airgun/views/activationkey.py @@ -1,24 +1,23 @@ -from widgetastic.widget import ParametrizedView -from widgetastic.widget import Select -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import ParametrizedView, Select, Table, Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import AddRemoveResourcesView -from airgun.views.common import AddRemoveSubscriptionsView -from airgun.views.common import BaseLoggedInView -from airgun.views.common import LCESelectorGroup -from airgun.views.common import SatTab -from airgun.views.common import SatTabWithDropdown -from airgun.views.common import SearchableViewMixin -from airgun.widgets import ActionsDropdown -from airgun.widgets import ConfirmationDialog -from airgun.widgets import EditableEntry -from airgun.widgets import EditableEntrySelect -from airgun.widgets import EditableLimitEntry -from airgun.widgets import LimitInput +from airgun.views.common import ( + AddRemoveResourcesView, + AddRemoveSubscriptionsView, + BaseLoggedInView, + LCESelectorGroup, + SatTab, + SatTabWithDropdown, + SearchableViewMixin, +) +from airgun.widgets import ( + ActionsDropdown, + ConfirmationDialog, + EditableEntry, + EditableEntrySelect, + EditableLimitEntry, + LimitInput, +) class ActivationKeysView(BaseLoggedInView, SearchableViewMixin): diff --git a/airgun/views/ansible_role.py b/airgun/views/ansible_role.py index c9d367669..fcb524db9 100644 --- a/airgun/views/ansible_role.py +++ b/airgun/views/ansible_role.py @@ -1,14 +1,9 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import Table -from widgetastic.widget import Text +from widgetastic.widget import Checkbox, Table, Text from widgetastic_patternfly import BreadCrumb -from widgetastic_patternfly4 import Button -from widgetastic_patternfly4 import PatternflyTable +from widgetastic_patternfly4 import Button, PatternflyTable -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SearchableViewMixin -from airgun.widgets import ActionsDropdown -from airgun.widgets import Pagination +from airgun.views.common import BaseLoggedInView, SearchableViewMixin +from airgun.widgets import ActionsDropdown, Pagination class ImportPagination(Pagination): diff --git a/airgun/views/ansible_variable.py b/airgun/views/ansible_variable.py index a9cd3b45b..2b23f0afe 100644 --- a/airgun/views/ansible_variable.py +++ b/airgun/views/ansible_variable.py @@ -1,17 +1,8 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import Select -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Checkbox, Select, Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTable -from airgun.views.common import SearchableViewMixinPF4 -from airgun.widgets import CustomParameter -from airgun.widgets import FilteredDropdown -from airgun.widgets import Pagination -from airgun.widgets import SatSelect +from airgun.views.common import BaseLoggedInView, SatTable, SearchableViewMixinPF4 +from airgun.widgets import CustomParameter, FilteredDropdown, Pagination, SatSelect class AnsibleVariablesView(BaseLoggedInView, SearchableViewMixinPF4): @@ -105,9 +96,7 @@ def expand_button(self): @property def expanded(self): """Check whether this section is expanded""" - return 'active' in self.browser.get_attribute( - 'class', self.expand_optional_input_validator - ) + return 'active' in self.browser.get_attribute('class', self.expand_optional_input_validator) def expand(self): """Expand the Optional Input Validator section""" diff --git a/airgun/views/architecture.py b/airgun/views/architecture.py index 2788ea629..d5f150bf4 100644 --- a/airgun/views/architecture.py +++ b/airgun/views/architecture.py @@ -1,10 +1,7 @@ -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput +from widgetastic.widget import Table, Text, TextInput from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SearchableViewMixinPF4 +from airgun.views.common import BaseLoggedInView, SearchableViewMixinPF4 from airgun.widgets import MultiSelect diff --git a/airgun/views/audit.py b/airgun/views/audit.py index 789328a51..9e72185d7 100644 --- a/airgun/views/audit.py +++ b/airgun/views/audit.py @@ -1,14 +1,11 @@ -from widgetastic.widget import Text -from widgetastic.widget import View +from widgetastic.widget import Text, View from airgun.exceptions import ReadOnlyWidgetError -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SearchableViewMixinPF4 +from airgun.views.common import BaseLoggedInView, SearchableViewMixinPF4 from airgun.widgets import SatTableWithoutHeaders class AuditEntry(View): - ROOT = ".//div[@id='audit-list']/div/div[contains(@class, 'list-group-item')]" user = Text(".//a[@class='user-info']") action_type = Text(".//div[@class='list-group-item-text' and normalize-space(.)]") diff --git a/airgun/views/bookmark.py b/airgun/views/bookmark.py index 4f306d1c4..324ca273f 100644 --- a/airgun/views/bookmark.py +++ b/airgun/views/bookmark.py @@ -1,10 +1,7 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import Text -from widgetastic.widget import TextInput +from widgetastic.widget import Checkbox, Text, TextInput from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SearchableViewMixinPF4 +from airgun.views.common import BaseLoggedInView, SearchableViewMixinPF4 from airgun.widgets import SatTable diff --git a/airgun/views/cloud_insights.py b/airgun/views/cloud_insights.py index 1cfd7da43..88d66c8eb 100644 --- a/airgun/views/cloud_insights.py +++ b/airgun/views/cloud_insights.py @@ -1,16 +1,9 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View -from widgetastic_patternfly4 import Button -from widgetastic_patternfly4 import Pagination +from widgetastic.widget import Checkbox, Text, TextInput, View +from widgetastic_patternfly4 import Button, Pagination from widgetastic_patternfly4.dropdown import Dropdown -from widgetastic_patternfly4.ouia import Modal -from widgetastic_patternfly4.ouia import PatternflyTable -from widgetastic_patternfly4.ouia import Switch +from widgetastic_patternfly4.ouia import Modal, PatternflyTable, Switch -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SearchableViewMixinPF4 +from airgun.views.common import BaseLoggedInView, SearchableViewMixinPF4 class CloudTokenView(BaseLoggedInView): diff --git a/airgun/views/cloud_inventory.py b/airgun/views/cloud_inventory.py index 8347d5e1d..e8dae505f 100644 --- a/airgun/views/cloud_inventory.py +++ b/airgun/views/cloud_inventory.py @@ -1,10 +1,8 @@ from selenium.common.exceptions import NoSuchElementException from wait_for import wait_for from widgetastic.utils import ParametrizedLocator -from widgetastic.widget import Text -from widgetastic.widget import View -from widgetastic_patternfly import Button -from widgetastic_patternfly import Tab +from widgetastic.widget import Text, View +from widgetastic_patternfly import Button, Tab from widgetastic_patternfly4.button import Button as Pf4Button from widgetastic_patternfly4.switch import Switch @@ -83,7 +81,7 @@ def status(self): @property def is_active(self): classes = self.browser.classes(self) - return any(['expand-active' in class_ for class_ in classes]) + return any('expand-active' in class_ for class_ in classes) def child_widget_accessed(self, widget): if not self.is_active: @@ -109,9 +107,7 @@ class CloudInventoryListView(BaseLoggedInView): title = Text('//h1[normalize-space(.)="Red Hat Inventory"]') auto_update = Switch('.//label[@for="rh-cloud-switcher-allow_auto_inventory_upload"]') - obfuscate_hostnames = Switch( - './/label[@for="rh-cloud-switcher-obfuscate_inventory_hostnames"]' - ) + obfuscate_hostnames = Switch('.//label[@for="rh-cloud-switcher-obfuscate_inventory_hostnames"]') obfuscate_ips = Switch('.//label[@for="rh-cloud-switcher-obfuscate_inventory_ips"]') exclude_packages = Switch('.//label[@for="rh-cloud-switcher-exclude_installed_packages"]') cloud_connector = Pf4Button(locator='//button[normalize-space(.)="Configure Cloud Connector"]') diff --git a/airgun/views/common.py b/airgun/views/common.py index 840fe61de..3b2711001 100644 --- a/airgun/views/common.py +++ b/airgun/views/common.py @@ -1,36 +1,36 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import ConditionalSwitchableView -from widgetastic.widget import do_not_read_this_widget -from widgetastic.widget import ParametrizedLocator -from widgetastic.widget import ParametrizedView -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View -from widgetastic.widget import WTMixin -from widgetastic_patternfly import BreadCrumb -from widgetastic_patternfly import Button -from widgetastic_patternfly import Tab -from widgetastic_patternfly import TabWithDropdown +from widgetastic.widget import ( + Checkbox, + ConditionalSwitchableView, + ParametrizedLocator, + ParametrizedView, + Text, + TextInput, + View, + WTMixin, + do_not_read_this_widget, +) +from widgetastic_patternfly import BreadCrumb, Button, Tab, TabWithDropdown from widgetastic_patternfly4.ouia import Dropdown -from airgun.utils import get_widget_by_name -from airgun.utils import normalize_dict_values -from airgun.widgets import ACEEditor -from airgun.widgets import ContextSelector -from airgun.widgets import FilteredDropdown -from airgun.widgets import GenericRemovableWidgetItem -from airgun.widgets import ItemsList -from airgun.widgets import LCESelector -from airgun.widgets import Pf4ConfirmationDialog -from airgun.widgets import PF4Search -from airgun.widgets import ProgressBar -from airgun.widgets import ReadOnlyEntry -from airgun.widgets import SatFlashMessages -from airgun.widgets import SatSubscriptionsTable -from airgun.widgets import SatTable -from airgun.widgets import SatVerticalNavigation -from airgun.widgets import Search -from airgun.widgets import ValidationErrors +from airgun.utils import get_widget_by_name, normalize_dict_values +from airgun.widgets import ( + ACEEditor, + ContextSelector, + FilteredDropdown, + GenericRemovableWidgetItem, + ItemsList, + LCESelector, + Pf4ConfirmationDialog, + PF4Search, + ProgressBar, + ReadOnlyEntry, + SatFlashMessages, + SatSubscriptionsTable, + SatTable, + SatVerticalNavigation, + Search, + ValidationErrors, +) class BaseLoggedInView(View): @@ -63,7 +63,7 @@ def read(self, widget_names=None): """ if widget_names is None: return super().read() - if not isinstance(widget_names, (list, tuple)): + if not isinstance(widget_names, list | tuple): widget_names = [widget_names] values = {} for widget_name in widget_names: @@ -287,7 +287,7 @@ def remove(self, value): def fill(self, values): """Remove associated resource(s).""" if not isinstance(values, list): - values = list((values,)) + values = [values] for value in values: self.remove(value) @@ -318,7 +318,7 @@ def add(self, value): def fill(self, values): """Associate resource(s)""" if not isinstance(values, list): - values = list((values,)) + values = [values] for value in values: self.add(value) diff --git a/airgun/views/computeprofile.py b/airgun/views/computeprofile.py index e4fbda995..49c11a910 100644 --- a/airgun/views/computeprofile.py +++ b/airgun/views/computeprofile.py @@ -1,10 +1,7 @@ -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput +from widgetastic.widget import Table, Text, TextInput from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SearchableViewMixinPF4 +from airgun.views.common import BaseLoggedInView, SearchableViewMixinPF4 from airgun.widgets import ActionsDropdown diff --git a/airgun/views/computeresource.py b/airgun/views/computeresource.py index 7be880f87..eb13f4cee 100644 --- a/airgun/views/computeresource.py +++ b/airgun/views/computeresource.py @@ -1,29 +1,30 @@ import re -from widgetastic.widget import Checkbox -from widgetastic.widget import ConditionalSwitchableView -from widgetastic.widget import Select -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import ( + Checkbox, + ConditionalSwitchableView, + Select, + Table, + Text, + TextInput, + View, +) from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixin +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixin from airgun.views.host import HostCreateView -from airgun.widgets import ActionsDropdown -from airgun.widgets import FilteredDropdown -from airgun.widgets import GenericRemovableWidgetItem -from airgun.widgets import MultiSelect -from airgun.widgets import RadioGroup -from airgun.widgets import RemovableWidgetsItemsListView -from airgun.widgets import SatTable +from airgun.widgets import ( + ActionsDropdown, + FilteredDropdown, + GenericRemovableWidgetItem, + MultiSelect, + RadioGroup, + RemovableWidgetsItemsListView, + SatTable, +) class ComputeResourcesView(BaseLoggedInView, SearchableViewMixin): - title = Text('//*[(self::h1 or self::h5) and normalize-space(.)="Compute Resources"]') new = Text('//a[normalize-space(.)="Create Compute Resource"]') table = SatTable( @@ -319,9 +320,7 @@ class ComputeResourceVMwareProfileStorageItem(GenericRemovableWidgetItem): controller = FilteredDropdown( locator=".//div[@class='controller-header']//div[contains(@class, 'form-control')]" ) - remove_button = Text( - ".//button[contains(concat(' ', @class, ' '), ' btn-remove-controller ')]" - ) + remove_button = Text(".//button[contains(concat(' ', @class, ' '), ' btn-remove-controller ')]") disks = ComputeResourceVMwareProfileControllerVolumeList() @@ -370,9 +369,7 @@ class storage(RemovableWidgetsItemsListView): class EC2ResourceForm(View): flavor = FilteredDropdown(id='s2id_compute_attribute_vm_attrs_flavor_id') image = FilteredDropdown(id='s2id_compute_attribute_vm_attrs_image_id') - availability_zone = FilteredDropdown( - id='s2id_compute_attribute_vm_attrs_availability_zone' - ) + availability_zone = FilteredDropdown(id='s2id_compute_attribute_vm_attrs_availability_zone') subnet = FilteredDropdown(id='s2id_compute_attribute_vm_attrs_subnet_id') security_groups = MultiSelect(id='ms-compute_attribute_vm_attrs_security_group_ids') managed_ip = FilteredDropdown(id='s2id_compute_attribute_vm_attrs_managed_ip') @@ -418,9 +415,7 @@ class VMwareResourceForm(View): resource_pool = FilteredDropdown(id='s2id_compute_attribute_vm_attrs_resource_pool') folder = FilteredDropdown(id='s2id_compute_attribute_vm_attrs_path') guest_os = FilteredDropdown(id='s2id_compute_attribute_vm_attrs_guest_id') - virtual_hw_version = FilteredDropdown( - id='s2id_compute_attribute_vm_attrs_hardware_version' - ) + virtual_hw_version = FilteredDropdown(id='s2id_compute_attribute_vm_attrs_hardware_version') memory_hot_add = Checkbox(id='compute_attribute_vm_attrs_memoryHotAddEnabled') cpu_hot_add = Checkbox(id='compute_attribute_vm_attrs_cpuHotAddEnabled') cdrom_drive = Checkbox(id='compute_attribute_vm_attrs_add_cdrom') diff --git a/airgun/views/config_report.py b/airgun/views/config_report.py index 314b3cd29..39db42c40 100644 --- a/airgun/views/config_report.py +++ b/airgun/views/config_report.py @@ -1,10 +1,7 @@ from widgetastic.widget import Text -from widgetastic_patternfly import BreadCrumb -from widgetastic_patternfly import Button +from widgetastic_patternfly import BreadCrumb, Button -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTable -from airgun.views.common import SearchableViewMixin +from airgun.views.common import BaseLoggedInView, SatTable, SearchableViewMixin class ConfigReportsView(BaseLoggedInView, SearchableViewMixin): diff --git a/airgun/views/configgroup.py b/airgun/views/configgroup.py index 25321d039..f426898c9 100644 --- a/airgun/views/configgroup.py +++ b/airgun/views/configgroup.py @@ -1,10 +1,7 @@ -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput +from widgetastic.widget import Table, Text, TextInput from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SearchableViewMixin +from airgun.views.common import BaseLoggedInView, SearchableViewMixin from airgun.widgets import PuppetClassesMultiSelect diff --git a/airgun/views/containerimagetag.py b/airgun/views/containerimagetag.py index 79614393d..d34e812d9 100644 --- a/airgun/views/containerimagetag.py +++ b/airgun/views/containerimagetag.py @@ -1,12 +1,13 @@ -from widgetastic.widget import Text -from widgetastic.widget import View +from widgetastic.widget import Text, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import ReadOnlyEntry -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixin -from airgun.views.common import TaskDetailsView +from airgun.views.common import ( + BaseLoggedInView, + ReadOnlyEntry, + SatTab, + SearchableViewMixin, + TaskDetailsView, +) from airgun.widgets import SatTable @@ -21,6 +22,7 @@ def is_displayed(self): class ContainerImageTagDetailsView(TaskDetailsView): breadcrumb = BreadCrumb() + BREADCRUMB_LENGTH = 2 @property def is_displayed(self): @@ -28,7 +30,7 @@ def is_displayed(self): return ( breadcrumb_loaded and self.breadcrumb.locations[0] == 'Container Image Tags' - and len(self.breadcrumb.locations) >= 2 + and len(self.breadcrumb.locations) >= self.BREADCRUMB_LENGTH ) @View.nested diff --git a/airgun/views/contentcredential.py b/airgun/views/contentcredential.py index 24bc94444..da0e778b2 100644 --- a/airgun/views/contentcredential.py +++ b/airgun/views/contentcredential.py @@ -1,17 +1,8 @@ -from widgetastic.widget import FileInput -from widgetastic.widget import Select -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import FileInput, Select, Table, Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixin -from airgun.widgets import ConfirmationDialog -from airgun.widgets import EditableEntry -from airgun.widgets import ReadOnlyEntry +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixin +from airgun.widgets import ConfirmationDialog, EditableEntry, ReadOnlyEntry class ContentCredentialsTableView(BaseLoggedInView, SearchableViewMixin): diff --git a/airgun/views/contenthost.py b/airgun/views/contenthost.py index 45cfb4351..32b06541b 100644 --- a/airgun/views/contenthost.py +++ b/airgun/views/contenthost.py @@ -1,35 +1,40 @@ import re -from widgetastic.widget import Checkbox -from widgetastic.widget import GenericLocatorWidget -from widgetastic.widget import ParametrizedView -from widgetastic.widget import Select -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View -from widgetastic.widget import Widget -from widgetastic_patternfly import BreadCrumb -from widgetastic_patternfly import Button - -from airgun.views.common import AddRemoveResourcesView -from airgun.views.common import AddRemoveSubscriptionsView -from airgun.views.common import BaseLoggedInView -from airgun.views.common import LCESelectorGroup -from airgun.views.common import SatTab -from airgun.views.common import SatTable -from airgun.views.common import SatTabWithDropdown -from airgun.views.common import SearchableViewMixin -from airgun.views.common import TaskDetailsView -from airgun.widgets import ActionDropdownWithCheckbox -from airgun.widgets import ActionsDropdown -from airgun.widgets import ConfirmationDialog -from airgun.widgets import EditableEntry -from airgun.widgets import EditableEntryCheckbox -from airgun.widgets import EditableEntryMultiCheckbox -from airgun.widgets import EditableEntrySelect -from airgun.widgets import Pagination -from airgun.widgets import ReadOnlyEntry -from airgun.widgets import Search +from widgetastic.widget import ( + Checkbox, + GenericLocatorWidget, + ParametrizedView, + Select, + Text, + TextInput, + View, + Widget, +) +from widgetastic_patternfly import BreadCrumb, Button + +from airgun.views.common import ( + AddRemoveResourcesView, + AddRemoveSubscriptionsView, + BaseLoggedInView, + LCESelectorGroup, + SatTab, + SatTable, + SatTabWithDropdown, + SearchableViewMixin, + TaskDetailsView, +) +from airgun.widgets import ( + ActionDropdownWithCheckbox, + ActionsDropdown, + ConfirmationDialog, + EditableEntry, + EditableEntryCheckbox, + EditableEntryMultiCheckbox, + EditableEntrySelect, + Pagination, + ReadOnlyEntry, + Search, +) class StatusIcon(GenericLocatorWidget): @@ -321,13 +326,15 @@ def read(self): class ContentHostTaskDetailsView(TaskDetailsView): + BREADCRUMB_LENGTH = 2 + @property def is_displayed(self): breadcrumb_loaded = self.browser.wait_for_element(self.breadcrumb, exception=False) return ( breadcrumb_loaded and self.breadcrumb.locations[0] == 'Content Hosts' - and len(self.breadcrumb.locations) > 2 + and len(self.breadcrumb.locations) > self.BREADCRUMB_LENGTH ) @@ -344,8 +351,8 @@ def is_displayed(self): class ErrataDetailsView(BaseLoggedInView): - breadcrumb = BreadCrumb() + BREADCRUMB_LENGTH = 3 advisory = Text("//h3") type = ReadOnlyEntry(name='Type') title = ReadOnlyEntry(name='Title') @@ -363,5 +370,5 @@ def is_displayed(self): return ( breadcrumb_loaded and self.breadcrumb.locations[1] == 'Errata' - and len(self.breadcrumb.locations) > 3 + and len(self.breadcrumb.locations) > self.BREADCRUMB_LENGTH ) diff --git a/airgun/views/contentview.py b/airgun/views/contentview.py index 755eba049..b7cfd704f 100644 --- a/airgun/views/contentview.py +++ b/airgun/views/contentview.py @@ -1,27 +1,25 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import ParametrizedView -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View -from widgetastic_patternfly import BreadCrumb -from widgetastic_patternfly import Button - -from airgun.views.common import AddRemoveResourcesView -from airgun.views.common import BaseLoggedInView -from airgun.views.common import LCESelectorGroup -from airgun.views.common import SatSecondaryTab -from airgun.views.common import SatTab -from airgun.views.common import SatTabWithDropdown -from airgun.views.common import SearchableViewMixin -from airgun.widgets import ActionsDropdown -from airgun.widgets import ConfirmationDialog -from airgun.widgets import EditableEntry -from airgun.widgets import EditableEntryCheckbox -from airgun.widgets import PublishPromoteProgressBar -from airgun.widgets import ReadOnlyEntry -from airgun.widgets import SatSelect -from airgun.widgets import Search +from widgetastic.widget import Checkbox, ParametrizedView, Table, Text, TextInput, View +from widgetastic_patternfly import BreadCrumb, Button + +from airgun.views.common import ( + AddRemoveResourcesView, + BaseLoggedInView, + LCESelectorGroup, + SatSecondaryTab, + SatTab, + SatTabWithDropdown, + SearchableViewMixin, +) +from airgun.widgets import ( + ActionsDropdown, + ConfirmationDialog, + EditableEntry, + EditableEntryCheckbox, + PublishPromoteProgressBar, + ReadOnlyEntry, + SatSelect, + Search, +) class ContentViewTableView(BaseLoggedInView, SearchableViewMixin): @@ -56,6 +54,7 @@ def is_displayed(self): class ContentViewCopyView(BaseLoggedInView): breadcrumb = BreadCrumb() + BREADCRUMB_LENGTH = 3 new_name = TextInput(id='copy_name') create = Text(".//button[@type='submit']") @@ -66,14 +65,14 @@ def is_displayed(self): return ( breadcrumb_loaded and self.breadcrumb.locations[0] == 'Content Views' - and len(self.breadcrumb.locations) == 3 + and len(self.breadcrumb.locations) == self.BREADCRUMB_LENGTH and self.breadcrumb.read() == 'Copy' ) class ContentViewRemoveView(BaseLoggedInView): breadcrumb = BreadCrumb() - + BREADCRUMB_LENGTH = 3 conflicts = Text("//div[@ng-show='conflictingVersions.length > 0']") table = Table('.//table') remove = Text(".//button[@ng-click='delete()']") @@ -89,7 +88,7 @@ def is_displayed(self): return ( breadcrumb_loaded and self.breadcrumb.locations[0] == 'Content Views' - and len(self.breadcrumb.locations) == 3 + and len(self.breadcrumb.locations) == self.BREADCRUMB_LENGTH and self.breadcrumb.read() == 'Deletion' and (self.conflicts_present or self.remove.is_displayed) ) @@ -97,6 +96,7 @@ def is_displayed(self): class ContentViewEditView(BaseLoggedInView): breadcrumb = BreadCrumb() + BREADCRUMB_LENGTH = 3 publish = Button("Publish New Version") actions = ActionsDropdown("//div[contains(@class, 'btn-group')]") dialog = ConfirmationDialog() @@ -106,7 +106,7 @@ def is_displayed(self): breadcrumb_loaded = self.browser.wait_for_element(self.breadcrumb, exception=False) return ( breadcrumb_loaded - and len(self.breadcrumb.locations) <= 3 + and len(self.breadcrumb.locations) <= self.BREADCRUMB_LENGTH and self.breadcrumb.locations[0] == 'Content Views' and self.breadcrumb.read() != 'New Content View' ) @@ -228,13 +228,14 @@ def search(self, query, repo=None): class ContentViewVersionDetailsView(BaseLoggedInView): breadcrumb = BreadCrumb() + BREADCRUMB_LENGTH = 3 @property def is_displayed(self): breadcrumb_loaded = self.browser.wait_for_element(self.breadcrumb, exception=False) return ( breadcrumb_loaded - and len(self.breadcrumb.locations) > 3 + and len(self.breadcrumb.locations) > self.BREADCRUMB_LENGTH and self.breadcrumb.locations[0] == 'Content Views' and self.breadcrumb.locations[2] == 'Versions' ) @@ -287,7 +288,7 @@ def is_displayed(self): class ContentViewVersionRemoveView(BaseLoggedInView): breadcrumb = BreadCrumb() - + BREADCRUMB_LENGTH = 3 table = Table( locator='.//table', column_widgets={ @@ -304,7 +305,7 @@ def is_displayed(self): return ( breadcrumb_loaded and self.breadcrumb.locations[0] == 'Content Views' - and len(self.breadcrumb.locations) == 3 + and len(self.breadcrumb.locations) == self.BREADCRUMB_LENGTH and self.breadcrumb.read() == 'Deletion' and self.next.is_displayed ) @@ -312,7 +313,7 @@ def is_displayed(self): class ContentViewVersionRemoveConfirmationView(BaseLoggedInView): breadcrumb = BreadCrumb() - + BREADCRUMB_LENGTH = 3 cancel = Text(".//button[normalize-space(.)='Cancel']") back = Text(".//button[@ng-click='transitionBack()']") confirm_remove = Text(".//button[@ng-click='performDeletion()']") @@ -324,7 +325,7 @@ def is_displayed(self): return ( breadcrumb_loaded and self.breadcrumb.locations[0] == 'Content Views' - and len(self.breadcrumb.locations) == 3 + and len(self.breadcrumb.locations) == self.BREADCRUMB_LENGTH and self.breadcrumb.read() == 'Deletion' and self.confirm_remove.is_displayed ) diff --git a/airgun/views/contentview_new.py b/airgun/views/contentview_new.py index 71c64d558..5b558c04f 100644 --- a/airgun/views/contentview_new.py +++ b/airgun/views/contentview_new.py @@ -1,12 +1,7 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View -from widgetastic_patternfly4.ouia import Button as PF4Button -from widgetastic_patternfly4.ouia import ExpandableTable - -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SearchableViewMixinPF4 +from widgetastic.widget import Checkbox, Text, TextInput, View +from widgetastic_patternfly4.ouia import Button as PF4Button, ExpandableTable + +from airgun.views.common import BaseLoggedInView, SearchableViewMixinPF4 class NewContentViewTableView(BaseLoggedInView, SearchableViewMixinPF4): diff --git a/airgun/views/contentviewfilter.py b/airgun/views/contentviewfilter.py index 8e7c9e54a..07435786a 100644 --- a/airgun/views/contentviewfilter.py +++ b/airgun/views/contentviewfilter.py @@ -1,24 +1,29 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import ConditionalSwitchableView -from widgetastic.widget import ParametrizedLocator -from widgetastic.widget import Select -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View -from widgetastic_patternfly import BreadCrumb -from widgetastic_patternfly import Button - -from airgun.views.common import AddRemoveResourcesView -from airgun.views.common import AddTab -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatSecondaryTab -from airgun.views.common import SearchableViewMixin -from airgun.widgets import DatePickerInput -from airgun.widgets import EditableEntry -from airgun.widgets import RadioGroup -from airgun.widgets import SatSelect -from airgun.widgets import SatTable +from widgetastic.widget import ( + Checkbox, + ConditionalSwitchableView, + ParametrizedLocator, + Select, + Table, + Text, + TextInput, + View, +) +from widgetastic_patternfly import BreadCrumb, Button + +from airgun.views.common import ( + AddRemoveResourcesView, + AddTab, + BaseLoggedInView, + SatSecondaryTab, + SearchableViewMixin, +) +from airgun.widgets import ( + DatePickerInput, + EditableEntry, + RadioGroup, + SatSelect, + SatTable, +) ACTIONS_COLUMN = 4 @@ -164,8 +169,8 @@ def is_displayed(self): class EditYumFilterView(BaseLoggedInView): breadcrumb = BreadCrumb() + BREADCRUMB_LENGTH = 3 filter_type = Text('//header/small') - content_tabs = ConditionalSwitchableView(reference='filter_type') @property @@ -173,7 +178,7 @@ def is_displayed(self): breadcrumb_loaded = self.browser.wait_for_element(self.breadcrumb, exception=False) return ( breadcrumb_loaded - and len(self.breadcrumb.locations) > 3 + and len(self.breadcrumb.locations) > self.BREADCRUMB_LENGTH and self.breadcrumb.locations[2] == 'Yum Filters' and self.breadcrumb.read() != 'Create Yum Filter' ) diff --git a/airgun/views/dashboard.py b/airgun/views/dashboard.py index 142007116..5c805bdfe 100644 --- a/airgun/views/dashboard.py +++ b/airgun/views/dashboard.py @@ -1,13 +1,7 @@ -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import View -from widgetastic.widget import Widget - -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTable -from airgun.widgets import ActionsDropdown -from airgun.widgets import PieChart -from airgun.widgets import Search +from widgetastic.widget import Table, Text, View, Widget + +from airgun.views.common import BaseLoggedInView, SatTable +from airgun.widgets import ActionsDropdown, PieChart, Search class ItemValueList(Widget): diff --git a/airgun/views/discoveredhosts.py b/airgun/views/discoveredhosts.py index a62a164ef..08494db5b 100644 --- a/airgun/views/discoveredhosts.py +++ b/airgun/views/discoveredhosts.py @@ -1,19 +1,15 @@ from wait_for import wait_for -from widgetastic.widget import Checkbox -from widgetastic.widget import Select -from widgetastic.widget import TableColumn -from widgetastic.widget import TableRow -from widgetastic.widget import Text -from widgetastic_patternfly import BreadCrumb -from widgetastic_patternfly import Button - -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SearchableViewMixin +from widgetastic.widget import Checkbox, Select, TableColumn, TableRow, Text +from widgetastic_patternfly import BreadCrumb, Button + +from airgun.views.common import BaseLoggedInView, SearchableViewMixin from airgun.views.host import HostCreateView -from airgun.widgets import ActionsDropdown -from airgun.widgets import FilteredDropdown -from airgun.widgets import SatTable -from airgun.widgets import SatTableWithoutHeaders +from airgun.widgets import ( + ActionsDropdown, + FilteredDropdown, + SatTable, + SatTableWithoutHeaders, +) class DiscoveredHostsViewTable(SatTable): diff --git a/airgun/views/discoveryrule.py b/airgun/views/discoveryrule.py index bbae72d05..d0d9410ef 100644 --- a/airgun/views/discoveryrule.py +++ b/airgun/views/discoveryrule.py @@ -1,17 +1,15 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Checkbox, Text, TextInput, View from widgetastic_patternfly import BreadCrumb from widgetastic_patternfly4 import Button as PF4Button -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.widgets import ActionsDropdown -from airgun.widgets import AutoCompleteTextInput -from airgun.widgets import FilteredDropdown -from airgun.widgets import MultiSelect -from airgun.widgets import SatTable +from airgun.views.common import BaseLoggedInView, SatTab +from airgun.widgets import ( + ActionsDropdown, + AutoCompleteTextInput, + FilteredDropdown, + MultiSelect, + SatTable, +) class DiscoveryRulesView(BaseLoggedInView): diff --git a/airgun/views/domain.py b/airgun/views/domain.py index dbbdd5610..c5fcb9f1c 100644 --- a/airgun/views/domain.py +++ b/airgun/views/domain.py @@ -1,15 +1,8 @@ -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Table, Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixinPF4 -from airgun.widgets import CustomParameter -from airgun.widgets import FilteredDropdown -from airgun.widgets import MultiSelect +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixinPF4 +from airgun.widgets import CustomParameter, FilteredDropdown, MultiSelect class DomainListView(BaseLoggedInView, SearchableViewMixinPF4): @@ -37,21 +30,21 @@ class DomainCreateView(BaseLoggedInView): cancel_button = Text(".//a[@href='/domains']") @View.nested - class domain(SatTab): # noqa + class domain(SatTab): dns_domain = TextInput(id='domain_name') full_name = TextInput(id='domain_fullname') dns_capsule = FilteredDropdown(id='domain_dns_id') @View.nested - class parameters(SatTab): # noqa + class parameters(SatTab): params = CustomParameter(id='global_parameters_table') @View.nested - class locations(SatTab): # noqa + class locations(SatTab): multiselect = MultiSelect(id='ms-domain_location_ids') @View.nested - class organizations(SatTab): # noqa + class organizations(SatTab): multiselect = MultiSelect(id='ms-domain_organization_ids') @property diff --git a/airgun/views/errata.py b/airgun/views/errata.py index 23c390869..f8c25607d 100644 --- a/airgun/views/errata.py +++ b/airgun/views/errata.py @@ -1,18 +1,10 @@ import re -from widgetastic.widget import Checkbox -from widgetastic.widget import Text -from widgetastic.widget import View +from widgetastic.widget import Checkbox, Text, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import TaskDetailsView -from airgun.widgets import ItemsList -from airgun.widgets import ReadOnlyEntry -from airgun.widgets import SatSelect -from airgun.widgets import SatTable -from airgun.widgets import Search +from airgun.views.common import BaseLoggedInView, SatTab, TaskDetailsView +from airgun.widgets import ItemsList, ReadOnlyEntry, SatSelect, SatTable, Search class ErratumView(BaseLoggedInView): @@ -201,11 +193,13 @@ class ErrataInstallationConfirmationView(BaseLoggedInView): class ErrataTaskDetailsView(TaskDetailsView): + BREADCRUMB_LENGTH = 2 + @property def is_displayed(self): breadcrumb_loaded = self.browser.wait_for_element(self.breadcrumb, exception=False) return ( breadcrumb_loaded and self.breadcrumb.locations[0] == 'Errata' - and len(self.breadcrumb.locations) > 2 + and len(self.breadcrumb.locations) > self.BREADCRUMB_LENGTH ) diff --git a/airgun/views/filter.py b/airgun/views/filter.py index 69223dc46..b955ae348 100644 --- a/airgun/views/filter.py +++ b/airgun/views/filter.py @@ -1,18 +1,21 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import ConditionalSwitchableView -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import ( + Checkbox, + ConditionalSwitchableView, + Table, + Text, + TextInput, + View, +) from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.widgets import ActionsDropdown -from airgun.widgets import FilteredDropdown -from airgun.widgets import MultiSelect -from airgun.widgets import Pagination -from airgun.widgets import Search +from airgun.views.common import BaseLoggedInView, SatTab +from airgun.widgets import ( + ActionsDropdown, + FilteredDropdown, + MultiSelect, + Pagination, + Search, +) class FiltersView(BaseLoggedInView): diff --git a/airgun/views/hardware_model.py b/airgun/views/hardware_model.py index aa0acb9fd..cf0ef5070 100644 --- a/airgun/views/hardware_model.py +++ b/airgun/views/hardware_model.py @@ -1,12 +1,8 @@ -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic_patternfly import BreadCrumb -from widgetastic_patternfly import Button - -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SearchableViewMixinPF4 -from airgun.widgets import ConfirmationDialog -from airgun.widgets import SatTable +from widgetastic.widget import Text, TextInput +from widgetastic_patternfly import BreadCrumb, Button + +from airgun.views.common import BaseLoggedInView, SearchableViewMixinPF4 +from airgun.widgets import ConfirmationDialog, SatTable class DeleteHardwareModelDialog(ConfirmationDialog): diff --git a/airgun/views/host.py b/airgun/views/host.py index 5e499f06d..2daa912f5 100644 --- a/airgun/views/host.py +++ b/airgun/views/host.py @@ -2,45 +2,47 @@ from wait_for import wait_for from widgetastic.utils import ParametrizedLocator -from widgetastic.widget import Checkbox -from widgetastic.widget import ConditionalSwitchableView -from widgetastic.widget import GenericLocatorWidget -from widgetastic.widget import NoSuchElementException -from widgetastic.widget import Select -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View -from widgetastic.widget import Widget -from widgetastic_patternfly import BreadCrumb -from widgetastic_patternfly import Button -from widgetastic_patternfly4.ouia import BreadCrumb as PF4BreadCrumb -from widgetastic_patternfly4.ouia import Button as PF4Button -from widgetastic_patternfly4.ouia import FormSelect +from widgetastic.widget import ( + Checkbox, + ConditionalSwitchableView, + GenericLocatorWidget, + NoSuchElementException, + Select, + Table, + Text, + TextInput, + View, + Widget, +) +from widgetastic_patternfly import BreadCrumb, Button +from widgetastic_patternfly4.ouia import ( + BreadCrumb as PF4BreadCrumb, + Button as PF4Button, + FormSelect, +) from widgetastic_patternfly4.tabs import Tab -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixinPF4 -from airgun.views.job_invocation import JobInvocationCreateView -from airgun.views.job_invocation import JobInvocationStatusView +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixinPF4 +from airgun.views.job_invocation import JobInvocationCreateView, JobInvocationStatusView from airgun.views.task import TaskDetailsView -from airgun.widgets import ActionsDropdown -from airgun.widgets import BaseMultiSelect -from airgun.widgets import CheckboxWithAlert -from airgun.widgets import ConfigGroupMultiSelect -from airgun.widgets import CustomParameter -from airgun.widgets import FilteredDropdown -from airgun.widgets import GenericRemovableWidgetItem -from airgun.widgets import Link -from airgun.widgets import MultiSelect -from airgun.widgets import Pf4ConfirmationDialog -from airgun.widgets import PuppetClassesMultiSelect -from airgun.widgets import RadioGroup -from airgun.widgets import RemovableWidgetsItemsListView -from airgun.widgets import SatTable -from airgun.widgets import SatTableWithUnevenStructure -from airgun.widgets import ToggleButton +from airgun.widgets import ( + ActionsDropdown, + BaseMultiSelect, + CheckboxWithAlert, + ConfigGroupMultiSelect, + CustomParameter, + FilteredDropdown, + GenericRemovableWidgetItem, + Link, + MultiSelect, + Pf4ConfirmationDialog, + PuppetClassesMultiSelect, + RadioGroup, + RemovableWidgetsItemsListView, + SatTable, + SatTableWithUnevenStructure, + ToggleButton, +) class TableActions(View): @@ -428,16 +430,14 @@ def read(self): """Return a list of dictionaries. Each dictionary consists of global parameter name, value and whether overridden or not. """ - parameters = [] - for row in self.rows(): - parameters.append( - { - 'name': row['Name'].widget.read(), - 'value': row['Value'].widget.read(), - 'overridden': not row['Actions'].widget.is_displayed, - } - ) - return parameters + return [ + { + 'name': row['Name'].widget.read(), + 'value': row['Value'].widget.read(), + 'overridden': not row['Actions'].widget.is_displayed, + } + for row in self.rows() + ] def override(self, name): """Override a single global parameter. @@ -562,7 +562,7 @@ def before_fill(self, values): field_value = values.get('general').get(field) if field_value: wait_for( - lambda: self.general.__getattribute__(field).is_enabled, + lambda field=field: self.general.__getattribute__(field).is_enabled, timeout=30, delay=2, logger=self.logger, @@ -616,10 +616,10 @@ def text(self): def read(self): if self.expanded: - return dict(name=self.name, label=self.label, text=self.text) + return {'name': self.name, 'label': self.label, 'text': self.text} else: self.expand() - return dict(name=self.name, label=self.label, text=self.text) + return {'name': self.name, 'label': self.label, 'text': self.text} class RecommendationListView(View): @@ -742,9 +742,10 @@ class HostsTaxonomyMismatchRadioGroup(GenericLocatorWidget): taxonomy = None fix_mismatch = Text("//input[contains(@id, 'optimistic_import_yes')]") fail_on_mismatch = Text("//input[contains(@id, 'optimistic_import_no')]") - buttons_text = dict( - fix_mismatch='Fix {taxonomy} on Mismatch', fail_on_mismatch='Fail on Mismatch' - ) + buttons_text = { + 'fix_mismatch': 'Fix {taxonomy} on Mismatch', + 'fail_on_mismatch': 'Fail on Mismatch', + } def __init__(self, parent, **kwargs): self.taxonomy = kwargs.pop('taxonomy') @@ -763,9 +764,9 @@ def read(self): def fill(self, value): """Select the button with text equal to value""" for name, text in self.buttons_text.items(): - text = text.replace('{taxonomy}', self.taxonomy) + _text = text.replace('{taxonomy}', self.taxonomy) widget = getattr(self, name) - if text == value and not self._is_checked(widget): + if _text == value and not self._is_checked(widget): widget.click() @property diff --git a/airgun/views/host_new.py b/airgun/views/host_new.py index e4116e9ec..ac8bffec1 100644 --- a/airgun/views/host_new.py +++ b/airgun/views/host_new.py @@ -1,31 +1,27 @@ import time from selenium.webdriver.common.keys import Keys -from widgetastic.widget import Checkbox -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View -from widgetastic.widget import Widget +from widgetastic.widget import Checkbox, Text, TextInput, View, Widget from widgetastic.widget.table import Table -from widgetastic_patternfly4 import Button -from widgetastic_patternfly4 import Dropdown -from widgetastic_patternfly4 import Pagination -from widgetastic_patternfly4 import Select -from widgetastic_patternfly4 import Tab -from widgetastic_patternfly4.ouia import BreadCrumb -from widgetastic_patternfly4.ouia import Button as OUIAButton -from widgetastic_patternfly4.ouia import ExpandableTable -from widgetastic_patternfly4.ouia import FormSelect as OUIAFormSelect -from widgetastic_patternfly4.ouia import PatternflyTable -from widgetastic_patternfly4.ouia import Select as OUIASelect +from widgetastic_patternfly4 import Button, Dropdown, Pagination, Select, Tab +from widgetastic_patternfly4.ouia import ( + BreadCrumb, + Button as OUIAButton, + ExpandableTable, + FormSelect as OUIAFormSelect, + PatternflyTable, + Select as OUIASelect, +) from airgun.views.common import BaseLoggedInView -from airgun.widgets import Accordion -from airgun.widgets import CheckboxGroup -from airgun.widgets import ItemsList -from airgun.widgets import Pf4ActionsDropdown -from airgun.widgets import Pf4ConfirmationDialog -from airgun.widgets import SatTableWithoutHeaders +from airgun.widgets import ( + Accordion, + CheckboxGroup, + ItemsList, + Pf4ActionsDropdown, + Pf4ConfirmationDialog, + SatTableWithoutHeaders, +) class SearchInput(TextInput): @@ -92,9 +88,9 @@ def read(self): 'Please double check xpaths.' ) for key, value in zip(labels, values): - value = self.browser.text(value) - key = self.browser.text(key).replace(' ', '_').lower() - items[key] = value + _value = self.browser.text(value) + _key = self.browser.text(key).replace(' ', '_').lower() + items[_key] = _value return items @@ -230,9 +226,7 @@ class system_purpose(Card): class details(Tab): ROOT = './/div[contains(@class, "host-details-tab-item")]' - card_collapse_switch = Text( - './/button[contains(@data-ouia-component-id, "expand-button")]' - ) + card_collapse_switch = Text('.//button[contains(@data-ouia-component-id, "expand-button")]') @View.nested class system_properties(Card): @@ -295,9 +289,7 @@ class hw_properties(Card): ROOT = './/article[.//div[text()="HW properties"]]' model = Text('.//div[contains(@class, "pf-c-description-list__group")][1]//dd') - number_of_cpus = Text( - './/div[contains(@class, "pf-c-description-list__group")][2]//dd' - ) + number_of_cpus = Text('.//div[contains(@class, "pf-c-description-list__group")][2]//dd') sockets = Text('.//div[contains(@class, "pf-c-description-list__group")][3]//dd') cores_per_socket = Text( './/div[contains(@class, "pf-c-description-list__group")][4]//dd' @@ -358,9 +350,7 @@ class packages(Tab): select_all = Checkbox(locator='.//div[@id="selection-checkbox"]/div/label') searchbar = SearchInput(locator='.//input[contains(@class, "pf-m-search")]') status_filter = Dropdown(locator='.//div[@aria-label="select Status container"]/div') - upgrade = Pf4ActionsDropdown( - locator='.//div[div/button[normalize-space(.)="Upgrade"]]' - ) + upgrade = Pf4ActionsDropdown(locator='.//div[div/button[normalize-space(.)="Upgrade"]]') dropdown = Dropdown(locator='.//div[button[@aria-label="bulk_actions"]]') table = PatternflyTable( @@ -813,13 +803,11 @@ class EditAnsibleRolesView(View): class ModuleStreamDialog(Pf4ConfirmationDialog): - confirm_dialog = Button(locator='.//button[@aria-label="confirm-module-action"]') cancel_dialog = Button(locator='.//button[@aria-label="cancel-module-action"]') class RecurringJobDialog(Pf4ConfirmationDialog): - confirm_dialog = Button(locator='.//button[@data-ouia-component-id="btn-modal-confirm"]') cancel_dialog = Button(locator='.//button[@data-ouia-component-id="btn-modal-cancel"]') diff --git a/airgun/views/hostcollection.py b/airgun/views/hostcollection.py index e8bb94cda..98a875d61 100644 --- a/airgun/views/hostcollection.py +++ b/airgun/views/hostcollection.py @@ -1,26 +1,25 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import ParametrizedView -from widgetastic.widget import Select -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Checkbox, ParametrizedView, Select, Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import AddRemoveResourcesView -from airgun.views.common import BaseLoggedInView -from airgun.views.common import LCESelectorGroup -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixin -from airgun.views.common import TaskDetailsView +from airgun.views.common import ( + AddRemoveResourcesView, + BaseLoggedInView, + LCESelectorGroup, + SatTab, + SearchableViewMixin, + TaskDetailsView, +) from airgun.views.job_invocation import JobInvocationCreateView -from airgun.widgets import ActionDropdownWithCheckbox -from airgun.widgets import ActionsDropdown -from airgun.widgets import ConfirmationDialog -from airgun.widgets import EditableEntry -from airgun.widgets import EditableLimitEntry -from airgun.widgets import RadioGroup -from airgun.widgets import ReadOnlyEntry -from airgun.widgets import SatTable +from airgun.widgets import ( + ActionDropdownWithCheckbox, + ActionsDropdown, + ConfirmationDialog, + EditableEntry, + EditableLimitEntry, + RadioGroup, + ReadOnlyEntry, + SatTable, +) class HostCollectionsView(BaseLoggedInView, SearchableViewMixin): @@ -127,15 +126,14 @@ def get_input_by_name(self, name): @property def selected(self): """Return the name of the button that is currently selected.""" - for name in self.buttons_name_id_map.keys(): + for name in self.buttons_name_id_map: btn = self.get_input_by_name(name) if btn and btn.get_attribute('checked') is not None: return name - else: - raise ValueError( - "Whether no radio button is selected or proper attribute " - "should be added to framework" - ) + raise ValueError( + "Whether no radio button is selected or proper attribute " + "should be added to framework" + ) def select(self, name): """Select specific radio button in the group""" @@ -185,7 +183,9 @@ def get_action_button(self, name): """Return an action button by it's name""" action_button = getattr(self, name) if not isinstance(action_button, ActionsDropdown): - raise ValueError(f'Action with name: "{name}" does not exists') + raise TypeError( + f'Action with name: "{name}" does not exist or is not an ActionsDropdown' + ) return action_button def apply_action(self, name, action_via='via Katello Agent'): diff --git a/airgun/views/hostgroup.py b/airgun/views/hostgroup.py index 48f3f725c..b2e4f45a2 100644 --- a/airgun/views/hostgroup.py +++ b/airgun/views/hostgroup.py @@ -1,20 +1,16 @@ -from widgetastic.widget import ConditionalSwitchableView -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import ConditionalSwitchableView, Table, Text, TextInput, View from widgetastic_patternfly import BreadCrumb from widgetastic_patternfly4 import Button as PF4Button -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixinPF4 -from airgun.widgets import ActionsDropdown -from airgun.widgets import ConfigGroupMultiSelect -from airgun.widgets import FilteredDropdown -from airgun.widgets import MultiSelect -from airgun.widgets import PuppetClassesMultiSelect -from airgun.widgets import RadioGroup +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixinPF4 +from airgun.widgets import ( + ActionsDropdown, + ConfigGroupMultiSelect, + FilteredDropdown, + MultiSelect, + PuppetClassesMultiSelect, + RadioGroup, +) class ActivationKeyDropDown(ActionsDropdown): diff --git a/airgun/views/http_proxy.py b/airgun/views/http_proxy.py index ed209e926..af1d86134 100644 --- a/airgun/views/http_proxy.py +++ b/airgun/views/http_proxy.py @@ -1,12 +1,7 @@ -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Table, Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixin +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixin from airgun.widgets import MultiSelect diff --git a/airgun/views/job_invocation.py b/airgun/views/job_invocation.py index a71302ced..5f668dc79 100644 --- a/airgun/views/job_invocation.py +++ b/airgun/views/job_invocation.py @@ -1,17 +1,16 @@ from wait_for import wait_for -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from widgetastic_patternfly4 import Button -from widgetastic_patternfly4 import Radio +from widgetastic_patternfly4 import Button, Radio from widgetastic_patternfly4.ouia import Select -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SatTable -from airgun.views.common import SearchableViewMixin -from airgun.views.common import WizardStepView +from airgun.views.common import ( + BaseLoggedInView, + SatTab, + SatTable, + SearchableViewMixin, + WizardStepView, +) from airgun.widgets import ActionsDropdown @@ -129,6 +128,7 @@ def is_displayed(self): class JobInvocationStatusView(BaseLoggedInView): breadcrumb = BreadCrumb() + BREADCRUMB_LENGTH = 2 @property def is_displayed(self): @@ -136,7 +136,7 @@ def is_displayed(self): return ( breadcrumb_loaded and self.breadcrumb.locations[0] == 'Jobs' - and len(self.breadcrumb.locations) == 2 + and len(self.breadcrumb.locations) == self.BREADCRUMB_LENGTH ) rerun = Text("//a[normalize-space(.)='Rerun']") diff --git a/airgun/views/job_template.py b/airgun/views/job_template.py index e5106ddff..132a93897 100644 --- a/airgun/views/job_template.py +++ b/airgun/views/job_template.py @@ -1,21 +1,20 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import Select -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Checkbox, Select, Table, Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixinPF4 -from airgun.views.common import TemplateEditor -from airgun.views.common import TemplateInputItem -from airgun.widgets import ActionsDropdown -from airgun.widgets import FilteredDropdown -from airgun.widgets import GenericRemovableWidgetItem -from airgun.widgets import MultiSelect -from airgun.widgets import RemovableWidgetsItemsListView +from airgun.views.common import ( + BaseLoggedInView, + SatTab, + SearchableViewMixinPF4, + TemplateEditor, + TemplateInputItem, +) +from airgun.widgets import ( + ActionsDropdown, + FilteredDropdown, + GenericRemovableWidgetItem, + MultiSelect, + RemovableWidgetsItemsListView, +) class JobTemplatesView(BaseLoggedInView, SearchableViewMixinPF4): diff --git a/airgun/views/ldapauthentication.py b/airgun/views/ldapauthentication.py index 665aaaa42..72745f78d 100644 --- a/airgun/views/ldapauthentication.py +++ b/airgun/views/ldapauthentication.py @@ -1,15 +1,13 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Checkbox, Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.widgets import AuthSourceAggregateCard -from airgun.widgets import FilteredDropdown -from airgun.widgets import MultiSelect -from airgun.widgets import SatTable +from airgun.views.common import BaseLoggedInView, SatTab +from airgun.widgets import ( + AuthSourceAggregateCard, + FilteredDropdown, + MultiSelect, + SatTable, +) class LDAPAuthenticationsView(BaseLoggedInView): diff --git a/airgun/views/lifecycleenvironment.py b/airgun/views/lifecycleenvironment.py index 540915383..201e6ad06 100644 --- a/airgun/views/lifecycleenvironment.py +++ b/airgun/views/lifecycleenvironment.py @@ -1,20 +1,21 @@ -from widgetastic.widget import ParametrizedLocator -from widgetastic.widget import ParametrizedView -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View -from widgetastic_patternfly import BreadCrumb -from widgetastic_patternfly import Button - -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixin -from airgun.widgets import EditableEntry -from airgun.widgets import EditableEntryCheckbox -from airgun.widgets import ReadOnlyEntry -from airgun.widgets import SatSelect -from airgun.widgets import Search +from widgetastic.widget import ( + ParametrizedLocator, + ParametrizedView, + Table, + Text, + TextInput, + View, +) +from widgetastic_patternfly import BreadCrumb, Button + +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixin +from airgun.widgets import ( + EditableEntry, + EditableEntryCheckbox, + ReadOnlyEntry, + SatSelect, + Search, +) class LCEView(BaseLoggedInView, ParametrizedView): diff --git a/airgun/views/location.py b/airgun/views/location.py index 225b930b7..0dc241bbd 100644 --- a/airgun/views/location.py +++ b/airgun/views/location.py @@ -1,17 +1,13 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Checkbox, Table, Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatVerticalTab -from airgun.views.common import SearchableViewMixinPF4 -from airgun.widgets import ActionsDropdown -from airgun.widgets import CustomParameter -from airgun.widgets import FilteredDropdown -from airgun.widgets import MultiSelect +from airgun.views.common import BaseLoggedInView, SatVerticalTab, SearchableViewMixinPF4 +from airgun.widgets import ( + ActionsDropdown, + CustomParameter, + FilteredDropdown, + MultiSelect, +) class LocationsView(BaseLoggedInView, SearchableViewMixinPF4): diff --git a/airgun/views/login.py b/airgun/views/login.py index 1422f6780..3a9a9197b 100644 --- a/airgun/views/login.py +++ b/airgun/views/login.py @@ -1,7 +1,4 @@ -from widgetastic.widget import ClickableMixin -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import ClickableMixin, Text, TextInput, View class LoginView(View, ClickableMixin): diff --git a/airgun/views/media.py b/airgun/views/media.py index f3fcd30e9..b2debdfad 100644 --- a/airgun/views/media.py +++ b/airgun/views/media.py @@ -1,14 +1,8 @@ -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Table, Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixinPF4 -from airgun.widgets import FilteredDropdown -from airgun.widgets import MultiSelect +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixinPF4 +from airgun.widgets import FilteredDropdown, MultiSelect class MediumView(BaseLoggedInView, SearchableViewMixinPF4): diff --git a/airgun/views/modulestream.py b/airgun/views/modulestream.py index 8a1fb4c04..464b827b0 100644 --- a/airgun/views/modulestream.py +++ b/airgun/views/modulestream.py @@ -1,12 +1,12 @@ -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import View +from widgetastic.widget import Table, Text, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SatTable -from airgun.views.common import SearchableViewMixinPF4 +from airgun.views.common import ( + BaseLoggedInView, + SatTab, + SatTable, + SearchableViewMixinPF4, +) from airgun.widgets import SatTableWithUnevenStructure diff --git a/airgun/views/organization.py b/airgun/views/organization.py index 79dc179df..f39bfc4bb 100644 --- a/airgun/views/organization.py +++ b/airgun/views/organization.py @@ -1,17 +1,13 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Checkbox, Table, Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatVerticalTab -from airgun.views.common import SearchableViewMixinPF4 -from airgun.widgets import ActionsDropdown -from airgun.widgets import CustomParameter -from airgun.widgets import FilteredDropdown -from airgun.widgets import MultiSelect +from airgun.views.common import BaseLoggedInView, SatVerticalTab, SearchableViewMixinPF4 +from airgun.widgets import ( + ActionsDropdown, + CustomParameter, + FilteredDropdown, + MultiSelect, +) class OrganizationsView(BaseLoggedInView, SearchableViewMixinPF4): diff --git a/airgun/views/os.py b/airgun/views/os.py index aa6332b5a..c661e9c78 100644 --- a/airgun/views/os.py +++ b/airgun/views/os.py @@ -1,16 +1,13 @@ -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Table, Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixinPF4 -from airgun.widgets import ActionsDropdown -from airgun.widgets import CustomParameter -from airgun.widgets import FilteredDropdown -from airgun.widgets import MultiSelect +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixinPF4 +from airgun.widgets import ( + ActionsDropdown, + CustomParameter, + FilteredDropdown, + MultiSelect, +) class TemplatesList(View): diff --git a/airgun/views/oscapcontent.py b/airgun/views/oscapcontent.py index d609f1f3a..bec6ac088 100644 --- a/airgun/views/oscapcontent.py +++ b/airgun/views/oscapcontent.py @@ -1,15 +1,8 @@ -from widgetastic.widget import FileInput -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import FileInput, Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixinPF4 -from airgun.widgets import ActionsDropdown -from airgun.widgets import MultiSelect -from airgun.widgets import SatTable +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixinPF4 +from airgun.widgets import ActionsDropdown, MultiSelect, SatTable class SCAPContentsView(BaseLoggedInView, SearchableViewMixinPF4): diff --git a/airgun/views/oscappolicy.py b/airgun/views/oscappolicy.py index 199085d2e..4686f2395 100644 --- a/airgun/views/oscappolicy.py +++ b/airgun/views/oscappolicy.py @@ -1,19 +1,15 @@ -from widgetastic.widget import ConditionalSwitchableView -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import ConditionalSwitchableView, Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixin -from airgun.views.dashboard import ItemValueList -from airgun.views.dashboard import TotalCount -from airgun.widgets import ActionsDropdown -from airgun.widgets import FilteredDropdown -from airgun.widgets import MultiSelect -from airgun.widgets import RadioGroup -from airgun.widgets import SatTable +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixin +from airgun.views.dashboard import ItemValueList, TotalCount +from airgun.widgets import ( + ActionsDropdown, + FilteredDropdown, + MultiSelect, + RadioGroup, + SatTable, +) class SCAPPoliciesView(BaseLoggedInView, SearchableViewMixin): diff --git a/airgun/views/oscaptailoringfile.py b/airgun/views/oscaptailoringfile.py index 52789359c..809f07bc2 100644 --- a/airgun/views/oscaptailoringfile.py +++ b/airgun/views/oscaptailoringfile.py @@ -1,15 +1,8 @@ -from widgetastic.widget import FileInput -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import FileInput, Table, Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixin -from airgun.widgets import ActionsDropdown -from airgun.widgets import MultiSelect +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixin +from airgun.widgets import ActionsDropdown, MultiSelect class SCAPTailoringFilesView(BaseLoggedInView, SearchableViewMixin): diff --git a/airgun/views/package.py b/airgun/views/package.py index 9128e265d..2a5e54198 100644 --- a/airgun/views/package.py +++ b/airgun/views/package.py @@ -1,15 +1,8 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import Select -from widgetastic.widget import Text -from widgetastic.widget import View +from widgetastic.widget import Checkbox, Select, Text, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import ReadOnlyEntry -from airgun.views.common import SatTab -from airgun.views.common import SatTable -from airgun.widgets import ItemsListReadOnly -from airgun.widgets import Search +from airgun.views.common import BaseLoggedInView, ReadOnlyEntry, SatTab, SatTable +from airgun.widgets import ItemsListReadOnly, Search class PackagesView(BaseLoggedInView): diff --git a/airgun/views/partitiontable.py b/airgun/views/partitiontable.py index b753e37b9..f5c84eda0 100644 --- a/airgun/views/partitiontable.py +++ b/airgun/views/partitiontable.py @@ -1,25 +1,29 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import ConditionalSwitchableView -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View -from widgetastic_patternfly import BreadCrumb -from widgetastic_patternfly import Button - -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixinPF4 -from airgun.views.common import TemplateInputItem -from airgun.widgets import ACEEditor -from airgun.widgets import ActionsDropdown -from airgun.widgets import FilteredDropdown -from airgun.widgets import MultiSelect -from airgun.widgets import RemovableWidgetsItemsListView +from widgetastic.widget import ( + Checkbox, + ConditionalSwitchableView, + Table, + Text, + TextInput, + View, +) +from widgetastic_patternfly import BreadCrumb, Button + +from airgun.views.common import ( + BaseLoggedInView, + SatTab, + SearchableViewMixinPF4, + TemplateInputItem, +) +from airgun.widgets import ( + ACEEditor, + ActionsDropdown, + FilteredDropdown, + MultiSelect, + RemovableWidgetsItemsListView, +) class PartitionTablesView(BaseLoggedInView, SearchableViewMixinPF4): - title = Text("//h1[text()='Partition Tables']") new = Button("Create Partition Table") table = Table( diff --git a/airgun/views/product.py b/airgun/views/product.py index fe03ddcd0..0eb2dc861 100644 --- a/airgun/views/product.py +++ b/airgun/views/product.py @@ -1,26 +1,32 @@ from wait_for import wait_for -from widgetastic.widget import Checkbox -from widgetastic.widget import ConditionalSwitchableView -from widgetastic.widget import Select -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import ( + Checkbox, + ConditionalSwitchableView, + Select, + Table, + Text, + TextInput, + View, +) from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixin -from airgun.views.common import TaskDetailsView +from airgun.views.common import ( + BaseLoggedInView, + SatTab, + SearchableViewMixin, + TaskDetailsView, +) from airgun.views.syncplan import SyncPlanCreateView -from airgun.widgets import ActionsDropdown -from airgun.widgets import ConfirmationDialog -from airgun.widgets import EditableEntry -from airgun.widgets import EditableEntrySelect -from airgun.widgets import ReadOnlyEntry -from airgun.widgets import SatSelect -from airgun.widgets import SatTable -from airgun.widgets import Search +from airgun.widgets import ( + ActionsDropdown, + ConfirmationDialog, + EditableEntry, + EditableEntrySelect, + ReadOnlyEntry, + SatSelect, + SatTable, + Search, +) class CreateDiscoveredReposView(View): @@ -38,7 +44,7 @@ class CreateDiscoveredReposView(View): def fill(self, values): """Select necessary repo/repos to be added to new or existing product""" if not isinstance(values, list): - values = list((values,)) + values = [values] for value in values: self.table.row(discovered_repository__contains=value)[0].fill(True) self.create_action.click() @@ -94,6 +100,7 @@ def is_displayed(self): class ProductEditView(BaseLoggedInView): breadcrumb = BreadCrumb() + BREADCRUMB_LENGTH = 3 actions = ActionsDropdown("//div[contains(@class, 'btn-group')]") dialog = ConfirmationDialog() @@ -104,7 +111,7 @@ def is_displayed(self): breadcrumb_loaded and self.breadcrumb.locations[0] == 'Products' and self.breadcrumb.read() not in ('New Product', 'Discover Repositories') - and len(self.breadcrumb.locations) <= 3 + and len(self.breadcrumb.locations) <= self.BREADCRUMB_LENGTH ) @View.nested @@ -216,6 +223,8 @@ def wait_repo_created(self): class ProductTaskDetailsView(TaskDetailsView): + BREADCRUMB_LENGTH = 3 + @property def is_displayed(self): breadcrumb_loaded = self.browser.wait_for_element(self.breadcrumb, exception=False) @@ -223,7 +232,7 @@ def is_displayed(self): breadcrumb_loaded and self.breadcrumb.locations[0] == 'Products' and self.breadcrumb.locations[2] == 'Tasks' - and len(self.breadcrumb.locations) > 3 + and len(self.breadcrumb.locations) > self.BREADCRUMB_LENGTH ) diff --git a/airgun/views/provisioning_template.py b/airgun/views/provisioning_template.py index 0dc159fa5..51f2ec3e8 100644 --- a/airgun/views/provisioning_template.py +++ b/airgun/views/provisioning_template.py @@ -1,22 +1,20 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import Select -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View -from widgetastic_patternfly import BreadCrumb -from widgetastic_patternfly import Button - -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixinPF4 -from airgun.views.common import TemplateEditor -from airgun.views.common import TemplateInputItem -from airgun.widgets import ActionsDropdown -from airgun.widgets import FilteredDropdown -from airgun.widgets import GenericRemovableWidgetItem -from airgun.widgets import MultiSelect -from airgun.widgets import RemovableWidgetsItemsListView +from widgetastic.widget import Checkbox, Select, Table, Text, TextInput, View +from widgetastic_patternfly import BreadCrumb, Button + +from airgun.views.common import ( + BaseLoggedInView, + SatTab, + SearchableViewMixinPF4, + TemplateEditor, + TemplateInputItem, +) +from airgun.widgets import ( + ActionsDropdown, + FilteredDropdown, + GenericRemovableWidgetItem, + MultiSelect, + RemovableWidgetsItemsListView, +) class TemplateHostEnvironmentAssociation(GenericRemovableWidgetItem): diff --git a/airgun/views/puppet_class.py b/airgun/views/puppet_class.py index 45d560393..63191b30e 100644 --- a/airgun/views/puppet_class.py +++ b/airgun/views/puppet_class.py @@ -1,16 +1,9 @@ -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixin +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixin from airgun.views.smart_class_parameter import SmartClassParameterContent -from airgun.widgets import FilteredDropdown -from airgun.widgets import ItemsList -from airgun.widgets import MultiSelect -from airgun.widgets import SatTable +from airgun.widgets import FilteredDropdown, ItemsList, MultiSelect, SatTable class PuppetClassesView(BaseLoggedInView, SearchableViewMixin): diff --git a/airgun/views/puppet_environment.py b/airgun/views/puppet_environment.py index a9784be18..00e674f3e 100644 --- a/airgun/views/puppet_environment.py +++ b/airgun/views/puppet_environment.py @@ -1,14 +1,8 @@ -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SatTable -from airgun.views.common import SearchableViewMixin -from airgun.widgets import ActionsDropdown -from airgun.widgets import MultiSelect +from airgun.views.common import BaseLoggedInView, SatTab, SatTable, SearchableViewMixin +from airgun.widgets import ActionsDropdown, MultiSelect class PuppetEnvironmentTableView(BaseLoggedInView, SearchableViewMixin): diff --git a/airgun/views/redhat_repository.py b/airgun/views/redhat_repository.py index cfaef4835..2a96b04ba 100644 --- a/airgun/views/redhat_repository.py +++ b/airgun/views/redhat_repository.py @@ -1,8 +1,5 @@ from wait_for import wait_for -from widgetastic.widget import GenericLocatorWidget -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import GenericLocatorWidget, Text, TextInput, View from airgun.views.common import BaseLoggedInView from airgun.widgets import ( @@ -96,7 +93,7 @@ def read_items(self): def read(self): """Return the name and label of this repository.""" - return dict(name=self.name, label=self.label) + return {"name": self.name, "label": self.label} def enable(self, item): """Enable a repository of this repository set. @@ -253,7 +250,7 @@ def search(self, value, category='Available', types=None): elif category == 'Enabled': return self.enabled.read() else: - return dict(available=self.available.read(), enabled=self.enabled.read()) + return {"available": self.available.read(), "enabled": self.enabled.read()} @property def is_displayed(self): diff --git a/airgun/views/report_template.py b/airgun/views/report_template.py index edd783723..9d7fcad57 100644 --- a/airgun/views/report_template.py +++ b/airgun/views/report_template.py @@ -1,21 +1,20 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View -from widgetastic_patternfly import BreadCrumb -from widgetastic_patternfly import Button - -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixinPF4 -from airgun.views.common import TemplateEditor -from airgun.views.common import TemplateInputItem -from airgun.widgets import ActionsDropdown -from airgun.widgets import FilteredDropdown -from airgun.widgets import MultiSelect -from airgun.widgets import RemovableWidgetsItemsListView -from airgun.widgets import TextInputsGroup +from widgetastic.widget import Checkbox, Table, Text, TextInput, View +from widgetastic_patternfly import BreadCrumb, Button + +from airgun.views.common import ( + BaseLoggedInView, + SatTab, + SearchableViewMixinPF4, + TemplateEditor, + TemplateInputItem, +) +from airgun.widgets import ( + ActionsDropdown, + FilteredDropdown, + MultiSelect, + RemovableWidgetsItemsListView, + TextInputsGroup, +) class ReportTemplatesView(BaseLoggedInView, SearchableViewMixinPF4): diff --git a/airgun/views/repository.py b/airgun/views/repository.py index a23f25313..3c82c85a9 100644 --- a/airgun/views/repository.py +++ b/airgun/views/repository.py @@ -1,22 +1,25 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import ConditionalSwitchableView -from widgetastic.widget import FileInput -from widgetastic.widget import Select -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import ( + Checkbox, + ConditionalSwitchableView, + FileInput, + Select, + Text, + TextInput, + View, +) from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SearchableViewMixin -from airgun.widgets import ActionsDropdown -from airgun.widgets import ConfirmationDialog -from airgun.widgets import EditableEntry -from airgun.widgets import EditableEntryCheckbox -from airgun.widgets import EditableEntrySelect -from airgun.widgets import ReadOnlyEntry -from airgun.widgets import SatTable -from airgun.widgets import SatTableWithUnevenStructure +from airgun.views.common import BaseLoggedInView, SearchableViewMixin +from airgun.widgets import ( + ActionsDropdown, + ConfirmationDialog, + EditableEntry, + EditableEntryCheckbox, + EditableEntrySelect, + ReadOnlyEntry, + SatTable, + SatTableWithUnevenStructure, +) class RepositoriesView(BaseLoggedInView, SearchableViewMixin): @@ -167,7 +170,6 @@ def is_displayed(self): class AuthorizationEntry(EditableEntry): - clear_button = Text(".//span[contains(@ng-hide, 'editMode')]/i[@ng-show='deletable']") @View.nested diff --git a/airgun/views/rhai.py b/airgun/views/rhai.py index 2ad0188a7..b78d2a2bf 100644 --- a/airgun/views/rhai.py +++ b/airgun/views/rhai.py @@ -1,17 +1,14 @@ from widgetastic.utils import ParametrizedLocator -from widgetastic.widget import Checkbox -from widgetastic.widget import ParametrizedView -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Checkbox, ParametrizedView, Table, Text, TextInput, View from widgetastic_patternfly import Button from airgun.views.common import BaseLoggedInView -from airgun.widgets import ActionsDropdown -from airgun.widgets import GenericRemovableWidgetItem -from airgun.widgets import RemovableWidgetsItemsListView -from airgun.widgets import SatTable +from airgun.widgets import ( + ActionsDropdown, + GenericRemovableWidgetItem, + RemovableWidgetsItemsListView, + SatTable, +) class InsightsOrganizationErrorView(BaseLoggedInView): diff --git a/airgun/views/rhsso_login.py b/airgun/views/rhsso_login.py index be1fbb67a..5a82bf49f 100644 --- a/airgun/views/rhsso_login.py +++ b/airgun/views/rhsso_login.py @@ -1,7 +1,4 @@ -from widgetastic.widget import ClickableMixin -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import ClickableMixin, Text, TextInput, View class RhssoLoginView(View, ClickableMixin): diff --git a/airgun/views/role.py b/airgun/views/role.py index 8b1a3a3d9..15f7295c8 100644 --- a/airgun/views/role.py +++ b/airgun/views/role.py @@ -1,12 +1,8 @@ -from widgetastic.widget import Text -from widgetastic.widget import TextInput +from widgetastic.widget import Text, TextInput from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SearchableViewMixinPF4 -from airgun.widgets import ActionsDropdown -from airgun.widgets import MultiSelect -from airgun.widgets import SatTable +from airgun.views.common import BaseLoggedInView, SearchableViewMixinPF4 +from airgun.widgets import ActionsDropdown, MultiSelect, SatTable class RolesView(BaseLoggedInView, SearchableViewMixinPF4): diff --git a/airgun/views/settings.py b/airgun/views/settings.py index e44c63897..f87592e74 100644 --- a/airgun/views/settings.py +++ b/airgun/views/settings.py @@ -1,11 +1,8 @@ from wait_for import wait_for -from widgetastic.widget import Table -from widgetastic.widget import Text +from widgetastic.widget import Table, Text from widgetastic_patternfly import Button -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixinPF4 +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixinPF4 from airgun.widgets import PopOverWidget diff --git a/airgun/views/smart_class_parameter.py b/airgun/views/smart_class_parameter.py index 71aa66f57..2ad669e86 100644 --- a/airgun/views/smart_class_parameter.py +++ b/airgun/views/smart_class_parameter.py @@ -1,15 +1,15 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import ParametrizedLocator -from widgetastic.widget import Select -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import ( + Checkbox, + ParametrizedLocator, + Select, + Text, + TextInput, + View, +) from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SearchableViewMixin -from airgun.widgets import SatTable -from airgun.widgets import TextInputHidden +from airgun.views.common import BaseLoggedInView, SearchableViewMixin +from airgun.widgets import SatTable, TextInputHidden class MatcherAttribute(View): @@ -64,9 +64,7 @@ class matchers(View): column_widgets={ 'Attribute type': MatcherAttribute(), 'Value': TextInputHidden(locator=".//textarea[contains(@id, 'value')]"), - 'Omit': Checkbox( - locator=".//input[contains(@name, '[omit]') and @type!='hidden']" - ), + 'Omit': Checkbox(locator=".//input[contains(@name, '[omit]') and @type!='hidden']"), }, ) add_new_matcher = Text( @@ -120,6 +118,7 @@ def is_displayed(self): class SmartClassParameterEditView(BaseLoggedInView): breadcrumb = BreadCrumb() + BREADCRUMB_LENGTH = 2 parameter = SmartClassParameterContent(locator="//div[@class='tab-pane fields']") submit = Text('//input[@name="commit"]') @@ -129,5 +128,5 @@ def is_displayed(self): return ( breadcrumb_loaded and self.breadcrumb.locations[0] == 'Smart Class Parameters' - and len(self.breadcrumb.locations) == 2 + and len(self.breadcrumb.locations) == self.BREADCRUMB_LENGTH ) diff --git a/airgun/views/subnet.py b/airgun/views/subnet.py index 3f897a9e4..aa104ba5d 100644 --- a/airgun/views/subnet.py +++ b/airgun/views/subnet.py @@ -1,16 +1,8 @@ -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Table, Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixin -from airgun.widgets import CustomParameter -from airgun.widgets import FilteredDropdown -from airgun.widgets import MultiSelect -from airgun.widgets import RadioGroup +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixin +from airgun.widgets import CustomParameter, FilteredDropdown, MultiSelect, RadioGroup class SubnetsView(BaseLoggedInView, SearchableViewMixin): diff --git a/airgun/views/subscription.py b/airgun/views/subscription.py index 0341fe0b2..ec0b23b27 100644 --- a/airgun/views/subscription.py +++ b/airgun/views/subscription.py @@ -1,22 +1,23 @@ from wait_for import wait_for -from widgetastic.widget import Checkbox -from widgetastic.widget import FileInput -from widgetastic.widget import GenericLocatorWidget -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View -from widgetastic_patternfly import BreadCrumb -from widgetastic_patternfly import Button +from widgetastic.widget import ( + Checkbox, + FileInput, + GenericLocatorWidget, + Text, + TextInput, + View, +) +from widgetastic_patternfly import BreadCrumb, Button from airgun.exceptions import ReadOnlyWidgetError -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixin -from airgun.widgets import ConfirmationDialog -from airgun.widgets import ItemsListReadOnly -from airgun.widgets import ProgressBar -from airgun.widgets import SatTable -from airgun.widgets import Search +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixin +from airgun.widgets import ( + ConfirmationDialog, + ItemsListReadOnly, + ProgressBar, + SatTable, + Search, +) # Search field and button on Subscriptions page uses different locators, @@ -231,7 +232,6 @@ class SubscriptionDetailsView(BaseLoggedInView): @View.nested class details(SatTab): - associations = SatTable( locator=".//div[h2[normalize-space(.)='Associations']]/table", column_widgets={ diff --git a/airgun/views/sync_status.py b/airgun/views/sync_status.py index aca71fb92..8fa566d0c 100644 --- a/airgun/views/sync_status.py +++ b/airgun/views/sync_status.py @@ -1,7 +1,6 @@ from cached_property import cached_property from widgetastic.exceptions import NoSuchElementException -from widgetastic.widget import Checkbox -from widgetastic.widget import Text +from widgetastic.widget import Checkbox, Text from airgun.views.common import BaseLoggedInView from airgun.widgets import SatTable diff --git a/airgun/views/sync_templates.py b/airgun/views/sync_templates.py index 3b61f52f4..ef83842f8 100644 --- a/airgun/views/sync_templates.py +++ b/airgun/views/sync_templates.py @@ -1,10 +1,12 @@ from wait_for import wait_for -from widgetastic.widget import Checkbox -from widgetastic.widget import ConditionalSwitchableView -from widgetastic.widget import Select -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import ( + Checkbox, + ConditionalSwitchableView, + Select, + Text, + TextInput, + View, +) from widgetastic_patternfly import BreadCrumb from airgun.views.common import BaseLoggedInView @@ -54,7 +56,6 @@ class ExportTemplates(View): class TemplatesReportView(BaseLoggedInView): - title = Text("//h1") REPORTS = "//div[contains(@class, 'list-group-item')]" diff --git a/airgun/views/syncplan.py b/airgun/views/syncplan.py index 4c7292a47..c1837e784 100644 --- a/airgun/views/syncplan.py +++ b/airgun/views/syncplan.py @@ -1,22 +1,22 @@ -from widgetastic.widget import Select -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Select, Table, Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import AddRemoveResourcesView -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixin -from airgun.widgets import ActionsDropdown -from airgun.widgets import ConfirmationDialog -from airgun.widgets import DateTime -from airgun.widgets import EditableDateTime -from airgun.widgets import EditableEntry -from airgun.widgets import EditableEntryCheckbox -from airgun.widgets import EditableEntrySelect -from airgun.widgets import ReadOnlyEntry +from airgun.views.common import ( + AddRemoveResourcesView, + BaseLoggedInView, + SatTab, + SearchableViewMixin, +) +from airgun.widgets import ( + ActionsDropdown, + ConfirmationDialog, + DateTime, + EditableDateTime, + EditableEntry, + EditableEntryCheckbox, + EditableEntrySelect, + ReadOnlyEntry, +) class SyncPlansView(BaseLoggedInView, SearchableViewMixin): diff --git a/airgun/views/task.py b/airgun/views/task.py index 69b1252dc..25bd7be15 100644 --- a/airgun/views/task.py +++ b/airgun/views/task.py @@ -1,18 +1,16 @@ from wait_for import wait_for -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import View +from widgetastic.widget import Table, Text, View from widgetastic_patternfly import BreadCrumb from widgetastic_patternfly4 import Pagination -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixinPF4 -from airgun.widgets import ActionsDropdown -from airgun.widgets import PieChart -from airgun.widgets import ProgressBar -from airgun.widgets import ReadOnlyEntry -from airgun.widgets import SatTable +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixinPF4 +from airgun.widgets import ( + ActionsDropdown, + PieChart, + ProgressBar, + ReadOnlyEntry, + SatTable, +) class TaskReadOnlyEntry(ReadOnlyEntry): @@ -23,7 +21,7 @@ class TaskReadOnlyEntry(ReadOnlyEntry): class TaskReadOnlyEntryError(ReadOnlyEntry): - BASE_LOCATOR = "//span[contains(., '{}')]//parent::div" "/following-sibling::pre" + BASE_LOCATOR = "//span[contains(., '{}')]//parent::div/following-sibling::pre" class TasksView(BaseLoggedInView, SearchableViewMixinPF4): @@ -73,6 +71,7 @@ class ScheduledChart(View): class TaskDetailsView(BaseLoggedInView): breadcrumb = BreadCrumb() + BREADCRUMB_LENGTH = 2 @property def is_displayed(self): @@ -80,7 +79,7 @@ def is_displayed(self): return ( breadcrumb_loaded and self.breadcrumb.locations[0] == 'Tasks' - and len(self.breadcrumb.locations) == 2 + and len(self.breadcrumb.locations) == self.BREADCRUMB_LENGTH ) @View.nested diff --git a/airgun/views/user.py b/airgun/views/user.py index 34dc6334b..58f36a340 100644 --- a/airgun/views/user.py +++ b/airgun/views/user.py @@ -1,15 +1,8 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Checkbox, Table, Text, TextInput, View from widgetastic_patternfly import BreadCrumb -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixinPF4 -from airgun.widgets import FilteredDropdown -from airgun.widgets import MultiSelect +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixinPF4 +from airgun.widgets import FilteredDropdown, MultiSelect class UsersView(BaseLoggedInView, SearchableViewMixinPF4): diff --git a/airgun/views/usergroup.py b/airgun/views/usergroup.py index 8a77327bb..3e7f973a1 100644 --- a/airgun/views/usergroup.py +++ b/airgun/views/usergroup.py @@ -1,16 +1,9 @@ -from widgetastic.widget import Checkbox -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Checkbox, Table, Text, TextInput, View from widgetastic_patternfly import BreadCrumb from widgetastic_patternfly4 import Button as P4Button -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixinPF4 -from airgun.widgets import FilteredDropdown -from airgun.widgets import MultiSelect +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixinPF4 +from airgun.widgets import FilteredDropdown, MultiSelect class UserGroupsView(BaseLoggedInView, SearchableViewMixinPF4): diff --git a/airgun/views/virtwho_configure.py b/airgun/views/virtwho_configure.py index a386a0b7c..5e724af34 100644 --- a/airgun/views/virtwho_configure.py +++ b/airgun/views/virtwho_configure.py @@ -1,20 +1,19 @@ from widgetastic.exceptions import NoSuchElementException -from widgetastic.widget import Checkbox -from widgetastic.widget import ConditionalSwitchableView -from widgetastic.widget import GenericLocatorWidget -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View -from widgetastic.widget import Widget +from widgetastic.widget import ( + Checkbox, + ConditionalSwitchableView, + GenericLocatorWidget, + Table, + Text, + TextInput, + View, + Widget, +) from widgetastic_patternfly import BreadCrumb from airgun.exceptions import ReadOnlyWidgetError -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SatTab -from airgun.views.common import SearchableViewMixin -from airgun.widgets import ActionsDropdown -from airgun.widgets import FilteredDropdown +from airgun.views.common import BaseLoggedInView, SatTab, SearchableViewMixin +from airgun.widgets import ActionsDropdown, FilteredDropdown class VirtwhoConfigureStatus(GenericLocatorWidget): @@ -230,15 +229,11 @@ class overview(SatTab): kubeconfig_path = Text('.//span[contains(@class,"config-kubeconfig_path")]') prism_flavor = Text('.//span[contains(@class,"config-prism_flavor")]') - _label_locator = ( - "//span[contains(@class, '{class_name}')]/../preceding-sibling::div/strong" - ) + _label_locator = "//span[contains(@class, '{class_name}')]/../preceding-sibling::div/strong" status_label = Text(_label_locator.format(class_name="config-status")) debug_label = Text(_label_locator.format(class_name="config-debug")) hypervisor_type_label = Text(_label_locator.format(class_name="config-hypervisor_type")) - hypervisor_server_label = Text( - _label_locator.format(class_name="config-hypervisor_server") - ) + hypervisor_server_label = Text(_label_locator.format(class_name="config-hypervisor_server")) hypervisor_username_label = Text( _label_locator.format(class_name="config-hypervisor_username") ) diff --git a/airgun/views/webhook.py b/airgun/views/webhook.py index 98a7dfb2f..e685daa7b 100644 --- a/airgun/views/webhook.py +++ b/airgun/views/webhook.py @@ -1,16 +1,10 @@ from wait_for import wait_for -from widgetastic.widget import Checkbox -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View +from widgetastic.widget import Checkbox, Text, TextInput, View from widgetastic_patternfly import Button -from widgetastic_patternfly4 import Button as PF4Button -from widgetastic_patternfly4 import Tab +from widgetastic_patternfly4 import Button as PF4Button, Tab -from airgun.views.common import BaseLoggedInView -from airgun.views.common import SearchableViewMixinPF4 -from airgun.widgets import AutoCompleteTextInput -from airgun.widgets import SatTable +from airgun.views.common import BaseLoggedInView, SearchableViewMixinPF4 +from airgun.widgets import AutoCompleteTextInput, SatTable class WebhooksView(BaseLoggedInView, SearchableViewMixinPF4): diff --git a/airgun/widgets.py b/airgun/widgets.py index eaa4c9083..fc828e14f 100644 --- a/airgun/widgets.py +++ b/airgun/widgets.py @@ -1,32 +1,36 @@ from cached_property import cached_property from wait_for import wait_for -from widgetastic.exceptions import NoSuchElementException -from widgetastic.exceptions import WidgetOperationFailed -from widgetastic.widget import Checkbox -from widgetastic.widget import ClickableMixin -from widgetastic.widget import do_not_read_this_widget -from widgetastic.widget import GenericLocatorWidget -from widgetastic.widget import ParametrizedLocator -from widgetastic.widget import Select -from widgetastic.widget import Table -from widgetastic.widget import Text -from widgetastic.widget import TextInput -from widgetastic.widget import View -from widgetastic.widget import Widget +from widgetastic.exceptions import NoSuchElementException, WidgetOperationFailed +from widgetastic.widget import ( + Checkbox, + ClickableMixin, + GenericLocatorWidget, + ParametrizedLocator, + Select, + Table, + Text, + TextInput, + View, + Widget, + do_not_read_this_widget, +) from widgetastic.xpath import quote -from widgetastic_patternfly import AggregateStatusCard -from widgetastic_patternfly import Button -from widgetastic_patternfly import FlashMessage -from widgetastic_patternfly import FlashMessages -from widgetastic_patternfly import Kebab -from widgetastic_patternfly import VerticalNavigation -from widgetastic_patternfly4.ouia import BaseSelect -from widgetastic_patternfly4.ouia import Button as PF4Button -from widgetastic_patternfly4.ouia import ContextSelector as OUIAContextSelector -from widgetastic_patternfly4.ouia import Dropdown - -from airgun.exceptions import DisabledWidgetError -from airgun.exceptions import ReadOnlyWidgetError +from widgetastic_patternfly import ( + AggregateStatusCard, + Button, + FlashMessage, + FlashMessages, + Kebab, + VerticalNavigation, +) +from widgetastic_patternfly4.ouia import ( + BaseSelect, + Button as PF4Button, + ContextSelector as OUIAContextSelector, + Dropdown, +) + +from airgun.exceptions import DisabledWidgetError, ReadOnlyWidgetError from airgun.utils import get_widget_by_name @@ -99,8 +103,8 @@ def _get_parent_label(self, name): return next( btn for btn in self.browser.elements(self.LABELS) if self.browser.text(btn) == name ) - except StopIteration: - raise NoSuchElementException(f"RadioButton {name} is absent on page") + except StopIteration as err: + raise NoSuchElementException(f"RadioButton {name} is absent on page") from err @property def selected(self): @@ -109,11 +113,10 @@ def selected(self): btn = self.browser.element(self.BUTTON, parent=self._get_parent_label(name)) if btn.get_attribute('checked') is not None: return name - else: - raise ValueError( - "Whether no radio button is selected or proper attribute " - "should be added to framework" - ) + raise ValueError( + "Whether no radio button is selected or proper attribute " + "should be added to framework" + ) def select(self, name): """Select specific radio button in the group""" @@ -161,11 +164,10 @@ def selected(self): btn = self.browser.element(self._get_parent_label(name)) if 'active' in btn.get_attribute('class'): return name - else: - raise ValueError( - "Whether no radio button is selected or proper attribute " - "should be added to framework" - ) + raise ValueError( + "Whether no radio button is selected or proper attribute " + "should be added to framework" + ) def select(self, name): """Select specific radio button in the group""" @@ -1059,7 +1061,7 @@ def __init__(self, parent, **kwargs): "or @title='Remove Parameter']" ), } - self.name = list(self.column_widgets.keys())[0] + self.name = next(iter(self.column_widgets.keys())) self.name_key = '_'.join(self.name.lower().split(' ')) self.value = list(self.column_widgets.keys())[1] self.value_key = '_'.join(self.value.lower().split(' ')) @@ -1115,8 +1117,8 @@ def fill(self, values): try: names_to_fill = [param[self.name_key] for param in params_to_fill] - except KeyError: - raise KeyError("parameter value is missing 'name' key") + except KeyError as err: + raise KeyError("parameter value is missing 'name' key") from err # Check if duplicate names were passed in and skip incase list if names_to_fill and not isinstance(names_to_fill[0], dict): if len(set(names_to_fill)) < len(names_to_fill): @@ -1273,7 +1275,7 @@ def fill(self, value): :param value: dictionary that consist of single checkbox name and value that should be assigned to that checkbox """ - checkbox_name = list(value.keys())[0] + checkbox_name = next(iter(value.keys())) checkbox_value = value[checkbox_name] checkbox_locator = self.CHECKBOX.format(checkbox_name) return self.select(checkbox_locator, checkbox_value) @@ -1340,7 +1342,7 @@ class TextInputHidden(TextInput): def read(self): value = super().read() hidden = 'masked-input' in self.browser.classes(self) - return dict(value=value, hidden=hidden) + return {'value': value, 'hidden': hidden} class EditableEntry(GenericLocatorWidget): @@ -1572,9 +1574,7 @@ def fill(self, value): :param value: string with value that should be used for field update procedure """ - self.browser.execute_script( - f"ace.edit('{self.ace_edit_id}').setValue(arguments[0])", value - ) + self.browser.execute_script(f"ace.edit('{self.ace_edit_id}').setValue(arguments[0])", value) def read(self): """Returns string with current widget value""" @@ -1763,7 +1763,7 @@ def _read_all(self): # ensure that we are at the right page (to not read the same page twice) and # to escape any ui bug that will cause hanging on this loop. wait_for( - lambda: self.pagination.current_page == page_number, + lambda page_number=page_number: self.pagination.current_page == page_number, timeout=30, delay=1, logger=self.logger, @@ -2413,7 +2413,7 @@ def item_select(self, items, close=True): items: Items to be selected close: Close the dropdown when finished """ - if not isinstance(items, (list, tuple, set)): + if not isinstance(items, list | tuple | set): items = [items] if isinstance(items, str): items = items.split(',') diff --git a/pyproject.toml b/pyproject.toml index a61a7db4a..34f7e4b00 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,17 +1,122 @@ +[tool.pytest.ini_options] +testpaths = ["tests"] +addopts = ["-v", "-l", "--color=yes", "--code-highlight=yes"] + [tool.black] -line-length = 99 +line-length = 100 skip-string-normalization = true +target-version = ["py310", "py311"] include = '\.pyi?$' exclude = ''' /( \.git - | \.hg - | \.mypy_cache - | \.tox | \.venv - | _build - | buck-out | build | dist + | tests/data )/ ''' + +[tool.ruff] +target-version = "py311" +fixable = ["ALL"] + +select = [ + "B002", # Python does not support the unary prefix increment + "B007", # Loop control variable {name} not used within loop body + "B009", # Do not call getattr with a constant attribute value + "B010", # Do not call setattr with a constant attribute value + "B011", # Do not `assert False`, raise `AssertionError` instead + "B013", # Redundant tuple in exception handler + "B014", # Exception handler with duplicate exception + "B023", # Function definition does not bind loop variable {name} + "B026", # Star-arg unpacking after a keyword argument is strongly discouraged + "BLE001", # Using bare except clauses is prohibited + "C", # complexity + "C4", # flake8-comprehensions + "COM818", # Trailing comma on bare tuple prohibited + # "D", # docstrings + "E", # pycodestyle + "F", # pyflakes/autoflake + "G", # flake8-logging-format + "I", # isort + "ISC001", # Implicitly concatenated string literals on one line + "N804", # First argument of a class method should be named cls + "N805", # First argument of a method should be named self + "N999", # Invalid module name: '{name}' + "PERF", # Perflint rules + "PGH004", # Use specific rule codes when using noqa + "PLC0414", # Useless import alias. Import alias does not rename original package. + "PLC", # pylint + "PLE", # pylint + "PLR", # pylint + "PLW", # pylint + "RUF", # Ruff-specific rules + "S103", # bad-file-permissions + "S108", # hardcoded-temp-file + "S110", # try-except-pass + "S112", # try-except-continue + "S306", # suspicious-mktemp-usage + "S307", # suspicious-eval-usage + "S601", # paramiko-call + "S602", # subprocess-popen-with-shell-equals-true + "S604", # call-with-shell-equals-true + "S609", # unix-command-wildcard-injection + "SIM105", # Use contextlib.suppress({exception}) instead of try-except-pass + "SIM117", # Merge with-statements that use the same scope + "SIM118", # Use {key} in {dict} instead of {key} in {dict}.keys() + "SIM201", # Use {left} != {right} instead of not {left} == {right} + "SIM208", # Use {expr} instead of not (not {expr}) + "SIM212", # Use {a} if {a} else {b} instead of {b} if not {a} else {a} + "SIM300", # Yoda conditions. Use 'age == 42' instead of '42 == age'. + "SIM401", # Use get from dict with default instead of an if block + "T100", # Trace found: {name} used + "T20", # flake8-print + "TRY004", # Prefer TypeError exception for invalid type + "TRY200", # Use raise from to specify exception cause + "TRY302", # Remove exception handler; error is immediately re-raised + "PLR0911", # Too many return statements ({returns} > {max_returns}) + "PLR2004", # Magic value used in comparison, consider replacing {value} with a constant variable + "PLW2901", # Outer {outer_kind} variable {name} overwritten by inner {inner_kind} target + "UP", # pyupgrade + "W", # pycodestyle +] + +ignore = [ + "ANN", # flake8-annotations + "D203", # 1 blank line required before class docstring + "D213", # Multi-line docstring summary should start at the second line + "D406", # Section name should end with a newline + "D407", # Section name underlining + "E501", # line too long + "E731", # do not assign a lambda expression, use a def + "G004", # Logging statement uses string formatting + "PGH001", # No builtin eval() allowed + "PLR0912", # Too many branches ({branches} > {max_branches}) + "PLR0913", # Too many arguments to function call ({c_args} > {max_args}) + "PLR0915", # Too many statements ({statements} > {max_statements}) + "PLW0603", # Using the global statement + "RUF012", # Mutable class attributes should be annotated with typing.ClassVar + "D107", # Missing docstring in __init__ +] + +[tool.ruff.per-file-ignores] +# Allow pprint for docs formatting +"docs/create_*.py" = ["T203"] + +[tool.ruff.flake8-pytest-style] +fixture-parentheses = false + +[tool.ruff.isort] +force-sort-within-sections = true +known-first-party = [ + "broker", +] +combine-as-imports = true + +[tool.ruff.mccabe] +max-complexity = 25 + +[tool.coverage.run] +omit = ["tests/*"] +include = ["nailgun/*.py"] diff --git a/requirements-optional.txt b/requirements-optional.txt index 5638af3e1..7cb6f69cf 100644 --- a/requirements-optional.txt +++ b/requirements-optional.txt @@ -1,5 +1,8 @@ -flake8 pre-commit sphinx sphinx-autoapi sphinxcontrib-spelling + +# For linting +ruff + diff --git a/setup.py b/setup.py index 77723e483..444430eff 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,5 @@ #!/usr/bin/env python -from setuptools import find_packages -from setuptools import setup +from setuptools import find_packages, setup with open('README.rst') as f: README = f.read() diff --git a/tests/conftest.py b/tests/conftest.py index d49bf6341..6cb70ea55 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,5 @@ from airgun import settings - pytest_plugins = ["airgun.fixtures"]