当前位置: 首页 > news >正文

Selenium 多窗口截图(窗口切换)二次封装方法详解 —— Python 实践

        在Web自动化测试过程中,经常会遇到点击链接或按钮后打开新窗口的情况。为了验证新窗口是否成功加载,并确保测试流程顺利进行,我们需要对新窗口进行截图操作
        然而,直接使用 time.sleep() 等待新窗口加载完成并不稳定,容易导致截图失败或截取到旧页面内容。因此,本文将详细介绍如何通过 显式等待 + 多窗口切换 + 截图封装 的方式,实现一个 健壮、可复用的多窗口截图解决方案。

🧾  一、项目背景

在自动化测试中,经常遇到如下场景:

  • 点击一个链接或按钮后,浏览器会打开一个新的页签(Tab)。
  • 测试需要切换到新页签并执行后续操作(如断言、截图等)。
  • 如果不进行适当的等待和切换,截图可能会失败或者截取到错误页面的内容。

🧱 二、核心思路

要实现多窗口截图功能,我们需要以下几个步骤:

  1. 触发新窗口打开:通过点击某个元素,打开新的页签。
  2. 等待新窗口出现:使用 WebDriverWait 显式等待新窗口句柄出现。
  3. 切换到新窗口:获取所有窗口句柄,切换到最后一个窗口。
  4. 等待页面加载完成:等待某个关键元素可见,确保页面内容加载完毕。
  5. 执行截图操作:调用截图方法保存新窗口内容。

🛠️ 三、代码封装

我们将上述逻辑封装成一个通用的方法,便于在多个测试用例中复用。

1. 在 TestBase 基类中添加方法

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
import os
import logging
from utils.logger import Loggerclass TestBase(unittest.TestCase):def wait_for_new_window(self, timeout=10):"""等待新窗口出现:param timeout: 最大等待时间(秒)"""WebDriverWait(self.driver, timeout).until(lambda driver: len(driver.window_handles) > 1)def switch_to_new_window(self):"""切换到最新打开的窗口"""window_handles = self.driver.window_handlesself.driver.switch_to.window(window_handles[-1])def wait_for_page_load(self, locator, timeout=10):"""等待页面某个元素加载完成:param locator: 元素定位器 (By, value):param timeout: 最大等待时间(秒)"""WebDriverWait(self.driver, timeout).until(EC.visibility_of_element_located(locator))def get_browser_img(self, filename=None):"""截图并保存到项目根目录下的 screenshots 文件夹中:param filename: 自定义文件名(可选)"""base_dir = os.path.dirname(os.path.abspath(__file__))  # 获取当前文件路径screenshot_dir = os.path.join(base_dir, 'screenshots')  # 构建截图目录路径# 如果目录不存在,则自动创建os.makedirs(screenshot_dir, exist_ok=True)# 生成时间戳文件名if not filename:timestamp = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))filename = f"{timestamp}.png"screen_path = os.path.join(screenshot_dir, filename)try:self.driver.get_screenshot_as_file(screen_path)logger.info(f"截图已保存至: {screen_path}")except Exception as e:logger.error(f"截图失败!{e}")

2. 使用示例:在测试用例中调用

假设我们有一个测试用例,点击百度热搜第一条后跳转到新页面并截图。

def test_baidu_search_link(self):input = Cloud(self.driver)input.open('https://www.baidu.com/')input.click_link()  # 点击热搜链接,打开新页签self.wait_for_new_window(10)           # 等待新窗口打开self.switch_to_new_window()            # 切换到新窗口self.wait_for_page_load((By.TAG_NAME, 'body'), 10)  # 等待页面 body 加载完成input.get_browser_img()                # 执行截图

📦 四、关键点说明

✅ 显式等待 vs 隐式等待

  • 显式等待(WebDriverWait)是推荐的做法,因为它会等待特定条件成立后再继续执行,避免因网络延迟或页面加载慢导致的问题。
  • 隐式等待(implicitly_wait)虽然可以全局设置,但无法精准控制等待条件。

✅ 窗口切换逻辑

  • 使用 window_handles 获取所有窗口句柄列表。
  • 使用 switch_to.window() 切换到目标窗口。
  • 推荐切换到最后一个窗口(window_handles[-1]),即最新打开的窗口。

✅ 截图路径管理

  • 使用 os.makedirs(..., exist_ok=True) 自动创建截图目录。
  • 使用 time.strftime() 生成唯一文件名,避免命名冲突。
  • 日志输出截图路径,便于调试和验证。

📝 五、总结

通过将多窗口截图逻辑封装为基类方法,我们可以:

  • 提高代码复用率,减少重复代码;
  • 提升测试稳定性,避免因页面加载未完成导致的截图失败;
  • 统一截图命名和存储路径,便于后期分析和报告展示;
  • 使测试逻辑更清晰,易于维护和扩展。
http://www.lryc.cn/news/576110.html

相关文章:

  • 【Python】实现对LGBT+ rights worldwide (2025)数据集的可视化展示
  • MySQL在C中常用的API接口
  • TiDB AUTO_RANDOM 超大主键前端精度丢失排查:JavaScript Number 限制与解决方案
  • 玩转Linux CAN/CAN FD—SocketCAN的使用
  • opensuse安装rabbitmq
  • 【编译原理】期末复习知识总结
  • 【大数据】大数据产品基础篇
  • 【开源项目】「安卓原生3D开源渲染引擎」:Sceneform‑EQR
  • ArcGIS Pro利用擦除工具,矢量要素消除另一矢量部分区域
  • 【网络安全】密码学知识普及
  • 高可用与低成本兼得:全面解析 TDengine 时序数据库双活与双副本
  • OkHttp 简单配置
  • pandas---使用教程
  • 解构SAP RISE与Cloud ERP授权新政:从许可模式到迁移策略的深度指南
  • (一)miniconda安装配置
  • Dubbo服务调用超时问题解决方案
  • Hyperledger Fabric 入门笔记(二十)Fabric V2.5 测试网络进阶之Tape性能测试
  • Linux tcp_info:监控TCP连接的秘密武器
  • 【RAG面试题】如何获取准确的语义表示
  • MCP-安全(代码实例)
  • ubuntu安装达梦数据库
  • Java8方法引用:简洁高效的编程利器
  • algorithm ——————》双指针(移动0 复写0 快乐数 装水问题 以及数组中找几个数和为指定的元组)
  • TCP四层模型:网络协议核心解密
  • WPF 3D 开发全攻略:实现3D模型创建、旋转、平移、缩放
  • HTTP协议中Connection: Keep-Alive和Keep-Alive: timeout=60, max=100的作用
  • Linux入门攻坚——49、高可用HA之corosync/pacemaker(2)
  • Linux命令行操作基础
  • 关于css的height:100%
  • JAVA-泛型通配符的上界和下界