Python-Selenium报错截图
报错截图设计方案:
功能:截图层主要用来存放selenium运行时的报错截图信息
1. 截图路径管理
分层存储:在项目根目录下创建
screenshots
文件夹,并按日期进一步分类(如20250601
)。命名规范:截图文件名包含错误类型和精确时间戳(如
error_el_message_20250601_143022.png
),便于快速定位问题。自动创建目录:使用
os.makedirs(exist_ok=True)
确保目录存在,避免手动创建。def get_screenshot_path(self, error_type="unknown"): """获取截图保存路径""" # 获取项目根目录 project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 在项目根目录下创建screenshots文件夹 screenshot_dir = os.path.join(project_root, "screenshots") # 创建截图目录(如果不存在) os.makedirs(screenshot_dir, exist_ok=True) # 获取当前日期作为子文件夹名 date_folder = time.strftime("%Y%m%d") screenshot_path_dir = os.path.join(screenshot_dir, date_folder) # 创建日期子目录(如果不存在) os.makedirs(screenshot_path_dir, exist_ok=True) # 生成带完整日期时间的截图文件名 timestamp = time.strftime("%Y%m%d_%H%M%S") return os.path.join(screenshot_path_dir, f"error_{error_type}_{timestamp}.png")
2. 多类型错误检测
多样化定位策略:支持 XPath、ID、ClassName、CSS 选择器等多种定位方式,覆盖不同框架的错误组件(如 Element UI、Ant Design)。
自定义错误类型:为不同定位方式设置专属错误类型标签(如
el_message
、ant_message
),便于后续分析。def check_and_capture_error(self): """检查页面是否存在错误提示,并在发现时截图""" # 定义多种定位方式的错误提示元素 error_locators = [ # XPath定位 (By.XPATH, "//div[contains(@class, 'el-message--error')]//p", "el_message"), (By.XPATH, "//div[contains(@class, 'ant-message-error')]", "ant_message"), (By.XPATH, "//div[contains(@class, 'error-text')]", "error_text"), (By.XPATH, "//div[contains(@class, 'toast-error')]", "toast_error"), # ID定位 (By.ID, "errorMessage", "error_message_id"), (By.ID, "error-container", "error_container_id"), # Class Name定位 (By.CLASS_NAME, "error-message", "error_message_class"), (By.CLASS_NAME, "alert-danger", "alert_danger_class"), # CSS选择器定位 (By.CSS_SELECTOR, ".error-box .message", "error_box_css"), (By.CSS_SELECTOR, "#errorContent", "error_content_css"), # Name属性定位 (By.NAME, "error-display", "error_display_name"), (By.NAME, "errorInfo", "error_info_name") ] try: # 遍历所有可能的错误提示元素 for locator_type, locator_value, error_type in error_locators: try: error_element = WebDriverWait(self.driver, 1).until( EC.visibility_of_element_located((locator_type, locator_value)) ) error_text = error_element.text return self.save_screenshot(error_type, f"⚠️ 捕获到错误: {error_text}") except (TimeoutException, NoSuchElementException): continue # 如果没有找到自定义错误提示,则检查DOM状态和页面加载 try: # 检查页面是否完全加载 page_state = self.driver.execute_script('return document.readyState') if page_state != 'complete': return self.save_screenshot("page_loading", "⚠️ 页面加载未完成") # 检查网络请求状态 network_status = self.driver.execute_script(""" return window.performance.getEntries().filter( e => e.entryType === 'resource' ).some(e => e.responseStatus >= 400); """) if network_status: return self.save_screenshot("network_error", "⚠️ 检测到网络请求异常") # 检查表单验证状态 invalid_inputs = self.driver.execute_script(""" return Array.from(document.querySelectorAll('input:invalid')).length; """) if invalid_inputs > 0: return self.save_screenshot("form_validation", "⚠️ 表单验证未通过") # 检查动画和过渡是否完成 animations_running = self.driver.execute_script(""" return document.getAnimations().some(a => a.playState === 'running'); """) if animations_running: return self.save_screenshot("animation_pending", "⚠️ 页面动画未完成") print("✅ 页面状态正常") return False except Exception as e: return self.save_screenshot("check_error", f"❌ 状态检查异常: {str(e)}") except Exception as e: return self.save_screenshot("general_error", f"❌ 检查错误时发生异常: {str(e)}")
3. 信息完整性
- 错误信息记录:截图时保存错误文本内容(如
用户名不存在/密码错误
),便于后续分析。 - 操作反馈:通过打印日志提示截图路径和错误详情,支持自定义消息。
4. 扩展性设计
- 可配置定位器:错误定位器以元组形式存储在列表中,便于添加新的定位方式。
- 错误类型分类:支持自定义错误类型标签,方便后续统计和筛选。
5. 异常安全保障
- 多层异常捕获:在不同层级捕获异常,确保即使某个检测环节失败,仍能生成通用错误截图。
- 健壮的路径生成:使用
os.path
模块处理路径,确保跨平台兼容性。
示例代码:
import time
import os
from datetime import datetime
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException, TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
class ErrorChecker:
def __init__(self, driver):
self.driver = driver
def get_screenshot_path(self, error_type="unknown"):
"""获取截图保存路径"""
# 获取项目根目录
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 在项目根目录下创建screenshots文件夹
screenshot_dir = os.path.join(project_root, "screenshots")
# 创建截图目录(如果不存在)
os.makedirs(screenshot_dir, exist_ok=True)
# 获取当前日期作为子文件夹名
date_folder = time.strftime("%Y%m%d")
screenshot_path_dir = os.path.join(screenshot_dir, date_folder)
# 创建日期子目录(如果不存在)
os.makedirs(screenshot_path_dir, exist_ok=True)
# 生成带完整日期时间的截图文件名
timestamp = time.strftime("%Y%m%d_%H%M%S")
return os.path.join(screenshot_path_dir, f"error_{error_type}_{timestamp}.png")
def save_screenshot(self, error_type="unknown", message=""):
"""保存截图并打印消息"""
screenshot_path = self.get_screenshot_path(error_type)
self.driver.save_screenshot(screenshot_path)
if message:
print(message)
print(f"📸 错误截图已保存至: {screenshot_path}")
return True
def check_and_capture_error(self):
"""检查页面是否存在错误提示,并在发现时截图"""
# 定义多种定位方式的错误提示元素
error_locators = [
# XPath定位
(By.XPATH, "//div[contains(@class, 'el-message--error')]//p", "el_message"),
(By.XPATH, "//div[contains(@class, 'ant-message-error')]", "ant_message"),
(By.XPATH, "//div[contains(@class, 'error-text')]", "error_text"),
(By.XPATH, "//div[contains(@class, 'toast-error')]", "toast_error"),
# ID定位
(By.ID, "errorMessage", "error_message_id"),
(By.ID, "error-container", "error_container_id"),
# Class Name定位
(By.CLASS_NAME, "error-message", "error_message_class"),
(By.CLASS_NAME, "alert-danger", "alert_danger_class"),
# CSS选择器定位
(By.CSS_SELECTOR, ".error-box .message", "error_box_css"),
(By.CSS_SELECTOR, "#errorContent", "error_content_css"),
# Name属性定位
(By.NAME, "error-display", "error_display_name"),
(By.NAME, "errorInfo", "error_info_name")
]
try:
# 遍历所有可能的错误提示元素
for locator_type, locator_value, error_type in error_locators:
try:
error_element = WebDriverWait(self.driver, 1).until(
EC.visibility_of_element_located((locator_type, locator_value))
)
error_text = error_element.text
return self.save_screenshot(error_type, f"⚠️ 捕获到错误: {error_text}")
except (TimeoutException, NoSuchElementException):
continue
# 如果没有找到自定义错误提示,则检查DOM状态和页面加载
try:
# 检查页面是否完全加载
page_state = self.driver.execute_script('return document.readyState')
if page_state != 'complete':
return self.save_screenshot("page_loading", "⚠️ 页面加载未完成")
# 检查网络请求状态
network_status = self.driver.execute_script("""
return window.performance.getEntries().filter(
e => e.entryType === 'resource'
).some(e => e.responseStatus >= 400);
""")
if network_status:
return self.save_screenshot("network_error", "⚠️ 检测到网络请求异常")
# 检查表单验证状态
invalid_inputs = self.driver.execute_script("""
return Array.from(document.querySelectorAll('input:invalid')).length;
""")
if invalid_inputs > 0:
return self.save_screenshot("form_validation", "⚠️ 表单验证未通过")
# 检查动画和过渡是否完成
animations_running = self.driver.execute_script("""
return document.getAnimations().some(a => a.playState === 'running');
""")
if animations_running:
return self.save_screenshot("animation_pending", "⚠️ 页面动画未完成")
print("✅ 页面状态正常")
return False
except Exception as e:
return self.save_screenshot("check_error", f"❌ 状态检查异常: {str(e)}")
except Exception as e:
return self.save_screenshot("general_error", f"❌ 检查错误时发生异常: {str(e)}")