Python+selenium 【第六章】UI自动化框架操作测试对象

UI自动化层级定位+切换iframe框架

题记:  

  今天给大家讲一下ui的层级定位/父子级定位,以及切换iframe框架

 

层级定位

    在实际的项目测试中,经常会遇到无法直接定位到需要选取的元素,但是其父元素比较容易定位,通过定位父元素再遍历其子元素选择需要的目标元素,或者需要定位某个元素下所有的子元素。

层级定位的思想是先定位父对象,然后再从父对象中精确定位出其我们需要选取的后代元素。

语法举例

  driver.find_element_by_id(‘***’).find_element_by_link_text(‘***’) 
  • 示例代码

# -*- 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.frame('frame1') #移动到id为frame1的frame上printdriver.find_element_by_css_selector("#div1").text

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处理

 
  WebDriver中处理原生JS的alertconfirm以及prompt非常方便。具体思路是使用switchTo.alert()方法定位到当前的alert/confirm/prompt(这里注意当前页面只能同时含有一个控件,如果多了会报错的,所以这就需要一一处理了),然后在调用Alert的方法进行操作
 

Alert提供了以下几个方法

 
 text:返回alert/confirm/prompt中的文字内容
 accept:点击确认按钮
 dismiss:点击取消按钮如果有取消按钮的话
 sendKeys:向prompt中输入文字
 
  • 语法举例

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处理

  利用cookie完成网站的免密码应用代码思路:
  
第一阶段:
 
打开网站的登录页面获取登录之前的cookie等待60s,这个时间手动去输入用户名、密码、验证码登录获取登录之后的cookie把登录之后的cookie与登录之前的cookie打印并进行对比找出登录之后不同的cookie或增加的cookie信息
  
第二阶段:
 
新编写一个脚本打开网站的登录页面用add_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

原文地址:https://www.cnblogs.com/yushengaqingzhijiao/p/15748483.html