WebUI自动化学习(Selenium+Python+Pytest框架)004

接下来,WebUI基础知识最后一篇。

1.下拉框操作

关于下拉框的处理有两种方式

(1)按普通元素定位

        安装普通元素的定位方式来定位下拉框,使用元素的操作方法element.click()方法来操作下拉框内容的选择

(2)使用Select()类

        Select()封装了3种可以查找下拉框选项的方法,实现对下拉框选项的选择,不用在进行点击动作,找到就直接选中了

        使用流程:

                定位到下拉框元素        driver.find_element_by_xxx('XXX')

                实例化下拉框选项类        select= Select(element)

                调用查找方法               

                                select.select_by_index('选项下标')

                                select_by_value('选项的Value值')

                                select_by_visible_text('选项的文本内容')

                    

2.滚动条操作

Selenium没有对于滚动条的相关处理类或者方法,但是Selenium提供了其他脚本语言的执行方法,所以我们可以使用其他脚本语言来实现对滚动条的操作,再使用Selenium的execute_Script()方法调用这个实现语句,执行对滚动条的操作。

代码示例

# 导包
from time import sleepfrom selenium import webdriver# 实例化浏览器对象
driver = webdriver.Chrome()
# 打开浏览器
driver.get('https://www.baidu.com')
# 展示效果
sleep(1)
# 浏览器窗口最大化
driver.maximize_window()
# 隐式等待
driver.implicitly_wait(10)
sleep(2)
driver.find_element_by_id('kw').send_keys('Test')
driver.find_element_by_id('su').click()
sleep(2)
# 设置JS脚本控制滚动条(左边距,上边距),将JS代码作为字符串,传参给excuse_sctipt()方法
js1 = "window.scrollTo(0,2000)"
js2 = "window.scrollTo(0,0)"
# 执行JS脚本,利用selenium提供的执行脚本方法excuse_script()
driver.execute_script(js1)
sleep(2)
driver.execute_script(js2)
sleep(2)
# 关闭浏览器
driver.quit()

3.弹窗处理

(1)为什么要进行弹窗处理

在项目中有些特殊页面,需要在用户进行了错误操作或遗漏了某些操作时,进行弹窗提示。例如:博客写完没保存,用户就想离开页面会关闭浏览器。

这里说的弹窗是通过页面右键没有"检查"选项的那种浏览器弹窗,如下图。不是指前端写的具备风格的、可以定位到的那种。

当这种弹窗弹出的时候,如果不对它进行处理,是不可以再继续进行页面操作的,不管是选择确认还是选择取消,都要处理。

(2)弹窗有哪几种

警告类:alert,只是警告用户遗漏了操作,用户可以选择继续操作或取消操作留在当前页面

确认类:confirm,用户进行了有风险的操作,或者浏览器想要进行某种操作需要用户允许。

业务流程类:需要用户输入内容来判断页面给出哪种操作,例如,输入密码才能显示某些内容。

(3)怎样处理弹窗

以上提到的弹窗,在Selenium中统一被称为alert类,处理思路如下:

①将操作对象切换到弹窗上

        alert = driver.switch_to.alert                提示:没有括号

②对弹窗进行操作

        alert.text        获取弹窗的文本,用作断言

        alert.accept()        接受弹窗内容,即确认

        alert.dismiss()        拒绝弹窗内容,即取消

4.切换Frame

(1)为什么要切换frame

有些项目,页面部署分为多个模块,每个模块实现不同的功能区,通常会把这些模块写成不同的frame。或者在接收到用户的特定操作后,弹出一个处理弹窗,这个弹窗通常也会写成一个单独的frame。

例如CSDN的登录功能,当没有登录的用户在首页点击登录时,弹出一个登录窗。在这个登录窗口上右键"检查",沿层级向上查找,我们就可以看到,这个窗口全部封装在一个叫做 iframe的模块标签里。

当遇到这类页面时,采用普通定位方法去定位元素时,我们就会发现,写的代码绝对没有问题,但是就是找不到报错。就是因为我们在进入页面时,操作对象在这个页面的默认frame里,不同的frame是存在隔绝的,如果页面出现了除了默认frame之外的frame,我们在默认frame里是看不到里面的内容的。

(2)怎样实现frame切换

        ①定位iframe,找到frame的属性(id,name,xpath或CSS)

        ②driver.swicth_to.frame(id/name/element)         参数值可以是唯一标识frame的id值、name值、也可以是一个元素对象driver.find_element_by_XXX(XXX)

(3)多个frame切换时,怎样实现

用一个实例理解一下:一个页面好比是一栋房子,多个frame就像这个房子的多个房间,每个房间之间有墙隔开,只能通过门相互进出。我们使用get方法打开这个页面,就像进入一个房子的时候会默认进客厅(一个公共区域),在客厅里我们没办法拿到卧室的东西,也看不到卧室有什么。想要进卧室拿东西就要打开卧室门进去,driver.swicth_to.frame()就是开门进入卧室这个动作。那么我们进入卧室拿到了想要的东西以后还想进厨房怎么办呢?就要先从卧室出来,回到公共区域,在从公共区域打开厨房门进入厨房。

所以当页面有多个frame,想要实现两个frame之间的切换,就要先从frame回到默认模块driver.switch_to.default_content()    再从默认模块进入另一个frame。

代码示例

# 进入frame1,以下三种写法都可以
driver.switch_to.frame('frame1_id')
driver.switch_to.frame('frame1_name')
driver.switch_to.frame(driver.find_element_by_xpath('//*[@frame1_key="value"]'))
# 回到公共区域模块
driver.switch_to.default_content()
# 再进入frame2,写法与进入frame1相同,都有三种
driver.switch_to.frame('frame2_id')

    

5.切换窗口

(1)为什么要切换窗口

        真实的业务流程:用户进行了某些操作,打开了一个新的标签页,接下来的功能要在这个新的标签页中进行。

        这些标签页在当前的大多数的浏览器中都看起来是在一个窗口打开的,其实这是浏览器提供的显示功能,实际上这些标签页每一个都是一个新的窗口,只是浏览器为了提升用户体验,将它整合显示在了一个窗口内。

        用户在真人体验的时候,浏览器会自动把新的窗口打开在最上层供用户操作。但是在自动化代码执行时,如果我们没有进行窗口切换动作,代码的操作对象永远都只能停留在初始页面,新打开的窗口内容我们永远无法进行操作。

(2)怎样实现窗口切换

        在这里引入一个句柄的概念:句柄是浏览器窗口的唯一标识,叫做handle。

        既然句柄能唯一标识一个窗口,那么我们进行窗口切换的时候,就可以使用句柄作为切换的依据。

        ①获取当前页面句柄:        driver.current_window_handle        ,返回值是当前页面的句柄值

        ②获取全部页面的句柄:        driver.window_handles        ,返回值是一个列表,列表内容为当前打开的全部页面的句柄值,顺序与页面打开顺序相同。

        ③因为我们只打开了两个页面,不是当前页,就是我们要切换的窗口。遍历handles列表,判断是否为当前页句柄,如果不是,则执行切换窗口动作.driver.switch_to.window(handle)

        ④如果想要切回之前那个页面怎么办呢?把现在这个页面当做当前页,再执行以上3个步骤就可以了。

(3)多个窗口之间互相切换,要怎样实现

上面我们说的是两个窗口切换,如果我们打开了N个页面怎么办呢?

我们知道,driver.window_handles的返回值是一个列表,列表就可以使用下标来获取列表中的值。

利用列表的特性,我们就可以知道driver.switch_to.window(handle_list[-1]),打开的永远是最新的那个页面,driver.switch_to.window(handle_list[0])打开的永远是第一个页面,依次类推,想要跳转切换到哪一个页面就找到它打开的顺序,使用列表定位到它的handle传参给driver.switch_to.window()就可以打开指定页面啦。

代码示例

# 获取当前页面handle并打印出来
print(driver.current_window_handle)
# 获取所有打开窗口的句柄并打印
print(driver.window_handles)# 切换到最新窗口
driver.switch_to.window(driver.window_handles[-1])
# 切换到第一个窗口
driver.switch_to.window(driver.window_handles[0])
# 切换到第四个窗口
driver.switch_to.window(driver.window_handles[3])   # 列表下标从0开始

扩展

如果我们切换到最新页面,完成应有的操作之后,关闭当前页面,再操作其他页面,可以直接操作吗?

我们可以用以下代码试一下:

# 导包
from time import sleepfrom selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.support.wait import WebDriverWait# 实例化浏览器对象
driver = webdriver.Chrome()
# 打开浏览器
driver.get('https://www.baidu.com')
# 浏览器窗口最大化
driver.maximize_window()
# 隐式等待:通常设置10s
driver.implicitly_wait(10)
sleep(2)# 在百度首页打开新闻页
driver.find_element_by_link_text('新闻').click()
sleep(5)# 切换到新闻页
driver.switch_to.window(driver.window_handles[-1])# 关闭新闻页
driver.close()      # 此时百度首页就成了最新的页面,我们试一下能不能操作# 在百度首页,搜索框输入“test”
driver.find_element_by_id('kw').send_keys('test')
sleep(2)# 关闭浏览器
driver.quit()

执行代码以后我们可以看到,代码报错no such window: target window already closed

意思是:没有这个窗口,目标窗口已经被关闭。

也就是说,我们的操作对象还是新闻页,没有自动切换到百度首页,在新闻页查找百度搜索框,但是页面已经被关闭了,所以报错

所以,即使关闭了当前页,再去其他页面进行操作的时候依然要切换。

修改代码如下:

# 导包
from time import sleepfrom selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.support.wait import WebDriverWait# 实例化浏览器对象
driver = webdriver.Chrome()
# 打开浏览器
driver.get('https://www.baidu.com')
# 浏览器窗口最大化
driver.maximize_window()
# 隐式等待:通常设置10s
driver.implicitly_wait(10)
sleep(2)# 在百度首页打开新闻页
driver.find_element_by_link_text('新闻').click()
sleep(5)# 切换到新闻页
driver.switch_to.window(driver.window_handles[-1])# 关闭新闻页
driver.close()
# 切回百度首页
driver.switch_to.window(driver.window_handles[-1])
"""因为我并没有使用变量接收driver.window_handles的结果,每次使用driver.window_handles,都会重新获取handle_list,跟页面打开与关闭都无关不管之前关闭了多少页面或打开多少新页面,driver.window_handles获取的都是在执行这一语句时,打开页面的全部句柄
"""
# 因为关闭了新闻页,所以百度首页就是当前最新的页面,所以使用driver.window_handles[-1]可以获取它的句柄
# 因为我们只打开了两个页面,百度首页此时既是最新页又是第一个页面。所以driver.window_handles[0]也可以获取它的句柄# 在百度首页,搜索框输入“test”
driver.find_element_by_id('kw').send_keys('test')
sleep(2)# 关闭浏览器
driver.quit()

6.验证码处理

(1)直接规避

        验证码这个功能,本身就是防自动化爬虫的,所以自动化测试可以说没啥必要正验证码。一般在测试环境中最简单直接的处理方式就是把这个功能干掉,发布之前再加上。

        测试环境或者生产内部专用的环境一般都会屏蔽掉这个功能。

(2)使用万能验证码

        如果项目已经上线了,不能屏蔽掉验证码功能,可以设置的一个万能码。

        请开发配合,将万能码写在项目验证码的判断逻辑里,不管明面上显示的是什么验证码,只要输入提前约定的万能码,验证都可以通过。

        这个方法需要注意的一点就是保证万能码保密,不要流出,否则会造成巨大损失。


(3)使用python插件

        python有一个测试图片验证码的框架Python_tesseract,但是这个图像识别技术并不是100%成功。

(4)使用cookie绕过验证码

        如果不需要测试登录模块,我们可以选择绕过登录验证。

        客户端登录账号后将登录状态相关的cookie信息,发送给服务器保存,  再次发送请求,携带的cookie信息,如果和登录状态一致,服务器默认登录成功

        提前手动登录,获取cookie值,然后使用这个cookie值绕过登录,直接进行功能测试。

如何查看cookie值:F12(开发者工具)-Application-cookie

        cookie的值具体包含在页面的哪一个字段,需要向开发询问,或者自行手动登录一下,对比登录前后多了哪一个字段。百度的cookie在BDUSS字段。

        注意:使用cookie时要保证有一个浏览器处于登录项目的状态,不能退出,一旦退出则cookie失效。任何一个浏览器都可以,不一定是我们用来测试的这个,只要打开登录着就行。

代码示例:

# 实例化浏览器对象
driver = webdriver.Chrome()
# 打开浏览器
driver.get('https://www.baidu.com')
# 展示效果
sleep(1)
# 浏览器窗口最大化
driver.maximize_window()
# 隐式等待
driver.implicitly_wait(10)
sleep(2)
# 实现需求
cookie_value = {'name': 'BDUSS','value': 'ZaaVlTRUZ0ZWZaOXBBQ0JZLXV-NDhFQkRhTnhzfmQ1MDFmcWktR3RMeVA0SVpsRVFBQUFBJCQAAAAAAAAAAAEAAAA1c09WwfjD98LlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI9TX2WPU19lak'}
driver.add_cookie(cookie_value)
driver.refresh()
sleep(2)
# 关闭浏览器
driver.quit()

好啦,关于Web自动化相关的基础知识,到这里我们就学习结束啦。后边就是学习测试框架的内容啦。再接再厉哟~~~。

发帖的全部内容是博主自学后整理的笔记,如果有错漏,希望各位小伙伴指正!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/183197.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PCB设计注意事项

四个二极管不能省略 pwm波跟电机频率不要是倍频 运放越靠近取样电阻越好 反向输入端跟输出端很敏感,有寄生电容就容易震荡 距离取样电阻近就会距离单片机远,那么线上会有寄生电容,这时候在输出端接一个10k电阻到地

深度学习-模型调试经验总结

1、 这句话的意思是:期望张量的后端处理是在cpu上,但是实际是在cuda上。排查代码发现,数据还在cpu上,但是模型已经转到cuda上,所以可以通过把数据转到cuda上解决。 解决代码: tensor.to("cuda")…

Redis 入门和环境搭建

认识Redis Redis是一种NoSQL数据库,以键值对形式存储数据,支持多种数据结构,包括字符串、哈希、列表、集合、有序集合等,使其适用于多种应用场景。由于所有数据都存储在内存中,Redis的读写性能非常高。同时&#xff0…

安网AC智能路由系统actpt_5g.data敏感信息泄露漏洞复现 [附POC]

文章目录 安网AC智能路由系统actpt_5g.data敏感信息泄露漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 安网AC智能路由系统actpt_5g.data敏感信息泄露漏洞复现 [附POC] 0x01 前言 免责声明:请勿利…

面试:说一下深拷贝,浅拷贝,引用拷贝吧;Object类中的clone是哪种呢?

目录 深拷贝、浅拷贝、引用拷贝Object类的clone()方法 深拷贝、浅拷贝、引用拷贝 ● 浅拷贝: 对基本数据类型进行值传递; 对引用类型,复制了一份引用类型的变量 里面存储的内存地址一样 指向的对象也一样。 ● 深拷贝:对基本数据…

kettle入门教程

一、概述 1.什么是kettle Kettle是一款开源的ETL(Extract-Transform-Load)工具,纯java编写,可以在Window、Linux、Unix上运行,绿色无需安装,数据抽取高效稳定。 2.kettle工程存储方式 (1)以XML形式存储 …

数据结构树与二叉树(5)Huffman树

#include <iostream> #include <stack> #include <queue>using namespace std;struct Node {char name ;int code[200];int num 0;//code的下标int weight 0;//权重&#xff08;次数&#xff09;Node* lchild;//左孩子Node* rchild;//右孩子Node* parent;N…

力扣 --- 三数之和

目录 题目描述&#xff1a; 思路描述&#xff1a; 代码&#xff1a; 提交结果&#xff1a; 官方代码&#xff1a; 官方提交结果&#xff1a; 题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k…

使用STM32 HAL库驱动烟雾传感器的设计和优化

STM32 HAL库是STMicroelectronics提供的针对STM32系列微控制器的一套硬件抽象层库&#xff0c;可以简化开发过程并提供对各种外设的支持。本文将介绍如何使用STM32 HAL库来驱动烟雾传感器&#xff0c;并对传感器数据采集和处理进行优化。将包括HAL库的初始化、模拟信号采集、数…

UE5、CesiumForUnreal实现加载GeoJson绘制多面(MultiPolygon)功能(支持点选高亮)

文章目录 1.实现目标2.实现过程2.1 数据与预处理2.2 GeoJson解析2.3 Mesh构建与属性存储2.4 核心代码2.5 材质2.6 蓝图应用测试3.参考资料1.实现目标 在之前的文章中,基于GeoJson数据加载,实现了绘制单面功能,但只支持单个要素Feature。本文这里实现对Geojson内所有面要素的…

Abaqus飞机起落架扭力臂拓扑优化

Abaqus飞机起落架扭力臂拓扑优化 Abaqus除了可以对结构进行强度分析&#xff0c;同样也自带强大的优化功能&#xff0c;下面通过一个简 单的实例演示在Abaqus中进行拓扑优化&#xff0c;另外&#xff0c;如果需要更加强大的拓扑优化仿真&#xff0c;可以 在TOSCA中进行。 定义接…

软件工程(九)

软件过程 定义 是软件生存周期中的一系列相关软件工程活动的集合&#xff0c;活动是任务的集合。 任务是将输入变换为输出的操作。 活动的执行可以是顺序的&#xff0c;重复的&#xff0c;并行的、嵌套的。 每一个软件过程由一组工作任务、项目里程碑、软件工程产品和交付…

最稳定的app分发平台怎么签到领取点数

第一步 登点击录《咕噜分发平台官网》 ●首页点击绿色箭头所指向的转盘 ●点击天数然后点击今日签到 ● 图下是我们的签到应该获得的点数 ● 图下是我们的签到累积获得的点数&#xff0c;以及连续签到的次数 控制台查看 查看签到获得点数通知 ●查看签到结果以及累积签到点数…

使用影刀指令+python实现简单的长文本乱序加密

本文意在利用影刀指令python代码&#xff0c;实现一种较为简单的长文本加密和解密&#xff0c;流程结构分为两步&#xff1a; 加密原理–是把字符转为列表&#xff0c;利用列表random模块中的shuffle函数做随机乱序。解密原理–是利用了列表的索引追踪&#xff0c;先前创建字典…

原神:夏洛蒂是否值得培养?全队瞬抬治疗量不输五星,但缺点也很明显

作为四星冰系治疗角色&#xff0c;夏洛蒂的实战表现可以说相当让人惊喜。不仅有相当有意思的普攻动作以及技能特效&#xff0c;而且她还有治疗和挂冰等功能性。下面就来详细聊聊夏洛蒂是否值得培养。 【治疗量让人惊喜&#xff0c;但也有缺点】 说实话&#xff0c;在使用夏洛蒂…

AcWing 3555:二叉树(北京大学考研机试题)→公共父结点

【题目来源】https://www.acwing.com/problem/content/description/3435/【题目描述】 如下图所示&#xff0c;由正整数 1, 2, 3, … 组成了一棵无限大的&#xff08;满&#xff09;二叉树。 1/ \2 3/ \ / \4 5 6 7 /\ /\ /\ /\ ... ... 从任意一个结点到根结点&…

【Web】NewStarCTF Week3 个人复现

①Include &#x1f350; ?filephpinfo 提示查下register_argc_argv 发现为on LFI包含 pearcmd命令执行学习 pearcmd.php文件包含妙用 ?file/usr/local/lib/php/pearcmd&config-create/<?eval($_POST[a])?>./ha.php ?file./ha post传&#xff1a; asystem…

C++ 通过CryptoPP计算Hash值

Crypto (CryptoPP) 是一个用于密码学和加密的 C 库。它是一个开源项目&#xff0c;提供了大量的密码学算法和功能&#xff0c;包括对称加密、非对称加密、哈希函数、消息认证码 (MAC)、数字签名等。Crypto 的目标是提供高性能和可靠的密码学工具&#xff0c;以满足软件开发中对…

3 测试驱动的Spring Boot应用程序开发数据层示例

文章目录 用户故事数据模型选择数据库SQL与NoSQLH2、Hibernate和JPA Spring Boot Data JPA依赖关系和自动配置Spring Data JPA技术栈数据源&#xff08;自动&#xff09;配置 实体存储库存储User和ChallengeAttempt显示最近的ChallengeAttempt服务层控制器层用户界面 小结 文章…

go学习之文件操作与命令行参数

文章目录 一、文件操作1.基本介绍2.常用文件操作函数和方法3.关于文件操作应用实例4.写文件操作应用实例&#xff08;创建文件并写入文件&#xff09;1&#xff09;基本介绍2&#xff09;基本应用实例-方式一 5.判断文件是否存在6.统计英文、数字、空格和其他字符数量 二、命令…