视觉画布设计
canvas-design
基于设计原则创作静态视觉作品,用于海报与品牌图形。
accelint-react-testing【文档与办公】Use when writing, reviewing, or refactoring React component tests with Testing Library. Load when you see render(), screen, fireEvent, userEvent, waitFor, or *.test.tsx files. Covers query priority (getByRole > getByLabelText > getByText), user-centric testing patterns, async utilities, custom renders with providers, and accessibility-first assertion…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Expert guidance for writing maintainable, user-centric React component tests with Testing Library. Focused on query selection, accessibility-first testing, and avoiding implementation details.
data-testid="submit" but no accessible name works in tests but fails for screen reader users. When tests pass with test IDs, you ship inaccessible UIs. Query hierarchy: getByRole > getByLabelText > getByText > getByTestId. Each step down this list means less confidence your UI is usable.fireEvent for user interactions when userEvent is available - fireEvent dispatches single DOM events, missing the event sequence real users trigger: fireEvent.click() fires one click event, but real users trigger focus → mousedown → mouseup → click. Components that work with fireEvent break in production when users interact normally. userEvent.click() simulates the full interaction sequence, catching bugs fireEvent misses.container or use destructured queries after initial render - const { getByText } = render(<Component />) creates stale queries that miss updates: after state changes, destructured queries search the initial DOM snapshot, missing newly rendered elements. This causes "element not found" errors for elements that are actually present. Always use screen.getByText() which automatically queries the current DOM state. Using screen consistently also makes tests more maintainable - adding a new query doesn't require updating the destructuring.aria-label="submit-button" or role="button" just so tests can find elements, you're working backwards. Tests should verify the component is already accessible, not make it accessible for tests. Adding test-only ARIA pollutes production code and masks real accessibility problems. Fix the component's semantic HTML and existing ARIA first.waitFor for actions that return promises - waitFor(() => expect(element).toBeInTheDocument()) polls repeatedly until timeout when a promise-based findBy query solves it in one shot: await screen.findByText('loaded') waits for the element to appear without polling. Reserve waitFor for assertions that can't use findBy (checking element disappears, waiting for attribute changes).waitFor(() => { fireEvent.click(button); expect(text).toBeInTheDocument(); }) runs the click multiple times as waitFor retries, causing unpredictable behavior. waitFor is for waiting on assertions, not triggering actions. Perform all actions outside waitFor, then use waitFor only for the assertion: fireEvent.click(button); await waitFor(() => expect(text).toBeInTheDocument()); or better yet, await userEvent.click(button); expect(await screen.findByText(text)).toBeInTheDocument();.renderWithRedux function with undocumented required store shape breaks for every developer: they call render(<Component />) instead of renderWithRedux(), tests fail with cryptic "Cannot read property of undefined", wasting 15 minutes debugging. Centralize provider setup in test utils with TypeScript types that enforce correct usage, or document required wrappers prominently.@testing-library/react render and @testing-library/dom queries creates confusion: screen from react package doesn't work with getByRole from dom package, causing "screen.getByRole is not a function" errors. Import all queries from @testing-library/react for React components - it re-exports everything from dom with React-specific enhancements.Apply these thinking patterns before implementing React component tests:
rerender() or accesses component internals, you're testing implementation. Refactor to test through user actions.findBy* for anything loaded via useEffect, API calls, or setTimeout. getBy* throws immediately if element is missing; findBy* waits for it to appear. Using getBy for async content creates race conditions that only fail in CI.findBy* query. Disappearance = waitForElementToBeRemoved. State changes = waitFor with assertion. Each has different semantics; using the wrong one causes flaky tests or longer timeouts.This skill uses progressive disclosure to minimize context usage:
Read AGENTS.md for a concise overview of all rules with one-line summaries.
Use these explicit triggers to know when to load each reference file:
MANDATORY Loading (load entire file):
Load When You See These Patterns:
Do NOT Load Unless Specifically Needed:
Each reference file contains:
Use the provided scripts to audit existing test suites:
# Check query priority (testId usage, container.querySelector)
./scripts/check-query-priority.sh
# Find fireEvent that should be userEvent
./scripts/find-fire-event.sh
# Detect deprecated wrapper/container patterns
./scripts/detect-wrapper-queries.sh
When this skill is invoked for test code review, use the standardized report format:
Template: assets/output-report-template.md
The report format provides:
When to use the report template:
/accelint-react-testing <path>When NOT to use the report template:
Expert guidance on React Testing Library patterns:
Use this hierarchy when selecting queries - try options from top to bottom:
1. getByRole ← Preferred: Accessible, reflects how users & ATs interact
↓ Can't find role?
2. getByLabelText ← For form fields: matches how users read forms
↓ No label?
3. getByPlaceholderText ← For inputs: less accessible than labels
↓ No placeholder?
4. getByText ← For non-interactive content: headings, paragraphs
↓ Text not unique?
5. getByDisplayValue ← For form inputs: current value
↓ No display value?
6. getByAltText ← For images: alt attribute
↓ No alt text?
7. getByTitle ← For title attribute: less accessible
↓ No title?
8. getByTestId ← Last resort: no accessibility verification
Key principles:
screen export is not magic - It's just getQueriesForElement(document.body). Using screen.getByRole() is identical to destructured getByRole() from render, but screen never goes stale after re-renders.screen.debug() to see the current DOM or screen.logTestingPlaygroundURL() to get an interactive tool showing what queries work. Don't guess at selectors - let Testing Library show you what's available.getBy* throws with helpful suggestions about similar elements and available roles. queryBy* returns null, requiring you to add your own assertion with less helpful error output. Use queryBy only when asserting absence with .not.toBeInTheDocument().await on async queries. Not caused by correct use of findBy or waitFor.await userEvent.click() causes "act" warnings and flaky tests as state updates happen after assertions run.