ruan-cat/monorepo

init-playwright

- 在 pnpm monorepo 初始化 Playwright 三件套(@playwright/test + @playwright/cli + playwright-mcp),含 e2e/视觉测试骨架、MCP 配置、AI skills 生成、AI 记忆更新。 内置无头浏览器 CPU 过载事故复盘与故障排查指南:可排查 headless 模式下的 高 CPU 占用(100%)、浏览器卡死、Chromium 进程残留无法退出、 大屏 3D WebGL 渲染性能问题;提供紧急止损步骤和长期回归检查清单。 当用户…

Voir la source
Document Skill original

Rendu depuis le dépôt source en conservant titres, exemples, code, tableaux, liens et images.

在 pnpm monorepo 初始化 Playwright 工具链

本技能记录在 Vue 3 + Vite + TypeScript pnpm monorepo 中初始化 Playwright 三件套的完整工作流,及执行中发现的 2 个关键环境坑。

适用场景

  • pnpm monorepo 项目首次接入 Playwright
  • 大屏/可视化项目需要视觉回归测试
  • 需要为 AI agent 配备浏览器驱动能力(MCP + CLI skills)
  • Node 22 + Windows 环境(坑与 Node 版本/OS 相关)

⚠️ 无头浏览器 CPU 风险须知(重要)

headless(无头)≠ 轻量。无头 Chromium 仍然运行完整的浏览器引擎(Blink 排版、V8 JS 执行、WebGL/WebGPU 渲染管线),只是不显示窗口。在 大屏 3D/可视化项目 下,headless 模式的 CPU/GPU 消耗与 headed(有头)几乎无异:

场景风险等级说明
pw_core MCP 持久化连接🔴 高MCP 下的浏览器是长连接进程,AI 会话期间一直存活,不会用完即销毁。多个 Agent 反复调用 → 进程常驻 → 内存泄漏 → CPU 100%
大屏 3D 页面反复渲染🔴 高ECharts WebGL/3D 图表在无头模式下仍完整执行 GPU 渲染管线。每次截图/快照都触发重绘
pw_core + pw_visual 同时运行🟠 中高两个 Chromium 进程并行,每个 200-500MB 内存,大屏项目可能飙到 1GB+
CI 一次性测试🟢 低测试完成后进程自动退出,风险可控

因此,使用本技能初始化的项目,必须阅读并遵循「无头浏览器安全使用规范」章节的约束。尤其在大屏/可视化/3D 密集型项目上,优先使用 pwvisual(headed)驱动浏览器,避免让 pwcore(headless)长时间常驻。

工作流总览

plain
装三件套 → 端口固定 → 写根级 playwright.config.ts
    → visual-stability.css → .mcp.json + MCP 配置
    → playwright-cli + AI skills 生成
    → package.json scripts (test:e2e + ci)
    → e2e 冒烟测试 → 视觉基线测试
    → AI 记忆三处更新 → 验收

步骤 1:安装三件套

bash
pnpm add -D -w @playwright/test @playwright/cli playwright-mcp
pnpm exec playwright install chromium
pnpm exec playwright --version  # 验证

三件套职责:

用途何时用
@playwright/test编写和运行 e2e/visual 测试CI 固化、pnpm test:e2e
@playwright/cli为 AI agent 生成 skillsplaywright-cli install --skills
playwright-mcpAI 通过 MCP 直接驱动浏览器pwcore(headless,省 token **但高 CPU**)、pwvisual(headed,视觉推理)

步骤 2:monorepo 子 app dev server 端口固定

每个需要测试的 app 的 vite.config.ts 显式设端口,避免 playwright webServer 端口冲突:

ts
server: {
  port: 5174,          // 一期用 5173,二期用 5174,依此类推
  host: "127.0.0.1",   // 必须 127.0.0.1,不用 0.0.0.0
},

步骤 3:根级 playwright.config.ts

monorepo 推荐根目录单一配置,用 testDir + testMatch 集中管理,projects 区分不同 app(后续扩展):

ts
import { defineConfig, devices } from "@playwright/test";

const CI = !!process.env.CI;
const baseURL = "http://127.0.0.1:5174";

export default defineConfig({
	testDir: "./tests",
	testMatch: "**/*.spec.ts", // isolate from vitest *.test.ts
	outputDir: "artifacts/test-results",
	expect: {
		toHaveScreenshot: { maxDiffPixelRatio: 0.001 },
	},
	fullyParallel: false, // 大屏 3D 资源,并行争抢 GPU
	workers: 1,
	retries: CI ? 2 : 0,
	reporter: [["list"], ["html", { open: "never", outputFolder: "artifacts/playwright-report" }]],
	use: {
		baseURL,
		/** 显式声明 headless,不依赖默认值——确保 CI 和非 CI 行为一致 */
		headless: true,
		/** 禁用 GPU 及相关加速,降低 headless 模式下的 CPU 消耗 */
		launchOptions: {
			args: ["--disable-gpu", "--disable-software-rasterizer", "--disable-dev-shm-usage", "--no-sandbox"],
		},
		timezoneId: "Asia/Shanghai", // 中国大屏用上海时区
		viewport: { width: 1440, height: 900 },
		stylePath: "tests/visual/visual-stability.css",
		screenshot: "only-on-failure",
		trace: "retain-on-failure",
	},
	snapshotPathTemplate: "tests/visual/__screenshots__/{testFilePath}/{arg}{ext}",
	projects: [{ name: "chromium-desktop", use: { ...devices["Desktop Chrome"] } }],
	webServer: {
		command: "pnpm --filter <pkg-name> dev", // 见坑 #2
		url: baseURL,
		reuseExistingServer: !CI,
		timeout: 120_000,
	},
});

坑 #1:lint-staged prettier --experimental-cli 在 Node 22 崩溃

现象lint-staged.config.js"*": "prettier --experimental-cli --write" 在 Node 22 沙箱环境触发 WorkTankWorkerError: Terminated,阻塞所有 git commit。

根因:prettier 3.8.1 的 --experimental-cli 依赖 worktank worker 池,在部分 Node 22 环境不稳定。

修复

js
// lint-staged.config.js
export default {
	/**
	 * 临时去掉 prettier 的 --experimental-cli 标志。
	 * prettier 3.8.1 的 --experimental-cli worktank worker
	 * 在 Node 22 沙箱崩溃,回退到普通 --write,待上游修复后恢复。
	 *
	 * 另加 --ignore-unknown:跳过无 parser 的文件(如 .gitignore)
	 */
	"*": "prettier --write --ignore-unknown",
};

注意:--ignore-unknown 很重要——不加的话 .gitignore 等无 parser 文件也会被 prettier 报错阻塞提交。

坑 #2:playwright webServer 的 pnpm filter 吞掉 --host

现象playwright.config.tswebServer.command 设为 pnpm dev:<app> --host 127.0.0.1,webServer 自动启动后返回 404。CI 模式下 reuseExistingServer: false 会直接失败。

根因pnpm dev:<app> 展开为 pnpm --filter <pkg> dev,后面的 --host 127.0.0.1 被 pnpm filter 吞掉,没有传给 vite。

修复:不在 webServer.command 里传 --host/--port,依赖 vite.config.ts 已有的 server 配置:

ts
// playwright.config.ts
webServer: {
  // 不在命令行传 --host/--port,依赖 vite.config.ts 的 server 配置
  command: "pnpm --filter <pkg> dev",
  url: baseURL,
  reuseExistingServer: !CI,
  timeout: 120_000,
},

通用原则:vite 项目的 playwright webServer 所有 server 参数放 vite.config.ts,命令行只传 `dev`

步骤 4:vitest 与 playwright 命名隔离

测试类型文件尾缀目录谁跑
单元/组件/composable*.test.ts**/tests/vitest (pnpm test)
e2e/页面集成*.e2e.spec.tstests/e2e/playwright (pnpm test:e2e)
视觉回归*.visual.spec.tstests/visual/playwright (pnpm test:e2e)

两套配置天然隔离(vitest include*.test.ts,playwright testMatch*.spec.ts),无需互相 exclude。

步骤 5:基线截图提交策略

  • 基线截图提交到 tests/visual/__screenshots__/不进 .gitignore
  • artifacts/、test-results/、playwright-report/ 忽略
  • 首次跑 --update-snapshots 生成基线,二次跑 pnpm test:e2e 验证

⚠️ 无头浏览器安全使用规范

核心原则

headless Chromium 不是轻量模式,它在后台运行完整的浏览器引擎。以下规范帮助你在项目中安全使用 Playwright,避免 CPU 过载事故。

① 优先选择 headed 模式驱动浏览器

不是所有场景都适合 headless。按优先级选择:

推荐顺序驱动方式适用场景理由
✅ 最推荐pw_visual(headed)AI agent 日常驱动视觉效果可见、省 CPU 不会"空转"
⚠️ 酌情pw_core(headless)token 敏感、纯数据验证省 token 不省 CPU,大屏 3D 下 CPU 消耗与 headed 几乎相同
✅ 推荐playwright test(CI)自动化测试、回归验证短生命周期,用完即销毁,风险可控

② MCP 浏览器进程是持久化的,必须管理生命周期

pw_corepw_visual 通过 MCP 协议挂载,AI agent 启动后浏览器进程持续存活。不会自动关闭

  • 会话结束时:必须手动关闭浏览器。在 AI agent 退出前执行:
ts
  // 通过 pw_core 或 pw_visual 的 evaluate_script 关闭页面
  await page.close();
  // 或在测试脚本中使用 afterAll 钩子
  • 长时间不使用:建议在 .mcp.json 中配置进程超时或定期重启
  • 监控 CPU:大屏项目建议在 AI agent 使用浏览器后检查任务管理器,确认 Chromium 进程已退出

③ 大屏 3D 项目的特殊注意事项

如果你的项目包含 ECharts WebGL/3D 图表(如 Ring3DChart、3D 地图等),headless 模式的 CPU 消耗会显著高于纯 2D 页面:

  • 不要频繁截图:每次 get-screenshot 都会触发完整的 WebGL 帧渲染,CPU 飙升至 100%
  • 使用 pw_visual>pw_core:headed 模式至少让你能观察到浏览器的运行状态
  • 减少无意义的页面访问:AI agent 应避免在 headless 下反复 "看一眼" 大屏页面
  • 考虑降低截图分辨率:在非必要场景下调小 viewport 或截图分辨率

④ 在 agent-progress.md 或 AI 记忆中加入浏览器进程回收提醒

建议在项目的 AI 记忆文件中加入以下约束规则:

markdown
### Playwright 浏览器进程使用规则(CPU 安全)

- AI 驱动浏览器默认使用 pw_visual(headed),仅 token 敏感场景用 pw_core
- 每次使用浏览器后检查任务管理器,确认 Chromium 进程已退出
- 禁止在 headless 模式下对 3D 大屏页面做高频截图(每 10 秒 1 次以上)
- 大屏 3D 页面优先用 pw_visual 驱动,避免无头模式下的 GPU 空转

⑤ 在 session 结束时执行进程清理

AI 会话结束时,建议执行以下命令确认没有残留 Chromium 进程:

bash
# Windows - 检查遗留的 Chromium 进程
tasklist /FI "IMAGENAME eq chrome.exe" 2>NUL | find /I /N "chrome.exe"
# 可选:强制关闭残留(请先确认无其他用户进程)
# taskkill /F /IM chrome.exe 2>NUL
bash
# Linux/macOS
# ps aux | grep -i chromium | grep -v grep
# killall chromium  # 谨慎使用

📋 真实事故复盘:无头浏览器 CPU 过载

以下是一次真实事故的完整记录。该事故直接导致 Playwright 工具链从项目中被全面删除。记录于此,帮助后续使用者识别同类型风险。

事故时间线

时间事件状态
Day 1Playwright 工具链初始化完成:pwcore(headless)+ pwvisual(headed)MCP、playwright.config.ts、e2e 冒烟测试、视觉基线、AI 记忆三处同步✅ 12 项验收全通过
Day 1→3AI agent 通过 pw_core 反复驱动 headless 浏览器,对大屏 3D 页面做截图/快照/页面验证🔄 持续运行
Day 3主机 CPU 飙升至 100%,系统明显卡顿。浏览器进程长期驻留不退出🔴 严重
Day 3用户决定彻底删除 Playwright 工具链,涵盖 17 项:MCP 配置、测试代码、配置文件、基线截图、AI 技能文件、package.json 依赖、AI 记忆章节🗑️ 全部清除

根因分析

plain
初始化 Playwright(pw_core headless MCP)
  ↓ AI agent 在 3 天内反复通过 pw_core 驱动浏览器 "查看" 大屏 3D 页面
  ↓ headless Chromium 在后台完整执行 WebGL 渲染管线(3D 环形图、3D 地图等)
  ↓ 每次 get-screenshot / get-full-snapshot 都触发完整的 GPU 帧渲染
  ↓ MCP 协议下浏览器是长连接进程,不会用完即销毁
  ↓ 浏览器进程连续运行 3 天 → 内存持续增长 → CPU 100%
  ↓ 主机性能严重下降,用户被迫删除 Playwright

关键教训

  1. MCP 浏览器是长连接,不是一次性调用 — 它会在整个 AI 会话期间存活,用完不自动关闭。这是与 pnpm test:e2e 一次性测试的最大区别。
  2. headless 不省 CPU — headless 屏蔽的是窗口,不是渲染管线。大屏 3D 项目下 headless 和 headed 的 GPU 负载几乎一样。
  3. 3 天内就能酿成事故 — 从初始化到全面删除只有 3 天时间周期。一旦 AI agent 开始频繁调用浏览器,CPU 问题会快速恶化。
  4. 习惯性 "看一眼" 是最危险的用法 — AI agent 天然倾向于频繁截图/快照来确认页面状态,在 headless 模式下这种 "看一眼" 习惯会触发大量无用 GPU 渲染。

预防措施

  • 初始化时就确认:你的项目是 3D 大屏类吗?如果是,立即改用 pwvisual(headed)而非 pwcore
  • 使用前先设规则:在 AGENTS.md 中明确约束浏览器调用频率和方式(参考"AI 记忆更新模板"中的安全规则)
  • 使用后立即检查:每个 AI 会话结束时运行 tasklist 检查是否有残留 Chromium 进程
  • 避免长时间无人值守:headless 浏览器不要长时间挂机。如果必须使用,建议设置定时重启或进程超时

🧰 故障排查指南

如果你在使用 Playwright 过程中遇到以下现象,说明可能正在重演上述事故。

症状速查表

症状排查方向紧急程度
电脑风扇狂转、系统变卡打开任务管理器,检查是否有多个 chrome.exe 进程(每个 200-500MB 内存)🔴 立即处理
AI agent 每次回复都变慢检查是否每个 AI 消息循环都触发了浏览器截图/快照🟠 尽快优化
pnpm test:e2e 跑完风扇还在转检查是否有残留 Chromium 进程未被测试框架关闭🟠 尽快修复
浏览器自动弹出窗口(headed)确认是否混用了 pw_core 配置但误启动了 headed 模式🟡 观察调整

紧急止损步骤

如果发现 CPU 已经异常飙升:

bash
# 步骤 1:立即检查 Chromium 进程数
tasklist /FI "IMAGENAME eq chrome.exe" 2>NUL

# 步骤 2:如果存在大量 Chromium 进程,强制关闭
taskkill /F /IM chrome.exe 2>NUL

# 步骤 3:关闭重开 AI 会话,确认浏览器工具已不在会话中
# 步骤 4:检查 .mcp.json,临时移除 pw_core/pw_visual 条目
# 步骤 5:复盘分析 — 是哪个 AI agent 行为触发了高频调用

长期回归检查清单

每次 Playwright 使用后,复查以下项目:

  • [ ] tasklist 中无残留 chrome.exe
  • [ ] 任务管理器 CPU 占用率回归正常水平
  • [ ] AI 会话日志中无异常密集的浏览器调用记录
  • [ ] 各 app 的 vite dev server 已正常关闭
  • [ ] 如果是 CI 环境,检查 CI 日志中 Chromium 进程退出状态码

AI 记忆更新模板

在 CLAUDE.md / AGENTS.md / GEMINI.md 三处插入(<300 字):

markdown
## Playwright 工具链

三件套职责:@playwright/test (CI 固化) | @playwright/cli (生成 skills) | playwright-mcp (AI 驱动浏览器)

命名:vitest→*.test.ts,playwright→*.spec.ts

⚠️ 浏览器进程安全规则:

- AI 驱动浏览器默认用 pw_visual(headed),仅 token 敏感场景用 pw_core
- 每次使用浏览器后检查任务管理器,确保 Chromium 进程已退出
- 禁止在 headless 模式下对 3D 大屏页面做高频截图
- 大屏 3D 页面优先用 pw_visual 驱动,避免无头模式 GPU 空转

规则:视觉对齐后必须用 @playwright/test 固化。

环境注意

  • Node 22 + Windows:所有 node/pnpm 命令加 NODE_OPTIONS= 前缀(清空有问题的 NODE_OPTIONS=--use-system-ca
  • git commit:必须用 git-commit 技能(查远程 commit-types.ts emoji + commitlint 预校验 + -F 文件方式)
  • pre-commit hook:修改 lint-staged.config.js 后验证一次 commit 能通过

验收清单

  1. pnpm install 无报错
  2. pnpm exec playwright --version 输出版本号
  3. pnpm test:e2e 3 个测试全 pass(smoke + visual)
  4. pnpm run ci 全流程通过(vitest → build → test:e2e)
  5. .mcp.json 含 pwcore/pwvisual
  6. .agents/skills/playwright-cli/ 有技能文件
  7. AI 记忆三处 Playwright 工具链章节一致
  8. 子 app vite.config.ts 端口显式固定
  9. artifacts/ 被 gitignore
  10. ⚠️ 无头浏览器安全规范已阅读:确认项目属于 3D 大屏类,优先使用 pwvisual(headed)而非 pwcore
  11. ⚠️ 浏览器进程回收已检查:tasklist /FI "IMAGENAME eq chrome.exe" 无残留 Chromium 进程
du même dépôt

Autres Skills

Tous les Skills
ruan-cat
Communauté

add-favicon

- 为文档站、前端站点或 monorepo 内多个站点补全或重做 favicon.svg。用户提到 favicon、浏览器标签页图标、Iconify、Lucide 风格、VitePress/VuePress 文档站、 public/favicon.svg、head link icon、图标太丑/一团浆糊/不要背景块时必须使用; 尤其适合批量为多个 VitePress 站点设计本地 SVG favicon,并显式配置 head。

installations
1
GitHub Stars
5
Mis à jour
4 sept.
ruan-cat
Communauté

get-git-branch

- 诊断并修复 Git 仓库无法看到所有远程分支的问题,将受限的 fetch refspec 恢复为通配符模式, 使 git fetch 能拉取全部远程分支。当用户提及「看不到远程分支」「分支不全」 「只有 master/main」「fetch 所有分支」「shallow clone 补全分支」 「--single-branch 修复」「远程分支丢失」「获取全部分支」等关键词时使用此技能。 即使用户没有明确提到 refspec 或 shallow clone,只要意图是让仓库能看到并拉取所有远程分支, 就应触发此技能。

installations
1
GitHub Stars
5
Mis à jour
4 sept.
ruan-cat
Communauté

git-commit

- 创建高质量的 git 提交:审查/暂存预期的变更,拆分为逻辑提交,并编写清晰的提交信息 (遵循 Conventional Commits 规范,支持 Emoji)。当用户要求提交代码、编写提交信息、 暂存变更或将工作拆分为多个提交时使用此技能。当用户提及【破坏性变更】关键词时, 必须按照本技能的 BREAKING CHANGE 规范使用感叹号格式编写提交信息。 优先针对 git 暂存区(staged)中的文件进行提交,只有当暂存区为空时才考虑整个工作树。 当用户提及【分门别类】关键词时,必须按照本技能的多提交拆分规范, 从文件类型、业务模块、修改类型、修改范围四个维度认真拆分多个提交。

installations
1
GitHub Stars
5
Mis à jour
4 sept.
ruan-cat
Communauté

init-simple-memorix

- Use when 用户提到 init-simple-memorix、Memorix hooks 过多或噪音、项目级或全局 hooks 配置、Memorix MCP 工具缺失、full 模式、WorkBuddy MCP 启动失败、信任审批、Node 参数兼容、setup 或升级后重新精简等场景。

installations
1
GitHub Stars
5
Mis à jour
4 sept.