Skip to main content
ClaudeWave
Skill5k repo starsupdated 29d ago

ui-data-testid

This Claude Code skill automates addition of stable `data-testid` attributes to React/TSX UI components during implementation, ensuring reliable selectors for unit and end-to-end testing. Use it when building new components, refactoring existing views, configuring dropdowns and menus, or implementing interactive flows that require consistent test selectors across i18n changes and visual updates.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/dtyq/magic /tmp/ui-data-testid && cp -r /tmp/ui-data-testid/frontend/magic-web/.agents/skills/ui-data-testid ~/.claude/skills/ui-data-testid
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# UI Data-testid

## Overview

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`:
- preserve existing `data-testid` during refactor/migration
- use `data-testid-first` query strategy in project tests

## Workflow

1. Determine the scope prefix from feature/module context (for example: `user-menus`, `organization-switch`, `settings-profile`).
2. Add `data-testid` to the component root container.
3. Add `data-testid` to all primary interactive nodes:
   - button/link triggers
   - input/select/checkbox/radio controls
   - tabs/menu items/submenu triggers
   - modal/drawer open and confirm actions
4. For config-driven UI (for example `menu.items`), add `"data-testid"` in config and forward it to the real clickable DOM node in renderer/wrapper components.
5. For repeated list rows/items, put the stable `data-testid` on the row/item container first. Do not add separate unique ids to every child element by default.
6. Inside a list row/item, reuse the row scope in tests: locate the row by shared row id plus text/business data, then query child controls with `within(row)` or role/label selectors.
7. Add child-level `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.
8. Keep existing ids unchanged unless user explicitly asks to rename; never remove existing ids in migration tasks.
9. For interaction changes, add or update Vitest/RTL tests in colocated `__tests__` where feasible.

## Naming Rules

- Use lowercase kebab-case only.
- Use semantic format: `<scope>-<entity>-<action>`.
- Keep IDs text-agnostic (do not depend on i18n labels).
- Avoid dynamic/random values (`Date.now`, UUID, translated text).
- Do not embed secrets, emails, phone numbers, or tokens.
- Use stable suffixes when applicable: `trigger`, `content`, `button`, `input`, `option`, `item`, `row`, `loading`, `empty`, `error`.

## Minimum Coverage Checklist

For every newly created UI component, include at least:

- one root container test id
- one primary CTA test id
- test ids for each secondary action button
- test ids for each form field group/control
- test ids for menu item triggers when menus are present
- for repeated lists/tables, one list container id and one row/item container id; avoid per-cell/per-action dynamic ids unless row-scoped selectors are insufficient
- preserved historical `data-testid` in touched files
- loading/empty/error test ids for async UIs

## Query Priority

When writing or updating tests:

- prefer `getByTestId` for stable selectors in this project
- use `getByRole`, `getByLabelText`, `getByText` as complementary assertions
- avoid `container.querySelector(...)` selectors for user-facing behavior tests

This keeps alignment with `.cursor/rules/testing-guide.mdc`.

## Scenario Playbook

Apply these patterns for stable and accurate element targeting:

1. Forms
   - add ids for form container, inputs, submit/cancel buttons, and validation errors
2. Lists and tables
   - add list container id and row container id
   - prefer a shared row id, then select the intended row by text/business data
   - use stable business key for row id suffix only when there is a concrete need for direct row lookup
   - do not add separate dynamic ids to every field/action inside the row; query child actions with `within(row)` scope
   - if a child action needs a `data-testid`, use one shared id such as `collaborator-remove-button` and resolve it from the row scope
3. Menus and dropdowns
   - add ids for trigger, popup content, and each actionable menu item
   - if menu is config-driven, forward item-level `data-testid` to rendered node
4. Modal and drawer
   - add ids for open trigger, modal content, primary action, and close/cancel action
5. Async states
   - add ids for loading, empty, and error states

## Stability Rules

- Never generate ids from array index if order may change.
- Never generate ids from random values or timestamps.
- Keep singleton ids unique on a page.
- For repeated components, keep shared child ids and scope with `within(...)`.
- Prefer row-level uniqueness over child-level uniqueness in repeated rows; child ids should not encode row ids unless there is no row container to scope from.

## Patterns

### Component markup

```tsx
<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>
```

### Repeated list row

```tsx
<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()
```

### Config + renderer forwarding

```tsx
const items = [
  { key: "logout", label: t("logout"), "data-testid": "user-menus-logout" },
]

<ItemComponent data-testid={menuItem["data-testid"]}>{menuItem.label}</ItemComponent>
```

## Done Criteria

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.
guidesSkill
canvas-designerSkill

Core canvas design skill covering project management, multimedia principles, AI image generation, web image search, and design marker processing. Load for any canvas design task. CRITICAL - When user message contains [@design_canvas_project:...] or [@design_marker:...] mentions, or when the user wants to generate video/animation/clip on a canvas project, you MUST load this skill first before any operations.

compact-chat-historySkill

Summarize and compress the current conversation history into a structured context snapshot, then call compact_chat_history to save it. Read this skill only when the user explicitly asks to compact/summarize — system-triggered compaction injects the instructions directly without requiring a skill read.

creating-slidesSkill

Slide/PPT creation skill that provides complete slide creation, editing, and management capabilities. Use when users need to create slides, make presentations, edit slide content, or manage slide projects. CRITICAL - When user message contains [@slide_project:...] mention, you MUST load this skill first before any operations.

crew-creatorSkill

|

deep-researchSkill

|

develop-data-analysis-dashboardSkill

Data analysis dashboard (instrument panel) development skill. Use when users need to develop data dashboards, create/edit Dashboard projects, build large-screen data boards, or perform dashboard data cleaning. Includes dashboard project creation, card plan, data cleaning (data_cleaning.py), card management tools (create_dashboard_cards, update_dashboard_cards, delete_dashboard_cards, query_dashboard_cards), map download tool (download_dashboard_maps), dashboard development, and validation.

dingtalk-cliSkill

Use when the user wants to interact with DingTalk in any way — including but not limited to: reading, querying, searching, sending, replying to, forwarding, or recalling DingTalk chat messages and chat history; managing group chats and conversations; sending DING alerts; querying contacts, org structure, AI search, or coworkers; reading, searching, creating, or editing DingTalk docs, drive files, sheets, AI tables, wiki, mail, calendar events, meeting rooms, AI meeting minutes, attendance, OA approvals, todos, reports/logs, live sessions, AI apps, permissions, or open-platform docs.