selenium源码分析以及api讲解
第三方模块库(pip安装的)放在External Libraries下面的site-packages里,要把谷歌、火狐和IE浏览器的驱动放在python.exe的同级目录下,我的是放在C:\Miniconda3\Scripts(Scripts文件夹和python.exe文件是在同一个目录下),谷歌浏览器是51版本的,直接用那个驱动就行
什么是page object设计模式?
Page Object模式是使用Selenium的广大同行最为公认的一种设计模式,在设计测试时,把元素和方法按照页面抽象出来,分离成一定的对象,然后再进行组织
Page Object模式,创建一个对象来对应页面的一个应用,故我们可以为每个页面定义一个类,并为每个页面的属性和操作构建模型,体现在对界面交互细节的封装,测试在更上层使用页面对象,在底层的属性或者操作的更改不会中断测试,减少代码重复,提高测试代码的可读性和可维护性
将一个页面抽象成一个类,将这个页面上能够抽象成一个个方法
1、把每个页面当成一个页面对象,对页面的可操作功能进行封装
2、测试case通过调用页面对象的方式来完成case的编写
3、可以做到UI操作与case编写进行分离
UI自动化面试题的网址:http://www.imdsx.cn/index.php/2017/08/04/mianshi/
selenium流程:
selenium是经典的server-client设计模式,webdriver在启动的时候启动了server(浏览器),client(代码),创建了一个浏览器,通过session去指定我们要连接的浏览器,底层http请求调用浏览器源生api,处理我们的请求,点击、拖拽,执行完成之后返回结果,client端去处理,判断状态码是否为200,是否成功了,进而进行下一步操作
现在用的selenium是3.x版本的,完全用webdriver,之前的2.x版本采用selenium RC的方式,解析我们的客户端代码,转换成js代码执行操作,弊端是完全依赖于转换精准度
from selenium import webdriver
driver = webdriver.Chrome() # 启动谷歌浏览器
# driver = webdriver.Firefox() 启动浏览器,也可以使用火狐浏览器
# driver = webdriver.Ie() 启动浏览器,也可以使用IE浏览器
driver.get('http://ui.imdsx.cn/uitester/') # 请求目标网址,打开这个网址
driver.maximize_window() #全屏浏览器
from selenium import webdriver
option = webdriver.ChromeOptions() # Chrome的配置
option.add_argument('--start-maximized') # 启动就放大浏览器
driver = webdriver.Chrome(chrome_options=option) # 启动浏览器
driver.get('http://ui.imdsx.cn/uitester/') # 请求目标网址,打开这个网址
定位方式,也叫选择器(selenium提供了大概18种方式)
1、单数模式 8种(重点)
尽量用css_selector定位,css_selector定位不了使用xpath辅助定位
2、复数模式 8种,基本不用
3、底层实现 2种,基本不用
driver.find_element()
driver.find_elements()
常用api:
# 执行JavaScript语句,window.scrollTo(0,0)是操作滚动条,x轴是0,y轴>0就往下拉滚动条,重点
driver.execute_script('window.scrollTo(0,0)')
# 最大化当前窗口,不需要传参,重点
driver.maximize_window()
# 窗口操作:获取窗口的height和width
size = driver.get_window_size()
print(size) # 打印出{'width': 1936, 'height': 1056}
# 设置窗口的height和width
driver.set_window_size(2000, 1000)
# 浏览器的按钮操作
driver.find_element_by_link_text('跳转大师兄博客地址').click()
time.sleep(2)
driver.back() # 后退
time.sleep(2)
driver.forward() # 前进
time.sleep(2)
driver.refresh() # 刷新
截图当前页面:as_png的上层封装,只需要传入图片名称,在当前目录下自动生成图片,以.png结尾,如果以别的图片格式会报警告,重点
driver.get_screenshot_as_file('fileName.png')
# 返回当前url
print(driver.current_url)
# 返回浏览器名称
print(driver.name)
# 返回页面源码
print(driver.page_source)
# 返回标题
print(driver.title)
ElementApi接口:
# element.get_attribute,根据标签属性名称,获取属性value
element = driver.find_element_by_link_text('跳转大师兄博客地址')
data = element.get_attribute('innerText')
result = element.get_attribute('href')
print(data) # 打印出a标签之间的文案:跳转大师兄博客地址
print(result) # 打印出超链接路径:http://www.imdsx.cn/
# 向文本框发送字符串
element.send_keys('哈哈哈')
# is_selected(),判断是否勾选,返回一个布尔值
flag1 = driver.find_element_by_css_selector('#on').is_selected()
print(flag1) # 打印True
flag2 = driver.find_element_by_css_selector('#off').is_selected()
print(flag2) # 打印False
# is_displayed(),判断在页面是否展示,返回一个布尔值
flag = driver.find_element_by_css_selector('#dis1').is_displayed()
print(flag) # 源码里有display:none,打印False
# 清除文本框里的内容
element.clear()
# 鼠标左键点击操作
element.click()
# 获取浏览器全部的handles,和@property一起使用,后面不用加括号,重点
print(driver.window_handles)
# 获取当前浏览器handle,可以理解为窗口的名字,和@property一起使用,后面不用加括号,重点
print(driver.current_window_handle)
driver.find_element_by_link_text('新建标签页面').click()
# 获取浏览器全部的handles
print(driver.window_handles) # 打印的是一个list
# 获取当前浏览器handle
print(driver.current_window_handle) # 从打印结果可以看到,跳转到新的页面,默认还是显示之前的handle
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://ui.imdsx.cn/uitester/')
time.sleep(1)
driver.execute_script('window.scrollTo(0,0)') # 执行js脚本,操作滚动条,x轴是0,y轴>0就往下拉
time.sleep(1)
driver.maximize_window()
# 获取浏览器全部的handles
print(driver.window_handles)
# 获取当前浏览器handle
print(driver.current_window_handle)
driver.find_element_by_link_text('新建标签页面').click()
# 获取浏览器全部的handles
print(driver.window_handles)
# 获取当前浏览器handle
print(driver.current_window_handle) # 从打印结果可以看到,跳转到新的页面,默认还是显示之前的handle
driver.switch_to.window(driver.window_handles[-1]) # switch_to.window切换到另一个页面,-1代表新打开的窗口
print('切换完成后:', driver.current_window_handle)
driver.find_element_by_css_selector('#newtag').send_keys('切换成功了') # 在新页面输入内容
driver.close()
time.sleep(2)
driver.switch_to.window(driver.window_handles[-1]) # 关闭新页面后切换到最初的页面,取0和-1都可以
time.sleep(2)
driver.find_element_by_css_selector('#i1').send_keys(111111)
driver.quit()
# 关闭与退出:
# 全部退出webdriver的浏览器,重点
driver.quit()
# 只退出当前的tag页面
driver.close()
# alert三种操作方式,了解就行
driver.switch_to.alert.dismiss() # 取消
driver.switch_to.alert.accept() # 确认
print(driver.switch_to.alert.text) # 获取文案,和@property一起使用,后面不用加括号
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://ui.imdsx.cn/uitester/')
driver.execute_script('window.scrollTo(0,0);')
driver.find_element_by_css_selector('#alert').click() # 点击alert按钮,弹出提示框
driver.switch_to.alert.accept() # 关闭提示框,确定
driver.find_element_by_css_selector('#confirm').click()
driver.switch_to.alert.dismiss() # 关闭提示框,取消
driver.find_element_by_css_selector('#confirm').click()
print(driver.switch_to.alert.text) # 获取文案,在pycharm里打印文案,打印出CONFIRM弹框!!
可以switch_to window、alert也可以switch_to frame
标签iframe的重点:iframe是一层一层的跳转
1、driver.switch_to.frame('attribute') # 向下跳一层,直接传id或name的属性值
2、driver.switch_to.parent_frame() # 向上跳一层
3、driver.switch_to.default_content() # 跳到最外层
selenium学习页面->新建标签页面->百度页面,然后再从百度页面跳到新建标签页面的代码如下:
从selenium学习页面跳到新建标签页面,再跳到百度页面,在百度输入框里输入内容,然后跳到最外层,在id为i1的文本框里输入内容的代码如下:
# 如果没有id或name属性,切换iframe通过对象的方式也是ok的
element = driver.find_element_by_css_selector('[src="/new-index/"]')
driver.switch_to.frame(element)
driver.find_element_by_css_selector('#newtag').send_keys(111)
# select模块,HTML中通过select标签生成的下拉框,就可以通过Select模块进行处理
# 鼠标悬浮操作
点击鼠标悬浮下的双击按钮,第一种方式是用move_to_element,鼠标悬浮到目标元素上再click,代码如下:
import time
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains # 连贯操作,把多个函数名追加到一个数组里,然后.preform就能实现连贯操作
driver = webdriver.Chrome()
driver.get('http://ui.imdsx.cn/uitester/')
time.sleep(1)
driver.execute_script('window.scrollTo(0,0)')
time.sleep(1)
driver.maximize_window()
action = ActionChains(driver)
element = driver.find_element_by_css_selector('#a')
element2 = driver.find_element_by_css_selector('#dis1')
action.move_to_element(element).click(element2).perform() # 看源码把两个函数名放到一个list里,perform是使函数运行
time.sleep(3)
driver.quit()
第二种方式是用操作js,通过id找到鼠标悬浮清空下方input框value参数这个div,通过js将display为none改为空,然后可以看到双击按钮,点击即可
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://ui.imdsx.cn/uitester/')
time.sleep(1)
driver.execute_script('window.scrollTo(0,0)')
time.sleep(1)
driver.maximize_window()
js = "document.getElementById('dis1').style.display=''" # 将style属性的display属性干掉,把none改为空
driver.execute_script(js)
time.sleep(2)
driver.find_element_by_css_selector('#dis1').click()
time.sleep(3)
driver.quit()
拼图,drag_and_drop(element,target),element是源,target是拖拽到的位置,代码如下:
import time
from selenium.webdriver.common.action_chains import ActionChains # 连贯操作
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://ui.imdsx.cn/move/')
time.sleep(1)
driver.execute_script('window.scrollTo(0,0)')
time.sleep(1)
driver.maximize_window()
s0 = driver.find_element_by_css_selector('#dragger')
s1 = driver.find_element_by_css_selector('#dragger1')
s2 = driver.find_element_by_css_selector('#dragger2')
s3 = driver.find_element_by_css_selector('#dragger3')
t0 = driver.find_element_by_css_selector('#i1')
t1 = driver.find_element_by_css_selector('#i2')
t2 = driver.find_element_by_css_selector('#i3')
t3 = driver.find_element_by_css_selector('#i4')
time.sleep(2)
ActionChains(driver).drag_and_drop(s0, t0).drag_and_drop(s1, t1).drag_and_drop(s2, t2).drag_and_drop(s3, t3).perform()
time.sleep(3)
driver.quit()
# deselect_by_value,通过value属性,来取消对应option,取消选中,只用于多选,[@name='city'][2]是多选框
# element = driver.find_element_by_xpath("//select[@name='city'][2]")
# Select(element).deselect_by_value('4')
对于处理上传图片的定位,如果是input类型的可以通过send keys来搞定,图片写绝对路径,如下图: