# Quality Engineering Selector Stability

Cross-stack selector and test-id policy for web and mobile automation.

- Repository: https://github.com/HoangNguyen0403/agent-skills-standard (582 stars)
- Category: Design
- License: MIT
- Last updated: 2026-11-01
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add HoangNguyen0403/agent-skills-standard --skill quality-engineering-selector-stability -g -a claude-code -y`
Codex: `npx skills add HoangNguyen0403/agent-skills-standard --skill quality-engineering-selector-stability -g -a codex -y`
Cursor: `npx skills add HoangNguyen0403/agent-skills-standard --skill quality-engineering-selector-stability -g -a cursor -y`
Gemini CLI: `npx skills add HoangNguyen0403/agent-skills-standard --skill quality-engineering-selector-stability -g -a gemini-cli -y`

## Description

Cross-stack selector and test-id policy for web and mobile automation. Use when writing or reviewing E2E/UI test locators, or adding data-testid/accessibility identifiers to components.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Quality Engineering: Selector Stability

## **Priority: P0 (CRITICAL)**

## Web Ladder

`getByRole` / `getByLabel` > `getByTestId` (`data-testid`) > attribute CSS. Never XPath, `nth-child`, or generated class names.

## Mobile Ladder

Accessibility id > resource-id / `testTag` > predicate/uiautomator > XPath. Never XPath.

## Framework Map

- React/Next.js: `data-testid`.
- React Native: `testID` for automation; separate `accessibilityLabel` for VoiceOver/TalkBack.
- Flutter: `WidgetKeys` (`Key`) on widgets for widget tests, `integration_test`, and Patrol.
- SwiftUI/UIKit: `.accessibilityIdentifier` (automation only); `.accessibilityLabel` (screen reader).
- Jetpack Compose: `Modifier.testTag` + `testTagsAsResourceId = true` for automation; `contentDescription` for a11y.
## Naming

`<screen>-<element>-<role>`, kebab-case (e.g. `checkout-submit-button`).

## Insertion Policy

Add ids to leaf interactive/assertable elements only, never layout wrappers. Never rename an existing id, ids are a public contract other tests depend on.

## Drift Classes

`rename` (id changed), `restructure` (DOM/tree moved), `i18n` (visible text changed, id untouched).

## Anti-Patterns

- Text selectors on translated strings, index-based locators (`nth`), generated/hashed class names.
- Using `accessibilityLabel` / `contentDescription` as a test id (they are user-facing a11y strings, not stable test locators).
- Overwriting or stripping accessible labels to insert test identifiers.
- Using web CSS / XPath selectors in native mobile automation.
- "xpath just for now", there is no temporary XPath; use the ladder from the first commit.
## References

- [Selector Ladder Details](references/selector-ladder.md)
- [Test-ID Naming](references/testid-naming.md)
- [Insertion Policy](references/insertion-policy.md)
- [Drift Classification](references/drift-classification.md)

