Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 2546|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    4 天前
  • 签到天数: 803 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726482
    发表于 2021-9-7 16:27:26 | 显示全部楼层 |阅读模式

    在之前,遇到下拉框的时候我们可以用两次点击来选择我们需要的选项,不过对于下拉框,我们的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 \n  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
    


    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-11-21 14:20 , Processed in 0.691127 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表