# 08 — demo 浏览器级自动化测试(webapp-testing) `Type:` task · `Status:` resolved · `Blocked by:` 07 ## Question 用 skill:webapp-testing(Playwright)对 demo 做浏览器级自动化测试,产出测试记录 + 截图序列 + 发现问题清单(并入票 09 报告)。 工作项: - **前置确认**:8080 在监听(否则按 map Notes 起服命令重启)+ seed 数据就位(票 03)。 - **逐 tab 走查核心业务流程**:选人登录 → 三 workspace 切换(列表/卡片/看板)→ 列表检索/排序 → 详情 8 页签逐一渲染 → 跟进写入 → 新增查重弹窗(相似/硬拦两路)→ 关注/标记 → 成员添加/移除 → 归属动作 → 交割发起+分配 → 导入全链 → 提醒配置读写。 - **零容忍口径**(商机自测标准):console errors = 0、page errors = 0;每步截图留档(shot-01..NN)。 - **发现即录**:前端层 Bug(渲染错位/字段回显错误/交互断裂/JS 报错被吞)与**与原型不符的功能点**(对照 A4 页族原型:布局结构/字段/交互流)逐条记录为缺陷候选(D-xx 编号衔接票 04/05 已用的号段),标注原型页码依据。 - 产出:`.scratch/customer-e2e/demo-test-report.md`(或并入 e2e-report 草稿)+ 截图目录。 ## Answer **结论:demo/index.html 浏览器级自测终轮 31 步全绿(31 PASS / 0 FAIL),console errors = 0、page errors = 0,截图 30 张(`shots08/shot-01..30-*.png`)。** ### 前置修复(自测前实控的 demo 契约偏差,6 处) | # | 偏差 | 修复 | |---|------|------| | 1 | 联系人字段名 `contactName/position/isPrimary/remark` | → `name/jobTitleName/isKeyContact/isInternal/giftRemark/source`(对齐 ContactDTO 实控) | | 2 | 联系人 PUT/DELETE 用查询参数 | → `/{id}` 路径变量(CustomerContactController 实控) | | 3 | 导入失败明细 `/failures/page` | → `/api/customer/import/{taskId}/failures`(List 响应) | | 4 | file:// 下 AJAX 无跨源地址 | → 新增 `API_BASE`,fetch/模板下载链接加前缀(CorsConfig 放开 origin) | | 5 | 创建客户 `creditCode` | → `unifiedCreditCode` | | 6 | 跟进方式下拉 PHONE/VISIT/... | → 字典值 `follow_way_01..05` | ### 自测中发现并修复的 demo 真缺陷(2 处) 1. **oneBy() focus 族 URL 形态错误**:demo 用 `/api/customer/focus?id=` 查询参数形态,Controller 实为 `POST /{id}/focus` 路径变量(CustomerFocusController 实控);而 ownership 族(claim/assign/release-pool/archive/restore)确为 flat `?id=` 形态(CustomerOwnershipController 实控)保留不变。修复后 `PATH_OP = {focus,unfocus,star,unstar}` 走 `/{id}/{op}`。第一轮 8 个 console CORS-block 报错实为 404 无 CORS 头的误报(404 响应不带 CORS 头)。 2. **交割 tab 初次加载翻页错误**:tab 按钮 `onclick="transferPage(1)"` 的 1 是"下一页" dir 语义,TR.page 1→2,共 5 条 size=10 时第 2 页空 → "暂无交接单"。改为 `transferPage(0)` 回第 1 页。第一轮步骤 18-26 级联失败根因之一(另一根因:预览 dlgOpen 弹窗未关,`` 拦截后续所有点击——测试脚本已加 dlgClose())。 ### 四轮迭代 | 轮次 | 结果 | 关键动作 | |------|------|----------| | R1 | 21 PASS / 10 FAIL | 首跑:定位 oneBy URL 真缺陷 + 弹窗级联失败 + 撞码假代码 | | R2 | 28 PASS / 3 FAIL | 修 oneBy/撞码代码/弹窗后:零容忍口径达标(console=0/page=0) | | R3 | 30 PASS / 1 FAIL | 修交割 tab 翻页 + 空态行/英文文案断言后 | | R4 | **31 PASS / 0 FAIL** | 数据行计数(排除空态行)后全绿 | ### 定性为测试脚本 bug(非 demo 缺陷,3 处) - `tableHtml` 空态也渲染 1 个 `tr`(`无数据`),`count()` 区分不了空态与数据行 → 改为按"含编辑按钮的行"计数; - `IMP_ST` 状态文案是英文(DRAFT/RUNNING/DONE/FAILED),中文断言永假 → 改断言英文; - DELETE 后 `switchSub` 异步重载慢于固定等待 → 改轮询(最多 4s)。 ### 数据影响与清理 - R1 用假信用代码 `91440101MA9ABC1234` 未触发 L3 → `demo-selftest-撞码客户(KH202609040001)`真实落库(进公海);重跑前已走正门清理:`claim`(领取成 owner)→ `archive`(67004 仅销售负责人可归档 → 先领取)成功,归档后列表不可见(D19 归档=删除语义)。 - R2 起步骤 14 换 seed 真实代码 `91440101E2CHXDA001`,67003 硬拦验证通过(不落库)。 - 联系人甲每轮建/编辑/删闭环,无残留(API 复核 contacts=0)。 - 导入任务每轮 +1 条 DONE 记录(suspectCount=1:INSERT 行被查重判疑似重复不写入)——正常测试数据留存。 - 语义补充(D-05 观测面):本环境 INSERT 行走 **suspect 通道**(疑似重复不写入)而非 FAILED,效果一致(不落库)且 fail 表有明细;D-05 结论(is_biz_negotiated NOT NULL 无默认值致 INSERT 必 FAILED)不变。 ### 交付物 - `.scratch/customer-e2e/demo/index.html`(契约修复 + 2 缺陷修复) - `.scratch/customer-e2e/demo_selftest.py`(26 步自测脚本,四轮迭代版) - `.scratch/customer-e2e/demo-selftest-results.json` + `shots08/`(30 张截图) - `.scratch/customer-e2e/clean_pollution.py`(脏数据正门清理脚本,claim→archive 可复用) ### 遗留(不阻塞) - 自测脚本 note 文案 f-string `/{id}` 撞 Python 内置函数 `id`,输出显示 `DELETE /`——纯展示瑕疵,不影响判定。 - 发现即录的 UI 级问题并入票 09 报告:demo 为验证工具非交付产品,上述 2 缺陷已修复,无新增 D-xx 台账项。