# v4.3 路径启用/禁用 + E2E 测试 — 设计文档 **日期**: 2026-05-27 **分支**: v4.2(v4.3 后续创建) **状态**: 已确认 ## 概述 两项独立改进: 1. 路径启用/禁用(软开关):`string[]` → `PathEntry[]`,禁用状态存 JSON 文件 2. E2E 测试:Playwright + Mock IPC,覆盖 4 条关键流程 --- ## Part 1: 路径启用/禁用 ### 数据模型 ```typescript // src/core/path-entry.ts (新增) export interface PathEntry { path: string; enabled: boolean; } ``` 全栈从 `string[]` 迁移到 `PathEntry[]`。注册表读写时做转换。 ### 禁用状态持久化 文件:`%APPDATA%/PathEditor/disabled.json` 格式:`{ "system": ["path1"], "user": ["path2"] }` 加载流程:注册表读取 → `PathEntry[]`(全部 enabled:true)→ 读取 disabled.json → 匹配到的标记 enabled:false 保存流程:只将 enabled:true 的 path join 后写入注册表 切换流程:复选框点击 → 更新内存状态 → 立即调用 `save_disabled_state` 写入 JSON ### 新增 Rust 命令 - `save_disabled_state(system: Vec, user: Vec) -> Result<(), String>` - `load_disabled_state() -> Result, Vec, String>` 返回 `(system_disabled, user_disabled)` ### Undo 适配 - `OpRecord.oldPaths` / `newPaths` 从 `string[]` 改为 `PathEntry[]` - 新增 `OperationType.TOGGLE = 8`:单条路径切换启用/禁用,undo 翻转回去 - 8 种已有操作类型的 switch case 适配 `PathEntry` ### UI - 路径列表每行前加复选框,`#` 序号列与复选框合并 - 禁用行:灰色文字 + 删除线(`text-decoration: line-through`) - 工具栏不新增按钮(复选框独立操作) ### 状态层 - `app-store.ts` 新增 `togglePath(index, target)` 方法 - `loadPaths` 加载时合并 disabled 状态 - `savePaths` 保存时过滤 disabled 路径 --- ## Part 2: E2E 测试 ### 技术选型 `@playwright/test`,独立于 Vitest。Mock Tauri IPC 通过 `page.addInitScript()` 注入。 ### Mock IPC 页面加载前注入 `window.__TAURI_INTERNALS__.invoke` 的 mock 实现,按命令名返回假数据。 ### 4 条测试场景 | 场景 | 步骤 | |------|------| | 启动加载 | 访问页面 → 系统 PATH 显示 2 条 → 用户 PATH 显示 1 条 | | CRUD + 撤销 | 添加路径 → 出现在列表 → Ctrl+Z 撤销 → 路径消失 → Ctrl+Y 重做 → 路径恢复 | | 禁用 + 保存 | 点击复选框禁用 → 路径灰显+删除线 → 点保存 → 验证 save IPC 只传了 enabled 路径 | | 搜索 + 清理 | 输入搜索词 → 列表过滤 → 清空搜索 → 点清理 → 无效路径红色 | ### 运行方式 ```bash npx playwright test ``` 需要先启动 Vite 开发服务器:`npm run dev`