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 windowalert也可以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的文本框里输入内容的代码如下:

# 如果没有idname属性,切换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来搞定,图片写绝对路径,如下图:

posted @ 2018-05-09 14:08  laosun0204  阅读(1582)  评论(0编辑  收藏  举报