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 \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



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM