원클릭으로
locator-replacer
替换占位定位符为真实选择器(六级优先级)。触发:替换定位符、locator、selector、定位失败、元素找不到、DOM 分析。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
替换占位定位符为真实选择器(六级优先级)。触发:替换定位符、locator、selector、定位失败、元素找不到、DOM 分析。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Incrementally add regression test points to an existing PageObject. Trigger: add test point, add regression point, add test point, increase coverage, extend page methods.
POM layering and context sharing decision tree. Trigger: architecture, layering, POM, Page Object, base class design, add new role.
Browser viewport / headless / timeout layered configuration. Trigger: viewport, browser config, navigation timeout, headless, slow_mo, incognito.
Under a shared page, a test case that leaves the start page must return via the UI and assert. Trigger: round-trip closure, case round trip, reset timeout, scope shared page.
AST knowledge graph: change review, exploration, debugging, refactoring. Trigger: knowledge graph, code review, impact analysis, blast radius, refactoring.
One-click generation of PageObject + matching tests. Trigger: new page, generate page, gen page, create page, add page object.
| name | locator-replacer |
| description | 替换占位定位符为真实选择器(六级优先级)。触发:替换定位符、locator、selector、定位失败、元素找不到、DOM 分析。 |
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(不受构建影响)→ 文案变更则对照新文案更新。