UI自动化层级定位+切换iframe框架
题记:
今天给大家讲一下ui的层级定位/父子级定位,以及切换iframe框架
层级定位
在实际的项目测试中,经常会遇到无法直接定位到需要选取的元素,但是其父元素比较容易定位,通过定位父元素再遍历其子元素选择需要的目标元素,或者需要定位某个元素下所有的子元素。
层级定位的思想是先定位父对象,然后再从父对象中精确定位出其我们需要选取的后代元素。
语法举例
- 示例代码
# -*- coding: utf-8 -*-
# @Time : 2021/12/29 20:02
# @Author : Limusen
# @File : demo_father_son
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
# 执行这个语句会报错
# driver.find_element(By.XPATH,'//*[@id="form"]/span[1]').send_keys("ssdasd")
# 执行这个语句不会报错
# driver.find_element(By.XPATH,'//*[@id="kw"]').send_keys("ssdasd")
# 根据层级关系查找
driver.find_element_by_css_selector("span.bg.s_ipt_wr.new-pmd.quickdelete-wrap").find_element_by_id(
"kw").send_keys("测试父子级定位")
iframe框架概念跟操作
定位frame中的对象
在web应用中经常会出现frame嵌套的应用,假设页面上有A,B两个frame,其中B在A内,那么定位B中的内容则需要先到A,再到B。
switch_to_frame方法可以把当前定位的主题切换到frame里,在frame里实际是嵌套了另外一个页面,而webdriver每次只能在一个页面识别,所以需要用switch_to_frame方法去获取frame中嵌套的页面。
driver.switch_to.default_content()#将识别的主体切换出frame
print(driver.find_element_by_css_selector("#id1").text)
switch_to.frame的参数必须是id或者是name,所以一个frame只要有id和name处理起来很容易。
如果没有的话,两种解决思路:
1.让开发加上id或者name
2.使用xpath等方式定位然后实现跳转
- 示例代码
# -*- coding: utf-8 -*-
# @Time : 2021/12/29 20:15
# @Author : Limusen
# @File : demo_baidu_login
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://sahitest.com/demo/iframesTest.htm")
driver.implicitly_wait(10)
# # 直接定位到link位置
# driver.find_element_by_xpath("/html/body/table/tbody/tr/td[1]/a[1]").click() # 发现脚本会报错 找不到这个元素
# 定位到iframe 当前是定位到左边框架
element = driver.find_element_by_xpath('//iframe[@style="float:left;margin:20px;"]')
driver.switch_to.frame(element)
time.sleep(2)
driver.find_element_by_xpath('/html/body/table/tbody/tr/td[1]/a[1]').click()
# 跳出框架
driver.switch_to.default_content()
time.sleep(2)
# 定位iframe框架中的iframe框架
element = driver.find_element_by_xpath('//div[@id="another"]/iframe')
driver.switch_to.frame(element)
time.sleep(2)
driver.find_element_by_xpath('/html/body/table/tbody/tr/td[1]/a[1]').click()
操作浏览器弹出框
alert/confirm/prompt处理
Alert提供了以下几个方法
- 语法举例
driver.find_element_by_id(“alert”).click() time.sleep(3)
driver.switch_to.alert.accept()
driver.find_element_by_id(“confirm”).click() time.sleep(3)
driver.switch_to.alert.dismiss()
driver.find_element_by_id(“prompt”).click() time.sleep(3)
driver.switch_to.alert.send_keys(“123456”) time.sleep(3)
driver.switch_to.alert.accept()
备注:send_keys这个方法在chromedriver中输入后不会显示。
- 示例代码
# -*- coding: utf-8 -*-
# @Time : 2021/12/30 10:22
# @Author : Limusen
# @File : demo_iframe_09
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://sahitest.com/demo/jsPopup.htm")
driver.implicitly_wait(5)
driver.find_element_by_xpath('//button').click()
# 处理alert弹框
time.sleep(2)
driver.switch_to.alert.accept() # 确认按钮
time.sleep(2)
# 取消按钮
driver.switch_to.alert.dismiss()
time.sleep(2)
driver.switch_to.alert.send_keys("测试一下输入")
time.sleep(2)
driver.switch_to.alert.dismiss()
#备注:send_keys这个方法在chromedriver中输入后不会显示。
下拉框详解
下拉框处理
web页面上经常会有下拉框,对下拉框的处理比较简单,一般分为两种情况:
1、下拉框通过元素定位识别,举例:driver.find_element(By.XPATH,'//option[@value="mango"]').click()上面的元素为下拉框中的选项。
2、创建一个select的对象,然后通过相应方法处理,
举例:
selectElement=driver.find_element(By.XPATH,'//select[@id="Selector"]')
s=Select(selectElement)
s.select_by_index(2) #索引定位,索引从0开始
time.sleep(2)
s.select_by_value("mango")#value属性的值
time.sleep(2)
s.select_by_visible_text("桔子") #可见文本内容
- 示例代码
# -*- coding: utf-8 -*-
# @Time : 2021/12/30 10:22
# @Author : Limusen
# @File : demo_selector_10
import time
import random
from selenium import webdriver
from selenium.webdriver.support.select import Select
driver = webdriver.Chrome()
driver.get("https://sahitest.com/demo/selectTest.htm")
driver.implicitly_wait(5)
# 定位到下拉框元素
selectElement = driver.find_element_by_xpath("//select[@id='s3Id']")
s = Select(selectElement)
s.select_by_index(2) # 根据下标选择下拉框第三个元素
time.sleep(2)
s.select_by_value("o4val") # 元素的value值
time.sleep(2)
s.select_by_visible_text("o3") # 可见文本内容
# 定位到元素列表然后随机选择一个元素选择
time.sleep(2)
selectElement= driver.find_element_by_xpath("//select[@id='s1']")
time.sleep(2)
selectElement.click()
time.sleep(2)
elements = driver.find_elements_by_xpath("//select[@id='s1']/option")
time.sleep(2)
random.choice(elements).click()
调用js操作元素
调用javascript
当webdriver遇到无法完成的操作时候,这个时候可以使用javascript来完成,webdriver提供了execute_script()接口来调用js代码。
执行js有两种场景:
一种是在页面上直接执行js , 另一种是在某个已经定位的元素上执行js
举例:
driver.execute_script('alert(“hello!!”);')#弹出窗口
driver.execute_script(“arguments[0].style.border='5pxsolidred'”,wl)#加边框
js=“varuser_input=document.getElementById('su').getAttribute('id');
returnuser_input;”driver.execute_script(js)#识别并获取对象属性
driver.execute_script(“document.body.scrollTop=10000;”)#浏览器滚动条滚动
Js=‘arguments[0].removeAttribute(“value”);’#移除元素的value属性
Js=‘arguments[0].setAttribute(“value”,“newdream”);’#设置元素的value属性
driver.execute_script(js,wl)
- 示例代码
# -*- coding: utf-8 -*-
# @Time : 2021/12/30 11:45
# @Author : Limusen
# @File : demo_page_js_11
# 执行js脚本
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.maximize_window()
driver.implicitly_wait(10)
time.sleep(2)
# 执行js脚本
driver.execute_script("alert('测试页面弹框')")
time.sleep(2)
driver.switch_to.alert.accept()
wl = driver.find_element_by_xpath('//*[@id="kw"]')
driver.execute_script("arguments[0].style.border='5px solid red'", wl) # 加边框
time.sleep(2)
# 获取元素的属性
js = "var user_input= document.getElementById('su').getAttribute('id'); return user_input;"
driver.execute_script(js)
id = driver.execute_script('return document.getElementById("su").getAttribute("id");')
value = driver.execute_script('return document.getElementById("su").getAttribute("value");')
class_name = driver.execute_script('return document.getElementById("su").getAttribute("class");')
name = driver.execute_script('return document.getElementById("kw").getAttribute("name");')
print(id)
print(value)
print(class_name)
print(name)
# 滚动条操作,封装成函数
driver.find_element_by_name("wd").send_keys("测试一下")
time.sleep(2)
driver.find_element_by_id("su").click()
time.sleep(1)
js = "window.scrollBy(0,500)"
driver.execute_script(js)
time.sleep(2)
js = "window.scrollBy(0,500)"
driver.execute_script(js)
js = "window.scrollBy(0,-1000)"
driver.execute_script(js)
# def scoll(driver, heigh):
# time.sleep(2)
# js = "window.scrollBy(0," + str(heigh) + ")"
# driver.execute_script(js)
# scoll(driver, 500)
# time.sleep(2)
# scoll(driver, 1000)
# 改元素的属性
el = driver.find_element_by_name("wd")
js = 'arguments[0].removeAttribute("id")'
driver.execute_script(js,el)
js = 'arguments[0].setAttribute("value","newdream")'
driver.execute_script(js)
time.sleep(2)
driver.quit()
页面切换句柄
浏览器多窗口处理
有时候我们在测试一个web应用的时候会出现多个浏览器窗口的情况,webdriver提供了相应的解决方案,如下:首先要获得每一个窗口的唯一标识符号(句柄),通过获得的句柄来区分不同的窗口,从而对不同窗口上的元素进行操作。
举例:
now_handle=driver.current_window_handle#获取当前窗口句柄
driver.find_element_by_css_selector('a.pass-reglink').click()
time.sleep(2)
all_hands=driver.window_handles#获取所有窗口的句柄
for hands in all_hands:
if hands!=now_handle:
driver.switch_to_window(hands)#通过句柄跳转窗口
driver.find_element_by_name("account").send_keys("123456")
driver.close()#关闭新打开的窗口
driver.switch_to_window(nowhandle)#回到之前的窗口
driver.find_element_by_css_selector("a.close-btn").click()
- 示例代码
# -*- coding: utf-8 -*-
# @Time : 2021/12/30 11:45
# @Author : Limusen
# @File : demo_page_js_11
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.maximize_window()
driver.implicitly_wait(10)
time.sleep(2)
# 获取百度的句柄
now_handle = driver.current_window_handle
print(now_handle)
# 点击hao123
driver.find_element_by_xpath('//*[@id="s-top-left"]/a[2]').click()
# 获取所有句柄
all_handle = driver.window_handles
print(all_handle)
# 切换句柄 切换到新句柄当中
driver.switch_to.window(all_handle[1])
time.sleep(1)
driver.find_element_by_xpath('//*[@id="search"]/form/div[2]/input').send_keys("切换句柄之后输入")
time.sleep(1)
driver.find_element_by_xpath('//*[@id="search"]/form/div[3]/input').click()
# 跳回原来页面
driver.switch_to.window(now_handle)
通过处理cookie信息,绕过登录
cookie处理
- 示例代码
# -*- coding: utf-8 -*-
# @Time : 2021/12/30 11:45
# @Author : Limusen
# @File : demo_page_js_11
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.cnblogs.com/")
driver.implicitly_wait(10)
# # 获取cookie
# time.sleep(60)
# cookies = driver.get_cookies()
# for cookie in cookies:
# print(cookie)
# 添加cookies
time.sleep(2)
driver.add_cookie({'domain': '.cnblogs.com', 'httpOnly': True, 'name': '.CNBlogsCookie', 'path': '/', 'secure': False, 'value': '1314E64052AFA5D9C750AD2E9E465A723592E9CB678E6DA1B68F8535EB07C9C4971BB4B5C1AEF448245C67A196B926C14E0A7ADB11E22826E3719DC967E881A44D1021EBC1E1F3B489FBDEE52487A7B6A3BCE717'})
driver.add_cookie({'domain': 'www.cnblogs.com', 'httpOnly': True, 'name': '.AspNetCore.Antiforgery.b8-pDmTq1XM', 'path': '/', 'secure': False, 'value': 'CfDJ8GsLOKiGtk1Au0UP1SouGdWCoD8gCqTvivwLXs6zGnDbTlG2hDcH7vXTjBcuLfr2ORpoZDwNyPOYuRFEEUWa4P91FQz7HCl2AaAEBTZJs6fAf4QtmrVZ7NfGHHxdxJC5AGd3dDUUvmWLjYuUwOPGyYo'})
driver.add_cookie({'domain': '.cnblogs.com', 'expiry': 1703915500, 'httpOnly': False, 'name': '_ga', 'path': '/', 'secure': False, 'value': 'GA1.2.285569987.1640843473'})
driver.add_cookie({'domain': '.cnblogs.com', 'httpOnly': False, 'name': 'Hm_lpvt_866c9be12d4a814454792b1fd0fed295', 'path': '/', 'secure': False, 'value': '1640843500'}
)
driver.add_cookie({'domain': '.cnblogs.com', 'expiry': 1672379500, 'httpOnly': False, 'name': 'Hm_lvt_866c9be12d4a814454792b1fd0fed295', 'path': '/', 'secure': False, 'value': '1640843472'})
driver.add_cookie({'domain': '.cnblogs.com', 'expiry': 1703915499, 'httpOnly': False, 'name': '_ga_3Q0DVSGN10', 'path': '/', 'secure': False, 'value': 'GS1.1.1640843475.1.1.1640843499.36'})
driver.add_cookie({'domain': '.cnblogs.com', 'httpOnly': True, 'name': '.Cnblogs.AspNetCore.Cookies', 'path': '/', 'secure': False, 'value': 'CfDJ8GsLOKiGtk1Au0UP1SouGdUrAXCnnNWytA-q0doJUXW33Asw81g-6FAy__3mnkDZUSq-cYPkDXtJo9RCzXl7CfcAkX8no75DcaKyPDTlB52nME1_YNqBXaPjJxNQ_NKBnUIu0z7bWDX2Nlr3jKk8FtHfxXIM6GMIN5yn0RW2zVqZyGvWSPG6kwc68CnSNAhFArV8YZBrmJHrLGPp89F3kJkHQe8XotQjscvaj2E-FGHPbMPTXhh8U3iveHf8MDiAChZr2dkPhbe6VWp1RxWqgrkHitnaayzT_qY66qimE3_K2_B-7uHO23qUgQY8UFpbIk0zH-IxnKtQxWG2M-kk_X_q3b9oOCRx0GXrLYvRONQVzkgHIxu6c_BpEN3Ol-yHgr_EpFRtaDwZLi_7tFOVVwkyOWdBmVHHq220KG_LKloS0E2aPLBRmOVKvkGIjct8lTzCNmALcT0_NinO8oEhPqFmcMrtZrW-J5qJUMoo7MUZhqjd30ndzfxZRaawU1Crvfa2t-NBlQ1ipcpAmrAeSUGxsJRP_GRTFCTOgm0Tye6-'})
driver.add_cookie({'domain': '.cnblogs.com', 'expiry': 1640929900, 'httpOnly': False, 'name': '_gid', 'path': '/', 'secure': False, 'value': 'GA1.2.740095988.1640843473'}
)
driver.refresh()
- 获取cookie
- 添加cookies
- 刷新页面,登录成功
总结
本章节主要讲述了层级定位,iframe框架切换,句柄的切换,js的操作,以及如果使用cookies绕过登录,下一章节我们将学习unittest的一些操作
代码地址
https://gitee.com/todayisgoodday/PythonSelenium
CSDN地址
https://blog.csdn.net/weixin_42382016/category_11566096.html