generate-locator
Skill28 starsChanged 4 months agoMITView on GitHub
Sinh locator ổn định cho UI element. Hỗ trợ Playwright, Selenium, Appium.
- Reads credentials
In this repository26 other files it gives its agents.
- AGENTS.mdAGENTS.md
- analyze-flaky-testsSkill
- analyze-requirement-documentSkill
- fetch-jira-requirementsSkill
- flaky-test-analyzerSkill
- framework-architectSkill
- generate-api-tests-from-swaggerSkill
- generate-application-test-planSkill
- generate-automation-frameworkSkill
- generate-automation-from-testcasesSkill
- generate-automation-from-ui-flowSkill
- generate-combinatorial-test-dataSkill
- generate-cross-module-test-planSkill
- generate-manual-testcases-rbtSkill
- generate-requirements-from-websiteSkill
- generate-testcases-from-requirementsSkill
- generate-test-dataSkill
- import-test-results-xraySkill
- jira-integrationSkill
- locator-healer-agentSkill
- qa-automation-engineerSkill
- rbt-manual-testingSkill
- requirements-analyzerSkill
- smart-locator-agentSkill
- test-data-generatorSkill
- ui-debug-agentSkill
The file
Files
$generate-locator — Sinh Locator Ổn Định Cho UI Automation
User cung cấp element cần tìm locator (mô tả, screenshot, URL, hoặc HTML snippet). AI inspect DOM/UI hierarchy thực tế, sinh locator ổn định theo priority chuẩn, verify uniqueness, trả về kết quả.
BẮT BUỘC (MANDATORY): Trước khi bắt đầu, PHẢI nạp và đọc kỹ:
- Skill:
.agents/skills/smart-locator-agent/SKILL.md— Quy trình sinh locator- Skill:
.agents/skills/ui-debug-agent/SKILL.md— Quy trình inspect DOM- Rule:
.agents/rules/locator_strategy.md— Bản đồ ưu tiên locator- Rule:
.agents/rules/<framework>_rules.md— Quy tắc riêng framework đang dùng
Input cần từ User
| Input | Bắt buộc | Mô tả |
| Mô tả element | ✅ | VD: "nút Login", "dropdown chọn Country", "ô nhập Email" |
| URL trang chứa element | ✅ | Để AI navigate và inspect DOM thực tế |
| Framework | ✅ | playwright, selenium, hoặc appium |
| HTML snippet | ❌ | Nếu User đã có sẵn DOM context — AI dùng để phân tích nhanh |
| Page class đích | ❌ | File Page class mà locator sẽ được thêm vào |
| Login yêu cầu | ❌ | Nếu trang yêu cầu đăng nhập — User cho biết cách login |
Lưu ý về Login: Nếu trang yêu cầu đăng nhập, User PHẢI chỉ rõ cách login (fixture, script, URL login...). AI KHÔNG ĐƯỢC tự đọc
.envhay đoán credentials.
Các bước thực hiện
Phase 1: Phân tích yêu cầu
- Hiểu element cần tìm — Xác định rõ:
- Loại element: button, input, link, dropdown, dialog, table row, checkbox, radio...
- Context: Nằm trong page chính, dialog/modal, sidebar, table, iframe?
- Thao tác: click, fill, select, hover, verify text, verify visibility?
Xác định framework và đọc rules tương ứng:
Framework Rule file Playwright .agents/rules/playwright_rules.mdSelenium .agents/rules/selenium_rules.mdAppium .agents/rules/appium_rules.md- Kiểm tra Page class hiện tại (nếu User chỉ định):
- Đọc file Page class → biết locator đã có sẵn
- Tránh trùng lặp hoặc xung đột naming
Phase 2: Inspect DOM / UI Hierarchy thực tế
⚠️ NGUYÊN TẮC BẤT DI BẤT DỊCH: KHÔNG BAO GIỜ ĐOÁN LOCATOR. PHẢI INSPECT THỰC TẾ.
2A. Web (Playwright MCP)
- Navigate đến trang chứa element:
browser_navigate(url=<target_url>) - Resize viewport (BẮT BUỘC):
browser_resize(width=1920, height=1080) - Capture DOM:
browser_snapshot() - Phân tích element trong snapshot:
- Tìm ref element trong DOM tree
- Ghi lại tất cả attributes có giá trị:
role,aria-label,aria-labelledby,data-testid,data-test,data-qa,id,name,placeholder,type,href, text content - Ghi lại parent context (dialog? table? sidebar? iframe?)
- Nếu element bị ẩn (dropdown menu, modal, tooltip...):
- Thực hiện action mở element:
browser_click(ref=<trigger>) - Capture lại:
browser_snapshot()
- Thực hiện action mở element:
2B. Mobile (Appium)
- Dùng Appium Inspector hoặc
page_sourceđể lấy UI hierarchy - Ghi lại attributes:
accessibility-id,resource-id,content-desc,text,class,bounds - Nếu element nằm trong scroll view → scroll đến element trước khi inspect
Phase 3: Sinh locator theo Priority
Áp dụng bản đồ ưu tiên (Master Priority Map):
# Loại Khi nào dùng 1 Accessibility / Aria Element có role,aria-labelrõ ràng2 Test attribute Element có data-testid,data-test,data-qa3 ID / name Element có idhoặcnameổn định (không auto-generated)4 Framework semantic Playwright: getByRole,getByLabel...5 CSS Selector Dùng attribute cụ thể, tránh class động 6 XPath Lựa chọn cuối cùng — chỉ dùng XPath tương đối Sinh locator theo framework:
Playwright (TypeScript/JavaScript):
// Priority 1: Role-based page.getByRole('button', { name: 'Submit' }) // Priority 2: Test ID page.getByTestId('submit-btn') // Priority 3: Label / Placeholder page.getByLabel('Email') page.getByPlaceholder('Enter your password') // Priority 4: Text page.getByText('Submit') // Priority 5: CSS page.locator('#submit-button') page.locator('[data-testid="submit-btn"]') // Priority 6: XPath (cuối cùng) page.locator('//button[@type="submit"]')Playwright (Python):
# Priority 1: Role-based page.get_by_role("button", name="Submit") # Priority 2: Test ID page.get_by_test_id("submit-btn") # Priority 3: Label / Placeholder page.get_by_label("Email") page.get_by_placeholder("Enter your password") # Priority 4: Text page.get_by_text("Submit") # Priority 5: CSS page.locator("#submit-button") # Priority 6: XPath (cuối cùng) page.locator("//button[@type='submit']")Selenium (Java):
// Priority 1: ID driver.findElement(By.id("submit-button")); // Priority 2: Test attribute driver.findElement(By.cssSelector("[data-testid='submit-btn']")); // Priority 3: Name driver.findElement(By.name("submit")); // Priority 4: CSS Selector driver.findElement(By.cssSelector("button.btn-primary[type='submit']")); // Priority 5: XPath (cuối cùng) driver.findElement(By.xpath("//button[@type='submit']"));Appium (Java):
// Priority 1: Accessibility ID driver.findElement(AppiumBy.accessibilityId("login_button")); // Priority 2: Resource ID (Android) driver.findElement(AppiumBy.id("com.app:id/login_button")); // Priority 3: iOS Predicate driver.findElement(AppiumBy.iOSNsPredicateString("label == 'Login'")); // Priority 4: Class Chain (iOS) driver.findElement(AppiumBy.iOSClassChain("**/XCUIElementTypeButton[`label == 'Login'`]")); // Priority 5: XPath (cuối cùng) driver.findElement(AppiumBy.xpath("//android.widget.Button[@text='Login']"));
Phase 4: Validate locator
Verify uniqueness — PHẢI match đúng 1 element:
Web (Playwright MCP):
browser_evaluate(function="() => document.querySelectorAll('<css_selector>').length")Selenium:
List<WebElement> matches = driver.findElements(By.<strategy>("<locator>")); assert matches.size() == 1;Appium:
List<WebElement> matches = driver.findElements(AppiumBy.<strategy>("<locator>")); assert matches.size() == 1;- Verify visibility — Element phải tương tác được:
- Không bị overlay bởi element khác
- Không ở trạng thái
hidden,display:none,visibility:hidden - Không nằm ngoài viewport (cần scroll)
- Verify stability — Kiểm tra checklist:
- Không dùng dynamic CSS class (VD:
css-1n2xyz,sc-bdnxRM) - Không dùng XPath tuyệt đối (VD:
//html/body/div[1]/div[2]/button) - Không dùng auto-generated ID (VD:
ember123,react-select-2-input) - Không dùng
nth-child/nth-of-typekhi có lựa chọn tốt hơn - Sống sót qua page reload
- Ổn định trên nhiều trạng thái trang (loading, loaded, có data, không data)
- Không dùng dynamic CSS class (VD:
Phase 5: Trả kết quả
- Output Format — BẮT BUỘC cung cấp đầy đủ 3 phần:
## Locator Result: [Mô tả element]
**Framework:** [Playwright / Selenium / Appium]
### 🎯 Primary Locator (Recommended)
```<language>
// Locator code — copy-paste ready- Loại: [Role-based / Test ID / CSS / ...]
- Unique: ✅ Match 1 element
- Stability: ✅ Không dùng dynamic class / absolute xpath
🔄 Fallback Locator
// Locator thay thế khi primary hỏng- Loại: [CSS / XPath / ...]
- Khi nào dùng: Khi primary locator bị break do DOM thay đổi
💡 Reasoning
- Giải thích tại sao chọn Primary locator này
- Tại sao loại bỏ các candidate khác
- Rủi ro tiềm ẩn (nếu có)
📋 Usage Example (nếu User yêu cầu)
// Ví dụ sử dụng locator trong test code
15. **(Tùy chọn) Nếu User yêu cầu thêm vào Page class:**
- Thêm locator đúng vị trí trong Page class
- Đặt tên theo naming convention của project
- Tạo method sử dụng locator nếu cần
---
## Common Patterns (Tham khảo)
### Scoping locator trong Dialog / Modal:
```typescript
// Playwright — scope vào dialog trước
const dialog = page.getByRole('dialog');
dialog.getByRole('button', { name: 'Confirm' }).click();// Selenium — scope vào dialog
WebElement dialog = driver.findElement(By.cssSelector("[role='dialog']"));
dialog.findElement(By.cssSelector("button[data-testid='confirm']")).click();Dynamic text matching:
// Playwright — exact vs partial
page.getByText('Submit', { exact: true }) // exact match
page.getByText(/submit/i) // regex, case-insensitive# Playwright Python — normalize-space XPath
page.locator(f"//a[normalize-space()='{text}']")Table row action:
// Playwright — filter row rồi interact
const row = page.getByRole('row').filter({ hasText: 'John Doe' });
row.getByRole('button', { name: 'Edit' }).click();// Selenium — XPath relative trong table
driver.findElement(By.xpath("//tr[contains(., 'John Doe')]//button[text()='Edit']"));NGHIÊM CẤM
| ❌ Không được làm | ✅ Thay thế đúng |
| Đoán locator không inspect DOM/UI | browser_snapshot() hoặc Appium Inspector trước |
Dùng CSS class động (css-1n2xyz, sc-xxx) | Dùng role, aria, data-testid, text |
Dùng XPath tuyệt đối (//html/body/div[1]...) | Dùng XPath tương đối với attribute |
Dùng auto-generated ID (ember123, :r1:) | Dùng stable attribute hoặc text |
| Trả locator không verify uniqueness | Luôn verify match đúng 1 element |
| Chỉ trả 1 locator, không có fallback | Trả Primary + Fallback + Reasoning |
Đọc .env để lấy credentials login | Hỏi User cách login hoặc dùng fixture có sẵn |
Checklist cuối
- Đã inspect DOM/UI hierarchy thực tế (không đoán)
- Locator theo đúng priority: accessibility > test-id > id/name > semantic > css > xpath
- Primary locator match đúng 1 element duy nhất
- Có Fallback locator
- Có Reasoning giải thích lý do chọn
- Không dùng dynamic class, absolute xpath, auto-generated ID
- Locator ổn định qua page reload và nhiều trạng thái
- (Nếu thêm vào Page class) Đã verify code chạy không lỗi
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

