# miniprogram-ai-ui-tests-cdp **Repository Path**: chen_jialin123/miniprogram-ai-ui-tests-cdp ## Basic Information - **Project Name**: miniprogram-ai-ui-tests-cdp - **Description**: 微信小程序 AI UI 自动化测试框架:自然语言驱动、CDP 坐标视觉执行、可审计视觉证据报告。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-09-10 - **Last Updated**: 2026-09-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README
# 微信小程序 AI UI 自动化测试框架 **用自然语言描述用户目标,让模型基于页面截图定位坐标, 通过微信开发者工具 CDP 执行真实 UI 操作,并交付可离线审阅的证据报告。** [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D18-339933?logo=nodedotjs&logoColor=white)](https://nodejs.org/) [![CDP](https://img.shields.io/badge/CDP-%E8%A7%86%E8%A7%89%E5%9D%90%E6%A0%87-2563EB)](docs/framework-decision-flow.html) [![报告](https://img.shields.io/badge/%E8%AF%81%E6%8D%AE-%E5%8F%AF%E5%AE%A1%E8%AE%A1-0F766E)](#证据与报告) `自然语言 YAML` · `CDP 视觉坐标` · `真实 UI 输入` · `视觉裁决` · `单文件 HTML 报告` [快速开始](#快速开始) · [编写黑盒用例](#编写黑盒用例) · [查看证据报告](#证据与报告) · [理解执行链路](#cdp-视觉执行链路) · [Docker 运行](#docker-运行)
优惠券链路的语义化回放:从首页进入个人中心、打开优惠券、切换状态标签,直到点击领券中心
执行:模型看截图给坐标,CDP 操作真实小程序
报告首屏:passed 结论横幅、100% 通过率、结论摘要与步骤导航
交付:单文件 HTML 报告,可离线审阅与回放
均来自真实运行 run-2026-09-09T04-42-42;回放原始视频见 flow.mp4
--- ## 它解决什么问题 微信小程序的 UI 测试常常在两类成本之间取舍:维护 XPath、selector 与元素属性的**白盒测试**,或者依赖人工回归的**黑盒测试**。本项目为后者提供可执行、可复核的路径:测试作者只描述用户要做什么与看见什么;运行时由模型读取当前截图,给出动作与视觉坐标;框架通过开发者工具的 CDP 输入通道完成操作,并把每一步的截图、裁决和结果沉淀为证据。 | 你关心的事 | 框架如何处理 | | --- | --- | | 不想维护选择器 | CDP 主通道以截图和坐标执行黑盒自然语言用例,无需 XPath、CSS 或元素句柄。 | | 不只想知道“通过 / 失败” | 每个关键动作保留截图、功能结果和视觉审查,报告可回放和追溯。 | | 需要可交付的测试证据 | `report.html` 可作为单文件离线分享;`manifest.json` 可重新校验产物完整性。 | | 需要兼容已有白盒用例 | 保留 automator 通道,继续支持 selector、XPath 和元素级断言。 | > **推荐从 CDP 坐标视觉通道开始。** 它适合没有稳定选择器、希望按用户可见结果编写测试的小程序页面。已有 XPath 或元素属性断言的用例则继续使用 automator 通道。 ## 快速开始 下面的主路径面向 **CDP 坐标视觉通道**:安装依赖、启动微信开发者工具的调试端口、提供模型配置,然后运行一个黑盒用例。 ### 1. 准备环境 - Node.js `>= 18`(项目与 Docker 镜像使用 Node.js 22)。 - 已安装微信开发者工具,且拥有待测小程序的源码。 - 一个支持视觉输入的模型服务;决策模型与视觉模型默认可共用。 - 可选:安装 FFmpeg 生成 `flow.mp4`。缺少它不会影响截图、裁决或报告。 ```bash npm ci ``` ### 2. 启动 CDP 调试端口 先在微信开发者工具中打开并编译待测小程序,再使用调试端口启动或重启工具: ```bash open -a wechatwebdevtools --args \ --remote-debugging-port=9333 \ --remote-allow-origins=* ``` 确认端口和页面 target 已经出现: ```bash nc -z 127.0.0.1 9333 curl -s http://127.0.0.1:9333/json/list ``` 返回中应包含渲染层 `__pageframe__`、逻辑层 `appservice` 与 IDE 顶层 target。若端口不同,后续通过 `CDP_PORT` 覆盖默认的 `9333`。 ### 3. 配置模型并运行示例 凭据仅设置在当前 shell,不写入仓库、YAML、报告或 Manifest: ```bash export LLM_API_KEY='<你的 API Key>' export LLM_BASE_URL='https://<你的模型网关>' export LLM_MODEL='<支持视觉输入的模型名>' export CDP_PORT=9333 node src/run-all.js --channel cdp \ --cases cases/miniprogram-1/coupon-blackbox-flow.yaml ``` 运行结束后,终端会打印本次运行目录;默认位于 `test-results/ai-ui/run-*/`。先打开其中的 `report.html`,即可离线审阅完整流程。 ### 30 秒看懂用例 用例描述用户行为与可观察结果,而不是实现细节。下面是可作为起点的 CDP 黑盒用例: ```yaml name: 领取第一张优惠券 tags: [coupon, smoke] initialization: action: relaunch args: path: pages/home/home flow: - id: open-coupon ai: 在个人中心找到并点击「优惠券」入口 assert: 已进入优惠券页面,页面展示优惠券相关内容 - id: claim-first ai: 点击列表中第一张状态为「立即领取」的优惠券 assert: 出现「领取成功」文案 ``` 完整可运行的示例见 [coupon-blackbox-flow.yaml](cases/miniprogram-1/coupon-blackbox-flow.yaml)。 ## 核心能力 | 能力层 | 做什么 | 为什么可信 | | --- | --- | --- | | **黑盒编写** | 用 `ai` 描述用户操作,用 `assert` 描述用户可见的成功结果。 | 测试不绑定 XPath、CSS 或组件私有结构。 | | **视觉执行** | 模型阅读当前截图并返回坐标;框架将坐标映射到开发者工具 IDE 顶层输入。 | 坐标和模拟器几何每一步重新测量,避免换页、滚动或窗口缩放后沿用旧数据。 | | **分层裁决** | 功能结果、截图、视觉审查、可见文案与可选状态字段共同参与结论。 | 证据不足不会伪造成功,而是保留为 `needs_review`。 | | **审计交付** | `report.json` 是事实源,HTML、PDF 和完整性清单均由它派生。 | 截图、视频和结构化结果可通过 SHA-256 清单复验。 | ## CDP 视觉执行链路 ```text 自然语言 YAML │ ▼ 页面观测:截图 + 路径 / 数据摘要 / 滚动状态 │ ▼ 决策模型:根据当前画面给出动作和视觉坐标 │ ▼ CDP 坐标通道:映射到微信开发者工具 IDE 顶层输入 │ ▼ 等待页面稳定 → 截图留证 → 视觉审查 / 文案核对 / 语义断言 │ ▼ 确定性裁决:passed / failed / needs_review / aborted │ ▼ report.json → report.html / report.pdf / manifest.json ``` - 点击不会直接向渲染层注入鼠标事件,而是映射到 IDE 顶层窗口,保证小程序 tap 经由开发者工具输入桥触发。 - 能以路径、状态字段等方式确定性验证的结果优先确定性验证;无法稳定判断时进入 `needs_review`,而不是把不确定性伪装成通过。 深入了解 target 选择、坐标映射、原生反馈截图与模型职责,请查看 [CDP 判定链路图](docs/framework-decision-flow.html)。 ## 编写黑盒用例 批量运行的用例文件支持 YAML 和 JSON,必须通过 `--cases` 或 `AI_UI_CASES_FILE` 显式提供。推荐从 [cases/miniprogram-1/](cases/miniprogram-1/) 中的 `*-blackbox-flow.yaml` 开始。 ### 四个关键字段 | 字段 | 作用 | 编写建议 | | --- | --- | --- | | `initialization` | 让用例从已知状态开始。 | 常用 `relaunch` 配合稳定页面路径。 | | `ai` | 描述用户真正要完成的操作。 | 写“点击优惠券入口”,不要写坐标、selector 或内部组件名。 | | `assert` | 描述用户能看见或确认的结果。 | 优先写页面、路径、文案、列表变化和状态变化。 | | `expect` | 为幂等控件添加可选的结构化补强。 | 仅在稳定业务状态位于页面 data 中时使用。 | ### 幂等筛选项的确定性补强 点击已经选中的标签时,界面可能不会产生可见变化。对于“全部 / 好评 / 中评 / 差评”这类互斥项,可通过页面 data 中的稳定字段补强裁决: ```yaml - id: filter-positive ai: 点击评论筛选栏中的「好评」标签 expect: stateField: commentType stateValue: '3' assert: 已切换到「好评」筛选,下方评论列表刷新为好评内容 ``` 先点击未选中项,默认选中项最后恢复,可减少“无变化但操作合法”的歧义。 ### 运行与筛选 ```bash # 执行文件内全部用例 node src/run-all.js --channel cdp \ --cases cases/miniprogram-1/comments-blackbox-flow.yaml # 按标签或用例名筛选 node src/run-all.js --channel cdp --cases <用例文件> --tag smoke node src/run-all.js --channel cdp --cases <用例文件> --case '领取第一张优惠券' ``` ### CDP 用例边界 CDP 是纯视觉坐标范式,没有元素句柄。CDP 用例中不要使用 XPath、`aria-selected`、`element_*` 断言,也不要以“真实节点”等 DOM 前提描述成功条件;应使用自然语言、页面路径、可见文案、列表变化或数据字段。 ## 证据与报告 每次运行都会创建独立目录,避免不同批次的截图、视频和结论相互覆盖: ```text test-results/ai-ui/run-<时间戳>/ ├── report.json # 结构化事实来源 ├── report.html # 可独立分享的离线 HTML 报告 ├── report.pdf # 可下载的 PDF ├── report-pdf-preview.html # 目录内打印预览页 ├── manifest.json # SHA-256 完整性清单 └── cases/ └── 001-<用例标识>/ ├── result.json ├── flow.mp4 # FFmpeg 可用时生成 └── screenshots/ ``` ### 报告长什么样 下面的图片与视频全部来自本仓库的一次真实运行 `run-2026-09-09T04-42-42`:CDP 通道执行 [coupon-blackbox-flow.yaml](cases/miniprogram-1/coupon-blackbox-flow.yaml),9 个步骤、10 个动作、结论 `passed`,耗时 1 分 45 秒。 **证据工作台**把语义化回放与该步骤的留证截图并排放在同一屏,点击时间轴标记即可跳到对应步骤: ![证据工作台:左侧语义化回放播放器与时间轴标记,右侧当前步骤的留证截图](docs/assets/report/02-workbench.png)
回放单帧:优惠券列表上出现原生 toast「去领券中心」,底部字幕栏显示步骤 09、通过徽标与「已验证:出现「去领券中心」」 **回放是合成的,不是屏幕录制** 按语义时间线合成 H.264 视频(本次 430×834、30fps、22 秒):每个镜头烧录步骤序号、状态徽标与字幕,点击动作绘制落点波纹与指针,跳转、无变化与需复核的镜头时长按语义区分。 左图是第 9 步点击「领券中心」后的即时反应帧:原生 toast「去领券中心」被拍下,字幕同步写明核对了哪句文案,徽标显示该步已通过。 原生浮层只有 IDE 窗口截图能拍到,渲染层截图看不见它——这也是断言里的可见文案能被真正核对的前提。 原始文件:[07-flow.mp4](docs/assets/report/07-flow.mp4) · 323 KB · 可直接下载播放
展开后可以看到每一步的标识、指令、完成状态,以及本次运行的模型与环境信息: ![展开的步骤清单与运行环境信息:运行 ID、决策与视觉模型、耗时、操作系统与开发者工具版本](docs/assets/report/03-run-meta.png) 同一份事实还派生出可下载的 PDF,以及每个关键动作后独立留存的留证截图:
report.pdf 第 1 页:报告编号 RPT-20260909-044242、用例统计、元数据表格与步骤明细
report.pdf:报告编号、用例概览与逐步明细
关键步骤截图:初始首页、个人中心、优惠券状态标签切换、点击领券中心后的反应帧
逐步留证截图,可独立复核画面变化
以上图片与视频由 [scripts/build-doc-assets.js](scripts/build-doc-assets.js) 从运行目录直接生成,不做任何手工合成或美化: ```bash node scripts/build-doc-assets.js # 用最新一次完整运行 node scripts/build-doc-assets.js test-results/ai-ui/run-<时间戳> # 指定运行目录 ``` ### 运行状态 | 状态 | 含义 | 进程退出码 | | --- | --- | ---: | | `passed` | 功能与核心证据均通过。 | `0` | | `failed` | 动作、功能断言或高置信视觉审查失败。 | `1` | | `needs_review` | 低置信、证据不足或无法稳定判断。 | 仅此状态时为 `3` | | `aborted` | 环境、模型或执行通道中断。 | `1` | 配置错误、缺少凭据或端口不可用时,退出码为 `2`。 ### 报告模板与完整性校验 `report.html` 内联实际引用的截图和录屏,可脱离运行目录离线打开与回放;`report-pdf-preview.html` 仍使用相对路径,仅适合保留在目录内查看或打印。 ```bash # 研发排查:包含完整诊断信息 node src/run-all.js --channel cdp --cases <用例文件> --template default # 对外交付:裁剪内部诊断字段 node src/run-all.js --channel cdp --cases <用例文件> --template delivery # 重新校验运行目录中的证据文件 node src/run-all.js --verify test-results/ai-ui/run-<时间戳> ``` - `default` 适合研发排查,保留步骤、视觉审查、置信度与拒绝原因。 - `delivery` 只保留对外交付需要的结论与关键证据,避免把内部诊断数据写入共享的页面数据中。 - `--verify` 会输出 `valid`、`missing`、`modified` 或 `unexpected`;审计应以该结果为准。 完整设计与单文件边界见 [单文件报告设计说明](docs/single-file-report-design.md)。 ## 通道选择与配置 ### CDP 主通道与 automator 兼容通道 | | CDP 坐标视觉(推荐) | automator | | --- | --- | --- | | 运行方式 | `node src/run-all.js --channel cdp` | `node src/run-all.js` | | 默认端口 | `9333` | `9420` | | 定位方式 | 截图理解 + 视觉坐标 | selector、XPath、元素句柄 | | 断言边界 | `page_*`、`data_*`、可见文案 | 支持元素级断言 | | 适合用例 | 黑盒自然语言测试 | 已有白盒定位或元素属性断言 | 如需运行历史 automator 用例,先启动微信开发者工具的自动化服务: ```bash /Applications/wechatwebdevtools.app/Contents/MacOS/cli \ auto --project <小程序项目路径> --auto-port 9420 node src/run-all.js --cases cases/miniprogram-1/coupon-fastpath-flow.yaml ``` ### 常用环境变量 模型 API Key 只存在于运行进程内;序列化日志、报告与 Manifest 不会记录 Key 或 Authorization。 ```bash # 必填:决策模型 export LLM_API_KEY='<你的 API Key>' export LLM_BASE_URL='https://<模型网关>' export LLM_MODEL='<模型名>' # 可选:使用独立视觉模型;未设置时继承 LLM_* 配置 export VISION_API_KEY='<视觉模型 API Key>' export VISION_BASE_URL='https://<视觉模型网关>' export VISION_MODEL='<视觉模型名>' export VISION_API_STYLE=chat_completions # 或 responses # 常用运行边界 export AGENT_MAX_STEPS=45 export AGENT_MAX_STEP_ATTEMPTS=5 export AI_UI_SCREENSHOT_QUALITY=78 export AI_UI_VISION_THRESHOLD=0.8 export AI_UI_VIDEO_ENABLED=true ``` ### 推理档位与输出设置 `LLM_REASONING_EFFORT` 与 `VISION_REASONING_EFFORT` 支持 `none`、`minimal`、`low`、`medium`、`high`、`xhigh`、`max`,默认是 `none`。视觉档位未单独设置时继承决策档位。模型适配器会根据模型名称处理 GLM、Qwen、Kimi、豆包、GPT 与 DeepSeek 等网关的参数差异;不要在业务调用层拼接厂商特有的思考字段。 | 目标 | CLI 参数 | 环境变量 | 默认值 | | --- | --- | --- | --- | | 用例文件 | `--cases <路径>` | `AI_UI_CASES_FILE` | 必填 | | 通道 | `--channel cdp` | `AI_UI_CHANNEL` | `automator` | | 输出目录 | `--results-dir <路径>` | `AI_UI_RESULTS_DIR` | `test-results/ai-ui` | | 报告模板 | `--template <名称>` | `AI_UI_REPORT_TEMPLATE` | `default` | | 公司名称 | `--company <名称>` | `AI_UI_REPORT_COMPANY` | `XXXX 公司` | | 报告编号 | `--report-no <编号>` | `AI_UI_REPORT_NO` | 按运行时间生成 | | SVG 标识 | `--logo <路径>` | `AI_UI_REPORT_LOGO` | 内置标识 | ## Docker 运行 `docker/` 提供包含微信开发者工具 Linux 版、Xvfb、noVNC、Node.js 与测试框架的运行环境。构建镜像时会从公开 demo 仓库获取示例小程序;使用自己的项目时,可通过 Compose 卷挂载覆盖 `/workspace/miniprogram`。 首次使用仍需在 noVNC 中完成扫码登录;登录状态由 Docker 卷持久化,之后可复用。 ```bash cd docker docker compose build docker compose up -d ``` 浏览器访问 ,连接后启动开发者工具并完成登录: ```bash docker exec -it wechat-devtools-test /docker-scripts/start-devtools.sh ``` 登录完成后,启动 CDP 通道并运行黑盒用例: ```bash docker exec -it wechat-devtools-test \ /docker-scripts/start-cdp.sh /workspace/miniprogram 9333 docker exec -it wechat-devtools-test bash -lc ' cd /workspace/ai-ui-tests && CDP_PORT=9333 node src/run-all.js --channel cdp \ --cases cases/miniprogram-1/coupon-blackbox-flow.yaml ' ``` 完整的登录、端口、挂载、工具版本和容器排障说明见 [docker/README.md](docker/README.md)。 ## 排障速查 | 现象 | 优先检查 | | --- | --- | | CDP 端口不可用 | `nc -z 127.0.0.1 9333`;确认工具通过 `--remote-debugging-port=9333` 启动。 | | 看不到页面 target | 访问 `/json/list`,确认有 `__pageframe__`、`appservice` 与 IDE 顶层 target;检查项目已打开并完成编译。 | | 点击没有触发小程序 tap | 不要直接向渲染层注入鼠标事件;使用框架的 CDP 坐标通道映射 IDE 顶层输入。 | | CDP 用例反复失败 | 检查是否混入 XPath、`element_*` 或元素属性断言;改为页面、文案或数据字段断言。 | | automator 连接失败 | 确认工具服务端口已开启,且 `9420` 正在监听。 | | 缺少流程视频 | 检查 `ffmpeg` 在 PATH 中,或通过 `FFMPEG_PATH` 指定;截图与报告仍可正常使用。 | 调试模型请求和响应时,将日志重定向到临时文件: ```bash AI_UI_DEBUG=true node src/run-all.js --channel cdp \ --cases <用例文件> 2> /tmp/ai-ui-debug.log ``` 调试日志会对密钥、授权字段、Cookie 和图片 Base64 脱敏或截断。不要把 API Key 放进 YAML、报告品牌参数、用例描述或调试日志。 ## 开发与协作 安装依赖后,先运行本地验证: ```bash npm test npm run check ``` `npm test` 使用 Node 内置测试运行器覆盖 `tests/**/*.test.js`;`npm run check` 对主要入口和 `src/lib/` JavaScript 执行语法检查。修改坐标映射、点击吸附或 CDP 输入链路后,除单元测试外,请用真实开发者工具跑一条 CDP 黑盒用例,确认目标点击和报告证据。 提交改动时请保持通道边界清晰: - CDP 用例只写黑盒自然语言及页面、文案、数据结果。 - automator 用例才使用 XPath、selector 和元素断言。 - 报告渲染以 `report.json` 为唯一事实来源;对外交付模板必须裁剪注入数据,而不仅是隐藏页面元素。 - 不要提交 API Key、访问令牌、用户数据或运行产生的敏感证据。 ### 深入阅读 - [CDP 判定链路图](docs/framework-decision-flow.html) - [单文件报告设计说明](docs/single-file-report-design.md) - [Docker 使用说明](docker/README.md) - [黑盒与 automator 示例用例](cases/miniprogram-1/)