class fields(ParametrizedView): # noqa PARAMETERS = ('name', ) ROOT = ParametrizedLocator( './/tr[./td[1][contains(normalize-space(.), "({name})")]]') ALL_FIELDS = './/table//tr/td[1]' @cached_property def row_id(self): attr = self.browser.get_attribute( 'id', './td/input[starts-with(@id, "cls_inst_value_")]', parent=self) return int(attr.rsplit('_', 1)[-1]) value = Input(name=ParametrizedString('cls_inst_value_{@row_id}')) on_entry = Input( name=ParametrizedString('cls_inst_on_entry_{@row_id}')) on_exit = Input(name=ParametrizedString('cls_inst_on_exit_{@row_id}')) on_error = Input( name=ParametrizedString('cls_inst_on_error_{@row_id}')) collect = Input(name=ParametrizedString('cls_inst_collect_{@row_id}')) @classmethod def all(cls, browser): results = [] for e in browser.elements(cls.ALL_FIELDS): text = re.sub(r'^\(|\)$', '', browser.text(e)) results.append((text, )) return results
class fields(ParametrizedView): # noqa PARAMETERS = ("key", ) input = Input(id=Parameter("key")) param_input = Input(id=ParametrizedString("param_{key}")) dropdown = VersionPick({ Version.lowest(): BootstrapSelect(Parameter("key")), "5.9": DialogFieldDropDownList( ParametrizedLocator(".//div[@input-id={key|quote}]")) }) param_dropdown = VersionPick({ Version.lowest(): BootstrapSelect(ParametrizedString("param_{key}")), "5.9": DialogFieldDropDownList( ParametrizedLocator(".//div[@input-id='param_{key}']")) }) @property def visible_widget(self): if self.input.is_displayed: return self.input elif self.dropdown.is_displayed: return self.dropdown elif self.param_input.is_displayed: return self.param_input elif self.param_dropdown.is_displayed: return self.param_dropdown def read(self): return self.visible_widget.read() def fill(self, value): return self.visible_widget.fill(value)
class attribute(ParametrizedView): # noqa PARAMETERS = ("number",) key = Input(name=ParametrizedString("attribute_{number}")) value = Input(name=ParametrizedString("value_{number}")) @classmethod def all(cls, browser): return [(i,) for i in range(1, 6)]
class AnsibleExtraVariables(View): """Represents extra variables part of ansible service catalog edit form. Args: tab (str): tab name where this view is located. Can be "provisioning" or "retirement". """ variable = Input(name=ParametrizedString("{@tab}_key")) default_value = Input(name=ParametrizedString("{@tab}_value")) add = Button( **{"ng-click": ParametrizedString("vm.addKeyValue('{@tab}')")}) variables_table = Table( ".//div[@id='variables_div']//table", column_widgets={"Actions": ActionsCell(tab=Parameter("@tab"))}) def __init__(self, parent, tab, logger=None): View.__init__(self, parent, logger=logger) self.tab = tab def _values_to_remove(self, values): return list(map(tuple, set(self.all_vars) - set(values))) def _values_to_add(self, values): return list(map(tuple, set(values) - set(self.all_vars))) def fill(self, values): """ Args: values (list): [] to remove all vars or [("var", "value"), ...] to fill the view. """ if set(values) == set(self.all_vars): return False else: for value in self._values_to_remove(values): rows = list(self.variables_table) for row in rows: if row[0].text == value[0]: row["Actions"].widget.delete.click() break for value in self._values_to_add(values): self.variable.fill(value[0]) self.default_value.fill(value[1]) self.add.click() return True @property def all_vars(self): if self.variables_table.is_displayed: return [(row["Variable"].text, row["Default value"].text) for row in self.variables_table] else: return [] def read(self): return self.all_vars
class ActionsCell(View): edit = Button( **{"ng-click": ParametrizedString( "vm.editKeyValue('{@tab}', this.key, this.key_value, $index)")} ) delete = Button( **{"ng-click": ParametrizedString( "vm.removeKeyValue('{@tab}', this.key, this.key_value, $index)")} ) def __init__(self, parent, tab, logger=None): View.__init__(self, parent, logger=logger) self.tab = parent.parent.parent.parent.tab
class fields(ParametrizedView): # noqa PARAMETERS = ("key", ) input = Input(id=Parameter("key")) select = Select(id=Parameter("key")) param_input = Input(id=ParametrizedString("param_{key}")) dropdown = BootstrapSelect(locator=ParametrizedLocator( ".//div[contains(@class, 'bootstrap-select')]/select[@id={key|quote}]/.." )) param_dropdown = BootstrapSelect(locator=ParametrizedLocator( ".//div[contains(@class, 'bootstrap-select')]/select[@id='param_{key}']/.." )) @property def visible_widget(self): for widget in (self.input, self.dropdown, self.param_input, self.param_dropdown, self.select): try: widget.wait_displayed('2s') return widget except TimedOutError: pass else: raise ItemNotFound("Visible widget is not found") def read(self): return self.visible_widget.read() def fill(self, value): return self.visible_widget.fill(value)
class fields(ParametrizedView): # noqa PARAMETERS = ("key", ) input = Input(id=Parameter("key")) select = Select(id=Parameter("key")) param_input = Input(id=ParametrizedString("param_{key}")) dropdown = VersionPick({ Version.lowest(): BootstrapSelect(Parameter("key")), "5.9": BootstrapSelect(locator=ParametrizedLocator( './/div[contains(@class, "bootstrap-select")]/select[@id={key|quote}]/..' )) }) param_dropdown = VersionPick({ Version.lowest(): BootstrapSelect(ParametrizedString("param_{key}")), "5.9": BootstrapSelect(locator=ParametrizedLocator( ".//div[contains(@class, 'bootstrap-select')]/select[@id='param_{key}']/.." )) }) @property def visible_widget(self): if self.browser.wait_for_element(self.input.locator, exception=False): return self.input elif self.browser.wait_for_element(self.dropdown.locator, exception=False): return self.dropdown elif self.browser.wait_for_element(self.param_input.locator, exception=False): return self.param_input elif self.browser.wait_for_element(self.param_dropdown.locator, exception=False): return self.param_dropdown elif self.browser.wait_for_element(self.select.locator, exception=False): return self.select else: raise ItemNotFound("Visible widget is not found") def read(self): return self.visible_widget.read() def fill(self, value): return self.visible_widget.fill(value)
class fields(ParametrizedView): # noqa PARAMETERS = ("key", ) input = Input(id=Parameter("key")) select = Select(id=Parameter("key")) param_input = Input(id=ParametrizedString("param_{key}")) dropdown = VersionPick({ Version.lowest(): BootstrapSelect(Parameter("key")), "5.9": BootstrapSelect(locator=ParametrizedString( ".//div[contains(@class, 'bootstrap-select') and " "select[@id={key|quote}]]")) }) param_dropdown = VersionPick({ Version.lowest(): BootstrapSelect(ParametrizedString("param_{key}")), "5.9": BootstrapSelect(locator=ParametrizedString( ".//div[contains(@class, 'bootstrap-select') and " "select[@id='param_{key}']]")) }) @property def visible_widget(self): if self.input.is_displayed: return self.input elif self.dropdown.is_displayed: return self.dropdown elif self.param_input.is_displayed: return self.param_input elif self.param_dropdown.is_displayed: return self.param_dropdown elif self.select.is_displayed: return self.select else: raise ItemNotFound("Visible widget is not found") def read(self): return self.visible_widget.read() def fill(self, value): return self.visible_widget.fill(value)
class fields(ParametrizedView): # noqa PARAMETERS = ('name', ) ROOT = ParametrizedLocator( './/tr[./td[contains(normalize-space(.), {name|quote})]]') @cached_property def row_id(self): attr = self.browser.get_attribute( 'id', './td/select[starts-with(@id, "per_time_")]', parent=self) return int(attr.rsplit('_', 1)[-1]) @cached_property def sub_row_id(self): attr = self.browser.get_attribute( 'id', './td/input[starts-with(@id, "fixed_rate_")]', parent=self) return int(attr.rsplit('_', 1)[-1]) per_time = Select(id=ParametrizedString('per_time_{@row_id}')) per_unit = Select(id=ParametrizedString('per_unit_{@row_id}')) start = Input(id=ParametrizedString('start_{@row_id}_{@sub_row_id}')) finish = Input(id=ParametrizedString('finish_{@row_id}_{@sub_row_id}')) fixed_rate = Input( id=ParametrizedString('fixed_rate_{@row_id}_{@sub_row_id}')) variable_rate = Input( id=ParametrizedString('variable_rate_{@row_id}_{@sub_row_id}')) action_add = Button(title='Add a new tier') action_delete = Button(title='Remove the tier')
class ParametersForm(View): ROOT = ParametrizedLocator( "//generic-object-table-component[@key-type='{@param_type}'] " " | //generic-object-table[@key-type='{@param_type}']" ) ALL_PARAMETERS = './/input[contains(@class, "ng-not-empty")]' add = Button(ParametrizedString('Add {@param_type}')) name = Input(locator='.//input[contains(@class, "ng-empty")]') type_class = BootstrapSelect( locator='.//input[contains(@class, "ng-empty")]//ancestor::tr//button') def __init__(self, parent, param_type, logger=None): View.__init__(self, parent, logger=logger) self.param_type = param_type def all(self): return [(element.get_attribute('value'), element.get_attribute('name')) for element in self.browser.elements(self.ALL_PARAMETERS)] @property def empty_field_is_present(self): try: return self.browser.element(self.name) except NoSuchElementException: return False def add_parameter_row(self): if not self.empty_field_is_present: self.add.click() def fill(self, parameters): if parameters: if isinstance(parameters, dict): for name, type_class in parameters.items(): self.add_parameter_row() type_result = self.type_class.fill(type_class.capitalize()) result = self.name.fill(name) return result and type_result elif isinstance(parameters, list): for name in parameters: self.add_parameter_row() result = self.name.fill(name) return result def delete(self, name): all_params = self.all() for param in all_params: param_name, element_name = param if param_name == name: self.browser.element( '//td[contains(@ng-class, "{}")]/ancestor::tr' '//div[@title = "Delete Row"]'.format(element_name)).click()
class table_row(ParametrizedView): PARAMETERS = ('rowid', ) ROOT = ParametrizedLocator('.//tr[@data-test={rowid|quote}]') col1 = Text('./td[2]') checkbox = Checkbox( locator=ParametrizedString('.//td/input[@id={rowid|quote}]')) @classmethod def all(cls, browser): result = [] for e in browser.elements( './/table[@id="with-thead"]//tr[td]'): result.append((browser.get_attribute('data-test', e), )) return result
class variable(ParametrizedView): # noqa PARAMETERS = ("key", ) value_input = Input(id=ParametrizedString("param_{key}")) @property def value(self): return self.browser.get_attribute("value", self.value_input) def read(self): return self.value_input.value def fill(self, value): current_value = self.value_input.value if value == current_value: return False self.browser.click(self.value_input) self.browser.clear(self.value_input) self.browser.send_keys(value, self.value_input) return True
class fields(ParametrizedView): # noqa PARAMETERS = ("key", ) input = Input(id=Parameter("key")) select = Select(id=Parameter("key")) param_input = Input(id=ParametrizedString("param_{key}")) dropdown = BootstrapSelect(locator=ParametrizedLocator( ".//div[contains(@class, 'bootstrap-select')]/select[@id={key|quote}]/.." )) param_dropdown = BootstrapSelect(locator=ParametrizedLocator( ".//div[contains(@class, 'bootstrap-select')]/select[@id='param_{key}']/.." )) multi_drop = BootstrapSelect(locator=ParametrizedLocator( ".//div[contains(@class, 'bootstrap-select')]/select[@input-id={key|quote}]/.." )) checkbox = Checkbox(id=Parameter("key")) refresh = Text(locator=ParametrizedLocator( '//label[contains(text(), "{key}")]/following-sibling::div/button') ) radiogroup = RadioGroup(locator=( '//div[contains(@ng-switch-when, "DialogFieldRadioButton")]/span[contains(@class, ' '"ng-scope")]')) @property def visible_widget(self): for widget in (self.input, self.dropdown, self.param_input, self.param_dropdown, self.select): try: widget.wait_displayed('15s') return widget except TimedOutError: pass else: raise ItemNotFound("Visible widget is not found") def read(self): return self.visible_widget.read() def fill(self, value): return self.visible_widget.fill(value)
class MyView(View): ROOT = ParametrizedLocator("./foo/bar") test_str = ParametrizedString("{@ROOT}/baz")
class owner(View): # noqa p_str1 = ParametrizedString('{@parent/child_item/foo}')
class MyView(View): ROOT = ParametrizedLocator('./foo/bar') test_str = ParametrizedString('{@ROOT}/baz')
class TestForm(View): my_value = 3 header = Text(ParametrizedString(".//h{header}")) header_cls = Text(ParametrizedString(".//h{@my_value}")) input = TextInput(name=ParametrizedString("input{input}"))
class MyView(View): my_param = ParametrizedString('{foo} {foo|quote}')
class fields(ParametrizedView): # noqa PARAMETERS = ('name', ) # Points to the <tr> ROOT = ParametrizedLocator( './/input[starts-with(@id, "fields_name_") and @value={name|quote}]/../..') ALL_FIELDS = './/input[starts-with(@name, "fields_name_")]' @cached_property def row_id(self): attr = self.browser.get_attribute( 'id', './td/input[starts-with(@id, "fields_name_")', parent=self) return int(attr.rsplit('_', 1)[-1]) name = Input(name=ParametrizedString('fields_name_{@row_id}')) type = BootstrapSelect(ParametrizedString('fields_aetype_{@row_id}')) data_type = BootstrapSelect(ParametrizedString('fields_datatype_{@row_id}')) default_value = Input(name=ParametrizedString('fields_default_value_{@row_id}')) display_name = Input(name=ParametrizedString('fields_display_name_{@row_id}')) description = Input(name=ParametrizedString('fields_description_{@row_id}')) substitute = Checkbox(name=ParametrizedString('fields_substitute_{@row_id}')) collect = Input(name=ParametrizedString('fields_collect_{@row_id}')) message = Input(name=ParametrizedString('fields_message_{@row_id}')) on_entry = Input(name=ParametrizedString('fields_on_entry_{@row_id}')) on_exit = Input(name=ParametrizedString('fields_on_exit_{@row_id}')) on_error = Input(name=ParametrizedString('fields_on_error_{@row_id}')) max_retries = Input(name=ParametrizedString('fields_max_retries_{@row_id}')) max_time = Input(name=ParametrizedString('fields_max_time_{@row_id}')) def delete(self): if self.browser.product_version < '5.10': xpath = './/img[@alt="Click to delete this field from schema"]' else: xpath = './/a[@title="Click to delete this field from schema"]' self.browser.click(xpath, parent=self) try: del self.row_id except AttributeError: pass @classmethod def all(cls, browser): result = [] for e in browser.elements(cls.ALL_FIELDS): result.append((browser.get_attribute('value', e), )) return result
class widgets(ParametrizedView): # noqa PARAMETERS = ('title', ) ALL_LOCATOR = '//div[starts-with(@id, "w_")]//h2[contains(@class, "card-pf-title")]' BLANK_SLATE = './/div[contains(@class, "blank-slate-pf")]//h1' CHART = './div/div/div[starts-with(@id, "miq_widgetchart_")]' RSS = './div/div[contains(@class, "rss_widget")]' RSS_TABLE = './div[./div[contains(@class, "rss_widget")]]/div/table' TABLE = './div/table|./div/div/table' MC = ( './/div[contains(@class, "mc")]/*[1]|.//div[starts-with(@id, "dd_w") ' 'and contains(@id, "_box")]/*[1]') ROOT = ParametrizedLocator( './/div[starts-with(@id, "w_") and .//h2[contains(@class, "card-pf-title")' ' and normalize-space(.)={title|quote}]]') title = Text('.//h2[contains(@class, "card-pf-title")]') menu = Kebab(button_id=ParametrizedString('btn_{@widget_id}')) contents = ConditionalSwitchableView(reference='content_type') # Unsupported reading yet contents.register(None, default=True, widget=Widget()) contents.register('chart', widget=Widget()) # Reading supported contents.register('table', widget=Table(TABLE)) contents.register('rss', widget=Table(RSS_TABLE)) footer = Text('.//div[contains(@class, "card-pf-footer")]') @property def column(self): """Returns the column position of this widget. Numbered from 1!""" if self.browser.product_version < "5.10": parent = self.browser.element('..') else: parent = self.browser.element('../../..') try: parent_id = self.browser.get_attribute('id', parent).strip() return int(re.sub(r'^col(\d+)$', '\\1', parent_id)) except (ValueError, TypeError, AttributeError): raise ValueError( 'Could not get the column index of widget') @property def minimized(self): return not self.browser.is_displayed(self.MC) @cached_property def widget_id(self): id_attr = self.browser.get_attribute('id', self) return int(id_attr.rsplit('_', 1)[-1]) @cached_property def content_type(self): if self.browser.elements(self.BLANK_SLATE): # No data yet return None elif self.browser.elements(self.RSS): return 'rss' elif self.browser.is_displayed(self.CHART): return 'chart' elif self.browser.is_displayed(self.TABLE): return 'table' else: return None @property def blank(self): return bool(self.browser.elements(self.BLANK_SLATE)) @classmethod def all(cls, browser): return [(browser.text(e), ) for e in browser.elements(cls.ALL_LOCATOR)]
class MyView(View): my_param = ParametrizedString('{foo} {foo|quote}') nested_thing = ParametrizedString('foo {"id-{foo}"|quote}')