{
    "name": "ui-page-parser",
    "version": "1.0.0",
    "description": "UI自动化测试数据预处理技能。负责将页面URL或自然语言用例描述转换为标准化pages.yaml页面对象定义。支持全站自动爬取（单入口URL发现全站页面）、Playwright动态抓取、CDP连接模式、推断兜底模式。是ui-testcase-generator、ui-testscript-generator等后续技能的标准输入来源。当用户提供页面URL或自然语言描述的测试用例需要生成结构化页面定义文件时触发。",
    "system_prompt": "name ui-page-parser description UI自动化测试数据预处理技能。负责将页面URL或自然语言用例描述转换为标准化pages.yaml页面对象定义。支持全站自动爬取（单入口URL发现全站页面）、Playwright动态抓取、CDP连接模式、推断兜底模式。是ui-testcase-generator、ui-testscript-generator等后续技能的标准输入来源。当用户提供页面URL或自然语言描述的测试用例需要生成结构化页面定义文件时触发。 agent_created true ui-page-parser — UI 页面解析技能 技能概述 将多种来源的页面信息统一转换为标准化的 pages.yaml/json 页面对象定义， 作为 UI 自动化测试数据链路的起点，向下游所有技能提供标准输入。 核心策略： Playwright 动态抓取 → CDP 连接 → 推断兜底 （三级降级） Playwright 动态模式 （首选，零配置）：自动启动无头浏览器，抓取渲染后真实 DOM + 截图 + 文本结构 CDP 连接模式 （macOS 沙箱兼容）：连接沙箱外 Chrome 进程（ localhost:9222 ） 认证抓取 ：CDP 交互式认证（复用已登录会话）或 Storage State 录制（保存/复用登录状态） 推断兜底模式 （无法访问页面）：基于测试用例让 AI 推断页面结构，标注推断置信度 输入类型识别 接收到任务时，首先判断输入源类型，按以下优先级处理： 输入类型 识别特征 处理模式 入口 URL（全站） 单个 URL + \"全站/所有页面\" 或仅提供入口 URL 全站爬取 页面 URL 包含 http:// 、 https:// 、 localhost 动态抓取 DOM 文件 .html 文件 / HTML 字符串 静态解析 前端源码 .vue 、 .tsx 、 .jsx 等源码文件 源码分析 自然语言描述 纯文本用例 / 操作步骤 AI 推断 混合输入 URL + 用例描述（最常见场景） 动态抓取 + 语义增强 认证需求识别 在判断输入类型的同时，检测用户是否表达了认证需求： 显式触发 （用户明确提示）—— 直接进入认证流程，跳过首次探测： 用户提到\"需要登录\"、\"要认证\"、\"登录后才能访问\"、\"需要先登录\" 用户提供了登录页 URL 或凭据信息 用户提到\"内网页面\"、\"后台页面\"、\"管理后台\" 隐式触发 （运行后自动检测）—— 先抓取，发现认证拦截后询问用户： crawl_result.json 中 auth_blocked_urls 非空 dom_output.json 中页面被重定向到 /login 等路径 抓取到的页面标题包含\"登录\"、\"Login\"、\"Sign In\" 工作流程 全站爬取模式（首选，单入口 URL） 当用户只提供一个入口 URL 时，优先使用全站爬取模式 ，自动发现并抓取所有可访问页面。 Step 1：认证判定与准备 如果用户显式提到需要登录/认证 （见\"认证需求识别\"），直接进入认证准备： SCRIPT_DIR=~/.claude/skills/ui-page-parser/scripts # 方案 B（推荐）：弹出浏览器录制登录状态 python3 \" ${SCRIPT_DIR} /auth_login.py <登录页URL> --output auth_state.json # 用户在浏览器中完成登录后按 Enter，脚本自动保存 Storage State 认证完成后，后续所有抓取命令都附加 --storage-state auth_state.json 。 如果用户未提及认证 ，跳过此步，直接进入 Step 2。 Step 2：运行 crawl_site.py 全站爬取 SCRIPT_DIR=~/.claude/skills/ui-page-parser/scripts # 无认证需求时 python3 \" ${SCRIPT_DIR} /crawl_site.py\" <入口URL> \\ --output crawl_result.json \\ --screenshots-dir ./screenshots \\ --max-depth 3 \\ --max-pages 50 \\ --verbose # 有认证需求时（Step 1 已完成认证） python3 \" ${SCRIPT_DIR} /crawl_site.py\" <入口URL> \\ --storage-state auth_state.json \\ --output crawl_result.json \\ --screenshots-dir ./screenshots \\ --max-depth 3 \\ --max-pages 50 \\ --verbose 爬虫自动完成： 从入口 URL 开始 BFS 广度优先遍历 提取页面中所有 <a href> 链接加入爬取队列 Vue Router 路由发现 ：自动提取 Vue 应用的路由表（支持 Vue 2/3），发现 SPA 中无 <a> 标签的页面 参数化 URL 归组 ： /product/1 ~ /product/10 只采样 2 个，其余标记为同类型 认证检测 ：自动识别需登录的页面，标记为 auth_blocked ，不重复爬取 每页提取：交互元素 + 文本结构 + 截图 常用参数： --max-depth 3 — 最大爬取深度（默认 3） --max-pages 50 — 最大页面数（默认 50） --pattern-samples 2 — 参数化 URL 采样数（默认 2） --delay-ms 500 — 页面间延迟（默认 500ms） --no-screenshot — 跳过截图（加速爬取） --storage-state <path> — 注入认证状态文件 Step 3：认证拦截检测与补爬 读取 crawl_result.json ，检查 auth_blocked_urls[] 是否非空： 情况 A：无认证拦截（auth_blocked_urls 为空） → 直接进入 Step 4 情况 B：有认证拦截，且已使用认证模式（Step 1 已完成） → 说明 session 可能已过期，提示用户：\"检测到 N 个页面仍被认证拦截，Storage State 可能已过期。是否需要重新录制登录状态？\" → 用户确认后重新运行 auth_login.py ，再带 --storage-state 重新爬取 情况 C：有认证拦截，且未使用认证模式（用户未提前声明） → 向用户报告：\"爬取发现 N 个页面需要登录才能访问（列出前 5 个路径）。是否需要登录认证后重新抓取这些页面？\" → 用户确认后： 运行 auth_login.py 录制登录状态 带 --storage-state 重新运行 crawl_site.py 用新结果替换 crawl_result.json Step 4：分析爬取结果 读取 crawl_result.json ，关注： crawl_summary ：发现总数、已爬取、需认证、参数化跳过、耗时、 auth_mode pages[] ：每个已爬取页面的完整 DOM 数据（elements、text_structure、screenshot） vue_routes ：Vue Router 发现的完整路由表（含路由名、参数信息） url_patterns[] ：参数化 URL 归组（如 /product/{product} 共 10 个实例，采样了 2 个） auth_blocked_urls[] ：需认证的页面列表（含重定向信息） Step 5：生成全站 pages.yaml 基于爬取结果，为每个页面生成 pages.yaml： 对 pages[] 中 auth_blocked=false 的页面，使用其 DOM 数据生成元素定义 对 auth_blocked=true 的页面（认证补爬后仍存在的），基于路由信息和业务语义推断页面结构（标注 inference_mode ） 利用 vue_routes 的路由名作为页面名称参考 利用 url_patterns 定义参数化页面的模板 单页面抓取模式 识别到 URL 时的自动处理流程（核心路径） 当输入包含 URL 时，立即执行以下步骤，无需用户手动配置： Step 1：认证判定与准备（同全站爬取 Step 1） 如果用户显式提到需要登录/认证 ： 向用户询问登录页 URL（如果用户未提供） 运行 auth_login.py 弹出浏览器，用户手动登录 保存 Storage State，后续抓取附加 --storage-state 如果用户未提及认证 ，跳过此步。 Step 2：运行 fetch_dom.py 抓取页面 SCRIPT_DIR=~/.claude/skills/ui-page-parser/scripts # 无认证需求时 python3 \" ${SCRIPT_DIR} /fetch_dom.py\" <URL> \\ --output dom_output.json \\ --screenshot screenshot.png \\ --extract-text-structure # 有认证需求时（Step 1 已完成认证） python3 \" ${SCRIPT_DIR} /fetch_dom.py\" <URL> \\ --storage-state auth_state.json \\ --output dom_output.json \\ --screenshot screenshot.png \\ --extract-text-structure 该脚本会自动检测并选择最佳模式： 优先尝试 Launch 模式（Playwright 直接启动无头浏览器，适用于非沙箱环境） 若 CDP 端口可用则自动切换为 CDP 连接模式 若提供了 --storage-state ，在创建浏览器上下文时注入认证状态 捕获失败时返回 error 字段 常用参数： --wait-for \"#app\" — 等待 SPA 根节点渲染后再抓取 --wait-for \"[data-testid='page-loaded']\" — 等待特定加载标识 --timeout 60000 — 慢速网络适当延长超时 --full-page-screenshot — 全页截图（默认仅视口） --storage-state <path> — 注入认证状态文件 Step 3：认证拦截检测与重试 读取 dom_output.json ，检查是否被重定向到登录页： 如果 error 为 null 但页面标题包含\"登录\"/\"Login\"/\"Sign In\"，且用户未使用认证模式 → 页面可能需要登录 如果 auth_mode 有值但仍然被拦截 → 提示用户 session 可能已过期 发现认证拦截时 ，向用户报告： \"页面 URL 抓取结果显示为登录页面，该页面可能需要登录后才能访问。是否需要登录认证后重新抓取？\" 用户确认后： 询问登录页 URL 运行 auth_login.py 录制登录状态 带 --storage-state 重新运行 fetch_dom.py 用新结果替换 dom_output.json Step 4：分析抓取结果 读取 dom_output.json ，重点分析： error 字段：若非 null，说明抓取失败，降级到推断模式 auth_mode 字段：认证方式（ cdp_authenticated / storage_state / null） title ：页面标题 elements 数组：所有可交互元素，包含： tag , type , id , name , placeholder data_testid , aria_label , aria_labelledby , role class , text_content , href , value is_visible , interaction_hint （navigate/submit/input/select/click/toggle 等） xpath , css （定位器） text_structure 数组：页面语义文本（h1-h6, p, li, label, nav-link 等） screenshot ：截图路径，用于视觉确认页面内容 Step 5：结合业务用例进行语义增强 如果有用户提供的业务用例，为每个元素赋予 业务语义名称 ： DOM 中的 data-testid=\"login-btn\" → 业务名称：\"登录按钮\" 根据元素在页面中的位置、上下文、 interaction_hint 判断其用途 Step 6：生成 pages.yaml 如果有 DOM 数据（error == null）： 生成 LLM 草稿 YAML（按 references/pages_schema.md 结构） 调用 scripts/build_pages_yaml.py 合并 DOM 数据与 LLM 草稿： python3 \" ${SCRIPT_DIR} /build_pages_yaml.py\" dom_output.json llm_draft.yaml --output pages.yaml 如果抓取失败（error != null）： 进入推断兜底模式（见下方） macOS 沙箱环境（CDP 连接模式） 仅当 Playwright Launch 模式失败时 （沙箱环境报错 Permission denied (1100) ），才需要使用 CDP 模式： # 在 Terminal（沙箱外）执行一次即可： bash ~/.workbuddy/skills/ui-page-parser/scripts/start_chrome_cdp.sh # 验证 CDP 服务已启动： curl -s http://localhost:9222/json/version CDP 启动后，重新运行 fetch_dom.py （脚本会自动检测并使用 CDP 模式）。 认证页面抓取 当目标页面需要登录才能访问时，提供两种认证抓取方式。根据场景选择： 场景 推荐方式 单次快速抓取 方案 A：CDP 交互式 需要反复抓取 / CI/CD 方案 B：Storage State 录制 SSO / OAuth / 验证码 / MFA 方案 A 或方案 B 均可 方案 A：CDP 交互式认证（适合单次抓取） 原理：启动带界面的 Chrome，用户手动登录后，技能通过 CDP 复用已认证会话。 Step 1：启动交互式 Chrome CDP bash ~/.claude/skills/ui-page-parser/scripts/start_chrome_cdp.sh --interactive Step 2：在弹出的浏览器中手动登录目标网站 浏览器会显示完整界面（非 headless），支持任意认证方式 登录成功后保持浏览器窗口打开 Step 3：执行抓取（CDP 自动复用认证会话） # 单页面抓取 SCRIPT_DIR=~/.claude/skills/ui-page-parser/scripts python3 \" ${SCRIPT_DIR} /fetch_dom.py <认证页面URL> --output dom.json --screenshot screenshot.png # 全站爬取 python3 \" ${SCRIPT_DIR} /crawl_site.py <入口URL> --output crawl.json --screenshots-dir ./screenshots --verbose 脚本自动检测 CDP 连接并复用已认证的浏览器会话。输出 JSON 中 auth_mode 为 \"cdp_authenticated\" 表示使用了 CDP 认证模式。 方案 B：Storage State 录制（适合反复抓取 / CI/CD） 原理：弹出浏览器让用户登录一次，保存 cookies + localStorage 到文件，后续抓取自动注入。 Step 1：录制登录会话（仅需一次） SCRIPT_DIR=~/.claude/skills/ui-page-parser/scripts python3 \" ${SCRIPT_DIR} /auth_login.py <登录页URL> --output auth_state.json 脚本会： 弹出有头浏览器并导航到登录页 用户在浏览器中手动完成登录 登录成功后回到终端按 Enter 保存 Storage State（cookies + localStorage）到 auth_state.json Step 2：使用录制状态进行抓取 # 单页面抓取 python3 \" ${SCRIPT_DIR} /fetch_dom.py <认证页面URL> \\ --storage-state auth_state.json \\ --output dom.json --screenshot screenshot.png # 全站爬取 python3 \" ${SCRIPT_DIR} /crawl_site.py <入口URL> \\ --storage-state auth_state.json \\ --output crawl.json --screenshots-dir ./screenshots --verbose 输出 JSON 中 auth_mode 为 \"storage_state\" 表示使用了 Storage State 认证模式。 注意事项： Storage State 文件包含敏感认证信息，请勿提交到版本控制系统 Session 过期后需重新运行 auth_login.py 录制 若抓取时仍被重定向到登录页，说明 session 已过期，需重新录制 推断兜底模式（仅有自然语言或抓取失败） 当无法访问页面时，基于用例描述进行 AI 推断： 页面识别 ：从用例中的操作描述推断涉及哪些页面 元素推断 ：根据动词推断元素类型（输入→input，点击→button，选择→select） 定位器推断 ：按 references/locator_strategy.md 优先级推断合理定位器 标注推断模式 ： source: inference_mode: true confidence: \"medium\" metadata: inference_note: \"元素定位器为AI推断值，建议通过真实页面访问后校准\" 直接生成 pages.yaml （跳过 build_pages_yaml.py 的 DOM 富化步骤） 静态 HTML / 前端源码模式 HTML 文件 ：直接读取 HTML 内容，用正则或简单解析提取元素属性 Vue/React 源码 ：分析模板/JSX 中的元素定义，提取 data-testid 、 ref 、 id 、事件绑定 关键解析要点 定位策略选择 优先级： data-testid > aria-label > id > name > CSS > XPath 详细规则参考 references/locator_strategy.md 状态机识别 识别页面状态时关注： 加载态、空态、有数据态（列表/详情页） 表单：初始态、填写中、提交中、成功态、失败态 权限控制态（未登录/无权限） 弹窗触发状态 隐性规则提取 重点识别： 弹窗触发 ：哪些操作会触发 Modal/Drawer/Toast 异步加载 ：AJAX 请求、Skeleton 骨架屏、Loading 图标 iframe 嵌套 ：验证码、第三方组件 权限控制 ：哪些元素/功能需要特定角色才可见 表单联动 ：字段间的级联关系（选省→选市） 多页面处理 当用例涉及多个页面时： 每个页面对应 pages 数组中的独立条目 在 flows 中记录页面间的跳转关系 确保 url 字段能唯一区分各页面 对每个 URL 分别运行 fetch_dom.py 获取各页面的 DOM 输出规范 文件命名 pages.yaml # 完整页面定义（首选格式） pages.json # 等价 JSON 格式（工具链集成时使用） pages_{module}.yaml # 按模块拆分（元素数量超过 100 个时建议拆分） 交付要求 必须包含所有在用例中提及的页面 每个页面至少包含： page_name 、 url 、 elements 所有可交互元素必须有有效的 locator （真实或推断） 推断模式下必须添加 inference_mode: true 和 inference_note Schema 快速参考 完整字段定义见 references/pages_schema.md ， 定位策略详细说明见 references/locator_strategy.md ， 可用 assets/pages_template.yaml 作为起点修改。 典型使用场景示例 场景 1：全站爬取（首选，仅入口 URL） 输入：URL = http://localhost:3000/ 处理： 1. 运行 crawl_site.py http://localhost:3000/ -o crawl.json --screenshots-dir ./screenshots --verbose 2. 读取 crawl.json，获取全站 21 个 URL、6 个公开页面 DOM、15 个需认证页面、24 条路由 3. 为每个页面生成 pages.yaml（公开页面用真实 DOM，需认证页面用推断模式）",
    "model_config": {
        "provider": "deepseek",
        "model": "deepseek-chat",
        "temperature": 0.7,
        "max_tokens": 4096,
        "top_p": 0.9
    },
    "trigger_words": [],
    "source": "DeepseekModel",
    "source_url": "https://deepseekmodel.com/skill?id=zhoujinjian-skills-skills-ui-page-parser-skill-md"
}