在操作Web元素之前,需要先找到该元素,这个查找的过程称之为元素定位。
Selenium支持8种元素定位方法:
ID:根据元素的id属性值来定位元素。
Name:根据元素的name属性值来定位元素。
Class Name:根据元素的class属性值来定位元素。不允许使用复合类名,即当时,不能使用“class-a class-b”来定位该元素,但可以使用“class-a”或“class-b”来定位。
Tag Name:根据元素的HTML标签名来定位元素。
CSS Selector:根据CSS选择器来定位元素。CSS选择器常用语法如下表所示:
XPath:根据XPath表达式来定位元素。XPath全称XML Path Language,即XML路径语言,其常用语法如下表所示:
Link Text:根据超链接文本来定位元素。其基于XPath定位。
Partial Link Text:根据超链接中的部分文本来定位元素。其基于XPath定位。
By类中有8个类变量分别用于表示以上8种元素定位方法,然后结合WebDriver对象的find_element或find_elements方法使用,前者返回WebElement对象,后者返回WebElement列表对象。WebElement对象表示单个元素,WebElement列表对象表示一组元素。
一旦定位到了元素,即可对元素进行操作,比如输入文本、点击、获取文本等。
find_element和find_elements方法是WebDriver基类提供的,如果使用Chrome、Firefox等WebDriver的子类时,还可以调用诸如find_element_by_css_selector之类的快捷方法,可避免使用By类。
如果您还没部署IMS,请参考“Dubbo接口自动化测试(2):部署示例应用程序”。
以登录IMS为例演示元素定位及操作:
from time import sleepfrom selenium.webdriver import Chromefrom selenium.webdriver.common.by import Bywith Chrome() as driver: driver.get('http://localhost:9002/login') # 使用WebDriver基类的方法 username = driver.find_element(By.CSS_SELECTOR, "input[type='text']") username.send_keys('zhangsan') # 使用WebDriver子类Chrome的方法 password = driver.find_element_by_css_selector("input[type='password']") password.send_keys('zhangsan123456') button = driver.find_element_by_class_name('el-button') button.click() sleep(1) expected_element = driver.find_element_by_css_selector('#nav > div:nth-child(2) > span') assert expected_element.text == 'zhangsan'
以上代码分别使用send_keys和click方法进行了输入文本和点击的操作,并访问了WebElement对象的text属性获取元素的文本。在点击了登录按钮后,加了1秒的等待时间,否则有可能IMS首页还未加载完成,导致无法对IMS首页上的元素进行操作。
由于以上WebElement对象仅使用了一次,因此可以简化代码,比如将:
username = driver.find_element(By.CSS_SELECTOR, "input[type='text']")username.send_keys('zhangsan')
修改为:
driver.find_element(By.CSS_SELECTOR, "input[type='text']").send_keys('zhangsan')
除了以上介绍的send_keys和click方法,以及text属性,WebElement对象还可以进行更多操作,比如is_selected、is_enabled和is_displayed方法分别用于检验元素是否选中、检验元素是否启用和检验元素是否显示。
在实际项目中,经常需要遍历一组元素,并从该组元素中找到指定需求的某个元素。比如登录IMS后,在IMS首页的列表中查找是否存在MacBook Air电脑:
goods = driver.find_elements_by_css_selector('tbody > tr')exist = Falsefor good in goods: if good.find_element_by_class_name('el-table_1_column_2').text == 'MacBook Air': exist = True breakassert exist