npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

aitestuirunner

v2.0.1

Published

H5QA runner daemon: executes AI-driven UI test cases (Midscene / Playwright) on web and Android, reporting results back to the H5QA platform.

Readme

H5QA Runner · aitestuirunner

在本地或云端执行 H5QA 平台的 AI UI 测试用例(基于 Midscene / Playwright),并把执行结果回传平台。本包发布到 npm 后提供 aitestui 命令行工具。


30 秒上手(推荐)

路线一:从平台页面复制一行命令(最省事,ADR-0041)

打开平台「项目配置 → 本地测试机」,页面顶部已按你的访问地址生成好完整命令, 复制 → 粘到终端 → 回车即可:

npx aitestuirunner join --token <项目 Runner Token>

join 一条龙做完四件事:① 写 .env;② 下载 Chromium;③ doctor 自检;④ 常驻启动。 全程无需交互(缺参时若为终端环境才提问)。首次下载 Chromium 较慢,之后这台机器直接跑:

npx aitestuirunner start

路线二:init 逐步向导

想一项一项填、或不方便复制长命令时用:

npx aitestuirunner init     # 交互填 url / TOKEN / 测试机名称,自动安装 Chromium 并自检环境
aitestuirunner start        # 启动本地测试机,开始领取并执行任务

或先全局安装,后续用更短的 aitestui:

npm install -g aitestuirunner
aitestui join --token <项目 Runner Token>
# 之后每天只需:
aitestui start

join / init 都会做三件事:① 收集最小配置并写入 .env;② 自动 install-browser 下载 Chromium;③ 跑 doctor 自检环境。区别只在配置从哪来——join 从命令行参数来 (平台页面已拼好),init 逐项提问。填错的 Token 可随时重跑,或手动编辑 .env (见 附录 · 全部环境变量)。


命令

aitestui [command],不传子命令默认执行 start:

| 命令 | 说明 | |---|---| | aitestui join --url <api> --token <token> | 一行接入(写 .env + 装 Chromium + 自检 + 启动)。平台页面生成的就是它,首次使用首选。 | | aitestui init | 逐步向导:交互式填 url / TOKEN / 机器名,随后装 Chromium 并自检。 | | aitestui / aitestui start | 启动 Runner 守护进程(默认)。已接入过的机器每天只用这一条。 | | aitestui install-browser | 下载 Playwright 使用的 Chromium 二进制(首次部署执行一次)。 | | aitestui doctor | 自检 Node.js、Chromium 与后端连通性;安卓端还会检查 adb 与在线设备。 | | aitestui help | 显示命令帮助(--help / -h 同)。 | | aitestui version | 显示当前版本号(--version / -v 同)。 |

从源码开发时请用仓库内等价脚本:pnpm dev(= start)、pnpm install-browser、 pnpm doctor、pnpm cloud:* 等。上面的 aitestui 用法面向已通过 npm 安装的使用者。

join 的退出码

| 退出码 | 含义 | 下一步 | |---|---|---| | 0 | 已启动测试机(常驻进程,不会自己退出) | Ctrl+C 停止 | | 1 | 参数缺失或无法识别 | 回平台页面重新复制命令 | | 2 | .env 已写好,但自检未过(后端不可达 / Token 无效) | 修好后直接 aitestui start,不用重新接入 | | 3 | .env 已写好,但 Chromium 装不上 | 换镜像后重跑:H5QA_CHROMIUM_MIRROR=https://npmmirror.com/mirrors/playwright aitestui join ... |

前置条件:Node 18+

npx 依赖本机 Node(18+,推荐 20 LTS)。没装 Node 时终端会直接报 command not found: npx,Runner 此刻还没被启动,没法自己提示你—— 平台页面会按你的操作系统给出安装命令(含国内镜像)。离线/内网环境请先配好 npm 镜像, 否则 npx 拉不到包。


最小配置:只有 TOKEN 必填

绝大多数使用者只需关心一项,init 已经帮你写好了:

| 变量 | 必填 | 说明 | |---|---|---| | TOKEN | 是 | Runner Token(本地用项目共享 Token;云用一次性云 Token)。 | | url | 否 | 后端 API 基址,默认 https://aitestui.com/api(官方站);私有化部署必须显式设置。 |

其余变量都有合理默认值,一般不需要动。想看全部可选项见 附录。 配置可写在运行目录的 .env(H5QA_ENV_FILE 可指定其它路径;文件缺失静默跳过), 已导出的环境变量优先于 .env。


连接与鉴权

Runner 通过最小权限 Token 访问 /api/v1/runner/*。本地 Runner 用项目共享 Token; 云 Runner 用管理员创建、仅显示一次的云 Runner Token。模型调用默认走服务端代理, Runner 不持有任何厂商 Key(详见 附录 · 模型代理/直连)。


附录:进阶配置

全部环境变量

日常只需要 TOKEN 一个;url 有默认值(官方站),私有化部署才必须显式设置。其余项都有合理默认,绝大多数机器用不到。

| 变量 | 必填 | 默认值 | 说明 | |---|---|---|---| | TOKEN | 是 | — | 项目 Runner Token。 | | url | 否 | https://aitestui.com/api | 后端 API 基址。私有化部署必须显式设置,否则会连到官方站。容错:只写域名会自动补 /api,末尾误带的 /v1 会自动去掉。 | | H5QA_RUNNER_NAME | 否 | 主机名 | 人类可读的测试机名称。 | | H5QA_HEADFUL | 否 | false | 本地调试时显示浏览器窗口;云测试机必须保持 false。 | | H5QA_RUNNER_DEBUG | 否 | false | 开启本地全量调试日志(仅 stdout/日志文件,不上行)。 | | H5QA_CHROMIUM_MIRROR | 否 | npmmirror | 覆盖 Chromium 下载主机。 | | H5QA_MIDSCENE_CACHE | 否 | true | 设 0/false/no 强制本机禁用用例缓存。只能把「服务端说开」压成「本机不开」,不能反向打开。 | | ~~H5QA_CREDENTIAL_KEY~~ | 已下线(2.0.0 起) | — | ADR-0010 E17:claim 里的保密变量改由本机 Runner Token 现算派生密钥解锁,本机不再持有任何静态密钥。配了也不读取,无需与部署侧同步。 | | H5QA_TARGET_TYPE | 否 | web | 执行端:web 或 android。 | | H5QA_ANDROID_DEVICE_ID | 否 | 第一台在线设备 | 安卓设备 serial。 | | H5QA_ENV_FILE | 否 | <cwd>/.env | 指定要加载的 .env 文件路径。 | | H5QA_RUNNER_MAX_MEMORY | 否 | 2G | 仅限云测试机的 PM2 守护(ecosystem.config.cjs):内存超限重启阈值。Runner 进程本身不读它。 |

浏览器来源:优先复用本机标准路径下的 Chrome(macOS 的 /Applications/Google Chrome.app、 Linux 的 /usr/bin/google-chrome),找不到才回退 Playwright 自带的 Chromium。这里刻意不可配—— 手动指到某个自定义 Chrome 后,它会在某次自动升级时与 Playwright 的协议不再兼容,症状是一批用例 毫无征兆地集体失败,而那时没人会想起配过这个变量。

逐步执行的步数上限固定为 30 步,不可在本机调(见「自然语言(prompt)用例的执行模式」一节)。 不接受本机覆盖的原因:这是一个成本上限而不是偏好,由测试机单方面放宽等于让被计费的一方 自己决定这个用例能烧多少模型积分;真要放宽,应改服务端 executionTimeoutSeconds 或由平台下发。

调试模式

在 .env 设 H5QA_RUNNER_DEBUG=true:每个 /v1/runner/* 请求打印脱敏请求/响应摘要, 关键节点(领取、YAML 落盘、导航、回放、上报、OSS 上传)打印日志,输出走 stdout 并 tee 到 ~/.h5qa-runner/logs/runner-YYYY-MM-DD.log,不进入上行日志队列。

自然语言(prompt)用例的执行模式

用例格式为 prompt 时,Runner 用 Midscene JS SDK 逐步执行:每步只让模型给一个动作指令并立即执行, 把结果与截图回喂模型,步骤随页面变化调整。有可用缓存脚本时仍按 YAML 回放;无缓存才进入逐步执行。 失败步骤回喂原因换走法,连续失败 3 次判失败;跑通后把实际步骤反汇编成 YAML 回写缓存。 单步上限固定 30 步(不提供本机开关,理由见上方变量表注释)。Debug Run 同样逐步执行,每步前等控制命令。

模型代理与直连(平台侧 ADR-0022)

Runner 不持有任何厂商 API Key。走哪条路由服务端在 claim 时裁定,本机没有任何开关能单方面改变:

| 模式 | 触发条件 | Runner 侧配置 | 计费用量来源 | |---|---|---|---| | 代理模式(默认) | 平台付费模型;或自带 Key 且项目开着「安全代理」 | 无需任何配置 | 服务端权威计数(可熔断) | | 直连模式 | 自带 Key,且项目关掉了「安全代理」 | 无需任何配置(Key 由服务端随 claim 下发) | runner 自报 |

代理模式:服务端随 claim 下发 attempt 级短票据,Runner 注入为 MIDSCENE_MODEL_BASE_URL / MIDSCENE_MODEL_API_KEY,模型请求全部经后端转发。平台付费模型恒定走代理。 直连仅对「服务端够不到的内网/私有 Endpoint」的自带 Key 项目可能获批。

为什么本机没有开关:让测试机单方面决定要不要走代理,等于让被计费的一方自己决定是否被计费。 是否直连挂在项目的模型配置上(模型配置 → 安全代理开关),Runner 只负责执行服务端的裁定。

安卓执行(平台侧 ADR-0026 一期)

执行目标扩展到安卓真机/模拟器(驱动层 @midscene/android)。前置:本机装好 adb,设备 adb devices 状态为 device。用 H5QA_TARGET_TYPE=android 启动即可(H5QA_ANDROID_DEVICE_ID 缺省取第一台在线设备)。 端判定顺序:用例 YAML android 段 > 项目测试机类型 > 本机 H5QA_TARGET_TYPE > 网页。 ios/computer/harmony 段与非法 H5QA_TARGET_TYPE 会明确报 unsupported_target,不会静默拿 Chromium 跑。 安卓端暂不具备网页端的部分能力(回放录像、视觉基线比对、DOM 阻断检测、locate 缓存),日志会说明,不静默降级。

交互式 Debug

Debug Run 被领取后打开目标页并暂停,等待运行报告页发命令:「下一步」只跑当前步; 「运行剩余步骤」连续跑遇失败暂停;「重试当前失败步骤」在超时内可重复;「取消」持久化取消状态。 同一 Debug Run 复用同一浏览器上下文。云 Runner 恒 headless;本地可 H5QA_HEADFUL=true 看窗口。

云 Runner(Linux + Docker / PM2)

每台云主机只启动一个进程,固定并发一(勿用 cluster/多实例)。模型默认走服务端代理,云机不需要任何模型环境变量。

方式一:Docker(推荐)

docker build -t aitestuirunner .
docker run -d --name h5qa-cloud-runner \
  -e url=https://aitestui.com/api \
  -e TOKEN=<one-time-cloud-runner-token> \
  -e H5QA_RUNNER_NAME=cloud-runner-region-a \
  -e H5QA_CHROMIUM_MIRROR=https://npmmirror.com/mirrors/playwright \
  aitestuirunner

镜像 CMD 即 node dist/index.js start(headless)。Token 轮换后重建/重启容器替换 TOKEN 即可。

改 Dockerfile 时别把 Chromium 下载并回 pnpm build 那一层。 Chromium(~184MB)单独成层且排在 COPY src 之前,改业务代码才不会重下一次浏览器;.dockerignore 里的 .h5qa-runs 也别删—— 它是本地运行产物,漏掉会让每次 build 都打包上传几百 MB 上下文。

方式二:PM2(基于源码仓库部署)

pnpm install --frozen-lockfile && pnpm build && pnpm install-browser
export url=https://aitestui.com/api TOKEN=<one-time-cloud-runner-token> \
  H5QA_RUNNER_NAME=cloud-runner-region-a H5QA_CHROMIUM_MIRROR=https://npmmirror.com/mirrors/playwright
pnpm cloud:start && pnpm cloud:save

常用运维:pnpm cloud:status / cloud:logs / cloud:restart / cloud:stop / cloud:delete。 Token 轮换后 pnpm cloud:restart(脚本 --update-env 读取新值)。云 Runner 必须 H5QA_HEADFUL=false、HTTPS 访问后端。

裸机 / 容器依赖

Debian/Ubuntu(bookworm)安装 Chromium 系统库与中文字体:

apt-get update && apt-get install -y --no-install-recommends \
  libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 \
  libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 \
  libgbm1 libpango-1.0-0 libcairo2 libasound2 libatspi2.0-0 \
  fonts-noto-cjk fonts-wqy-microhei
fc-cache -f

中文字体是硬性依赖(ADR-0027)。容器镜像默认不含任何 CJK 字体,Chromium 会把每个汉字 都渲染成同一块「豆腐块」□□□——截图看着像乱码,视觉模型读到的只有等宽方框,用例必然全挂。 而本机 macOS / Windows 自带中文字体,所以这个故障只在云 runner 上复现,排查时容易误判成 页面编码或模型侧问题。aitestui doctor 会显式跑一次中文渲染探针并报出结论。 若已装过字体仍报不通过,检查 fontconfig 缓存(执行 fc-cache -f)。

docker build(基于 node:22-bookworm)已含上述依赖;裸机请自行保证。安卓端另需本机可用 adb。

源码与发布(保护说明,ADR-0002)

发布的 npm 包只含 3 个文件:压缩后的 dist/index.js(单文件、已 minify)、README.md、 ecosystem.config.cjs。src/ 从不进包;构建产物不带 .d.ts(不暴露内部 API 面); 源码映射(.map)留在构建机/私有位置,不随 npm 发布,仅供团队内部解栈排障。 因此从包里只能看到混淆后的执行逻辑,看不到可读源码与类型定义。