def all_selected_options(self): """Returns a list of all selected options as their displayed texts.""" return [ normalize_space(unescape(option)) for option in self.browser.execute_script( self.SELECTED_OPTIONS_TEXT, self.browser.element(self)) ]
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 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 fill(self, item_or_items): if item_or_items is None: items = [] elif isinstance(item_or_items, list): items = item_or_items else: items = [item_or_items] selected_values = self.all_selected_values selected_options = self.all_selected_options options_to_select = [] values_to_select = [] deselect = True for item in items: if isinstance(item, tuple): try: mod, value = item if not isinstance(mod, str): raise ValueError( "The select modifier must be a string") mod = mod.lower() except ValueError: raise ValueError( "If passing tuples into the S.fill(), they must be 2-tuples" ) else: mod = "by_text" value = item if mod == "by_text": value = normalize_space(value) if value in selected_options: deselect = False continue options_to_select.append(value) elif mod == "by_value": if value in selected_values: deselect = False continue values_to_select.append(value) else: raise ValueError(f"Unknown select modifier {mod}") if deselect: try: self.deselect_all() deselected = bool(selected_options or selected_values) except NotImplementedError: deselected = False else: deselected = False if options_to_select: self.select_by_visible_text(*options_to_select) if values_to_select: self.select_by_value(*values_to_select) return bool(options_to_select or values_to_select or deselected)
def all_options(self): """Returns a list of tuples of all the options in the Select. Text first, value follows. Returns: A :py:class:`list` of :py:class:`Option` """ # More reliable using javascript options = self.browser.execute_script(self.ALL_OPTIONS, self.browser.element(self)) parser = HTMLParser() return [ self.Option(normalize_space(parser.unescape(option[0])), option[1]) for option in options]