• web自动化测试第12步:selenium中下拉框的解决方法(Select)


    在之前,遇到下拉框的时候我们可以用两次点击来选择我们需要的选项,不过对于下拉框,我们的webdriver中有封装的Select包单独对于下拉框有一套处理的方法,我们可以来学习一下,然后在测试的时候根据不同的情况来选择需要哪儿种方法。

    1.select包方法的使用示例以及定位方式

     select方法示例

    select下拉框的定位




    2.select包内的方法详解

    1.获取option元素

    options获取包含select下拉框内所有option项element的列表

    all_selected_options: 获取当前选中项element的列表

    first_selected_option:获取所有下拉选项中的第一个选项的element(或者获取当前选中的这一项)


    2.选择option

    select_by_value(values):选择option标签中value属性为:values的选项

    select_by_index(index_number):选择索引为index_number的选项(索引从0开始)

    select_by_visible_text(text):选择option选项内容为:text的选项


    3.复选select的情况(select标签中,multiple="multiple"时,即可多选的select选择框)

    deselect_all: 取消所有已选择的选项

    deselect_by_value(values):取消选择option标签中value属性为:values的选项

    deselect_by_index(index_number):取消选择索引为index_number的选项(索引从0开始)

    deselect_by_visible_text(text):取消选择option选项内容为:text的选项


    3.实例验证(一)百度贴吧高级搜索下拉框

    百度贴吧高级搜索

    本条实例主要是获取选项元素和通过方法来选择某项option,代码如下

    from selenium import webdriver
    from selenium.webdriver.support.ui import Select
    from time import sleep
    
    # 打开Chrome浏览器
    driver = webdriver.Chrome()
    
    # 进入百度高级搜索页
    driver.get("http://tieba.baidu.com/f/search/adv")
    
    # 获取select下拉框的元素
    ele_select = driver.find_element_by_css_selector("select[name='sm']")
    
    # 获取下拉框中所有选项元素(element)
    options = Select(ele_select).options
    print("所有选项元素的列表:%s" % options)
    for i in options:
        print("元素对应的选项:%s"% i.text)
    
    # 获取下拉框当前显示(选中)的元素(element)
    options_selected = Select(ele_select).all_selected_options
    print("-----------------------分隔符---------------------------")
    print(options_selected)
    for j in options_selected:
        print("当前选中的选项(默认项):%s" % j.text)
    
    # 选择value值为2的选项
    Select(ele_select).select_by_value("2")
    sleep(1)
    
    # 输出默认项(当前选中项)
    now = Select(ele_select).first_selected_option
    print(now.text)
    


    4.实例验证(二)w3c多选multiple选择框

    由于w3c并没有多选multiple这一项,所以我们把我们自己写的表单信息给写入到页面上,然后再进行多选select框的验证

    from selenium import webdriver
    from selenium.webdriver.support.ui import Select
    from time import sleep
    
    # 打开浏览器,进入演示页面
    driver = webdriver.Chrome()
    driver.get("http://www.w3school.com.cn/tiy/t.asp?f=html_dropdownbox")
    
    # 定位输入框文本域
    ele_textarea = driver.find_element_by_css_selector("#TestCode")
    
    # 清空文本域
    ele_textarea.clear()
    
    # 输入多选下拉框的演示源码 (multiple="multiple")
    texts = "<html> " 
            "<body><form><select multiple="multiple" name="cars"><option value="volvo">Volvo</option>" 
            "<option value="saab">Saab</option><option value="fiat">Fiat</option>" 
            "<option value="audi">Audi</option></select></form></body></html>"
    ele_textarea.send_keys(texts)
    
    # 点击提交代码
    submit_button = driver.find_element_by_css_selector("#butt > input[type='button']")
    submit_button.click()
    sleep(2)
    
    # 定位frame和select元素
    driver.switch_to.frame("i")
    ele_select = driver.find_element_by_css_selector("body > form > select")
    # 选择全部的选项(多选)
    Select(ele_select).select_by_index(0)
    Select(ele_select).select_by_index(1)
    Select(ele_select).select_by_index(2)
    Select(ele_select).select_by_index(3)
    
    # 取消选择第一项选项(页面上可以观察到变化)
    Select(ele_select).deselect_by_index(0)
    
    # 输出当前选择的第一项
    now = Select(ele_select).first_selected_option
    print(now.text)
    
    

    5.源码展示

    class Select(object):
    
        def __init__(self, webelement):
            """
            Constructor. A check is made that the given element is, indeed, a SELECT tag. If it is not,
            then an UnexpectedTagNameException is thrown.
    
            :Args:
             - webelement - element SELECT element to wrap
    
            Example:
                from selenium.webdriver.support.ui import Select 
    
                Select(driver.find_element_by_tag_name("select")).select_by_index(2)
            """
            if webelement.tag_name.lower() != "select":
                raise UnexpectedTagNameException(
                    "Select only works on <select> elements, not on <%s>" %
                    webelement.tag_name)
            self._el = webelement
            multi = self._el.get_attribute("multiple")
            self.is_multiple = multi and multi != "false"
    
        @property
        def options(self):
            """Returns a list of all options belonging to this select tag"""
            return self._el.find_elements(By.TAG_NAME, 'option')
    
        @property
        def all_selected_options(self):
            """Returns a list of all selected options belonging to this select tag"""
            ret = []
            for opt in self.options:
                if opt.is_selected():
                    ret.append(opt)
            return ret
    
        @property
        def first_selected_option(self):
            """The first selected option in this select tag (or the currently selected option in a
            normal select)"""
            for opt in self.options:
                if opt.is_selected():
                    return opt
            raise NoSuchElementException("No options are selected")
    
        def select_by_value(self, value):
            """Select all options that have a value matching the argument. That is, when given "foo" this
               would select an option like:
    
               <option value="foo">Bar</option>
    
               :Args:
                - value - The value to match against
    
               throws NoSuchElementException If there is no option with specisied value in SELECT
               """
            css = "option[value =%s]" % self._escapeString(value)
            opts = self._el.find_elements(By.CSS_SELECTOR, css)
            matched = False
            for opt in opts:
                self._setSelected(opt)
                if not self.is_multiple:
                    return
                matched = True
            if not matched:
                raise NoSuchElementException("Cannot locate option with value: %s" % value)
    
        def select_by_index(self, index):
            """Select the option at the given index. This is done by examing the "index" attribute of an
               element, and not merely by counting.
    
               :Args:
                - index - The option at this index will be selected
    
               throws NoSuchElementException If there is no option with specisied index in SELECT
               """
            match = str(index)
            for opt in self.options:
                if opt.get_attribute("index") == match:
                    self._setSelected(opt)
                    return
            raise NoSuchElementException("Could not locate element with index %d" % index)
    
        def select_by_visible_text(self, text):
            """Select all options that display text matching the argument. That is, when given "Bar" this
               would select an option like:
    
                <option value="foo">Bar</option>
    
               :Args:
                - text - The visible text to match against
    
                throws NoSuchElementException If there is no option with specisied text in SELECT
               """
            xpath = ".//option[normalize-space(.) = %s]" % self._escapeString(text)
            opts = self._el.find_elements(By.XPATH, xpath)
            matched = False
            for opt in opts:
                self._setSelected(opt)
                if not self.is_multiple:
                    return
                matched = True
    
            if len(opts) == 0 and " " in text:
                subStringWithoutSpace = self._get_longest_token(text)
                if subStringWithoutSpace == "":
                    candidates = self.options
                else:
                    xpath = ".//option[contains(.,%s)]" % self._escapeString(subStringWithoutSpace)
                    candidates = self._el.find_elements(By.XPATH, xpath)
                for candidate in candidates:
                    if text == candidate.text:
                        self._setSelected(candidate)
                        if not self.is_multiple:
                            return
                        matched = True
    
            if not matched:
                raise NoSuchElementException("Could not locate element with visible text: %s" % text)
    
        def deselect_all(self):
            """Clear all selected entries. This is only valid when the SELECT supports multiple selections.
               throws NotImplementedError If the SELECT does not support multiple selections
            """
            if not self.is_multiple:
                raise NotImplementedError("You may only deselect all options of a multi-select")
            for opt in self.options:
                self._unsetSelected(opt)
    
        def deselect_by_value(self, value):
            """Deselect all options that have a value matching the argument. That is, when given "foo" this
               would deselect an option like:
    
                <option value="foo">Bar</option>
    
               :Args:
                - value - The value to match against
    
                throws NoSuchElementException If there is no option with specisied value in SELECT
            """
            if not self.is_multiple:
                raise NotImplementedError("You may only deselect options of a multi-select")
            matched = False
            css = "option[value = %s]" % self._escapeString(value)
            opts = self._el.find_elements(By.CSS_SELECTOR, css)
            for opt in opts:
                self._unsetSelected(opt)
                matched = True
            if not matched:
                raise NoSuchElementException("Could not locate element with value: %s" % value)
    
        def deselect_by_index(self, index):
            """Deselect the option at the given index. This is done by examing the "index" attribute of an
               element, and not merely by counting.
    
               :Args:
                - index - The option at this index will be deselected
    
                throws NoSuchElementException If there is no option with specisied index in SELECT
            """
            if not self.is_multiple:
                raise NotImplementedError("You may only deselect options of a multi-select")
            for opt in self.options:
                if opt.get_attribute("index") == str(index):
                    self._unsetSelected(opt)
                    return
            raise NoSuchElementException("Could not locate element with index %d" % index)
    
        def deselect_by_visible_text(self, text):
            """Deselect all options that display text matching the argument. That is, when given "Bar" this
               would deselect an option like:
    
               <option value="foo">Bar</option>
    
               :Args:
                - text - The visible text to match against
            """
            if not self.is_multiple:
                raise NotImplementedError("You may only deselect options of a multi-select")
            matched = False
            xpath = ".//option[normalize-space(.) = %s]" % self._escapeString(text)
            opts = self._el.find_elements(By.XPATH, xpath)
            for opt in opts:
                self._unsetSelected(opt)
                matched = True
            if not matched:
                raise NoSuchElementException("Could not locate element with visible text: %s" % text)
    
        def _setSelected(self, option):
            if not option.is_selected():
                option.click()
    
        def _unsetSelected(self, option):
            if option.is_selected():
                option.click()
    
        def _escapeString(self, value):
            if '"' in value and "'" in value:
                substrings = value.split(""")
                result = ["concat("]
                for substring in substrings:
                    result.append(""%s"" % substring)
                    result.append(", '"', ")
                result = result[0:-1]
                if value.endswith('"'):
                    result.append(", '"'")
                return "".join(result) + ")"
    
            if '"' in value:
                return "'%s'" % value
    
            return ""%s"" % value
    
        def _get_longest_token(self, value):
            items = value.split(" ")
            longest = ""
            for item in items:
                if len(item) > len(longest):
                    longest = item
            return longest
    


  • 相关阅读:
    jvm基本结构和解析
    多态的意思
    java中对象的简单解读
    double类型和int类型的区别
    python 解析xml文件
    win10不能映射Ubuntu共享文件
    Qt程序打包
    Ubuntu boot分区文件误删,系统无法启动,怎么解
    ubuntu Boot空间不够问题“The volume boot has only 5.1MB disk space remaining”
    Ubuntu 分辨率更改 xrandr Failed to get size of gamma for output default
  • 原文地址:https://www.cnblogs.com/CCGGAAG/p/7800325.html
Copyright © 2020-2023  润新知