Add stable `data-testid` attributes by default for new or refactored UI components. Use when implementing React/TSX views, shadcn/antd-style components, dropdown/menu configs, or interactive UI flows that need reliable selectors for unit/E2E tests.
68
83%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Add predictable data-testid attributes to UI code as part of implementation, not as a later patch.
Keep selectors stable across i18n text changes and visual refactors.
Follow project testing rules in .cursor/rules:
data-testid during refactor/migrationdata-testid-first query strategy in project testsuser-menus, organization-switch, settings-profile).data-testid to the component root container.data-testid to all primary interactive nodes:
menu.items), add "data-testid" in config and forward it to the real clickable DOM node in renderer/wrapper components.data-testid on the row/item container first. Do not add separate unique ids to every child element by default.within(row) or role/label selectors.data-testid inside repeated rows only when the child cannot be reliably selected from the row scope; if needed, keep the child id shared across rows instead of appending row ids.__tests__ where feasible.<scope>-<entity>-<action>.Date.now, UUID, translated text).trigger, content, button, input, option, item, row, loading, empty, error.For every newly created UI component, include at least:
data-testid in touched filesWhen writing or updating tests:
getByTestId for stable selectors in this projectgetByRole, getByLabelText, getByText as complementary assertionscontainer.querySelector(...) selectors for user-facing behavior testsThis keeps alignment with .cursor/rules/testing-guide.mdc.
Apply these patterns for stable and accurate element targeting:
within(row) scopedata-testid, use one shared id such as collaborator-remove-button and resolve it from the row scopedata-testid to rendered nodewithin(...).<div data-testid="user-menus-organization-info">
<button type="button" data-testid="user-menus-upgrade-button" />
<button type="button" data-testid="user-menus-recharge-button" />
</div><div data-testid="collaborator-list-content">
{collaborators.map((collaborator) => (
<div
key={collaborator.id}
data-testid="collaborator-item"
data-collaborator-id={collaborator.id}
>
<span>{collaborator.name}</span>
<button type="button" data-testid="collaborator-remove-button" />
</div>
))}
</div>
const row = page
.getByTestId("collaborator-list-content")
.locator('[data-testid="collaborator-item"]')
.filter({ hasText: receiverName })
await row.getByTestId("collaborator-remove-button").click()const items = [
{ key: "logout", label: t("logout"), "data-testid": "user-menus-logout" },
]
<ItemComponent data-testid={menuItem["data-testid"]}>{menuItem.label}</ItemComponent>Complete only when all new singleton interactive nodes in touched UI files have stable data-testid values and repeated list/table rows have row-level selectors that allow child controls to be found from the row scope.
Confirm no existing data-testid was removed unintentionally in migration/refactor diffs.
f9973c5
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.