多窗口处理和网页frame
Selenium
里面如何处理多窗口场景?
多个窗口识别。
多个窗口之间切换。
Selenium
里面如何处理frame
?
多个frame
识别。
多个frame
之间切换。
一、多窗口处理
1.如何识别多窗口
点击某些链接,会重新打开一个窗口,对于这种情况,想在新页面上操作,就得先切换窗口 获取窗口的唯一标识用句柄windowhandle
表示,通过切换句柄实现窗口切换 2.步骤
先获取当前窗口的句柄driver.current_window_handle
再获取所有窗口句柄windows=driver.window_handles
遍历所有句柄,判断是否是要操作的窗口,如果是直接操作;如果不是切换到对应窗口(driver.switch_to.window(windows[-1])
)
只有用switch_to.window()
才能运行
二、frame处理
1.web自动化中,如果一个元素定位不到,那么很大可能是在frame中
2.什么是frame?
frame是html中的框架,在html中,所谓的框架就是可以在同一个浏览器中显示不止一个页面,分为垂直框架(cols)和水平框架(rows)
3.frame分类
frame标签分为:frameset、frame、iframe *frameset和普通标签(div)一样,可以使用index,id,name,webelement任意方式定位frame
在frameset中定义多个frame.在frame中添加html页的地址
*frame
和iframe
对selenium
一样,selenium有一组方法对frame进行操作 4.frame切换
driver.switch_to.frame() #根据元素id或者index切换
driver.switch_to.default_content() #切换到默认frame
driver.switch_to.parent_frame() #切换到父级frame
1)处理无嵌套的frame
直接使用driver.switch_to.frame() #根据元素id或者index切换,索引从0开始
2)处理有嵌套的frame
对于嵌套的先进入frame的父节点,再进入子节点,然后对子节点里面的对象进行处理和操作,一层层的切换
driver.switch_to.frame('父节点')
driver.switch_to.frame(‘子节点’)
class TestFrame: def setup(self): self.driver = webdriver.Chrome() self.driver.implicitly_wait(3) self.driver.maximize_window() def teardown(self): self.driver.quit() def test_frame(self): self.driver.get("https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable") self.driver.switch_to.frame("iframeResult")#从默认的frame切换到ID是“iframeResult”的frame print(self.driver.find_element(By.ID,"draggable").text)#打印当前文本 #self.driver.switch_to.parent_frame()切换到父的frame self.driver.switch_to.default_content()#切换到默认的frame print(self.driver.find_element(By.ID,'submitBTN').text)
selenium多浏览器处理
chorme、firefox、headless等浏览器的自动化支持
传不同参数来测试不同的浏览器,用来做浏览器兼容性测试。
def setup(self): browser = os.getenv("browser")#os.getenv获取传过来的参数 if browser == 'firefox'#判断browserc self.driver = webdriver.Firefox() elif browser == 'headless' self.driver = webdriver.PhantomJS() else: self.driver = webdriver.Chrome() self.driver.implicitly_wait(3) self.driver.maximize_window()
执行javascript脚本
组件无法定位到时使用selenium直接在当前页面中进行js交互。
js的处理
1、直接使用js操作页面,能解决很多click()不生效的问题。
2、页面滚动到底部、顶部。
3、处理富文本,时间控件的输入
document.title
输出网页的名字
window.alert("文本")
输出网页的警告信息
JSON.stringify(performance.timing)
获取当前页面的一些性能数据
selenium中如何调用js
execute_script
执行js
return
:可以返回js的返回结果
execute_script
: arguments
传参
document.documentElement.scrollTop=10000
在console
中将页面滚动到底部
document.documentElement.scrollTop=0
:回到顶部
element = self.driver.execute_script("return document.getElementById('su')")#js的获取ID的方法:document.getElementById,return:返回元素值 element.click() #滑动到当前屏幕的最低端 self.driver.execute_script("document.documentElement.scrollTop=10000") sleep(3) self.driver.find_element(By.XPATH, "//*[@id='page']/div/a[10]").click() sleep(3) #for code in [ # 'return document.title', 'return JSON.stringify(performance,timing)' #]: print(self.driver.execute_script("return document.title")) #print(self.driver.execute_script("return JSON.stringify(performance, timing)"))
时间控件
大部分时间控件都是readonly
(只读)属性,需要手动去选择对应的时间,手工测试中很容易做到,自动化中对控件的操作可以使用js
来操作。
思路:
1、要取消日期的readonly
属性
2、给value
赋值
再webdriver对js进行处理
a = document.getElementById("train_date") <input type="text" class="input" value="2018-07-21" id="train_date" aria-label="请输入日期,例如2021杠01杠01" autocomplete="off"> a.removeAttribute("readonly")#移除只读属性 undefined a.value=2022-03-01#赋新值 2018 a.value='2022-03-01' '2022-03-01'
文件上传
input
标签可以直接使用send_keys(文件地址)上传文件
self.driver.find_element(By.XPATH,"//*[@id='sttb']/img[1]").click() # self.driver.find_element(By.ID,"uploadImg").send_keys("/C:/Users/10697/Desktop/git.jpg")#具体路径
el = driver.find_element_by_id("上传按钮id") el.send_keys("文件路径+文件名")
弹框处理机制
在页面操作时会遇到一些JavaScript生成的alert,confirm,prompt弹框,这个时候可以用switch_to.alert()方法定位到。然后用text/accept/dismiss/send_keys等方法进行操作。
switch_to.alert() # 获取当前页面上的警告框 text() # 返回alert/confirm/prompt中的文字信息 accept() # 接受现有警告框 dissmiss() # 解散现有警告框 send_keys(keysToSend) # 发送文本至警告框,keysToSend:将文本发送至警告框
百度里的新闻就是window,新窗口;
switch_to.alert()方法定位到
div页面很复杂,有各种链接
alert只有确定或取消按钮
识别弹框是JavaScript生成的alert还是个div组件的最简单粗暴的方法:alert无法在浏览器的开发者工具中定位到
配置pageobject设计模式
解决赋值混用的情况
案例抽象化:操作细节、结果验证、操作细节、结果验证
测试分为操作细节、验证
中心:细节封装形成接口对外只提供方法,不提供细节。
只对主要模块进行封装建模,混用时断言和配置要分开。
pageobject六大原则
1、公共方法应代替页面服务,例如用send_keys代替输入框服务。
2、不要暴露细节
3、不要使用断言,断言要和配置代码分开写
4、一个方法要返回其他的配置
5、需求不要代表整个页面,只为页面中重要的元素创建page类
6、不同的结果会返回不同的方法,一个页面只代表一个模型
复用浏览器
原因:1、自动化测试中存在人为介入场景(如:扫码登录)
2、提高调试UI自动化测试脚本效率
配置步骤:
1、需要退出当前所有的谷歌浏览器(特别注意)
2、输入启动命令(windows:chrome -remote-debugging-port=9222;mac:Google\ chrome--remote-debugging-port=9222),通过命令启动谷歌浏览器
(1)、找到chrome的启动路径
右击浏览器图标,属性点击快捷方式。复制目标里的内容,到chrome.exe之前,复制路径,配置环境变量,重启命令行
(2)、配置环境变量
3、验证是否启动成功要关闭所有谷歌进程(localhost:9222)
windows要关闭谷歌浏览器进程,在任务管理器
from selenium.webdriver.chrome.options import Options #定义配置的实例对象option,实例化的是Options的类 option = Options() #修改实例属性为debug模式启动的ip+端口 option.debugger_address = "localhost:9222" #实例化driver的时候,添加option配置 driver = webdriver.Chrome(options=option) driver.get("https://work.weixin.qq.com/wework_admin/loginpage_wx?from=myhome_baidu")
优点:直接在已经搭建好的网页中操作,不用再每次登录
cookie是什么
cookie是一些数据,存储于你电脑上的文本文件中。当web服务器向浏览器发送web页面时,在连接关闭后,服务端不会记录用户的信息。
为什么要使用cookie自动化登录
1、复用浏览器仍然在每次用例开始都需要人为介入
2、若用例需要经常执行,复用浏览器则不是一个好的选择
3、大多数cookie的时效性都很长,扫一次可以使用多次
使用cookie思路
1、打开浏览器,扫码登录
2、确保登录之后,通过get_cookies获取cookie
3、检查本地文件是否已经获取成功
4、再次打开浏览器,通过cookie直接进入主页
常见问题:
1、企业微信cookie有互踢机制,在获取cookie成功之后不要再进行扫码操作
2、获取cookie的时候,即执行get_cookies()时,一定要确保已经登陆
3、植入cookie之后需要进入登录页面,刷新验证是否自动登录成功
API:
获取cookiedriver.get_cookies()
添加cookiedriver。add_cookie(cookie)
#获取cookie from selenium import webdriver import time import yaml # noinspection PyUnresolvedReferences class TestCookieLogin: def setup_class(self): self.driver = webdriver.Chrome() def test_get_cookies(self): #1.访问企业微信主页、登录页面 self.driver.get("https://work.weixin.qq.com/wework_admin/loginpage_wx?from=myhome_baidu") #2.等待20s,人工扫码操作 time.sleep(20) #3.等成功登录之后,再去获取cookie信息 cookie = self.driver.get_cookies() #print(cookie) #将cookie存入一个可持久存储的地方,文件 #打开文件的时候添加写入权限 with open("cookie.yaml", "w") as f:#打开文件的时候添加写入权限 yaml.safe_dump(cookie, f) def test_add_cookie(self): #1.访问企业微信主页面 self.driver.get("https://work.weixin.qq.com/wework_admin/loginpage_wx?from=myhome_baidu") #2.定义cookie,cookie信息从已经写入的cookie文件中获取 cookie = yaml.safe_load(open("cookie.yaml")) #3.植入cookie,cookie是表格形式要用循环输入信息 for c in cookie: self.driver.add_cookie(c) time.sleep(3) #4.再次访问企业微信页面,发现无需扫码自动登录 self.driver.get("https://work.weixin.qq.com/wework_admin/loginpage_wx?from=myhome_baidu")