1. 简介
"压轴" 原本是戏曲名词, 指一场折子戏演出的倒数第二个剧目. 在现代社会中有很多应用, 比如 "压轴戏", 但压轴也是人们知识的一个盲区."压轴" 本意是指倒数第二个节目, 而不是人们常说的倒数第一个, 倒数第一个节目称 "压台". 想看 "压台篇", 敬请关注宏哥
等待压台篇发布. 当然了, 宏哥不是唱戏啊, 而是分享技术类文章的. 好了言归正传回归正题.
之前的文章中, 针对元素的各种属性, 进行了相对应的操作, 而且对模拟键盘和鼠标的操作也有简单介绍. 那么接下来由宏哥带着各位小伙伴和童鞋们来详细地看看 selenium 如何模拟操作键盘和鼠标; 练习如何执行 JavaScript, 多窗口切换, 处理 iframe 切换等知
识和内容.
2. 键盘事件
webdriver 可以模拟常规键盘上所有的按键操作, 在导入包的源码中可以看到所有命令对应的按键.
以代码的形式来展示:
- # coding=utf-8
- # 1. 先设置编码, utf-8 可支持中英文, 如上, 一般放在第一行
- # 2. 注释: 包括记录创建时间, 创建人, 项目名称.
- '''
- Created on 2019-12-06
- @author: 北京 - 宏哥 QQ 交流群: 705269076
- Project: 《手把手教你》系列练习篇之 7-python+ selenium 自动化测试
- '''
- # 3. 导入模块
- import time
- from selenium import webdriver
- from selenium.webdriver.common.by import By
- from selenium.webdriver.common.keys import Keys
- driver = webdriver.Chrome()
- driver.get("https://www.baidu.com")
- # 键盘事件
- driver.find_element(By.ID, 'kw').send_keys("selenium&python?")
- time.sleep(3)
- driver.find_element(By.ID, 'kw').send_keys(Keys.BACK_SPACE) # 利用 backspace 键删除字符串最后一位
- time.sleep(3)
- driver.find_element(By.ID, 'kw').send_keys(Keys.SPACE) # 在字符串后空格键添加空格
- driver.find_element(By.ID, 'kw').send_keys("学习") # 继续在字符串后面添加字符串
- driver.find_element(By.ID, 'kw').send_keys(Keys.ENTER) # 输入回车 enter 键进行搜索
- time.sleep(3)
- driver.find_element(By.ID, 'kw').send_keys(Keys.CONTROL, 'a') # 全选搜索框中的内容
- driver.find_element(By.ID, 'kw').send_keys(Keys.CONTROL, 'x') # 剪切搜索框中的内容, 也可以使用 c 进行复制
- time.sleep(3)
- # 打开另外一个搜索网站, 输入刚刚剪切的内容
- driver.get("https://www.google.com")
- driver.find_element(By.ID, 'lst-ib').send_keys(Keys.CONTROL,
- 'v') # 粘贴刚刚复制, 剪切的内容
- driver.find_element(By.ID, 'lst-ib').submit() # 提交搜索
- time.sleep(3)
- """
- send_keys(Keys.BACK_SPACE) 删除键(BackSpace)
- send_keys(Keys.SPACE) 空格键(Space)
- send_keys(Keys.TAB) 制表键(Tab)
- send_keys(Keys.ESCAPE) 回退键(Esc)
- send_keys(Keys.ENTER) 回车键(Enter)
- send_keys(Keys.CONTROL, 'a') 全选(Ctrl+A)
- send_keys(Keys.CONTROL, 'c') 复制(Ctrl+C)
- send_keys(Keys.CONTROL, 'x') 剪切(Ctrl+X)
- send_keys(Keys.CONTROL, 'v') 粘贴(Ctrl+V)
- send_keys(Keys.F1) 键盘 F1
- ...
- send_keys(Keys.F12) 键盘 F12
- """
- driver.quit()
3. 鼠标事件
上面的键盘事件比较好理解, 鼠标事件的话直接看源代码或许就有些纠结了, 但是源代码的注释说明其实对 ActionChains 说明的比较清楚.
ActionChains 是一种自动执行低级别交互的方法, 例如鼠标移动, 鼠标按钮操作, 按键和上下文菜单交互. 这对于执行更复杂的操作非常有用, 例如悬停和拖放.
用户操作.
在 ActionChains 对象上调用操作方法时, 操作将存储在 ActionChains 对象的队列中.
当调用 perform()时, 事件将按它们排队的顺序触发.
ActionChains 可以用于链式或者可以将操作逐个排队, 然后执行.
无论哪种方式, 动作都按照它们被调用的顺序执行, 一个在另一个之后执行.
这里还是以代码展示部分功能吧:
- # coding=utf-8
- # 1. 先设置编码, utf-8 可支持中英文, 如上, 一般放在第一行
- # 2. 注释: 包括记录创建时间, 创建人, 项目名称.
- '''
- Created on 2019-12-06
- @author: 北京 - 宏哥 QQ 交流群: 705269076
- Project: 《手把手教你》系列练习篇之 7-python+ selenium 自动化测试
- '''
- # 3. 导入模块
- import time
- from selenium import webdriver
- from selenium.webdriver.common.by import By
- from selenium.webdriver.common.action_chains import ActionChains
- driver = webdriver.Chrome()
- driver.get("https://www.baidu.com")
- time.sleep(3)
- # 定位元素
- ele_1 = driver.find_element(By.XPATH, '//*[@id="u1"]/a[9]')
- ele_2 = driver.find_element(By.XPATH, '//*[@id="u1"]/a[8]')
- # 将鼠标悬停在元素 1 上 3 秒后再次悬停到元素 2 上
- ActionChains(driver).move_to_element(ele_1).perform()
- time.sleep(3)
- ActionChains(driver).move_to_element(ele_2).perform()
- time.sleep(3)
- driver.quit()
上述代码实现了在元素上进行悬停, 再移动至另一元素上.
还有其他操作如下:
"""
click(on_element=None) -- 单击鼠标左键
click_and_hold(on_element=None) -- 点击鼠标左键, 不松开
context_click(on_element=None) -- 点击鼠标右键
double_click(on_element=None) -- 双击鼠标左键
drag_and_drop(source, target) -- 拖拽到某个元素然后松开
drag_and_drop_by_offset(source, xoffset, yoffset) -- 拖拽到某个坐标然后松开
key_down(value, element=None) -- 按下某个键盘上的键
key_up(value, element=None) -- 松开某个键
move_by_offset(xoffset, yoffset) -- 鼠标从当前位置移动到某个坐标
move_to_element(to_element) -- 鼠标移动到某个元素
move_to_element_with_offset(to_element, xoffset, yoffset) -- 移动到距某个元素 (左上角坐标) 多少距离的位置
perform() -- 执行链中的所有动作
release(on_element=None) -- 在某个元素位置松开鼠标左键
send_keys(*keys_to_send) -- 发送某个键到当前焦点的元素
send_keys_to_element(element, *keys_to_send) -- 发送某个键到指定元素
"""
通过这些键盘和鼠标的操作, 就可以做更多了
4. 执行 JavaScript
前面文章介绍了 ActionChains 下的鼠标悬停和右键操作, 其实 ActionChains 还有其他方法, 你可以 action = ActionChains, 通过这, 先初始化一个 ActionChains 实例对象, 然后在 action 后面输入一个点号, 查看支持哪些 action 方法. 本文开始介绍如何执行 JS 脚本, 会用两个例子说明.
示例一, 执行 JS 脚本触发一个 alert 弹出框.
相关脚本代码如下:
4.1 代码实现:
4.2 参考代码:
- # coding=utf-8
- # 1. 先设置编码, utf-8 可支持中英文, 如上, 一般放在第一行
- # 2. 注释: 包括记录创建时间, 创建人, 项目名称.
- '''
- Created on 2019-12-05
- @author: 北京 - 宏哥 QQ 交流群: 705269076
- Project: python+ selenium 自动化测试练习篇 5
- '''
- # 3. 导入模块
- import time
- from selenium import webdriver
- driver = webdriver.Chrome()
- driver.maximize_window()
- driver.implicitly_wait(6)
- driver.get("https://www.baidu.com")
- time.sleep(1)
- driver.execute_script("window.alert('这是一个 alert 弹框.');") # 注意这里的分号是英文输入法的分号, 不能用中文
4.3 运行结果:
运行代码后, 控制台打印如下图的结果
4.4 浏览器运行结果
为了看得清楚, 我们这里还是不退出浏览器, 浏览器运行后, 如下图:
4.5 示例二
执行 JS 脚本来控制浏览器竖向滚动条
打开百度贴吧, 然后拖动滚动条到左侧 "地区"
4.5.1 代码实现:
4.5.2 参考代码:
- # coding=utf-8
- # 1. 先设置编码, utf-8 可支持中英文, 如上, 一般放在第一行
- # 2. 注释: 包括记录创建时间, 创建人, 项目名称.
- '''
- Created on 2019-12-05
- @author: 北京 - 宏哥 QQ 交流群: 705269076
- Project: python+ selenium 自动化测试练习篇 5
- '''
- # 3. 导入模块
- import time
- from selenium import webdriver
- driver = webdriver.Chrome()
- driver.maximize_window()
- driver.implicitly_wait(6)
- driver.get("https://tieba.baidu.com/index.html")
- time.sleep(1)
- target_elem = driver.find_element_by_link_text("地区")
- driver.execute_script("return arguments[0].scrollIntoView();",target_elem) # 用目标元素参考去拖动
- #driver.execute_script("scroll(0,2400)") # 这个是第二种方法, 比较粗劣, 大概的拖动
4.5.3 运行结果:
运行代码后, 控制台打印如下图的结果
4.5.4 浏览器运行结果
为了看得清楚, 我们这里还是不退出浏览器, 浏览器运行后, 如下图:
5. 多窗口之间切换
本文来介绍如何处理 driver 在多窗口之间切换, 想一下这样的场景, 在页面 A 点击一个连接, 会触发在新 Tab 或者新窗口打开页面 B, 由于之前的 driver 实例对象在页面 A, 但是你接下来的脚本是操作页面 B 的元素, 这样就造成了找不到元素的报错. 本来介绍 selenium 中 switch_to.Windows()方法来处理这个问题.
测试场景: 打开百度新闻(页面 A), 点击热点新闻中第一个新闻链接(一般是国家领导人的新闻), 会在第二个窗口打开这个新闻的具体详情页(页面 B), 测试需要去判断你点击这个这个新闻, 在打开的详情页是否正确.
问题拆分:
1. 我们已经知道 switch_to.Windows()方法可以处理窗口切换的问题
2. 在页面 A 跳转到页面 B 之前, 我们需要用一个变量保存这个新闻的标题
3. 切换到页面 B 后, 我们获取这个新闻标题, 然后和前面这个变量保存的值去对比, 如果相等, 那么就测试通过.
我们分两个步骤去解答这个测试需求:
1. 先实现页面 A 切换到页面 B
2. 页面 A 和页面 B 两个新闻标题进行对比
先看看窗口切换的脚本代码:
5.1 代码实现:
5.2 参考代码:
- # coding=utf-8
- # 1. 先设置编码, utf-8 可支持中英文, 如上, 一般放在第一行
- # 2. 注释: 包括记录创建时间, 创建人, 项目名称.
- '''
- Created on 2019-12-06
- @author: 北京 - 宏哥 QQ 交流群: 705269076
- Project: python+ selenium 自动化测试练习篇 5
- '''
- # 3. 导入模块
- import time
- from selenium import webdriver
- driver = webdriver.Chrome()
- driver.maximize_window()
- driver.get('http://news.baidu.com')
- time.sleep(1)
- driver.find_element_by_xpath("//*[@id='pane-news']/div/ul/li[1]/strong/a").click()
- print (driver.current_window_handle) # 输出当前窗口句柄
- handles = driver.window_handles # 获取当前全部窗口句柄集合
- print (handles) # 输出句柄集合
- for handle in handles:# 切换窗口
- if handle != driver.current_window_handle:
- print ('switch to second window',handle)
- driver.close() # 关闭第一个窗口
- driver.switch_to.Windows(handle) #切换到第二个窗口
5.3 运行结果:
运行代码后, 控制台打印如下图的结果
5.4 浏览器运行结果
为了看得清楚, 我们这里还是不退出浏览器, 浏览器运行后, 如下图:
代码解释:
1. 先打印当前窗口 (页面 A) 句柄, 一个长字符串
2. 获取全部窗口句柄, 这里我们有两个, 打印出这两个句柄.
3. for 循环遍历, 当发现其中一个句柄和当前句柄不相等, 这里做了三件事, 第一件, 打印一个语句, 告诉你马上要切换到第二个窗口, 第二件, 关闭当前窗口, 这里指页面 A, 第三, 切换到页面 B 窗口.
这里在切换到第二个页面时候, 我关闭之前的页面 A, 只是我个人测试习惯, 你可以不关闭, 但是你的要思路清晰, 哪些元素在页面 A 还是在页面 B, 如果操作了页面 B 后还要操作页面 A 的元素, 你还要切换到页面 A, 为了麻烦, 建议你每次切换都把前面页面给关闭.
5.4 断言切换的是不是你刚刚点击的新闻
判断在打开新页面显示的新闻标题是不是你刚刚点击的新闻, 脚本代码如下:
5.4.1 代码实现:
5.4.2 参考代码:
- # coding=utf-8
- # 1. 先设置编码, utf-8 可支持中英文, 如上, 一般放在第一行
- # 2. 注释: 包括记录创建时间, 创建人, 项目名称.
- '''
- Created on 2019-12-06
- @author: 北京 - 宏哥 QQ 交流群: 705269076
- Project: python+ selenium 自动化测试练习篇 5
- '''
- # 3. 导入模块
- import time
- from selenium import webdriver
- driver = webdriver.Chrome()
- driver.maximize_window()
- driver.get('http://news.baidu.com')
- time.sleep(1)
- news_link = driver.find_element_by_xpath("//*[@id='pane-news']/div/ul/li[1]/strong/a")
- page1_title_string = news_link.text #得到页面 A 新闻标题
- print('page1_title_string'+ page1_title_string)
- news_link.click() # 点击新闻链接
- time.sleep(1)
- handles = driver.window_handles
- for handle in handles:# 切换窗口(切换到搜狗)
- if handle != driver.current_window_handle:
- print ('switch to second window',handle)
- driver.close() # 关闭第一个窗口
- driver.switch_to.Windows(handle) #切换到第二个窗口
- page2_title_string = driver.find_element_by_xpath(".//*[@id='title_area']/h1").text # 详情页有一个原标题
- print('page2_title_string'+ page2_title_string)
- try :
- assert page1_title_string in page2_title_string # 判断页面 B 标题是否包含页面 A 标题
- print ('Test Pass.')
- except Exception as e:
- print ('Test Fail')
5.4.3 运行结果:
运行代码后, 控制台打印如下图的结果
注意: 很有可能遇到, 页面 A 的标题是简短, 页面 B 的标题是长标题, 这个时候就需要采取, 字符串包含的关系去断言, 我这里刚好打开的详情页有一个叫 "原标题: xxxx", 由于这个新闻具有时效性, 等你看这篇文章, 可能脚本运行不成功, 需要调整下脚本, 如果不
好断言, 就放弃断言部分, 本文只学窗口切换, 至于测试断言技能, 需要你不断去写脚本, 去掌握和提高的部分.
6. 小结
好了, 今天的练习就到这里, 希望大家好好的练习和理解.
您的肯定就是我进步的动力. 如果你感觉还不错, 就请鼓励一下吧! 记得点波 推荐 不要忘记哦!!!
来源: https://www.cnblogs.com/du-hong/p/11982636.html