全网最细,web自动化测试实战场景(滚动元素的滚动操作)直接上干g货......
前言
使用 selenium 进行 web 自动化测试对我们来说是个常规操作。用了很多次后,我们经常会抱怨 selenium 封装的操作实在是太少了。
比如说 selenium 没有对页面的滚动提供丰富 API , 有的只有一个孤零零的 location_once_scrolled_into_view 方法,把一个元素滚动到可视范围之内。 这远远不能满足日常的需求啊!要知道,现在大多数的网页都需要不停的滚动鼠标加载新内容。
如果是单个窗口的滚动还好,但是遇到一些变态的 ERP 系统就为难了。 每一个页面都像是战国时代的诸侯国,被割裂成一块块相互独立的模块,每个模块都需要滚动操作, 全局的窗口滚动根本就不好使。
我们来看一个例子。
打开禅道的演示页面, 除了窗口本身需要滚动以获取底部的更多内容以外, “最新动态” 和 “我的待办” 都有自己独立的滚动条。
这样的模块实现的技术有几种。有的会把一个区域的内容放在一个 iframe 当中,有的是包裹在一个 div 标签当中。不管是哪一种方式,实际上,我们都可以把他们当成是单个元素进行处理,如何来操作这些可以被滚动的元素呢?
上面说过,官方的 Selenium API当中只有一个 el.location_once_scrolled_into_view 方法把某个元素滚动到可视范围内。这个方法并不够灵活,如果想要更加灵活的操作,比如滑动到底部、滑动一半等,就需要借助 JavaScript 。 基本上,如果 selenium 没有实现的操作,都可以借助 JS 操作。
对于一个网页的 DOM 对象来说呢,有全局的 window.scrollTo 方法,可以对整个窗口实现滚动操作。如果想把网页滚动到最底部,可以在任意网页按 F12 进入开发者工具,选择 console 输入 JS 代码:
window.scrollTo(0, document.body.scrollHeight);
同样的, 在 DOM 对象当中,也实现了对单个元素的滚动操作。 直接设置元素的 scrollTop 属性,表示讲可滚动元素的高度设置到多高。以禅道为例,如果要把 “最新动态” 这个元素向下滚动 800px,可以编写对应的 JS 代码:
// 定位元素
el = document.querySelector("div[data-name=最新动态]>div.panel-body");// 向下滚动 800 像素
el.scrollTop = 800;
如果想滚动到一半,也可以通过元素的 scrollHeight 属性控制:
el.scrollTop = el.scrollHeight * 0.5;
如果元素可以左右滚动,则可以设置元素的 scrollLeft 属性:
el.scrollLeft = el.scrollWidth * 0.5;
通过设置 scrollTop 和 scrollLeft 属性有时候比较麻烦,可以适用 scrollTo 方法简化操作, 表示滚动到一半的宽度,一半的高度;
el.scrollTo(el.scrollWidth * 0.5, el.scrollHeight * 0.5);
也可以适用 scrollBy 表示从现在的位置往右边和下边滑动多少像素点:
el.scrollBy(el.scrollWidth * 0.1, el.scrollHeight * 0.1);
如果希望通过 Selenium 实现滚动操作,可以调用 selenium 当中的 execute_script 方法去执行对应的js语句。要实现上面的效果,可以访问页面之后,执行 JS 语句:
from selenium import webdriverdriver = webdriver.Chrome()
driver.get("https://demo.zentao.net/my/")
js_code = """
el = document.querySelector("div[data-name=最新动态]>div.panel-body");
el.scrollTo(0, el.scrollHeight);
"""
driver.execute_script(js_code);
对 selenium 比较熟悉的同学可以封装一个上层 API, 当需要执行滚动操作时,直接调用方法就可以了:
class SeleniumUpAPI:"""Selenium的上层封装"""def __init__(self, driver:Remote):self.driver = driverdef element_scroll_to(self, el:WebElement, x_percent=0, y_percent=0):"""滚动元素到百分比位置.x: 宽度的比率,0.5y: 高度的比率,0.5"""jscode = """arguments[0].scrollTo(arguments[1] * arguments[0].scrollWidth,arguments[2] * arguments[0].scrollHeight);"""self.driver.execute_script(jscode, el, x_percent, y_percent)
最后完整的代码:
import time
from selenium.webdriver import Remote, Chrome
from selenium.webdriver.remote.webelement import WebElementclass SeleniumUpAPI:"""Selenium的上层封装"""def __init__(self, driver:Remote):self.driver = driverdef element_scroll_to(self, el:WebElement, x_percent=0, y_percent=0):"""滚动元素到百分比位置.x: 宽度的比率,0.5y: 高度的比率,0.5"""jscode = """arguments[0].scrollTo(arguments[1] * arguments[0].scrollWidth,arguments[2] * arguments[0].scrollHeight);"""self.driver.execute_script(jscode, el, x_percent, y_percent)def element_scroll_by(self, el:WebElement, x_percent=0, y_percent=0):"""每次滚动多少个像素点,以元素百分比操作x: 宽度的比率,0.1y: 高度的比率,0.1"""jscode = """arguments[0].scrollBy(arguments[1] * arguments[0].scrollWidth,arguments[2] * arguments[0].scrollHeight);"""self.driver.execute_script(jscode, el, x_percent, y_percent)class Element:def scroll(self, x_percent=0, y_percent=0):"""滚动.x: 宽度的比率,0.5y: 高度的比率,0.5"""jscode = """arguments[0].scroll({top:arguments[1] * arguments[0].scrollHeight,left:arguments[1] * arguments[0].scrollWidth});"""self.driver.execute_script(self, el, y_percent, x_percent)if __name__ == "__main__":driver = Chrome()driver.get("https://example.cypress.io/commands/actions")d = SeleniumUpAPI(driver)el = d.driver.find_element("id", "scroll-vertical")el.location_once_scrolled_into_viewtime.sleep(2)d.scroll_element(el, 0.5, 0.5)
最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!
相关文章:

全网最细,web自动化测试实战场景(滚动元素的滚动操作)直接上干g货......
前言 使用 selenium 进行 web 自动化测试对我们来说是个常规操作。用了很多次后,我们经常会抱怨 selenium 封装的操作实在是太少了。 比如说 selenium 没有对页面的滚动提供丰富 API , 有的只有一个孤零零的 location_once_scrolled_into_view 方法,把…...

Java特性之设计模式【过滤器模式】
一、过滤器模式 概述 过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。这种类型的…...

Linux设备模型(十) - bus/device/device_driver/class
四,驱动的注册 1,struct device_driver结构体 /** * struct device_driver - The basic device driver structure * name: Name of the device driver. * bus: The bus which the device of this driver belongs to. * owner: The module own…...

性能问题分析排查思路之机器(3)
本文是性能问题分析排查思路的展开内容之一,第2篇,主要分为日志1期,机器4期、环境2期共7篇系列文章,本期是第三篇,讲机器(硬件)的网络方面的排查方法和最佳实践。 主要内容如图所示:…...

PostgreSQL安装教程
系统环境 下载压缩包 下载压缩包 解压压缩包 查看解压文件 编译安装 编译 安装 用户权限和环境变量设置 创建用户 创建数据目录和日志目录 设置权限 设置环境变量 初始化数据库 数据库访问控制配置文件 postgresql.conf pg_hba.conf PostgreSQL启动与关闭 手…...
SLAM基础知识:前端和后端
在SLAM中前端和后端是被经常提到的一个概念。但是对于前端和后端的理解有着不同的看法,我的理解是: 前端:前端负责处理传感器数据,特征提取,进行状态估计和地图构建的初步步骤。 后端:后端接受不同时刻的里…...

一文彻底搞懂从输入URL到显示页面的全过程
简略版: 用户输入URL后,浏览器经过URL解析、DNS解析、建立TCP连接、发起HTTP请求、服务器处理请求、接收响应并渲染页面、关闭TCP连接等步骤,最终将页面显示给用户。 详细版: URL解析:浏览器根据用户输入的URL&#x…...

好书安利:《大模型应用开发极简入门:基于GPT-4和ChatGPT》这本书太好了!150页就能让你上手大模型应用开发
文章目录 前言一、ChatGPT 出现,一切都变得不一样了二、蛇尾书特色三、蛇尾书思维导图四、作译者简介五、业内专家书评总结 前言 如果问个问题:有哪些产品曾经创造了伟大的奇迹?ChatGPT 应该会当之无愧入选。仅仅发布 5 天,Chat…...
力扣题库第4题:移动零
题目内容: 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数组进行操作。 示例 : 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0] 答案&…...
Java解决IP地址无效化
Java解决IP地址无效化 01 题目 给你一个有效的 IPv4 地址 address,返回这个 IP 地址的无效化版本。 所谓无效化 IP 地址,其实就是用 "[.]" 代替了每个 "."。 示例 1: 输入:address "1.1.1.1" 输出…...

[数据结构初阶]队列
鼠鼠我呀,今天写一个基于C语言关于队列的博客,如果有兴趣的读者老爷可以抽空看看,很希望的到各位老爷观点和点评捏! 在此今日,也祝各位小姐姐女生节快乐啊,愿笑容依旧灿烂如初阳,勇气与童真永不…...
MySQL学习Day27——MySQL事务日志
事务的隔离性由锁机制实现,而事务的原子性、一致性和持久性由事务的redo日志和undo日志来保证。其中REDO LOG称为重做日志,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持久性,redo log是存储引擎层生成的日志,记录的是物理级别上的页修改操作,主要为了保证…...

ETAS工具链ISOLAR-AB重要概念,RTE配置,ECU抽取
RTE配置界面,包含ECU抽取关联 首次配置RTE,出现需要勾选的抽取EXTRACT 创建System System制作SWC到ECU的Mapping System制作System Data 的Mapping...

蓝桥杯倒计时 43天 - 前缀和
思路:如果用n^2复杂度暴力会超时。nlogn 可以,利用前缀和化简,提前存储某个位置前的每个石头搬运到该位置和每个石头后搬运到该位置的前缀和On最后直接输出 On。排序花 nlogn #include<bits/stdc.h> using namespace std; typedef pai…...

【Web - 框架 - Vue】随笔 - Vue的简单使用(01) - 快速上手
【Web - 框架 - Vue】随笔 - Vue的简单使用(01) - 快速上手 Vue模板代码 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>模板</title> </head> <body> <div></di…...

【简说八股】Redisson的守护线程是怎么实现的
Redisson Redisson 是一个 Java 语言实现的 Redis SDK 客户端,在使用分布式锁时,它就采用了「自动续期」的方案来避免锁过期,这个守护线程我们一般也把它叫做「看门狗」线程。 Redission是一个在Java环境中使用的开源的分布式缓存和分布式锁实…...

WPS/Office 好用的Word插件-查找替换
例如:一片文档:…………泰山…………泰(少打了山字)………… 要是把“泰”查找替换为“泰山”,就会把前面的“泰山”变成“泰山山”,这种问题除了再把“泰山山”查找替换为“泰山”,有没有更简单…...

Go 简单设计和实现可扩展、高性能的泛型本地缓存
相信大家对于缓存这个词都不陌生,但凡追求高性能的业务场景,一般都会使用缓存,它可以提高数据的检索速度,减少数据库的压力。缓存大体分为两类:本地缓存和分布式缓存(如 Redis)。本地缓存适用于…...

Vue.js 深度解析:模板编译原理与过程
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…...

Java多线程——如何保证原子性
目录 引出原子性保障原子性CAS 创建线程有几种方式?方式1:继承Thread创建线程方式2:通过Runnable方式3:通过Callable创建线程方式4:通过线程池概述ThreadPoolExecutor API代码实现源码分析工作原理:线程池的…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...

Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...