def _generate_locator(self, *text, **kwargs): classes = kwargs.pop("classes", []) if text: if kwargs: # classes should have been the only kwarg combined with text args raise TypeError( "If you pass button text then only pass classes in addition" ) if len(text) == 1: locator_conditions = "normalize-space(.)={}".format( quote(text[0])) elif len(text) == 2 and text[0].lower() == "contains": locator_conditions = "contains(normalize-space(.), {})".format( quote(text[1])) else: raise TypeError("An illegal combination of args/kwargs") else: # Join the kwargs, if any locator_conditions = " and ".join( "@{}={}".format(attr, quote(value)) for attr, value in kwargs.items()) if classes: if locator_conditions: locator_conditions += " and " locator_conditions += " and ".join( "contains(@class, {})".format(quote(klass)) for klass in classes) if locator_conditions: locator_conditions = "and ({})".format(locator_conditions) return (".//*[(self::a or self::button or (self::input and " "(@type='button' or @type='submit'))) and " f"contains(@class, 'pf-c-button') {locator_conditions}]")
def __init__(self, parent, *text, **kwargs): logger = kwargs.pop('logger', None) Widget.__init__(self, parent, logger=logger) self.args = text self.kwargs = kwargs if text: if kwargs and 'classes' not in kwargs: raise TypeError( 'If you pass button text then do not pass anything else.') if len(text) == 1: self.locator_conditions = 'normalize-space(.)={}'.format( quote(text[0])) elif len(text) == 2 and text[0].lower() == 'contains': self.locator_conditions = 'contains(normalize-space(.), {})'.format( quote(text[1])) else: raise TypeError('An illegal combination of text params') else: # Join the kwargs, if any self.locator_conditions = ' and '.join( '@{}={}'.format(attr, quote(value)) for attr, value in kwargs.items()) classes = kwargs.pop('classes', []) if classes: self.locator_conditions += ' and ' self.locator_conditions += ' and '.join( 'contains(@class, {})'.format(quote(klass)) for klass in classes) if self.locator_conditions: self.locator_conditions = 'and ({})'.format( self.locator_conditions)
class ContainerAllView(BaseLoggedInPage): """Containers All view""" summary = Text( VersionPick({ Version.lowest(): '//h3[normalize-space(.) = {}]'.format(quote('All Containers')), '5.8': '//h1[normalize-space(.) = {}]'.format(quote('Containers')) })) containers = Table(locator="//div[@id='list_grid']//table") @property def table(self): return self.containers @View.nested class Filters(Accordion): # noqa ACCORDION_NAME = "Filters" @View.nested class Navigation(VerticalNavigation): DIV_LINKS_MATCHING = './/div/ul/li/a[contains(text(), {txt})]' def __init__(self, parent, logger=None): VerticalNavigation.__init__(self, parent, '#Container_def_searches', logger=logger) tree = ManageIQTree() @property def is_displayed(self): return self.summary.is_displayed
def __init__(self, parent, *text, **kwargs): logger = kwargs.pop("logger", None) Widget.__init__(self, parent, logger=logger) self.args = text self.kwargs = kwargs self.classes = kwargs.pop("classes", []) if text: if kwargs: # classes should have been the only kwarg combined with text args raise TypeError("If you pass button text then only pass classes in addition") if len(text) == 1: self.locator_conditions = "normalize-space(.)={}".format(quote(text[0])) elif len(text) == 2 and text[0].lower() == "contains": self.locator_conditions = "contains(normalize-space(.), {})".format(quote(text[1])) else: raise TypeError("An illegal combination of text params") else: # Join the kwargs, if any self.locator_conditions = " and ".join( "@{}={}".format(attr, quote(value)) for attr, value in kwargs.items()) if self.classes: if self.locator_conditions: self.locator_conditions += " and " self.locator_conditions += " and ".join( "contains(@class, {})".format(quote(klass)) for klass in self.classes) if self.locator_conditions: self.locator_conditions = "and ({})".format(self.locator_conditions)
def select(self, *levels, **kwargs): """Select an item in the navigation. Args: *levels: Items to be clicked in the navigation. force: Force navigation to happen, defaults to False. """ self.logger.info("Selecting %r in navigation", levels) force = kwargs.get("force", False) if not force and list(levels) == self.currently_selected: return current_item = self for i, level in enumerate(levels, 1): try: li = self.browser.element(self.ITEM_MATCHING.format( quote(level)), parent=current_item) except NoSuchElementException: li = self.browser.element( self.ITEM_MATCHING_OUIA.format(text=quote(level)), parent=current_item) if "pf-m-expanded" not in li.get_attribute("class").split(): self.browser.click(li) if i == len(levels): return current_item = self.browser.element(self.SUB_ITEMS_ROOT, parent=li)
def _construct_xpath(path, by_id=False): items = [] for item in path: if by_id: items.append('ul/li[@id={}]'.format(quote(item))) else: items.append('ul/li[./span/a[normalize-space(.)={}]]'.format(quote(item))) return './' + '/'.join(items)
def __init__(self, parent, locator=None, id=None, name=None, logger=None): Widget.__init__(self, parent, logger=logger) if (locator and id) or (id and name) or (locator and name): raise TypeError('You can only pass one of the params locator, id, name into Select') if locator is not None: self.locator = locator elif id is not None: self.locator = './/select[@id={}]'.format(quote(id)) else: # name self.locator = './/select[@name={}]'.format(quote(name))
def _set_attrs( self, component_type: str, component_id: Optional[str] = None, ) -> None: self.component_type = quote(component_type) self.component_id = quote(component_id) component_id = f" and @data-ouia-component-id={quote(component_id)}" if component_id else "" self.component_id_suffix = component_id self.locator = self.ROOT.locator
def __init__(self, parent, id=None, name=None, logger=None): if not (id or name): raise ValueError('either id or name should be present') elif name is not None: id_attr = '@name={}'.format(quote(name)) else: id_attr = '@id={}'.format(quote(id)) self.input = './/input[{}]'.format(id_attr) Checkbox.__init__(self, parent, locator=self.ROOT, logger=logger)
def select(self, level1, level2=None): l1e = self.browser.element(self.LEVEL_1.format(quote(level1))) if not level2: # Clicking only the main menu item self.browser.click(l1e) return # Hover on the menu on the right spot self.browser.move_to_element(l1e) l2e = self.browser.wait_for_element( self.LEVEL_2.format(quote(level1), quote(level2))) self.browser.click(l2e)
def __init__(self, parent, label=None, id=None, locator=None, logger=None): Widget.__init__(self, parent, logger=logger) label_part = " and @label={}".format(quote(label)) if label else "" id_part = " and @id={}".format(quote(id)) if id else "" if locator is not None: self.locator = locator elif label_part or id_part: self.locator = self.LOCATOR_START.format(label_part + id_part) else: raise TypeError( 'You need to specify either, id, label or locator for Navigation' )
def nav_links(self, *levels): if not levels: return [ self.browser.text(el) for el in self.browser.elements(self.LINKS, parent=self) ] # Otherwise current_item = self for i, level in enumerate(levels): li = self.browser.element(self.ITEMS_MATCHING.format(quote(level)), parent=current_item) try: current_item = self.browser.element(self.SUB_ITEM_LIST, parent=li) except NoSuchElementException: if i == len(levels) - 1: # It is the last one return [] else: raise return [ self.browser.text(el) for el in self.browser.elements(self.LINKS, parent=current_item) ]
def nav_links(self, *levels): """Returns a list of all navigation items.""" if not levels: return [ el.get_property("textContent").strip() for el in self.browser.elements(self.ITEMS) ] current_item = self for i, level in enumerate(levels): li = self.browser.element(self.ITEM_MATCHING.format( quote(level.strip())), parent=current_item) try: current_item = self.browser.element(self.SUB_ITEMS_ROOT, parent=li) except NoSuchElementException: if i == len(levels) - 1: return [] else: raise return [ el.get_property("textContent").strip() for el in self.browser.elements(self.ITEMS, parent=current_item) ]
def select_item(self, item): if not self.item_enabled(item): raise ValueError('Cannot click disabled item {}'.format(item)) self.expand() self.logger.info('selecting item {}'.format(item)) self.browser.click('./ul/li[normalize-space(.)={}]'.format(quote(item)), parent=self)
def __init__(self, parent, label=None, id=None, locator=None, logger=None): super().__init__(parent, logger=logger) quoted_label = quote(label) if label else "" if label: label_part = " and @label={} or @aria-label={}".format(quoted_label, quoted_label) else: label_part = "" id_part = " and @id={}".format(quote(id)) if id else "" if locator is not None: self.locator = locator elif label_part or id_part: self.locator = self.LOCATOR_START.format(label_part + id_part) else: raise TypeError("You need to specify either, id, label or locator for Navigation")
def footer_item(self, item): """Returns a WebElement for given item name in modal footer.""" try: return self.browser.element(self.FOOTER_ITEM.format(quote(item))) except NoSuchElementException: raise ModalItemNotFound( f"Item {item} not found. Available items: {self.footer_items}")
def title(self): if not hasattr(self, 'TITLE_TEXT'): raise Exception( 'TITLE_TEXT is not defined for destination {} ("All").'.format( self.__class__.__name__)) return Text('//h1[normalize-space(.) = {}]'.format( quote(self.TITLE_TEXT)))
def child_items_with_text(self, item, text): """Returns all child items of given item that contain the given text. Args: item: WebElement of the node. text: Text to be matched Returns: List of all child items of the item *that contain the given text*. """ nodeid = quote(self.get_nodeid(item)) text = quote(text) node_indents = self.indents(item) return self.browser.elements(self.CHILD_ITEMS_TEXT.format( id=nodeid, text=text, indent=node_indents + 1), parent=self)
def __init__(self, parent, label=None, id=None, locator=None, logger=None): Widget.__init__(self, parent, logger=logger) quoted_label = quote(label) if label else "" if label: label_part = " and @label={} or @aria-label={}".format(quoted_label, quoted_label) else: label_part = "" id_part = " and @id={}".format(quote(id)) if id else "" if locator is not None: self.locator = locator elif label_part or id_part: self.locator = self.LOCATOR_START.format(label_part + id_part) else: raise TypeError("You need to specify either, id, label or locator for Navigation")
def __init__(self, parent, *text, **kwargs): logger = kwargs.pop('logger', None) Widget.__init__(self, parent, logger=logger) if text: if kwargs: raise TypeError('If you pass button text then do not pass anything else.') if len(text) == 1: self.locator_conditions = 'normalize-space(.)={}'.format(quote(text[0])) elif len(text) == 2 and text[0].lower() == 'contains': self.locator_conditions = 'contains(normalize-space(.), {})'.format(quote(text[1])) else: raise TypeError('An illegal combination of text params') else: # Join the kwargs self.locator_conditions = ' and '.join( '@{}={}'.format(attr, quote(value)) for attr, value in kwargs.items())
def __init__(self, parent, name=None, id=None, locator=None, logger=None): if (locator and (name or id)) or (name and (id or locator)) or (id and (name or locator)): raise TypeError('You can only pass one of name, id or locator!') Widget.__init__(self, parent, logger=logger) self.name = None self.id = None if name or id: if name is not None: id_attr = '@name={}'.format(quote(name)) self.name = name elif id is not None: id_attr = '@id={}'.format(quote(id)) self.id = id self.locator = './/*[(self::input or self::textarea) and {}]'.format(id_attr) else: self.locator = locator
def get_value_by_text(self, text): """Given the visible text, retrieve the underlying value.""" locator = ".//option[normalize-space(.)={}]".format( quote(normalize_space(text))) return self.browser.get_attribute("value", locator=locator, parent=self)
def child_items_with_text(self, item, text): """Returns all child items of given item that contain the given text. Args: item: WebElement of the node. text: Text to be matched Returns: List of all child items of the item *that contain the given text*. """ nodeid = quote(self.get_nodeid(item)) text = quote(text) node_indents = self.indents(item) return self.browser.elements( self.CHILD_ITEMS_TEXT.format(id=nodeid, text=text, indent=node_indents + 1), parent=self)
def item_enabled(self, item): if not self.has_item(item): raise ValueError('There is not such item {}'.format(item)) element = self.browser.element('./ul/li[normalize-space(.)={}]'.format( quote(item)), parent=self) return 'disabled' not in self.browser.classes(element)
def select_by_visible_text(self, *items): """Selects item(s) by their respective displayed text in the select. Args: *items: Items' visible texts to be selected. Raises: :py:class:`ValueError` - if you pass multiple values and the select is not multiple. :py:class:`ValueError` - if the text was not found. """ if len(items) > 1 and not self.is_multiple: raise ValueError( 'The Select {!r} does not allow multiple selections'.format( self)) for text in items: matched = False for opt in self.browser.elements( './/option[normalize-space(.)={}]'.format( quote(normalize_space(text))), parent=self): if not opt.is_selected(): opt.click() if not self.is_multiple: return matched = True if not matched: available = ", ".join( repr(opt.text) for opt in self.all_options) raise ValueError( "Cannot locate option with visible text: {!r}. Available options: {}" .format(text, available))
def select_by_value(self, *items): """Selects item(s) by their respective values in the select. Args: *items: Items' values to be selected. Raises: :py:class:`ValueError` - if you pass multiple values and the select is not multiple. :py:class:`ValueError` - if the value was not found. """ if len(items) > 1 and not self.is_multiple: raise ValueError( 'The Select {!r} does not allow multiple selections'.format( self)) for value in items: matched = False for opt in self.browser.elements('.//option[@value={}]'.format( quote(value)), parent=self): if not opt.is_selected(): opt.click() if not self.is_multiple: return matched = True if not matched: raise ValueError( "Cannot locate option with value: {!r}".format(value))
def _click_button(self, cmd): cur_page_btn = self.browser.element(self.PAGE_BUTTON_CTL.format(quote(cmd)), parent=self._paginator) if self._is_enabled(cur_page_btn): self.browser.click(cur_page_btn) else: raise NoSuchElementException('such button {} is absent/grayed out'.format(cmd))
def __init__(self, parent, button_id=None, logger=None): super(Kebab, self).__init__(parent, logger=logger) if button_id is not None: self.locator = ( './/div[contains(@class, "dropdown-kebab-pf") and ./button[@id={}]]'.format( quote(button_id))) else: self.locator = './/div[contains(@class, "dropdown-kebab-pf") and ./button][1]'
def select(self, sub_item): if not self.is_dropdown: raise TypeError( "{} is not a tab with dropdown and CHECK_IF_DROPDOWN is True") self.open() self.logger.info("clicking the sub-item %r", sub_item) self.browser.click(self.DROPDOWN.format(quote(sub_item)), parent=self._tab_el)
def __init__(self, parent, button_id=None, logger=None): super(Kebab, self).__init__(parent, logger=logger) if button_id is not None: self.locator = ( './/div[contains(@class, "dropdown-kebab-pf") and ./button[@id={}]]' .format(quote(button_id))) else: self.locator = './/div[contains(@class, "dropdown-kebab-pf") and ./button][1]'
def selected(self): names = self.button_names for name in names: bttn = self.browser.element(self.BUTTON.format(quote(name))) if bttn.get_attribute('checked') is not None: return name else: return names[0]
def selected(self): names = self.button_names for name in names: bttn = self.browser.element(self.BUTTON.format(quote(name))) if bttn.get_attribute("checked") is not None: return name else: return names[0]
def __init__(self, parent, id=None, locator=None, logger=None): """Create the widget""" Widget.__init__(self, parent, logger=logger) if id: self.locator = self.BASE_LOCATOR.format(quote(id)) elif locator: self.locator = locator else: raise TypeError("You need to specify either id or locator")
def __locator__(self): if self.locator: return self.locator elif self.text: return ('.//div[contains(@class, "pf-c-dropdown") and ' "child::button[normalize-space(.)={}]]").format( quote(self.text)) else: return ('.//div[contains(@class, "pf-c-dropdown")]')
def select_item(self, item): if not self.item_enabled(item): raise ValueError('Cannot click disabled item {}'.format(item)) self.expand() self.logger.info('selecting item {}'.format(item)) self.browser.click( './/a[@role="menuitem" and normalize-space(.)={}]'.format( quote(item)))
def select(self, *levels, **kwargs): """Select an item in the navigation. Args: *levels: Items to be clicked in the navigation. Keywords: anyway: Default behaviour is that if you try selecting an already selected item, it will not do it. If you pass ``anyway=True``, it will click it anyway. """ levels = list(levels) self.logger.info('Selecting %r in navigation', levels) anyway = kwargs.pop('anyway', True) if levels == self.currently_selected and not anyway: return passed_levels = [] current_div = self.get_child_div_for(*passed_levels) for level in levels: passed_levels.append(level) finished = passed_levels == levels link = self.browser.element( self.DIV_LINKS_MATCHING.format(txt=quote(level)), parent=current_div) expands = bool(self.browser.elements(self.SUB_LEVEL, parent=link)) if expands and not finished: self.logger.debug('moving to %s to open the next level', level) self.browser.move_to_element(link) @wait_for_decorator(timeout='10s', delay=0.2) def other_div_displayed(): return 'is-hover' in self.browser.classes( self.MATCHING_LI_FOR_DIV.format(quote(level)), parent=current_div) # The other child div should be displayed current_div_width = current_div.size['width'] new_div = self.get_child_div_for(*passed_levels) # We need to generate a correct stroke to a neighbouring div new_div_width = new_div.size['width'] mouse_stroke_x = (current_div_width / 2) + (new_div_width / 2) self.logger.debug( 'moving mouse by %d px right to the next level', mouse_stroke_x) self.browser.move_by_offset(mouse_stroke_x, 0) current_div = new_div elif not expands and not finished: raise ValueError( 'You are trying to expand {!r} which cannot be expanded'. format(passed_levels)) else: # finished self.logger.debug( 'finishing the menu selection by clicking on %s', level) self.browser.click(link, ignore_ajax=True) self.browser.handle_alert(wait=2.0, squash=True)
def __init__(self, parent, text=None, locator=None, logger=None): Widget.__init__(self, parent, logger=logger) if locator and text: raise ValueError("Either text or locator should be provided") if text: self.locator = self.TEXT_LOCATOR.format(quote(text)) elif locator: self.locator = locator else: self.locator = self.DEFAULT_LOCATOR
def get_child_div_for(self, *levels): current = self for level in levels: try: current = self.browser.element( self.CHILD_UL_FOR_DIV.format(quote(level)), parent=current) except NoSuchElementException: return None return self.browser.element('..', parent=current)
def child_items(self, id, ids=False): self.expand_id(id) items = self.browser.elements('.//li[@id={}]/ul/li'.format(quote(id)), parent=self) result = [] for item in items: if ids: result.append(self.browser.get_attribute('id', item)) else: text_item = self.browser.element('./span/a', parent=item) result.append(self.browser.text(text_item)) return result
def get_item_by_nodeid(self, nodeid): nodeid_q = quote(nodeid) try: return self.browser.element(self.ITEM_BY_NODEID.format(nodeid_q), parent=self) except NoSuchElementException: raise CandidateNotFound({ 'message': 'Could not find the item with nodeid {} in Boostrap tree {}'.format( nodeid, self.tree_id), 'path': '', 'cause': ''})
def __locator__(self): if self.locator: return self.locator elif self.text: return ( './/div[contains(@class, "pf-c-dropdown") and ' "child::button[normalize-space(.)={}]]" ).format(quote(self.text)) else: return ( './/div[contains(@class, "pf-c-dropdown")]' )
def select(self, *levels, **kwargs): """Select an item in the navigation. Args: *levels: Items to be clicked in the navigation. Keywords: anyway: Default behaviour is that if you try selecting an already selected item, it will not do it. If you pass ``anyway=True``, it will click it anyway. """ levels = list(levels) self.logger.info('Selecting %r in navigation', levels) anyway = kwargs.pop('anyway', True) if levels == self.currently_selected and not anyway: return passed_levels = [] current_div = self.get_child_div_for(*passed_levels) for level in levels: passed_levels.append(level) finished = passed_levels == levels link = self.browser.element( self.DIV_LINKS_MATCHING.format(txt=quote(level)), parent=current_div) expands = bool( self.browser.elements(self.SUB_LEVEL, parent=link)) if expands and not finished: self.logger.debug('moving to %s to open the next level', level) self.browser.move_to_element(link) @wait_for_decorator(timeout='10s', delay=0.2) def other_div_displayed(): return 'is-hover' in self.browser.classes( self.MATCHING_LI_FOR_DIV.format(quote(level)), parent=current_div) # The other child div should be displayed current_div_width = current_div.size['width'] new_div = self.get_child_div_for(*passed_levels) # We need to generate a correct stroke to a neighbouring div new_div_width = new_div.size['width'] mouse_stroke_x = (current_div_width / 2) + (new_div_width / 2) self.logger.debug('moving mouse by %d px right to the next level', mouse_stroke_x) self.browser.move_by_offset(mouse_stroke_x, 0) current_div = new_div elif not expands and not finished: raise ValueError( 'You are trying to expand {!r} which cannot be expanded'.format(passed_levels)) else: # finished self.logger.debug('finishing the menu selection by clicking on %s', level) self.browser.click(link) self.browser.handle_alert(wait=2.0, squash=True)
def child_items(self, item): """Returns all child items of given item. Args: item: WebElement of the node. Returns: List of *all* child items of the item. """ nodeid = quote(self.get_nodeid(item)) node_indents = self.indents(item) return self.browser.elements( self.CHILD_ITEMS.format(id=nodeid, indent=node_indents + 1), parent=self)
def item_element(self, item, close=True): """Returns a WebElement for given item name.""" try: self.open() result = self.browser.element(self.ITEM_LOCATOR.format(quote(item))) if close: self.close() return result except NoSuchElementException: raise SelectItemNotFound( "Item {!r} not found in {}. Available items: {}".format( item, repr(self), self.items ) )
def select(self, item, close=True): """Select a specific item from the kebab. Args: item: Item to be selected. close: Whether to close the kebab after selection. If the item is a link, you may want to set this to ``False`` """ try: self.open() self.browser.click(self.ITEM.format(quote(item))) finally: if close: self.close()
def checkbox_by_text(self, text): """Returns checkbox's WebElement by searched by its text.""" if self._access_func is not None: for cb in self.checkboxes: txt = self._access_func(cb) if txt == text: return cb else: raise NameError("Checkbox with text {} not found!".format(text)) else: # Has to be only single element = self.browser.element( ".//*[normalize-space(.)={}]/input[@type='checkbox']".format(quote(text)), self ) return Checkbox(self, id=element.get_attribute("id"))
def _format_generator(self, dimmed=False, include_dimmed_alt=False): """Generates a dict that will be passed to the formatting strings.""" d = {} for key, value in self.Button.__dict__.iteritems(): if not key.startswith("_"): d[key] = value d["ALT_EXPR"] = self.alt_expr(dimmed=dimmed) if include_dimmed_alt: d["DIMMED_ALT"] = quoteattr(self._dimmed_alt or self._alt) if self._classes: d['CLASSES'] = 'and ({})'.format( ' and '.join('contains(@class, {})'.format(quote(kls)) for kls in self._classes)) else: d['CLASSES'] = '' return d
def checkbox_by_text(self, text): """Returns checkbox's WebElement searched by its text.""" if self._access_func is not None: for cb in self.checkboxes: txt = self._access_func(cb) if txt == text: return cb else: raise NameError("Checkbox with text {} not found!".format(text)) else: # Has to be only single return Checkbox( self, locator=".//*[normalize-space(.)={}]/input[@type='checkbox']".format(quote(text)) )
def select(self, *levels, **kwargs): """Select an item in the navigation. Args: *levels: Items to be clicked in the navigation. force: Force navigation to happen, defaults to False. """ self.logger.info("Selecting %r in navigation", levels) force = kwargs.get("force", False) if not force and list(levels) == self.currently_selected: return current_item = self for i, level in enumerate(levels, 1): li = self.browser.element(self.ITEM_MATCHING.format(quote(level)), parent=current_item) self.browser.click(li) if i == len(levels): return current_item = self.browser.element(self.SUB_ITEMS_ROOT, parent=li)
def item_element(self, item, close=True): """Returns a WebElement for given item name.""" try: self.open() result = self.browser.element(self.ITEM_LOCATOR.format(quote(item))) if close: self.close() return result except NoSuchElementException: try: items = self.items except NoSuchElementException: items = [] if items: items_string = "These items are present: {}".format("; ".join(items)) else: items_string = "The dropdown is probably not present" raise DropdownItemNotFound("Item {!r} not found. {}".format(item, items_string))
def nav_links(self, *levels): if not levels: return [self.browser.text(el) for el in self.browser.elements(self.ITEMS)] current_item = self for i, level in enumerate(levels): li = self.browser.element(self.ITEM_MATCHING.format(quote(level)), parent=current_item) try: current_item = self.browser.element(self.SUB_ITEMS_ROOT, parent=li) except NoSuchElementException: if i == len(levels) - 1: return [] else: raise return [ self.browser.text(el) for el in self.browser.elements(self.ITEMS, parent=current_item) ]
def select_by_visible_text(self, *items): """Selects items in the select. Args: *items: Items to be selected. If the select does not support multiple selections and you pass more than one item, it will raise an exception. """ if len(items) > 1 and not self.is_multiple: raise ValueError( 'The BootstrapSelect {} does not allow multiple selections'.format(self.id)) self.open() for text in items: self.logger.info('selecting by visible text: %r', text) self.browser.click( './div/ul/li/a[./span[contains(@class, "text") and normalize-space(.)={}]]'.format( quote(text)), parent=self) self.close()
def nav_links(self, *levels): if not levels: return [self.browser.text(el) for el in self.browser.elements(self.LINKS, parent=self)] # Otherwise current_item = self for i, level in enumerate(levels): li = self.browser.element( self.ITEMS_MATCHING.format(quote(level)), parent=current_item) try: current_item = self.browser.element(self.SUB_ITEM_LIST, parent=li) except NoSuchElementException: if i == len(levels) - 1: # It is the last one return [] else: raise return [ self.browser.text(el) for el in self.browser.elements(self.LINKS, parent=current_item)]
def element_loc(self, element_type): return self.browser.element('.//dialog-editor-field/div[@class="form-group"]' '/label[normalize-space(.)={}]'.format(quote(element_type)))
def element_loc(self, element_data): return self.browser.element('//div[@class="panel-heading"]' '[contains(normalize-space(.), {})]/..'.format(quote(element_data)))
def __init__(self, parent, *args, **kwargs): kwargs['column_widgets'] = self.column_widgets VanillaTable.__init__(self, parent, self.BASELOC.format(quote('Disks')), *args, **kwargs)
def __locator__(self): return '//li[normalize-space(.)={}]'.format(quote(self.tab_name))
def __locator__(self): return self.ROOT_LOCATOR + self.A_LOCATOR.format(quote(self.accordion_name))