Files
lingxi/e2e/README.md
T
Stev_Wang 3e384febf3
ci / 质量门禁 (push) Canceled after 0s
fix(tooling): 给 db:reset 增加显式确认,避免误清本地密码
背景:
- 本轮部门管理联调后执行了 pnpm db:reset 清理测试数据,清空本地库,
  导致用户手工改过的登录密码被重置回 lingxi2026;
- 之前只保证了 ./dev.sh / pnpm dev / pnpm db:init 不会重置数据,
  db:reset 本身仍可被脚本或助手无提示执行,问题没有真正兜住。

改动:
- 新增 scripts/db-reset.mjs:默认拒绝执行并打印影响;只有显式
  ALLOW_DB_RESET=1 才调用 prisma migrate reset --force;
- package.json 的 db:reset 指向该脚本;
- README / AGENTS §6 §11 / e2e README / A1 实施报告同步:
  日常迁移补种子只用 pnpm db:init,验证/联调中禁止 db:reset;
  e2e 会改写 actor 密码,需使用专用账号或独立测试库。

影响面:
- 确需清库时多一步显式确认;迁移、启动、单测、int 测试不受影响。

回滚方式:
- 回滚本提交即恢复 db:reset 直接执行 prisma migrate reset --force。

验证证据:
- pnpm db:reset 无 ALLOW_DB_RESET 时退出码 1,并打印拦截说明;
- pnpm format:check / lint 通过;node --check scripts/db-reset.mjs 通过。
2026-11-03 15:16:52 +08:00

63 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# e2e(Playwright)
## 现有用例
| 文件 | 说明 | 默认是否执行 |
| --------------------- | --------------------------------------------- | ----------------- |
| `smoke.spec.ts` | A0 冒烟:登录、模块切换、403 / 404 | 是 |
| `a1-identity.spec.ts` | A1-QA-01 账号生命周期(①–⑥) | 否,需 `A1_E2E=1` |
| `a2-roles.spec.ts` | A2-QA-01 角色管理 / 权限三态 / SoD / 即时生效 | 否,需 `A2_E2E=1` |
## A1 账号生命周期用例
覆盖 6 类:首登强改 → 重登 → `/users`;刷新页面单飞刷新;登出后 refresh 失效;停用后旧会话与再登录被拒;角色变更下一次请求生效;无 `user:view` 访问 `/users` 显示 403。
### 前置
1. API:`pnpm --filter @lingxi/api dev`(`http://127.0.0.1:3000/api/v1`,真实 PG + Redis,已 `pnpm db:init`;**不要执行 `db:reset`**,会清空本地账号密码)。
2. Web:`pnpm --filter @lingxi/web dev`(`http://127.0.0.1:5173`,需 `VITE_PUBLIC_DEMO_SESSION=false`,否则登录走演示会话)。
3. 管理员 actor:默认用种子超管 `jiang.lan`(首登会把初始密码 `lingxi2026` 改成 `QaE2eAdmin2026`,之后复用)。
若本地已改密或想换账号,覆盖:`A1_E2E_ACTOR_ACCOUNT` / `A1_E2E_ACTOR_PASSWORD`。
⚠️ 不要用 `admin`:本地 `admin` 密码可能已被人工修改或触发登录锁定。
⚠️ e2e 会把 actor 密码改成 `QaE2eAdmin2026`(之后复用),请用专用测试账号/测试库,不要指向日常在用的账号。
### 运行
```bash
A1_E2E=1 pnpm exec playwright test e2e/a1-identity.spec.ts --reporter=list
```
- 可选覆盖:`A1_E2E_BASE_URL`(缺省 `http://127.0.0.1:5173`)、`A1_E2E_API_BASE_URL`(缺省 `http://127.0.0.1:3000/api/v1`)。
- 截图:`design/a1-ui-v1/shots/impl/e2e/`(`01-*` … `06-*`)。
- 数据自建自清:用管理员 token 通过 API 创建 `qa.first.* / qa.main.* / qa.noperm.* / qa.disable.*` 四个用户,结束后统一停用(不删除,便于审计回看);不改 admin 密码。
### 说明
- 门控未开启(无 `A1_E2E=1`)时整文件 `test.skip`,`pnpm test:e2e` 与 CI 行为不变。
- 若在 `vite preview`(4173)上执行,需把 API 的 `WEB_ORIGIN` 同时包含 `http://127.0.0.1:4173`,否则跨域请求被拦;本用例默认打 5173 dev,避免改动 API 配置。
## A2 角色管理用例(A2-QA-01)
覆盖一条完整旅程(真实 API + 真实 PG/Redis + 真实浏览器):
1. 管理员登录 → `/system/roles` → 新建角色(名称、2 个普通权限、数据范围「本部门」)→ 保存进入编辑器。
2. 编辑器改权限点;授予特殊权限(`delivery:export` 开关)触发**二次确认**,保存前再确认一次(特殊权限双确认)。
3. SoD 冲突:同时勾选 `script:write` × `script:review` → 顶部「命中职责互斥」拦截 + 底部「存在职责互斥,保存不可用」且保存按钮禁用;解除后恢复可保存。
4. 用 API 断言**权限即时生效**:绑定用户同一 access token 的 `/me` 在下一次请求即包含 `user:view` 与 `delivery:export`,`GET /users` 由 403 → 200;`GET /roles/{id}` 的普通权限与特殊权限分桶正确。
5. 权限三态(UI 侧):该用户有 `user:view` 但无 `role:view`,访问 `/system/roles` 显示 403 页。
6. 停用确认(勾选知晓 + 停用原因)→ 编辑器状态变「停用」;API 断言 `/me` 权限清空、`GET /users` 返回 403 `40301`;列表「停用」筛选下可见该角色且行内标记「停用」。
7. 数据自建自清:`beforeAll` 按前缀清理上次异常中断的遗留角色/用户;`afterAll` 解绑并停用 `qa2.roles.*` 用户、删除 `A2E2E-角色-*` 角色(不停用 admin、不改 admin 密码)。
### 前置与运行
前置与 A1 相同(API `http://127.0.0.1:3000/api/v1`、Web `http://127.0.0.1:5173` 非 demo 会话、已 `pnpm db:init`):
```bash
A2_E2E=1 pnpm exec playwright test e2e/a2-roles.spec.ts --reporter=list
```
- 门控未开启(无 `A2_E2E=1`)时整文件 `test.skip`,`pnpm test:e2e` / CI 行为不变。
- 可选覆盖:`A2_E2E_BASE_URL`(缺省 `http://127.0.0.1:5173`)、`A2_E2E_API_BASE_URL`(缺省 `http://127.0.0.1:3000/api/v1`)、`A2_E2E_ACTOR_ACCOUNT` / `A2_E2E_ACTOR_PASSWORD`(缺省 `jiang.lan` / `QaE2eAdmin2026`,首跑用种子口令 `lingxi2026` 自动完成首登改密)。
- 截图:`design/a2-ui-v1/shots/impl/e2e/`(`01-roles-list` … `11-roles-list-disabled`,共 11 张 1440×900)。
- 说明:用户按 A1 口径只停用不删除(用户不可删);角色在解绑后删除,可重复运行。