mcpField
P
playwright-verify

playwright-verify

github.com/rheinmir测试与质量10104 次安装2 周前更新
代码仓库

关于 playwright-verify

playwright-verify 是一项技能,通过独立的 Playwright 脚本和 Node.js 快速执行一次性浏览器检查。它帮助开发者验证本地或文件页面、检查浏览器与网络错误,并测量 UI 元素,无需配置测试运行器。

主要功能

  1. 01运行独立的 .mjs 验证脚本
  2. 02截取页面截图
  3. 03收集控制台、页面、HTTP 和请求错误
  4. 04测量元素尺寸与样式
  5. 05通过 CDP 保留浏览器状态

适用场景

  1. 01浏览器工具无法访问时验证 localhost 页面
  2. 02调查不可见或无法点击的元素
  3. 03无需创建测试套件即可验证代码假设
  4. 04保留浏览器会话以执行多步检查

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/rheinmir/setup --skill playwright-verify

安装后在 Claude Code 中输入/playwright-verify确认已加载。

详细介绍

技能:playwright-verify

总结自 GH#96——一种廉价(每次 < 5s、不使用 LLM)的验证工具,也是当 claude-in-chrome 在这台机器上屏蔽这两种 scheme 时,与 localhost/file:// 交互的唯一方式。

WHAT

用途和背景
  • 用途: 使用 Playwright,通过独立的 .mjs + node 快速验证代码,一次性运行(不使用测试运行器):截取 localhost/file:// 页面,提取 console/pageerror/http/requestfailed 错误,测量真实元素,绕过身份验证;需要多步操作时,使用持久会话 connectOverCDP。
  • 触发条件(何时使用):
  • claude-in-chrome 在 localhost:* / file:// 上报告 Frame with ID 0 is showing error page 或 Can't interact with browser-internal or unparseable URLs。
  • 需要诊断 UI 元素“看不见”/“点不了”——截图不够,需要真实测量值 (getBoundingClientRect、getComputedStyle)。
  • 需要验证一个代码假设,然后丢弃脚本(不值得创建 *.spec.ts + 测试运行器)。
  • 需要通过开发登录/模拟会话进行测试,而不是每次都登录真实 SSO。
    • 用户提到“用 playwright 验证”“截取页面截图”“用脚本快速测试 UI”“多步验证”“在多次运行之间保留会话”“无法点击/看不到元素”或 /playwright-verify。
  • 非目标: 不创建 *.spec.ts + 测试运行器(npx playwright test),不是 UAT 测试用例集(→ uat-nonit-testcase),不替代 claude-in-chrome 来操作普通外部网页,不将脚本提交到目标仓库。
思维模型

需要验证的假设 →(是否已安装?)→ 一次性 .mjs 脚本:启动 → 接入 4 种错误通道 → goto(加载 + 等待)→ 截图/测量 → 关闭 → 查看日志 + 图片 → 丢弃。多步操作分支:独立的 Chrome CDP(临时 profile)← 每轮由 step-N.mjs 连接,状态在各轮之间保留 → 完成后 pkill。

输入和输出约定
字段必填?含义
InURL(localhost:* / file:// / 其他)是需要验证的页面
In项目的 node_modules 中有 @playwright/test是脚本必须从该目录运行(或使用 NODE_PATH)
In开发登录 cookie/localStorage否用于绕过身份验证
Out截图(如 /tmp/check.png)+ [console]/[pageerror]/[http]/[reqfail] 日志是证据;仅有干净的截图并不足够
OutgetBoundingClientRect/getComputedStyle 测量值诊断元素时真实数值,而非根据截图猜测
Out“完成”—通过日志 + 截图确认/否定假设;脚本已清理;Chrome CDP(如有)已 pkill
规则与能力
  • RULE-01 (MUST):import { chromium } from "@playwright/test" 必须从包含 @playwright/test 的项目目录中运行,该目录的 node_modules 中需包含此包 — ESM 根据 cwd 解析,而不是根据脚本文件的位置解析。脚本位于其他目录(例如 /tmp)→ 运行前先将其 cp 到项目中,或设置 NODE_PATH。
  • RULE-02 (MUST):在 Next.js dev server 上,waitUntil: "networkidle" 会无限期挂起 — HMR/webpack dev 会保持一个 long-poll/websocket 连接持续存活,因此网络永远不会“空闲”。使用 waitUntil: "load" + 固定的 page.waitForTimeout(N)。
  • RULE-03 (MUST):绕过 dev-login 认证:context.addCookies([{url, name, value}])(优先使用 url,而不是单独使用 domain+path — 避免 cookie 不匹配)+ context.addInitScript(...) 设置 localStorage — 必须在调用 newPage() 之前设置状态,而不是之后。
  • RULE-04 (MUST):每个独立路由使用一个 context,如果应用有“辅助 API 遇到 401 → 自动清除全局 session”的逻辑 — 多次导航复用同一个 context 会导致路由 N 的错误连带破坏路由 N+1。
  • RULE-05 (MUST):诊断“看不到/点不了”:不要只看截图 — 调用 page.evaluate(() => el.getBoundingClientRect()) + getComputedStyle(el) 获取实际测量值;locator.click() 会明确报告错误(“element is not visible”)并附带重试步骤日志,先阅读日志再猜测原因。
  • RULE-06 (MUST):干净的截图不能证明任何事 — 始终检查 4 个错误渠道,而不只是 2 个:console(type error)· pageerror · response 中 status() >= 400 的响应 · requestfailed。Analytics 崩溃、API 5xx、promise rejection 不会体现在任何像素上。在 goto 之前将以下监听器绑定到 page:
    page.on("response", r => { if (r.status() >= 400) console.log("[http]", r.status(), r.url()); });
    page.on("requestfailed", r => console.log("[reqfail]", r.failure()?.errorText, r.url()));
    
  • RULE-07 (MUST):持久会话模式:使用独立的 Chrome 和独立的 profile(临时 --user-data-dir)。绝不要对用户的个人 Chrome 使用 --remote-debugging-port — macOS 会弹出权限请求对话框,脚本还会干扰用户正在使用的标签页。
  • RULE-08 (MUST):独立脚本文件不得进入 git — 从 scratchpad 运行,不要提交到目标 repo。
  • RULE-09 (MUST):只修改任务所需内容 — 不要顺手做其他更改。
  • 能力:本地运行无头浏览器 + 读取/写入临时文件;仅在安装 binary(CDN)时访问外网,并设置超时。
故障边界
  • npx playwright install 被网络阻止/挂起 → blocked,明确报告错误(设置超时),不要让命令无限期挂起。
  • ESM 无法解析 @playwright/test(运行时 cwd 错误)→ 将脚本 cp 到项目中或设置 NODE_PATH,然后重新运行。
  • networkidle 在 Next.js dev 上挂起 → 改用 load + waitForTimeout(不是应用错误)。
  • 看不到/点不了元素 → 测量实际值 + 阅读 locator.click() 日志后再下结论;不要根据截图猜测。

HOW

主要工作流
步骤类型输入操作输出/退出失败/后续
W01确定性机器检查是否已安装(ls ~/Library/Caches/ms-playwright);如果没有则安装二进制文件就绪CDN 被拦截 → blocked
W02判断假设 + URL编写一个可直接用 node 运行的 .mjs 文件,在 goto 前挂接 4 个错误通道脚本—
W03效果脚本从正确目录运行(node check.mjs),阅读日志 + 图片;清理脚本日志 + 图片解决错误 → cp/NODE_PATH,重复 W03
W04效果多步骤任务持久会话模式 connectOverCDP(B01)状态在各轮间保留完成 → pkill

各步骤详情(W01–W04 的权威说明):

  1. 检查是否已安装,再决定是否重新安装:ls ~/Library/Caches/ms-playwright(macOS)— 二进制缓存由所有项目共用,无需每个仓库都重新安装。
    • 如果没有:执行 pnpm add -D @playwright/test(如果项目的 devDependencies 中已有,则跳过),然后执行 npx playwright install chromium。
    • npx playwright install 会从外部 CDN(cdn.playwright.dev)下载二进制文件——在网络有 允许列表的沙盒/CI 中会卡住或失败。自动调用时设置超时;如果被拦截,应明确报告错误, 而不是让命令无限期挂起。
  2. 编写一个可直接用 node 运行的 .mjs 文件(不通过 npx playwright test)——对于 验证后即丢弃的任务来说更繁琐:
    import { chromium } from "@playwright/test"; // export chromium dùng được như package "playwright"
    
    const browser = await chromium.launch();
    const page = await browser.newPage({ viewport: { width: 1400, height: 900 } });
    page.on("console", m => console.log("[console]", m.type(), m.text()));
    page.on("pageerror", e => console.log("[pageerror]", e.message));
    
    await page.goto("http://localhost:3000/some-page", { waitUntil: "load" }); // KHÔNG "networkidle" — xem Rules #2
    await page.waitForTimeout(1500);
    await page.screenshot({ path: "/tmp/check.png", fullPage: true });
    
    await browser.close();
    
  3. 从正确目录运行(参见 Rules #1),执行 node check.mjs,阅读 console/pageerror 日志 + 截图。如果是在某个具体项目中运行,完成后清理 .mjs 文件(无需从 git 中删除任何内容—— 如果从 scratch 目录运行,脚本不在仓库中)。
  4. 有条件的多步骤任务 → 持久会话模式(借鉴 browser-use/browser-harness, 09/2026)。一次性脚本要求 Agent 盲目编写整个流程;某一步出错,就得从登录开始重跑。 不如启动一个带 CDP 端口的 Chrome,每轮运行一个小脚本接入——标签页、cookie、 localStorage 和滚动位置都会在各轮间保留,Agent 可以先观察,再决定下一步。
    # một lần — Chrome riêng, profile riêng; KHÔNG bám vào Chrome cá nhân của user
    CH="$HOME/Library/Caches/ms-playwright/chromium-1243/chrome-mac-arm64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing"
    "$CH" --remote-debugging-port=9333 --user-data-dir=/tmp/pw-prof --headless=new --no-first-run about:blank &
    
    // mỗi lượt — step-N.mjs
    import { chromium } from "@playwright/test";
    const browser = await chromium.connectOverCDP("http://localhost:9333");
    const ctx = browser.contexts()[0];
    const page = ctx.pages()[0] ?? await ctx.newPage();   // bám tab cũ, KHÔNG launch mới
    // ... một hành động + quan sát; state sống sang lượt sau ...
    await browser.close();   // chỉ ngắt kết nối, Chrome vẫn chạy
    
    完成后:pkill -f "remote-debugging-port=9333"。 09/09/2026 的测量结果(python-playwright,同一个 file:// 页面):每轮重新启动需要 1.1–1.9 秒,且会丢失状态;connectOverCDP 每轮需要 0.65–0.80 秒, window.__marker 在新进程启动后仍然存在(3/3)。 上面的 .mjs 版本在测量会话中尚未用 node 运行——API 与已运行的 python 版本一致。
分支
ID类型条件行为跳过/失败重新汇合
B01conditional_required有条件的多步骤任务(需要先观察,再决定下一步)启动一个独立 Chrome,使用 --remote-debugging-port=9333 + 临时配置文件;每轮通过 connectOverCDP 运行 step-N.mjs一次性任务 → 跳过;绝不接入个人 Chrome结束时执行 pkill -f "remote-debugging-port=9333"
B02user_optional页面需要开发登录/伪造会话在 newPage() 之前执行 context.addCookies + context.addInitScript;如果应用在 401 时会自行删除会话,则每个路由使用一个 context—W03
B03recovery元素“看不见/无法点击”执行 page.evaluate(() => el.getBoundingClientRect()) + getComputedStyle(el),阅读 locator.click() 的重试日志—W03
验证与停止

结论应基于 4 个错误通道 + 图片 + 测量数据,而不只是图片。每轮运行 < 5 秒,不使用大模型。假设得到证据支持后即停止;清理脚本 + 终止 CDP Chrome。

示例
  • 正向: claude-in-chrome 在 http://localhost:3000/some-page 上报告 Frame with ID 0 is showing error page → 将 check.mjs cp 到项目中 → 执行 node check.mjs → /tmp/check.png + [console]/[pageerror]/[http]/[reqfail] 日志均干净 → 确认页面已渲染,删除脚本。
  • 边界/失败: 脚本在 Next.js dev 上使用 waitUntil: "networkidle" → 无限期挂起;改为 waitUntil: "load" + page.waitForTimeout(1500) → 成功运行。图片干净,但日志中有 [http] 500 /api/x → 不要报告通过。

评论

支持 Markdown