From velocitai
Replaces placeholder locators with real selectors using a six-level priority strategy (role+text, visible text, form attributes, stable CSS, data-testid, relative XPath). Useful for fixing broken selectors after frontend rebuilds or adding new page elements.
How this skill is triggered — by the user, by Claude, or both
Slash command
/velocitai:locator-replacerThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
- 将页面对象中 `text=` 占位定位符替换为真实选择器
text= 占位定位符替换为真实选择器按优先级从高到低,逐级尝试,选中即停。优先使用页面上已有的语义化信息,避免依赖需要前端额外配合的属性:
# 通过 ARIA role + 可见文本定位
LOGIN_BTN = "role=button[name='登录']"
NAV_LINK = "role=link[name='<功能名>']"
SEARCH_INPUT = "role=textbox[name='搜索']"
# 精确匹配
FEATURE_BTN = "text=<功能名>"
# 包含匹配(文本可能嵌套在子元素中)
FEATURE_TAB = "text=<功能名>"
text= 是当前项目的占位方案,如果分析后发现 text= 已经足够稳定且元素唯一,可以保留并标记 # P1: text(已验证唯一)# placeholder 定位
EMAIL_INPUT = "[placeholder='请输入邮箱']"
# label 关联定位
PASSWORD_INPUT = "css=input[name='password']"
# type 属性
SUBMIT_BTN = "css=button[type='submit']"
name 属性通常由后端约定,相对稳定placeholder 跟随文案,稳定性中等# 业务语义类名 — 稳定
COURSE_CARD = "css=.list-card"
LOGIN_FORM = "css=#login-form"
NAV_MENU = "css=.main-navigation"
# ⚠️ 以下是哈希类名 — 绝对禁止使用
# BAD: "css=.sc-bdVaJa.bVjGWg" (styled-components 哈希)
# BAD: "css=.css-1a2b3c" (CSS Modules 哈希)
# BAD: "css=[class*='_component_']" (Vite CSS Modules)
哈希类名识别规则(必须跳过):
| 构建工具 | 哈希类名特征 | 示例 |
|---|---|---|
| styled-components | 随机字母组合 | .sc-bdVaJa, .bVjGWg |
| CSS Modules | 下划线 + 哈希 | .header_abc123, ._component_1x2y3 |
| Vite | 短哈希后缀 | .module_1a2b3c |
| Tailwind JIT | 动态工具类 | .[\31 /2], .[color:red] |
| Emotion | 前缀 css- | .css-1a2b3c |
可用的类名特征:
.list-card, .login-form, .nav-menu.header__title, .card--active.app-feature-list, .app-headerdata-testid 专用测试属性# Playwright locator 写法
SUBMIT_BTN = "[data-testid='submit-button']"
data-testid,可以直接使用,但不必强求前端为所有元素添加# ✅ 相对路径 — 从稳定祖先节点出发
SUBMIT_BTN = "xpath=//div[@class='login-form']//button[@type='submit']"
FIRST_COURSE = "css=.course-list > .course-item:first-child"
# ❌ 绝对路径 — 绝对禁止
# BAD: "xpath=/html/body/div[1]/div[2]/ul/li[3]/button"
XPath 编写规则:
/html/body 开始)div[3]),除非是列表且确实需要第 N 项使用 agent-browser 打开目标页面,获取交互元素信息(工具选型遵循 agent-behavior P0.4,agent-browser 未安装时降级到 Playwright MCP):
操作步骤:
1. browser_navigate → 访问目标页面(已认证状态)
2. browser_snapshot → 获取页面无障碍树(accessibility tree)
3. browser_evaluate → 执行 JS 提取元素属性:
- document.querySelectorAll('[data-testid]') → 已有 testid
- document.querySelectorAll('[role]') → ARIA role
- document.querySelectorAll('button, a, input') → 交互元素
对照页面对象中的每个占位定位符,按 P0→P5 逐级尝试,命中即停:
| 检查顺序 | 条件 | 使用 |
|---|---|---|
| P0 | 有 role + name | role=button[name='...'] |
| P1 | text= 唯一且稳定 | text=...(标记"已验证唯一") |
| P2 | 表单属性(placeholder/name/type) | [placeholder='...'] |
| P3 | 稳定 CSS class(非哈希) | css=.xxx |
| P4 | 有 data-testid | [data-testid='...'] |
| P5 | 以上均无 | 相对 XPath(≤3 层) |
class <PageName>(BasePage):
# 定位符 — 已替换为真实选择器(<日期>)
<PRIMARY_ACTION_BTN> = "role=button[name='<按钮文案>']" # P0: ARIA role
<SECONDARY_LINK> = "text=<链接文案>" # P1: text(已验证唯一)
PAGE_IDENTIFIER = "role=heading[name='<页面标题>']" # P0: ARIA role
更新规则:
# P0: ARIA role / # P1: text / ... / # P4: testid / # P5: XPath)text= 经验证确实稳定且唯一,注释标记 # P1: text(已验证唯一)# 定位符 — 后续替换为实际选择器 注释# 定位符 — 已替换为真实选择器(日期)# 在对应角色的回归文件中跑指定用例(运行前向用户确认 --env,见 agent-behavior P0.2)
pytest tests/<role>/test_<role>_flow.py --env=<pre|prod> -v -k "test_<story_name>"
更新 docs/regression-points.md 中对应 PageObject 的"关键定位符"段。
替换完成后,逐项确认:
/html/body/...)sc-xxx, css-xxx, _module_xxx)div[3],除非列表取第 N 项)# P0 ~ # P5)text= 不唯一降级到 P3/P5,用父容器 + 文本组合:css=.list-card:first-child >> text=查看详情
向前端团队提出添加 data-testid(P4)需求,附元素清单;临时用 P5 相对 XPath 过渡。
检查是否使用了哈希类名(违反 P3)→ 优先升级到 P0/P1(不受构建影响)→ 文案变更则对照新文案更新。
npx claudepluginhub danielsuo117/velocitai --plugin velocitaiScans a website URL and extracts optimized locators for every visible element, outputting a Page Object Model (POM) and/or JSON locator map for Playwright, Cypress, or WebdriverIO.
Provides Playwright patterns for resilient selectors, locator chaining, filtering, and waiting strategies to minimize flakiness in E2E tests and web scrapers.
Guides creating page objects and refactoring Playwright tests using Page Object Model patterns for maintainability, reusability, and scalability. Covers locators, principles, and TypeScript examples.