class advanced_options(View): expander = Text(".//a[text()='Display advanced fields']") effective_user = TextInput( locator=".//input[contains(@name, '[effective_user]')]") description = TextInput( locator=".//input[contains(@name, '[description]')]") use_default = Checkbox(id="description_format_override") description_content = ConditionalSwitchableView( reference='use_default') @description_content.register(False) class DescriptionTemplateForm(View): description_template = TextInput( id='job_invocation_description_format') timeout = TextInput( locator=".//input[contains(@name, '[execution_timeout_interval]')]" ) password = TextInput(id='job_invocation_password') passphrase = TextInput(id='job_invocation_key_passphrase') sudo_password = TextInput(id='job_invocation_sudo_password') concurrency_level = TextInput(id='job_invocation_concurrency_level') time_span = TextInput(id='job_invocation_time_span') query_type = RadioGroup( locator="//div[label[contains(., 'Type of query')]]") def __init__(self, parent, logger=None): """Expand advanced options section once we get to run job page. That is need to be able to read or change values there """ View.__init__(self, parent, logger=logger) if self.expander.is_displayed: self.expander.click() self.browser.wait_for_element(self.effective_user, visible=True, exception=False)
class VMwareResourceForm(View): cpus = TextInput(id='compute_attribute_vm_attrs_cpus') cores_per_socket = TextInput(id='compute_attribute_vm_attrs_corespersocket') memory = TextInput(id='compute_attribute_vm_attrs_memory_mb') firmware = RadioGroup( "//div[label[input[contains(@id, 'compute_attribute_vm_attrs_firmware')]]]") cluster = FilteredDropdown(id='s2id_compute_attribute_vm_attrs_cluster') 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') 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') annotation_notes = TextInput(id='compute_attribute_vm_attrs_annotation') image = FilteredDropdown(id='s2id_compute_attribute_vm_attrs_image_id') @View.nested class network_interfaces(RemovableWidgetsItemsListView): ROOT = "//fieldset[@id='network_interfaces']" ITEM_WIDGET_CLASS = ComputeResourceVMwareProfileNetworkItem @View.nested class storage(RemovableWidgetsItemsListView): ROOT = "//div[@id='scsi_controllers']" ITEMS = ".//div[@class='controller-container']" ITEM_WIDGET_CLASS = ComputeResourceVMwareProfileStorageItem add_item_button = Text(".//button[contains(@class, 'add-controller')]")
class operating_system(SatTab): TAB_NAME = 'Operating System' architecture = FilteredDropdown(id='hostgroup_architecture') operating_system = FilteredDropdown(id='hostgroup_operatingsystem') media_type = RadioGroup( locator="//div[label[contains(., 'Media Selection')]]") media = FilteredDropdown(id='hostgroup_medium') ptable = FilteredDropdown(id='hostgroup_ptable') root_password = TextInput(id='hostgroup_root_pass')
class affected_repositories(SatSecondaryTab): TAB_NAME = 'Affected Repositories' filter_toggle = RadioGroup(".//div[@class='col-sm-8']") product_filter = Select(locator=".//select[@ng-model='product']") searchbox = Search() update_repositories = Button('Update Repositories') table = SatTable( locator='//table', column_widgets={0: Checkbox(locator=".//input[@type='checkbox']")}, )
class affected_repositories(AffectedRepositoriesTab): filter_toggle = RadioGroup(".//div[@class='col-sm-8']") product_filter = Select(locator=".//select[@ng-model='product']") searchbox = TextInput(locator=".//input[@ng-model='repositorySearch']") update_repositories = Button('Update Repositories') select_all = Checkbox( locator=".//table//th[@class='row-select']/input") table = SatTable( locator='.//table', column_widgets={0: Checkbox(locator=".//input[@type='checkbox']")}, )
class add_tab(AddTab): security = Checkbox(locator=".//input[@ng-model='types.security']") enhancement = Checkbox( locator=".//input[@ng-model='types.enhancement']") bugfix = Checkbox(locator=".//input[@ng-model='types.bugfix']") date_type = RadioGroup( ".//div[label[contains(@class, 'radio-inline')]]") start_date = DatePickerInput( locator=".//input[@ng-model='rule.start_date']") end_date = DatePickerInput( locator=".//input[@ng-model='rule.end_date']") select_all = Checkbox( locator=".//table//th[@class='row-select']/input") def search(self, query=None, filters=None): """Custom search which supports all errata filters. :param str optional query: search query to type into search box. Optional as sometimes filtering is enough to find desired errata :param dict optional filters: dictionary containing widget names and values to set (like with regular `fill()`) """ if isinstance(filters, dict): for key, value in filters.items(): getattr(self, key).fill(value) if query: self.searchbox.search(query) return self.table.read() def add(self, errata_id=None, filters=None): """Add specific errata to filter or all available if id not provided. :param str optional errata_id: ID of errata to add. If not provided - all available errata in table will be selected (especially useful together with filtering) :param dict optional filters: dictionary containing widget names and values to set (like with regular `fill()`) """ query = None if errata_id: query = 'errata_id = {}'.format(errata_id) self.search(query, filters) if errata_id: self.table.row( ('Errata ID', errata_id))[0].widget.fill(True) else: self.select_all.fill(True) self.add_button.click() def fill(self, errata_id=None, filters=None): self.add(errata_id, filters)
class operating_system(SatTab): TAB_NAME = 'Operating System' architecture = FilteredDropdown(id='host_architecture') operating_system = FilteredDropdown(id='host_operatingsystem') build = Checkbox(id='host_build') image = FilteredDropdown(id='host_compute_attributes_image') media_type = RadioGroup(locator="//div[label[contains(., 'Media Selection')]]") media = FilteredDropdown(id='host_medium') ptable = FilteredDropdown(id='host_ptable') disk = TextInput(id='host_disk') root_password = TextInput(id='host_root_pass')
class SubnetDetailsView(BaseLoggedInView): name = TextInput(id='subnet_name') protocol = RadioGroup(locator="//div[label[contains(., 'Protocol')]]") network_address = TextInput(id='subnet_network') network_prefix = TextInput(id='subnet_cidr') network_mask = TextInput(id='subnet_mask') boot_mode = FilteredDropdown(id='subnet_boot_mode') submit = Text('//input[@name="commit"]') @property def is_displayed(self): return self.browser.wait_for_element(self.name, exception=False) is not None
class subnet(SatTab): name = TextInput(id='subnet_name') description = TextInput(id='subnet_description') protocol = RadioGroup(locator="//div[label[contains(., 'Protocol')]]") network_address = TextInput(id='subnet_network') network_prefix = TextInput(id='subnet_cidr') network_mask = TextInput(id='subnet_mask') gateway_address = TextInput(id='subnet_gateway') primary_dns = TextInput(id='subnet_dns_primary') secondary_dns = TextInput(id='subnet_dns_secondary') ipam = FilteredDropdown(id='subnet_ipam') vlanid = TextInput(id='subnet_vlanid') mtu = TextInput(id='subnet_mtu') boot_mode = FilteredDropdown(id='subnet_boot_mode')
class RecurringExecutionForm(View): repeats = FilteredDropdown(id='input_type_selector') repeats_content = ConditionalSwitchableView(reference='repeats') @repeats_content.register('cronline') class CronlineForm(View): cron_line = TextInput(id='triggering_cronline') @repeats_content.register('monthly') class RepeatMonthlyForm(View): at_days = TextInput(id='triggering_days') at_hours = FilteredDropdown(id='triggering_time_time_4i') at_minutes = FilteredDropdown(id='triggering_time_time_5i') @repeats_content.register('weekly') class RepeatWeeklyForm(View): on_mon = Checkbox(id='triggering_days_of_week_1') on_tue = Checkbox(id='triggering_days_of_week_2') on_wed = Checkbox(id='triggering_days_of_week_3') on_thu = Checkbox(id='triggering_days_of_week_4') on_fri = Checkbox(id='triggering_days_of_week_5') on_sat = Checkbox(id='triggering_days_of_week_6') on_sun = Checkbox(id='triggering_days_of_week_7') at_hours = FilteredDropdown(id='triggering_time_time_4i') at_minutes = FilteredDropdown(id='triggering_time_time_5i') @repeats_content.register('daily', default=True) class RepeatDailyForm(View): at_hours = FilteredDropdown(id='triggering_time_time_4i') at_minutes = FilteredDropdown(id='triggering_time_time_5i') @repeats_content.register('hourly') class RepeatHourlyForm(View): at_minutes = FilteredDropdown(id='triggering_time_time_5i') repeat_n_times = TextInput(id='triggering_max_iteration') ends = RadioGroup(locator="//div[@id='end_time_limit_select']") ends_date_content = ConditionalSwitchableView(reference='ends') @ends_date_content.register('Never', default=True) class NoEndsDateForm(View): pass @ends_date_content.register('On') class EndsDateEnabledForm(View): at_year = FilteredDropdown(id='triggering_end_time_end_time_1i') at_month = FilteredDropdown(id='triggering_end_time_end_time_2i') at_day = FilteredDropdown(id='triggering_end_time_end_time_3i') at_hours = FilteredDropdown(id='triggering_end_time_end_time_4i') at_minutes = FilteredDropdown(id='triggering_end_time_end_time_5i')
class SubnetDetailsView(BaseLoggedInView): breadcrumb = BreadCrumb() name = TextInput(id='subnet_name') protocol = RadioGroup(locator="//div[label[contains(., 'Protocol')]]") network_address = TextInput(id='subnet_network') network_prefix = TextInput(id='subnet_cidr') network_mask = TextInput(id='subnet_mask') boot_mode = FilteredDropdown(id='subnet_boot_mode') submit = Text('//input[@name="commit"]') @property def is_displayed(self): breadcrumb_loaded = self.browser.wait_for_element(self.breadcrumb, exception=False) return (breadcrumb_loaded and self.breadcrumb.locations[0] == 'Subnets' and self.breadcrumb.read().startswith('Edit '))
class operating_system(SatTab): TAB_NAME = 'Operating System' architecture = FilteredDropdown(id='hostgroup_architecture') operating_system = FilteredDropdown(id='hostgroup_operatingsystem') media_type = RadioGroup(locator="//div[label[contains(., 'Media Selection')]]") media_content = ConditionalSwitchableView(reference='media_type') @media_content.register('All Media') class TypeMedium(View): media = FilteredDropdown(id='hostgroup_medium') @media_content.register('Synced Content') class TypeSynced(View): synced_content = FilteredDropdown(id='host_group_kickstart_repository') ptable = FilteredDropdown(id='hostgroup_ptable') root_password = TextInput(id='hostgroup_root_pass')
class erratum_date_range(SatSecondaryTab): TAB_NAME = 'Erratum Date Range' security = Checkbox(locator=".//input[@ng-model='types.security']") enhancement = Checkbox( locator=".//input[@ng-model='types.enhancement']") bugfix = Checkbox(locator=".//input[@ng-model='types.bugfix']") date_type = RadioGroup( ".//div[label[contains(@class, 'radio-inline')]]") start_date = DatePickerInput( locator=".//input[@ng-model='rule.start_date']") end_date = DatePickerInput( locator=".//input[@ng-model='rule.end_date']") save = Text('//button[contains(@ng-click, "handleSave()")]') cancel = Text('//button[contains(@ng-click, "handleCancel()")]') def after_fill(self, was_change): self.save.click()
class SyncTemplatesView(BaseLoggedInView): breadcrumb = BreadCrumb() title = Text("//h2[contains(., 'Import or Export Templates')]") sync_type = RadioGroup("//div[label[contains(., 'Action type')]]") submit = Text("//button[@type='submit']") template = ConditionalSwitchableView(reference='sync_type') @property def is_displayed(self): breadcrumb_loaded = self.browser.wait_for_element(self.breadcrumb, exception=False) return (breadcrumb_loaded and self.browser.wait_for_element( self.title, exception=False) is not None) def before_fill(self, values): """Wait for Sync Type Radio Button to be displayed""" wait_for(lambda: self.sync_type.is_displayed, timeout=10, delay=1, logger=self.logger) @template.register('Import') class ImportTemplates(View): associate = Select(name='associate') branch = TextInput(name='branch') dirname = TextInput(name='dirname') filter = TextInput(name='filter') force_import = Checkbox(name='force') lock = Checkbox(name='lock') negate = Checkbox(name='negate') prefix = TextInput(name='prefix') repo = TextInput(name='repo') @template.register('Export') class ExportTemplates(View): branch = TextInput(name='branch') dirname = TextInput(name='dirname') filter = TextInput(name='filter') metadata_export_mode = Select(name='metadata_export_mode') negate = Checkbox(name='negate') repo = TextInput(name='repo')
class JobInvocationCreateView(BaseLoggedInView): breadcrumb = BreadCrumb() job_category = FilteredDropdown(id='job_invocation_job_category') job_template = FilteredDropdown( locator="//div[contains(@class, 'job_template_selector')]") bookmark = FilteredDropdown(id='targeting_bookmark') search_query = TextInput(name='targeting[search_query]') template_content = ConditionalSwitchableView(reference='job_template') @template_content.register('Run Command - SSH Default', default=True) class RunSSHCommandForm(View): command = TextInput(id='command') @template_content.register('Power Action - SSH Default') class RestartHostForm(View): action = FilteredDropdown(id='s2id_action') @template_content.register('Puppet Run Once - SSH Default') class RunPuppetForm(View): puppet_options = TextInput(id='puppet_options') @template_content.register('Module Action - SSH Default') class RunModuleForm(View): action = FilteredDropdown(id='s2id_action') module_spec = TextInput(id='module_spec') puppet_options = TextInput(id='options') @View.nested class advanced_options(View): expander = Text(".//a[normalize-space(.)='Display advanced fields']") effective_user = TextInput( locator=".//input[contains(@name, '[effective_user]')]") description = TextInput( locator=".//input[contains(@name, '[description]')]") use_default = Checkbox(id="description_format_override") description_content = ConditionalSwitchableView( reference='use_default') @description_content.register(False) class DescriptionTemplateForm(View): description_template = TextInput( id='job_invocation_description_format') timeout = TextInput( locator=".//input[contains(@name, '[execution_timeout_interval]')]" ) password = TextInput(id='job_invocation_password') passphrase = TextInput(id='job_invocation_key_passphrase') sudo_password = TextInput(id='job_invocation_sudo_password') concurrency_level = TextInput(id='job_invocation_concurrency_level') time_span = TextInput(id='job_invocation_time_span') execution_order = RadioGroup( locator="//div[label[contains(., 'Execution ordering')]]") def __init__(self, parent, logger=None): """Expand advanced options section once we get to run job page. That is need to be able to read or change values there """ View.__init__(self, parent, logger=logger) if self.expander.is_displayed: self.expander.click() self.browser.wait_for_element(self.effective_user, visible=True, exception=False) query_type = RadioGroup( locator="//div[label[contains(., 'Type of query')]]") schedule = RadioGroup( locator="//div[label[normalize-space(.)='Schedule']]") schedule_content = ConditionalSwitchableView(reference='schedule') @schedule_content.register('Execute now', default=True) class ExecuteNowForm(View): pass @schedule_content.register('Schedule future execution') class FutureExecutionForm(View): start_at = TextInput(id='triggering_start_at_raw') start_before = TextInput(id='triggering_start_before_raw') @schedule_content.register('Set up recurring execution') class RecurringExecutionForm(View): repeats = FilteredDropdown(id='input_type_selector') repeats_content = ConditionalSwitchableView(reference='repeats') @repeats_content.register('cronline') class CronlineForm(View): cron_line = TextInput(id='triggering_cronline') @repeats_content.register('monthly') class RepeatMonthlyForm(View): at_days = TextInput(id='triggering_days') at_hours = FilteredDropdown(id='triggering_time_time_4i') at_minutes = FilteredDropdown(id='triggering_time_time_5i') @repeats_content.register('weekly') class RepeatWeeklyForm(View): on_mon = Checkbox(id='triggering_days_of_week_1') on_tue = Checkbox(id='triggering_days_of_week_2') on_wed = Checkbox(id='triggering_days_of_week_3') on_thu = Checkbox(id='triggering_days_of_week_4') on_fri = Checkbox(id='triggering_days_of_week_5') on_sat = Checkbox(id='triggering_days_of_week_6') on_sun = Checkbox(id='triggering_days_of_week_7') at_hours = FilteredDropdown(id='triggering_time_time_4i') at_minutes = FilteredDropdown(id='triggering_time_time_5i') @repeats_content.register('daily', default=True) class RepeatDailyForm(View): at_hours = FilteredDropdown(id='triggering_time_time_4i') at_minutes = FilteredDropdown(id='triggering_time_time_5i') @repeats_content.register('hourly') class RepeatHourlyForm(View): at_minutes = FilteredDropdown(id='triggering_time_time_5i') repeat_n_times = TextInput(id='triggering_max_iteration') ends = RadioGroup(locator="//div[@id='end_time_limit_select']") ends_date_content = ConditionalSwitchableView(reference='ends') @ends_date_content.register('Never', default=True) class NoEndsDateForm(View): pass @ends_date_content.register('On') class EndsDateEnabledForm(View): at_year = FilteredDropdown(id='triggering_end_time_end_time_1i') at_month = FilteredDropdown(id='triggering_end_time_end_time_2i') at_day = FilteredDropdown(id='triggering_end_time_end_time_3i') at_hours = FilteredDropdown(id='triggering_end_time_end_time_4i') at_minutes = FilteredDropdown(id='triggering_end_time_end_time_5i') submit = Text('//input[@name="commit"]') @property def is_displayed(self): breadcrumb_loaded = self.browser.wait_for_element(self.breadcrumb, exception=False) return (breadcrumb_loaded and self.breadcrumb.locations[0] == 'Jobs' and self.breadcrumb.read() == 'Job invocation')