Python-Selenium报错截图

发布于:2025-06-06 ⋅ 阅读:(23) ⋅ 点赞:(0)

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_messageant_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)}")




网站公告

今日签到

点亮在社区的每一天
去签到