Co-Pilot / 辅助式
更新于 24 days ago

playwriter

Rremorses
2.7k
remorses/playwriter
80
Agent 评分

💡 摘要

Playwriter 通过扩展和 CLI 实现使用 Playwright API 的浏览器自动化。

🎯 适合人群

希望自动化测试的网页开发者需要简化浏览器交互的 QA 工程师希望高效抓取网页数据的数据分析师自动化部署任务的 DevOps 专业人员教授网页自动化技术的教育工作者

🤖 AI 吐槽:看起来很能打,但别让配置把人劝退。

安全分析高风险

风险:High。建议检查:是否执行 shell/命令行指令;是否发起外网请求(SSRF/数据外发);API Key/Token 的获取、存储与泄露风险;文件读写范围与路径穿越风险;依赖锁定与供应链风险。以最小权限运行,并在生产环境启用前审计代码与依赖。

Installation

  1. Install Extension from Chrome Web Store

  2. Click extension icon on a tab → turns green when connected

  3. Install the CLI and start automating the browser:

    npm i -g playwriter playwriter -s 1 -e "await page.goto('https://example.com')"
  4. Add skill to your agent:

    npx -y skills add remorses/playwriter

Quick Start

playwriter session new # creates stateful sandbox, outputs session id (e.g. 1) playwriter -s 1 -e "await page.goto('https://example.com')" playwriter -s 1 -e "console.log(await accessibilitySnapshot({ page }))" playwriter -s 1 -e "await page.locator('aria-ref=e5').click()"

CLI Usage

Each session has isolated state. Browser tabs are shared across sessions.

# Session management playwriter session new # creates stateful sandbox, outputs id (e.g. 1) playwriter session list # show sessions + state keys playwriter session reset <id> # fix connection issues # Execute (always use -s) playwriter -s 1 -e "await page.goto('https://example.com')" playwriter -s 1 -e "await page.click('button')" playwriter -s 1 -e "console.log(await page.title())"

Create your own page to avoid interference from other agents:

playwriter -s 1 -e "state.myPage = await context.newPage(); await state.myPage.goto('https://example.com')"

Multiline:

playwriter -s 1 -e $' const title = await page.title(); console.log({ title, url: page.url() }); '

Examples

Variables in scope: page, context, state (persists between calls), require, and Node.js globals.

Persist data in state:

playwriter -e "state.users = await page.$$eval('.user', els => els.map(e => e.textContent))" playwriter -e "console.log(state.users)"

Intercept network requests:

playwriter -e "state.requests = []; page.on('response', r => { if (r.url().includes('/api/')) state.requests.push(r.url()) })" playwriter -e "await Promise.all([page.waitForResponse(r => r.url().includes('/api/')), page.click('button')])" playwriter -e "console.log(state.requests)"

Set breakpoints and debug:

playwriter -e "state.cdp = await getCDPSession({ page }); state.dbg = createDebugger({ cdp: state.cdp }); await state.dbg.enable()" playwriter -e "state.scripts = await state.dbg.listScripts({ search: 'app' }); console.log(state.scripts.map(s => s.url))" playwriter -e "await state.dbg.setBreakpoint({ file: state.scripts[0].url, line: 42 })"

Live edit page code:

playwriter -e "state.cdp = await getCDPSession({ page }); state.editor = createEditor({ cdp: state.cdp }); await state.editor.enable()" playwriter -e "await state.editor.edit({ url: 'https://example.com/app.js', oldString: 'const DEBUG = false', newString: 'const DEBUG = true' })"

Screenshot with labels:

playwriter -e "await screenshotWithAccessibilityLabels({ page })"

MCP Setup

Using the CLI with the skill (step 4 above) is the recommended approach. For direct MCP server configuration, see MCP.md.

Visual Labels

Vimium-style labels for AI agents to identify elements:

await screenshotWithAccessibilityLabels({ page }) // Returns screenshot + accessibility snapshot with aria-ref selectors await page.locator('aria-ref=e5').click()

Color-coded: yellow=links, orange=buttons, coral=inputs, pink=checkboxes, peach=sliders, salmon=menus, amber=tabs.

Comparison

vs Playwright MCP

| | Playwright MCP | Playwriter | |---|---|---| | Browser | Spawns new Chrome | Uses your Chrome | | Extensions | None | Your existing ones | | Login state | Fresh | Already logged in | | Bot detection | Always detected | Can bypass (disconnect extension) | | Collaboration | Separate window | Same browser as user |

vs BrowserMCP

| | BrowserMCP | Playwriter | |---|---|---| | Tools | 12+ dedicated tools | 1 execute tool | | API | Limited actions | Full Playwright | | Context usage | High (tool schemas) | Low | | LLM knowledge | Must learn tools | Already knows Playwright |

vs Antigravity (Jetski)

| | Jetski | Playwriter | |---|---|---| | Tools | 17+ tools | 1 tool | | Subagent | Spawns for each browser task | Direct execution | | Latency | High (agent overhead) | Low |

vs Claude Browser Extension

| | Claude Extension | Playwriter | |---|---|---| | Agent support | Claude only | Any MCP client | | Windows WSL | No | Yes | | Context method | Screenshots (100KB+) | A11y snapshots (5-20KB) | | Playwright API | No | Full | | Debugger/breakpoints | No | Yes | | Live code editing | No | Yes | | Network interception | Limited | Full | | Raw CDP access | No | Yes |

Architecture

+---------------------+     +-------------------+     +-----------------+
|   BROWSER           |     |   LOCALHOST       |     |   MCP CLIENT    |
|                     |     |                   |     |                 |
|  +---------------+  |     | WebSocket Server  |     |  +-----------+  |
|  |   Extension   |<--------->  :19988         |     |  | AI Agent  |  |
|  +-------+-------+  | WS  |                   |     |  +-----------+  |
|          |          |     |  /extension       |     |        |        |
|    chrome.debugger  |     |       |           |     |        v        |
|          v          |     |       v           |     |  +-----------+  |
|  +---------------+  |     |  /cdp/:id <--------------> |  execute  |  |
|  | Tab 1 (green) |  |     +-------------------+  WS |  +-----------+  |
|  | Tab 2 (green) |  |                               |        |        |
|  | Tab 3 (gray)  |  |     Tab 3 not controlled      |  Playwright API |
+---------------------+     (no extension click)      +-----------------+

Remote CLI

Run CLI from a different machine (devcontainer, VM, SSH) while Chrome runs on your host.

On host:

playwriter serve --token <secret>

From remote:

playwriter --host 192.168.1.10 --token <secret> session new playwriter --host 192.168.1.10 --token <secret> -s 1 -e "await page.goto('https://example.com')"

Or with env vars:

export PLAYWRITER_HOST=192.168.1.10 export PLAYWRITER_TOKEN=<secret> playwriter -s 1 -e "await page.goto('https://example.com')"

Security

  • Local only: WebSocket server on localhost:19988
  • Origin validation: Only our extension IDs allowed (browsers can't spoof Origin)
  • Explicit consent: Only tabs where you clicked the extension icon
  • Visible automation: Chrome shows automation banner on controlled tabs
  • No remote access: Malicious websites cannot connect

Playwright API

Connect programmatically (without CLI):

import { chromium } from 'playwright-core' import { startPlayWriterCDPRelayServer, getCdpUrl } from 'playwriter' const server = await startPlayWriterCDPRelayServer() const browser = await chromium.connectOverCDP(getCdpUrl()) const page = browser.contexts()[0].pages()[0] await page.goto('https://example.com') await page.screenshot({ path: 'screenshot.png' }) // Don't call browser.close() - it closes the user's Chrome server.close()

Or connect to a running server:

npx -y playwriter serve --host 127.0.0.1
const browser = await chromium.connectOverCDP('http://127.0.0.1:19988')

Troubleshooting

View relay server logs to debug issues:

playwriter logfile # prints the log file path # typically: /tmp/playwriter/relay-server.log (Linux/macOS)

The relay log contains extension, MCP and WebSocket server logs. A separate CDP JSONL log is also created alongside it (see playwriter logfile). Both are recreated on each server start.

Example: summarize CDP traffic counts by direction + method:

jq -r '.direction + "\t" + (.message.method // "response")' /tmp/playwriter/cdp.jsonl | uniq -c

Known Issues

  • If all pages return about:blank, restart Chrome (Chrome bug in chrome.debugger API)
  • Browser may switch to light mode on connect (Playwright issue)
五维分析
清晰度8/10
创新性8/10
实用性9/10
完整性8/10
可维护性7/10
优缺点分析

优点

  • 与 Playwright 无缝集成
  • 支持复杂的浏览器自动化任务
  • 安全的隔离会话管理
  • 灵活的 CLI 命令

缺点

  • 需要安装浏览器扩展
  • 新用户可能有学习曲线
  • 仅限于本地浏览器自动化
  • 浏览器状态管理可能存在问题

相关技能

pytorch

S
toolCode Lib / 代码库
92/ 100

“它是深度学习的瑞士军刀,但祝你好运能从47种安装方法里找到那个不会搞崩你系统的那一个。”

agno

S
toolCode Lib / 代码库
90/ 100

“它承诺成为智能体领域的Kubernetes,但得看开发者有没有耐心学习又一个编排层。”

nuxt-skills

S
toolCo-Pilot / 辅助式
90/ 100

“这本质上是一份组织良好的小抄,能把你的 AI 助手变成一只 Nuxt 框架的复读机。”

免责声明:本内容来源于 GitHub 开源项目,仅供展示和评分分析使用。

版权归原作者所有 remorses.