提交 45a247b8 authored 作者: 陈泽健's avatar 陈泽健

docs(handoff): 会话50 交接——截图瘦身已部署5.44 + PRD/计划文档归档

- HANDOFF_UI自动化.md:新增会话50章节(三态截图模式实现/测试/5.44部署验证记录 + 存量清理与5.202/5.60部署待办 + 登录卡死遗留P0)
- 归档 定时任务截图瘦身 PRD 需求文档 + 执行计划文档(状态置已完成)
Co-Authored-By: 's avatarClaude <noreply@anthropic.com>
上级 228c732a
# PRD 需求文档 - 执行截图瘦身(失败步骤截图 + 压缩质量)
> **文档类型**: PRD 需求文档
> **创建日期**: 2026-09-07
> **作者**: czj
> **优先级**: P1
> **状态**: 开发中
---
## 一、需求背景
### 1.1 问题描述
当前执行引擎(`playwright_executor.py`)对**每个测试步骤无论成功失败都全量截图**(PNG 无损格式),导致:
- **定时任务场景灾难**:「每日定时自动化测试」每 6 小时执行 346 个用例,每用例 3~10 步,单轮执行产生 **2000+ 张 PNG 截图**
- 5.44 服务器 `data/screenshots/` 目录图片文件已累积占用 **数 GB**,存在磁盘写满风险;
- 绝大多数截图是"成功步骤"的截图,**事后几乎无人查看**——排查问题时真正需要的是**失败步骤的现场截图**
### 1.2 用户确认的方案
> **压缩质量 + 只截取关键失败步骤**
| 策略 | 说明 |
|------|------|
| 只截失败步骤 | 步骤最终失败(重试耗尽后)才截图,成功步骤不再截图 |
| 压缩质量 | 截图格式 PNG(无损)→ JPEG quality 60(可配置),单张体积从 ~300KB 降至 ~50KB |
### 1.3 关键事实(排查确认)
| # | 事实 | 依据 |
|---|------|------|
| 1 | 截图唯一触发点在 `execute_step` 末尾,`screenshot_enabled`(默认 True)时每步必截 | `playwright_executor.py:1991-1999` |
| 2 | Playwright 的 `quality` 参数**仅对 JPEG 生效**,PNG 忽略 | Playwright API 约束,必须改用 `.jpg` |
| 3 | 前端 `StepDetailPanel` 通过 `/api/files/{path}``<img>` 渲染截图,不挑格式 | `StepDetailPanel.vue:239-245`,JPEG 无需前端改动 |
| 4 | 用例步骤中的**显式 `screenshot` 动作**`_do_screenshot`)是用户主动配置的调试手段,与本需求的"步骤级自动截图"无关 | `playwright_executor.py:3213`,保持不动 |
| 5 | 已有清理能力:`CleanupService.cleanup_screenshots(days)` / `cleanup_orphan_screenshots()`,但依赖人工触发 | `cleanup_service.py`,本需求补充自动兜底 |
### 1.4 影响范围
- **后端**: `backend/app/executors/playwright_executor.py`(核心改动)
- **后端**: `backend/app/services/scheduler_service.py`(定时任务注入截图模式)
- **后端**: `backend/app/config.py`(全局配置项)
- **前端**: 无需改动(截图字段缺失/为 jpg 均已兼容)
---
## 二、功能需求
### 2.1 截图模式(screenshot_mode)
执行器新增三态截图模式,通过执行配置传入:
| 模式 | 值 | 行为 | 适用场景 |
|------|-----|------|---------|
| 全量截图 | `full` | 每步都截图(现状行为,PNG) | 录制调试、单用例手动执行 |
| **仅失败截图(默认)** | `failure_only` | 仅步骤最终失败时截图,JPEG 压缩 | **定时任务、批量执行(本项目核心)** |
| 关闭截图 | `off` | 完全不截图 | 极端省空间 |
- **`failure_only` 为执行器默认值**——即所有执行路径(手动/定时/批量)默认都瘦身为"仅失败截图",需要全量截图时显式传 `screenshot_mode=full`
- 用例级配置 `case_config.screenshot`(总开关,`playwright_executor.py:1292`)保持兼容:`screenshot=False` 时任何模式都不截图。
### 2.2 压缩质量(screenshot_quality)
- `failure_only` 模式截图改用 **JPEG + quality 60**(可配置,建议范围 40~80),文件扩展名 `.jpg`
- `full` 模式保持 PNG 不变(调试场景需要无损);
- 体积预期:单张 300KB+ → **50KB 左右**(降幅 ~85%)。
### 2.3 定时任务注入
- `scheduler_service.run_task_once()`(UI 路径)创建执行时,`config` 中注入 `screenshot_mode="failure_only"`
- 手动「立即执行」走同一函数,自动继承相同策略(避免定时/手动行为分叉造成困惑)。
### 2.4 磁盘自动兜底(防御性,可选开关)
- 全局新增 `SCREENSHOT_MAX_AGE_DAYS`(默认 14 天):每次执行开始时异步清理超期截图文件,防止长期运行再次累积;
- 清理逻辑复用"按修改时间删除过期文件"思路,容错(目录不存在/无权限仅告警不中断执行)。
### 2.5 非目标(明确不做)
- ❌ 不改用例级显式 `screenshot` 动作步骤的行为(用户主动配置的截图始终执行);
- ❌ 不改前端(`StepDetailPanel` 对 screenshot 字段的可选渲染天然兼容);
- ❌ 不改报告生成(报告不引用截图文件);
- ❌ 不做数据库表结构变更。
---
## 三、技术方案
### 3.1 执行器改造(`playwright_executor.py`)
```python
# __init__ 新增
self.screenshot_mode: str = self.config.get("screenshot_mode", "failure_only")
self.screenshot_quality: int = int(self.config.get("screenshot_quality", 60))
# execute_step 末尾截图块(原 1991-1999 行)改为:
if self.screenshot_enabled and self._should_capture_step(step_result):
if self.screenshot_mode == "failure_only":
screenshot_name = f"step_{order}_{ts}.jpg"
self._page.screenshot(path=..., type="jpeg", quality=self.screenshot_quality)
else:
screenshot_name = f"step_{order}_{ts}.png" # full 模式保持 PNG
self._page.screenshot(path=...)
step_result.screenshot = screenshot_path
def _should_capture_step(self, step_result) -> bool:
"""三态模式判定:off 不截 / failure_only 仅 failed / full 全截"""
```
约束:
- 截图动作放在 `try/except` 内,**截图失败不影响步骤结果**(现状已如此,保持);
- `cancelled/skipped` 状态的步骤不截图(现状 cancelled 分支先置 skipped,需确认 `_should_capture_step` 对非 failed 状态返回 False 天然覆盖)。
### 3.2 定时任务注入(`scheduler_service.py`)
```python
execution = await exec_service.create_execution(
...,
config={"auto_report": task.auto_report, "screenshot_mode": "failure_only"},
)
```
### 3.3 全局配置(`config.py`)
| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| `SCREENSHOT_MODE` | `failure_only` | 执行器默认截图模式 |
| `SCREENSHOT_QUALITY` | `60` | JPEG 压缩质量 |
| `SCREENSHOT_MAX_AGE_DAYS` | `14` | 截图保留天数(自动清理) |
### 3.4 存量清理(运维操作,不改码)
部署后对 5.44 执行一次性清理(复用现有 API/服务):
```
POST /api/cleanup/cleanup?days=7 # 清理 7 天前截图/报告
```
---
## 四、验收标准
| 测试项 | 预期结果 |
|--------|----------|
| 定时任务全量执行(含失败用例) | 仅失败步骤产生 `.jpg` 截图,成功步骤 0 截图 |
| 单轮 346 用例执行后截图目录增量 | < 20MB(对比现状 2000+ 张 PNG / 数百 MB) |
| `full` 模式手动执行 | 行为与现状一致(每步 PNG) |
| `off` 模式执行 | 全程 0 截图 |
| 失败步骤截图可在前端查看 | StepDetailPanel 正常显示 JPEG |
| 截图动作异常 | 不影响步骤执行结果与执行流程 |
| 超 `SCREENSHOT_MAX_AGE_DAYS` 的历史截图 | 执行启动时被自动清理 |
| 后端既有测试 | 全部通过(无回归) |
---
## 五、相关文档
- `Docs/PRD/需求文档/执行中心/_执行计划_定时任务截图瘦身.md` — 计划执行文档
- `Docs/PRD/问题处理/执行中心/_问题处理_定时任务看门狗失败执行无报告输出.md` — 5.44 截图/磁盘问题背景
- `backend/app/services/cleanup_service.py` — 既有清理服务
---
*本文档由 Claude Code 生成,遵循项目 PRD 文档规范。*
# 执行计划 - 定时任务截图瘦身(失败步骤截图 + 压缩质量)
> **文档类型**: 计划执行文档
> **创建日期**: 2026-09-07
> **作者**: czj
> **关联 PRD**: `_PRD_需求文档_定时任务截图瘦身.md`
> **状态**: 已完成(5.44 已部署,单测 403 全绿,通过用例 0 截图验证通过;遗留存量清理与 5.202/5.60 部署见 HANDOFF)
---
## Phase 1:执行器改造(核心,P0)
**目标**`playwright_executor.py` 支持三态截图模式 + JPEG 压缩。
### 1.1 `__init__` 新增配置(约 168 行附近)
- [x] `self.screenshot_mode = self.config.get("screenshot_mode", "failure_only")`
- [x] `self.screenshot_quality = int(self.config.get("screenshot_quality", 60))`
- [x] 同步更新类 docstring 的 config 说明
### 1.2 新增 `_should_capture_step(step_result)` 判定方法
- [x] `off` → False;`failure_only` → 仅 `status == "failed"``full` → True
- [x] `screenshot_enabled=False` 时一律 False(总开关优先)
### 1.3 改造 `execute_step` 截图块(原 1991-1999 行)
- [x] 条件改为 `if self.screenshot_enabled and self._should_capture_step(step_result)`
- [x] `failure_only` 模式:`.jpg` + `type="jpeg", quality=self.screenshot_quality`
- [x] `full` 模式:保持现状 PNG(`step_{order}_{ts}.png`
- [x] 保持 try/except 包裹(截图失败不影响执行)
### 1.4 `_do_screenshot`(显式动作)不动
- [x] 仅确认无回归影响
### 1.5 执行启动时过期截图清理
- [x] `start()` 中调用 `_cleanup_expired_screenshots()`:删除 mtime 早于 `SCREENSHOT_MAX_AGE_DAYS` 的文件
- [x] 全程 try/except 静默容错,新增 `cleanup_executed` 标记防重复执行
**验收**:单测 15/15 全绿;通过用例执行 0 截图产出。
---
## Phase 2:配置与定时任务注入(P0)
### 2.1 `config.py`
- [x] `Settings` 新增:`SCREENSHOT_MODE="failure_only"` / `SCREENSHOT_QUALITY=60` / `SCREENSHOT_MAX_AGE_DAYS=14`
- [x] 执行器默认值改为读全局配置:`config.get("screenshot_mode", settings.SCREENSHOT_MODE)`
### 2.2 `scheduler_service.py`
- [x] UI 路径 `create_execution(config={..., "screenshot_mode": "failure_only"})`(约 349 行)
- [x] security 路径确认不受影响(安全测试执行器不使用本截图逻辑)
**验收**:定时任务创建的 execution.config 含 `screenshot_mode=failure_only`(单元测试已校验)。
---
## Phase 3:验证与部署(P1)
### 3.1 本地验证
- [x] `pytest tests/ -v` 全量回归(403/403 全绿)
- [x] 单元测试 `test_screenshot_mode.py` 15/15 全绿
### 3.2 部署 5.44(走既有部署脚本)
- [x] `deploy_44_202.py` 同步后端文件(playwright_executor / config / scheduler_service 等 7 文件)
- [x] `docker restart plat-auto-test-app`(14:09 重启,healthy)
- [x] 触发一次小范围执行验证策略生效(通过用例 0 截图)
### 3.3 存量清理(5.44 一次性)
- [ ] `POST /api/cleanup/cleanup?days=7&dry_run=true` 预览(移至后续会话)
- [ ] 确认后去掉 `dry_run` 执行,回收数 GB 空间(当前存量 843 张 PNG/267MB)
### 3.4 收尾
- [x] 更新 `HANDOFF_UI自动化.md` 记录本次改动
- [x] 文档状态置"已完成"
---
## 风险与回滚
| 风险 | 缓解 |
|------|------|
| 用户仍需全量截图的调试场景 | 显式传 `screenshot_mode=full` 即恢复旧行为 |
| JPEG 压缩后关键信息看不清 | quality 可调(配置项),40~80 之间权衡 |
| 清理误删正在引用的截图 | 只按 mtime 清理且默认 14 天;另可手动跑 `cleanup_orphan_screenshots` 精确清理孤儿文件 |
---
*本文档由 Claude Code 生成,遵循项目计划执行文档规范。*
# HANDOFF — UI自动化测试交接文档
> **生成时间**: 2026-09-02
> **生成时间**: 2026-09-07
> **当前分支**: `platform-auto-test`
> **最近提交**: `d2660651` docs(ui-automation): HANDOFF 会话50 收尾(本地 `0aa58444` 变基为 `1924d77f` 后推送 `9b464802..1924d77f`,收尾 `d2660651`,本地与远程已同步
> **状态**: 🟢 **会话50 完成:会议巡检 3 条弱用例升级 navigate 直达,执行 3/3 通过,已同步三台(5.44/5.202→413、5.60→415,无重启)并提交推送;其余弱入口保持 drawer+click(memory 固化)。遗留 P1=并行会话 performance 改动(CSV 强制校验+登录监控)仍在工作区未提交,由该会话窗口自行提交**(历史会话见下章节
> **最近提交**: `228c732a` feat(screenshot): 定时任务截图瘦身(三态模式 + JPEG 压缩 + 过期自动清理
> **状态**: 🟢 **会话51:定时任务截图瘦身(failure_only + JPEG q60 + 14天过期清理)已实现并部署 5.44(重启后通过用例 0 截图验证 ✓);存量 843 张 PNG/267MB 待清理;5.202/5.60 未部署;5.44 全量套件 ~100% 失败(登录落首页问题)仍在排查中**(历史会话见下
---
## 📊 当前状态(会话 50,2026-09-02 · 会议巡检 navigate 直达升级)
## 📊 当前状态(会话 51,2026-09-07 · 定时任务截图瘦身)
**背景**:5.44 定时全量执行每次产生 800+ 张 PNG 步骤截图(267MB/次,累计数 GB),磁盘有撑满风险。用户选定方案:「压缩质量且只截取关键失败步骤」。
### ✅ 实现内容(PRD + 计划执行文档已归档至 `Docs/PRD/需求文档/执行中心/`)
| 改动 | 文件 |
|------|------|
| 三态截图模式:`full`=每步PNG / `failure_only`=仅失败步骤JPEG(q60,默认) / `off`=不截图;`_should_capture_step()` 判定 + `execute_step` 截图块重写 | `playwright_executor.py` |
| 配置项 `SCREENSHOT_MODE` / `SCREENSHOT_QUALITY=60` / `SCREENSHOT_MAX_AGE_DAYS=14`(环境变量可覆盖) | `config.py` |
| 执行启动时过期截图自动清理(mtime 判定,单实例只跑一次,全程容错) | `playwright_executor.py` `_cleanup_expired_screenshots()` |
| 定时任务创建执行注入 `config={"screenshot_mode": "failure_only"}` | `scheduler_service.py` `run_task_once` UI 路径 |
| 15 个单元测试(默认值/三态矩阵/清理/定时注入) | `tests/test_screenshot_mode.py` |
**测试**:新增 15/15 通过;后端全量回归 **403/403 通过**。用例级 `screenshot=False` 总开关、显式 `_do_screenshot` 动作、取消步骤(skipped)均不受影响。
**git 记录**:提交 `c8ac70c5` + HANDOFF 收尾,rebase 远程并行窗口(`9ea984a8` 等 7 提交)后推送。
### ✅ 5.44 部署与验证(2026-09-07)
- 部署前先取消卡死执行 `exec_6229809119ac...`(全量失败卡 100%)释放执行锁
- `deploy_44_202.py --host 192.168.5.44 --no-frontend` 增量上传 7 文件 → `docker restart plat-auto-test-app`(14:09 重启,healthy)
- **验证**
| 执行 | 用例 | 结果 | 截图行为 |
|------|------|------|---------|
| `exec_60f64b8c...` | 视讯设备-数据筛选验证 | 通过(30s) | **0 张截图** ✓(旧 full 模式会每步写 PNG) |
| `exec_8d6bb7cd...` / `exec_0a1faba2...` | 会议巡检-日历导航 / 管理看板-数据展示 | 看门狗中断(登录阶段挂起, steps_result 空) | 0 张截图(无失败步骤,符合预期) |
- 服务器截图目录:部署重启后**零新增文件**(843 张 PNG/267MB 全部为当日 10:00–12:01 旧代码定时全量跑产生)
- **失败步骤→.jpg 正向验证未完成**:服务器现有用例全卡在登录/落首页阶段(见遗留问题),产生不了步骤级失败样本;判定逻辑已由单测覆盖,待登录问题解决后补验
### 📋 待办(下次会话从这里继续)
1. **存量清理**`POST /api/cleanup/cleanup?days=7&dry_run=true` 预览 → 确认后真删(回收 ~267MB;14 天过期自动清理已随新代码生效,兜底后续增量)
2. **5.202 / 5.60 部署**本改动(本次仅部署了 5.44)
3. **失败步骤 .jpg 正向验证**(可构造含无效选择器的轻量用例,绕开登录问题)
4. ⚠️ **遗留 P0**:5.44 全量套件 ~100% 失败——`do_login` 后落不到首页,卡 `.nav_right_list.el-dropdown-selfdefine` 等待;首页/看板/会议巡检等大量用例被看门狗以「执行长时间无进展」中断(steps_result 为空、start_time 为 None)
---
## 📊 历史状态(会话 50,2026-09-02 · 会议巡检 navigate 直达升级)
**/sut-explore 弱模式入口直达探测**:对 5 个 drawer+click 入口(运维区域/告警列表/会议巡检/转录列表/会议审批)做 navigate 直达 URL 升级探测。
......@@ -43,7 +80,7 @@
**待办**
- ~~P1 提交本会话 UI 自动化改动~~ ✅ 已完成(`1924d77f` + `d2660651` 已推送)
- P1 并行会话 performance 改动(CSV 强制校验 + 登录监控,6 文件在工作区)待该窗口提交,勿混入本会话
- ~~P1 并行会话 performance 改动(CSV 强制校验 + 登录监控,6 文件在工作区)~~ ✅ 已由该窗口提交(`0aa655a5` + `9ea984a8`
---
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论