from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException, UnexpectedTagNameException
"""
1、如果抛出NoSuchElementException,UnexpectedTagNameException这两个异常,则是select语句哪里写错了。
2、只解读了select相关的方法。
"""
class Select(object):
def __init__(self, webelement):
"""
判断元素标签,如果不是select,则抛出
UnexpectedTagNameException("Select only works on <select> elements, not on <%s>" % webelement.tag_name)】
"""
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"
def options(self):
"""返回属于该选择标签的所有选项的列表 """
return self._el.find_elements(By.TAG_NAME, 'option')
def all_selected_options(self):
"""返回一个列表:包含所有选择的内容"""
ret = []
for opt in self.options:
if opt.is_selected():
ret.append(opt)
return ret
def first_selected_option(self):
"""返回列表的first,否则抛出异常
NoSuchElementException("No options are selected")
"""
for opt in self.options:
if opt.is_selected():
return opt
raise NoSuchElementException("No options are selected")
def select_by_value(self, value):
"""
选择元素的value属性值,例如:<option value="foo">Bar</option>
如果没有value属性值,则抛出异常:
NoSuchElementException("Cannot locate option with value: %s" % value)
"""
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):
"""
通过索引值来搜索对象,如果没有这个值,则抛出异常
NoSuchElementException("Could not locate element with index %d" % index)
"""
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):
"""
通过text值来获取选项的值,text类似如下的 Bar
<option value="foo">Bar</option>
如果text写错了,则抛出异常:
NoSuchElementException("Could not locate element with visible text: %s" % text)
"""
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)
以界面元素、实际运用举例:
from selenium import webdriverd
from selenium.webdriver.support.ui import Select
driver = webdriver.Firefox()
driver.get('http://sahitest.com/demo/selectTest.htm')
# 这是第一个下拉框!!!
s1 = Select(driver.find_element_by_id('s1Id')) # 注意 siID 是什么,这块容易出问题
s1.select_by_index(1) # 索引值
s1.select_by_value("o2") # value属性的值
s1.select_by_visible_text("o3") # 文本值
就记录下这三个,其他用的少,了解下就行,这三个是要封装在基本操作里面的。
po设计模式框架下的封装:
class Base:
# select一般都是有id的,所以这里定位直接上id,text比较常用,
def select_text(self, id, text):
return Select(self.find_element_by_id(id)).select_by_visible_text(text)
def select_index(self, id, index):
return Select(self.find_element_by_id(id)).select_by_index(index)
def select_value(self, id, value):
return Select(self.find_element_by_id(id)).select_by_value(value)