全网最细,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代码实现源码分析工作原理:线程池的…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...

