# {模块名称} - 业务流程测试编排

> **module**: {模块名}
> **doc_type**: E2ESpec
> **status**: Draft / Review / Active
> **owner**: {负责人}
> **upstream_docs**: 01-prd.md, 02-user-journey.md, 09-test-scenarios.md
> **last_verified**: YYYY-MM-DD
>
> **执行方式**: AI + Playwright MCP（不编写测试代码）
> **前置条件**: L0/L1 已通过，测试栈已启动

---

## 测试环境

L2 MCP E2E **必须运行在独立测试环境**，不得指向开发环境。

- **环境配置来源**: `testing/backend/docs/TEST_ENV_CONFIG.md`
- **启动脚本**: `testing/scripts/run-e2e.sh`
- **停止脚本**: `testing/scripts/stop-e2e-stack.sh`

| 服务 | 来源 |
|------|------|
| 前端（MCP 指向） | 见 `TEST_ENV_CONFIG.md` 中 E2E 前端地址 |
| 后端 API | 见 `TEST_ENV_CONFIG.md` 中 E2E 后端地址 |
| 测试数据库 | 见 `TEST_ENV_CONFIG.md` 中测试数据库连接 |

> 具体端口、库名、密码等环境值不在此模板中硬编码，统一维护在测试环境配置文档中。

---

## 执行规范

### 鉴权

- 首次登录后保存 `storageState`，不在每个流程重复走登录 UI
- 切换角色时重新登录并保存新的 storageState

### 元素定位

- 优先使用 accessibility tree（role/name）
- 不依赖 `data-testid`
- 输入组件优先使用可见文本和标签定位

### 断言要求

- 每个流程至少包含**页面级断言**和**结果级断言**
- 提交、发布、状态流转后必须断言回显或列表变化
- 权限场景必须断言"看不到"或"被拒绝"

### 测试账号

| 账号 | 角色 | 组织 | 用途 |
|------|------|------|------|
| {账号1} | {角色} | {组织} | {用于什么流程} |

> 测试账号由种子脚本自动创建，密码见 `TEST_ENV_CONFIG.md`。

---

## 流程编排

> 流程按业务依赖排序，前一个流程的输出状态是后一个流程的前置状态。

### 流程 1：{流程名称}（P0/P1）

**角色**: `{账号}`
**目标**: {一句话描述这个流程要完成什么}
**前置状态**: {系统需要处于什么状态，如"无"或"流程 N 输出"}
**输出状态**: {流程完成后系统处于什么状态}

| 步骤 | 操作 | 输入数据 | 断言 |
|------|------|---------|------|
| 1.1 | {用户做什么} | {输入什么数据} | {期望看到什么} |
| 1.2 | {用户做什么} | {输入什么数据} | {期望看到什么} |

---

### 流程 2：{流程名称}（P0/P1）

**角色**: `{账号}`
**前置状态**: 流程 1 输出 — {描述}
**输出状态**: {描述}

| 步骤 | 操作 | 输入数据 | 断言 |
|------|------|---------|------|
| 2.1 | {操作} | {数据} | {断言} |

---

> **编排原则**：
> - 流程数量按模块实际需要调整，覆盖 `01-prd.md` 验收标准中的所有条目
> - 每个流程有明确的角色、前置/输出状态，形成可串联的完整业务链
> - 输入数据使用具体值（不用占位符），让 MCP 可以直接填入
> - 断言使用可观察的 UI 状态（文本、标签、按钮状态），不依赖 API 返回

> **与 09-test-scenarios 的区别**：09 定义覆盖面（测什么），本文档定义执行编排（怎么测）。09 的场景 ID 和本文档的流程步骤可以交叉引用但不要求一一对应。
