@taole/dd-playwright 0.1.8 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,7 +11,7 @@ import { resolveConfig } from "../src/config.mjs";
11
11
  import { PlaywrightBrowserManager } from "../src/browser-manager.mjs";
12
12
  import { pathToFileURL } from "node:url";
13
13
 
14
- export const MCP_VERSION = "0.1.8";
14
+ export const MCP_VERSION = "0.1.10";
15
15
 
16
16
  function textResult(payload) {
17
17
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taole/dd-playwright",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "Standalone stdio MCP & CLI: Playwright browser automation + isolated whistle proxy + diandian account storageState injection",
5
5
  "type": "module",
6
6
  "license": "ISC",
@@ -383,13 +383,58 @@ const DASHBOARD_HTML = `<!DOCTYPE html>
383
383
  <b>2. 本地开发服务联调(Dev Server 代理映射):</b><br>
384
384
  • 本地服务启动后严禁改动系统 hosts,可通过单域名映射或项目规则目录全量注入:<br>
385
385
  • <b>单条映射</b>:<code>browser_set_proxy_rule({ domain: "p9527-test.tuwan.com", port: 9527 })</code><br>
386
- • <b>目录批量规则(推荐)</b>:若项目有 <code>.whistle-rules</code> 目录,直接调用 <code>browser_load_proxy_rules_dir({ rulesDir: "目录绝对路径" })</code> 全量激活代理与 Mock。<br><br>
386
+ • <b>目录批量规则(推荐)</b>:若项目有 <code>.whistle-rules</code> 目录,直接调用 <code>browser_load_proxy_rules_dir({ rulesDir: "目录绝对路径" })</code> 全量激活代理与 Mock。<br>
387
+ • <b>常用 Whistle 规则参考(.whistle-rules 编写)</b>:<br>
388
+ &nbsp;&nbsp;1) 域名映射:<code>p9527-test.tuwan.com http://127.0.0.1:9527</code><br>
389
+ &nbsp;&nbsp;2) 接口 Mock:<code>yapi.tuwan.com/act resBody://D:/mock/data.json</code><br>
390
+ &nbsp;&nbsp;3) 静态替换:<code>act.tuwan.com/cdn/index.js D:/dist/index.js</code><br>
391
+ &nbsp;&nbsp;4) 请求头注入:<code>y.tuwan.com reqHeaders://{debug: '1'}</code><br>
392
+ &nbsp;&nbsp;👉 官方完整语法参考:<a href="https://wproxy.org/whistle/rules/" target="_blank" style="color: #38bdf8; text-decoration: underline;">https://wproxy.org/whistle/rules/</a><br><br>
387
393
  <b>3. 页面交互规范:</b><br>
388
394
  • 复杂或动态页面定位困难时,优先调用 <code>browser_get_dom</code> 获取可见元素清单,严禁盲猜选择器。<br>
389
395
  • 表单填写使用 <code>browser_fill_text</code>,按键使用 <code>browser_press_key</code>。
390
396
  </div>
391
397
  </div>
392
- </div>
398
+
399
+ <!-- AI Agent 使用 SOP 与典型范例 -->
400
+ <div class="doc-section" style="margin-top: 24px;">
401
+ <h3>AI Agent 典型调用流程范例 (SOP)</h3>
402
+ <p>以下为 Agent 处理点点日常联调、排查与测试的三大标准工作流:</p>
403
+
404
+ <div class="code-title"><span>流程 1:本地开发服务(Dev Server)联调</span></div>
405
+ <div class="code-block" style="color: #93c5fd; font-size: 12px; margin-bottom: 12px;">// 方式 A:单域名映射
406
+ 1. 本地 Vite 启动在 127.0.0.1:9527
407
+ 2. 映射代理域名:browser_set_proxy_rule({ domain: "p9527-test.tuwan.com", port: 9527 })
408
+ 3. 免登访问页面:browser_navigate({ url: "http://p9527-test.tuwan.com/" })
409
+ -> 自动携带点点线上 Tuwan_Passport Cookie,无需改动系统 hosts!
410
+
411
+ // 方式 B:项目规则目录批量导入(推荐)
412
+ 1. 项目中已存在 .whistle-rules 目录(含域名映射、接口 Mock 等多份规则)
413
+ 2. 批量加载目录:browser_load_proxy_rules_dir({ rulesDir: "D:/projects/my-web/.whistle-rules" })
414
+ 3. 直接按规则访问测试页面,全量代理与 Mock 立即生效。</div>
415
+
416
+ <div class="code-title"><span>流程 2:游客拦截 vs 正常登录态对比测试</span></div>
417
+ <div class="code-block" style="color: #93c5fd; font-size: 12px; margin-bottom: 12px;">// 1. 游客态验证(验证未登录拦截弹窗/导流流程)
418
+ browser_navigate({ url: "https://y.tuwan.com/activity/...", anonymous: true })
419
+
420
+ // 2. 默认登录态验证(自动携带默认账号正常参与活动)
421
+ browser_navigate({ url: "https://y.tuwan.com/activity/..." })
422
+
423
+ // 3. 指定测试账号(切换特定身份排查权限或对账)
424
+ browser_navigate({ url: "https://y.tuwan.com/activity/...", uid: "28689781" })</div>
425
+
426
+ <div class="code-title"><span>流程 3:交互排查与元素定位</span></div>
427
+ <div class="code-block" style="color: #93c5fd; font-size: 12px; margin-bottom: 0;">// 1. 获取页面结构化交互元素,杜绝盲猜选择器
428
+ const dom = browser_get_dom({ interactiveOnly: true })
429
+
430
+ // 2. 表单精准输入与回车键提交
431
+ browser_fill_text({ selector: "input#keyword", text: "测试内容" })
432
+ browser_press_key({ selector: "input#keyword", key: "Enter" })
433
+
434
+ // 3. 结果截图与控制台报错收集
435
+ browser_screenshot({ selector: ".result-box" })
436
+ const errors = browser_get_console_errors()</div>
437
+ </div>
393
438
  </div>
394
439
 
395
440
  <!-- TAB 4: 全局配置 -->
@@ -638,10 +683,9 @@ const DASHBOARD_HTML = `<!DOCTYPE html>
638
683
  '# dd-playwright 自动化指南',
639
684
  '本技能必须通过 dd-playwright MCP 服务提供的 browser_* 系列工具执行:',
640
685
  '1. 登录态与身份切换:访问点点页面调用本 MCP 的 browser_navigate 自动注入激活账号免登;排查游客态或未登录拦截必须传 anonymous: true;指定测试账号传特定 uid。',
641
- '2. 本地 Dev Server 联调:严禁修改系统 hosts。先调用本 MCP 的 browser_set_proxy_rule 将本地端口映射到点点子域名(如 127.0.0.1:9527 映射为 p9527-test.tuwan.com),免改 hosts 携带线上 Cookie。',
686
+ '2. 本地 Dev Server 联调:严禁改动系统 hosts。支持 browser_set_proxy_rule 单条映射,或 browser_load_proxy_rules_dir 批量加载 .whistle-rules 目录(语法如:域名映射 p9527-test.tuwan.com http://127.0.0.1:9527、接口 Mock yapi.tuwan.com/act resBody://{mock.json}、官方文档 https://wproxy.org/whistle/rules/)。',
642
687
  '3. 页面交互规范:定位困难时优先调用 browser_get_dom 提取可见元素结构,严禁盲猜选择器;表单填写使用 browser_fill_text,按键使用 browser_press_key。'
643
688
  ].join('\\n');
644
-
645
689
  const cursorUrl = 'cursor://anysphere.cursor-deeplink/rule?name=' + encodeURIComponent(ruleName) + '&text=' + encodeURIComponent(compactRule);
646
690
  window.location.href = cursorUrl;
647
691
  }
package/src/updater.mjs CHANGED
@@ -1,6 +1,12 @@
1
1
  import { readFileSync, existsSync } from "node:fs";
2
2
  import { fileURLToPath } from "node:url";
3
3
  import { execSync } from "node:child_process";
4
+ import { resolveConfig } from "./config.mjs";
5
+ import {
6
+ getStoredWebPid,
7
+ stopWebDaemon,
8
+ startWebDaemon,
9
+ } from "./server/daemon.mjs";
4
10
 
5
11
  export const PACKAGE_NAME = "@taole/dd-playwright";
6
12
 
@@ -91,21 +97,48 @@ export async function handleUpdateCommand(overrideCurrentVersion = null) {
91
97
  console.log(` 🚀 发现新版本可用: v${currentVersion} -> v${latestVersion}`);
92
98
  console.log(`==================================================\n`);
93
99
 
94
- console.log(`[dd-playwright] 正在尝试自动执行全局升级 (npm install -g ${PACKAGE_NAME}@latest)...`);
100
+ const config = resolveConfig();
101
+ const runningPid = getStoredWebPid(config.webPidFile);
102
+ const wasWebRunning = Boolean(runningPid);
103
+
104
+ if (wasWebRunning) {
105
+ console.log(
106
+ `[dd-playwright] 检测到后台 Web 服务正在运行 (PID: ${runningPid}),正在安全停止以释放文件锁...`,
107
+ );
108
+ await stopWebDaemon(config.webPidFile);
109
+ // 等待 500ms 确保操作系统完全释放文件句柄
110
+ await new Promise((r) => setTimeout(r, 500));
111
+ }
112
+
113
+ console.log(`[dd-playwright] 正在执行全局升级 (npm install -g ${PACKAGE_NAME}@latest)...`);
95
114
 
96
115
  try {
97
- // 优先尝试自动升级
98
116
  execSync(`npm install -g ${PACKAGE_NAME}@latest`, {
99
117
  stdio: "inherit",
100
118
  windowsHide: true,
101
119
  });
102
- console.log(`\n🎉 自动更新完成!已成功升级至最新版本 v${latestVersion}。\n`);
103
- console.log(`提示:若当前后台正在运行 Web 服务,建议重启生效:`);
104
- console.log(` dd-pw stopweb && dd-pw startweb\n`);
120
+ console.log(`\n🎉 自动升级成功!已成功升级至最新版本 v${latestVersion}。\n`);
121
+
122
+ if (wasWebRunning) {
123
+ console.log(`[dd-playwright] 正在自动为您重启后台 Web 服务...`);
124
+ const restartRes = await startWebDaemon({
125
+ port: 12309,
126
+ dataDir: config.dataDir,
127
+ pidFile: config.webPidFile,
128
+ logFile: config.webLogFile,
129
+ });
130
+ if (restartRes.started) {
131
+ console.log(`[dd-playwright] Web 服务已成功重启并常驻后台!`);
132
+ console.log(` - 进程 PID: ${restartRes.pid}`);
133
+ console.log(` - 访问地址: ${restartRes.url}\n`);
134
+ }
135
+ }
105
136
  } catch (err) {
106
- // 若因系统权限不足等原因报错,优雅降级,打印完整手工升级命令
107
137
  console.warn(`\n⚠️ 自动升级未完成(可能需要管理员权限或当前终端权限受限)。`);
108
138
  console.log(`请复制下方命令并在终端中执行升级:\n`);
109
139
  console.log(`👉 npm install -g ${PACKAGE_NAME}@latest\n`);
140
+ if (wasWebRunning) {
141
+ console.log(`如需重新启动 Web 服务,请执行: dd-pw startweb\n`);
142
+ }
110
143
  }
111
144
  }