diff --git a/README.md b/README.md index 03e69b1..322fc5a 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The primary aim is to offer a comprehensive, AI-friendly knowledge base and star ## Core Components The core components of this repository are the README and markdown files found throughout the project. These files provide indexed documentation, guidelines, and best practices to support AI-assisted PatternFly development, regardless of which AI coding tool you use. -- **Table of Contents:** See [`.pf-ai-documentation/README.md`](documentation/README.md) for a full table of contents and navigation to all rules, guides, and best practices. +- **Table of Contents:** See [`.pf-ai-documentation/README.md`](.pf-ai-documentation/README.md) for a full table of contents and navigation to all rules, guides, and best practices. ## Using This Documentation with Cursor and AI Tools @@ -52,6 +52,14 @@ To get the full benefit of these docs and rules: > 3. Save and restart your client/editor. > 4. For more details and setup instructions for other editors, see the official guide: https://github.com/upstash/context7#installation +## Claude Code plugins + +For [Claude Code](https://code.claude.com) users, this repository includes plugins with agents for PatternFly development. + +See [`claude-code/`](claude-code/) for available plugins and installation instructions. + +--- + ## Reference Documentation - [PatternFly.org](https://www.patternfly.org/) - [PatternFly React GitHub Repository](https://github.com/patternfly/patternfly-react) diff --git a/claude-code/.claude-plugin/marketplace.json b/claude-code/.claude-plugin/marketplace.json new file mode 100644 index 0000000..5e85e60 --- /dev/null +++ b/claude-code/.claude-plugin/marketplace.json @@ -0,0 +1,13 @@ +{ + "name": "patternfly-ai-coding", + "owner": { + "name": "PatternFly Team" + }, + "plugins": [ + { + "name": "pf-react", + "source": "./plugins/pf-react", + "description": "PatternFly React coding standards and test generation agents" + } + ] +} diff --git a/claude-code/README.md b/claude-code/README.md new file mode 100644 index 0000000..5610078 --- /dev/null +++ b/claude-code/README.md @@ -0,0 +1,83 @@ +# PatternFly Claude Code Resources + +This directory contains [Claude Code](https://code.claude.com) resources for PatternFly development. + +## Available resources + +### Plugins +- **[pf-react](plugins/pf-react/)** - Coding standards and test generation agents for PatternFly React + +--- + +## Installing plugins + +### pf-react plugin + +Once installed, these agents work across all your projects: + +```bash +# 1. Add the PatternFly marketplace +/plugin marketplace add patternfly/patternfly-ai-coding + +# 2. Install the plugin +/plugin install pf-react@patternfly-ai-coding +``` + +Done! The agents are now available globally. + +## Using the agents + +Use these agents from any project directory: + +```bash +cd ~/my-patternfly-app # Any project directory +claude + +# Use the agents +/coding-standards # PatternFly React coding standards +/test-generator # Generate tests for components +``` + +## What's included + +The `pf-react` plugin provides two agents: + +### coding-standards +PatternFly v6 React coding standards based on official PatternFly guidelines: +- Component composition patterns +- Design token usage +- Accessibility requirements (WCAG 2.1 Level AA) +- React and TypeScript best practices +- Testing standards + +### test-generator +Unit test generation following Testing Library best practices: +- User behavior testing over implementation details +- Accessibility testing patterns +- Semantic queries and OUIA guidelines +- Proper mocking patterns + +## Updating + +Get the latest version: + +```bash +/plugin marketplace update patternfly-ai-coding +/plugin install pf-react@patternfly-ai-coding +``` + +## How it works + +- **One-time install** - Add marketplace and install plugin (done once) +- **Global availability** - Agents work in any project directory after installation +- **No project setup needed** - Just run `/coding-standards` or `/test-generator` from any project +- **Direct from GitHub** - No need to clone the repository + +## Sources + +The agents are based on: +- [PatternFly.org](https://www.patternfly.org/) official documentation +- [PatternFly React CONTRIBUTING.md](https://github.com/patternfly/patternfly-react/blob/main/CONTRIBUTING.md) +- [PatternFly React Testing Wiki](https://github.com/patternfly/patternfly-react/wiki/React-Testing-Library-Basics,-Best-Practices,-and-Guidelines) +- [React Testing Library](https://testing-library.com/docs/react-testing-library/intro) official documentation +- [React.dev](https://react.dev/learn) official documentation diff --git a/claude-code/plugins/pf-react/.claude-plugin/plugin.json b/claude-code/plugins/pf-react/.claude-plugin/plugin.json new file mode 100644 index 0000000..ee8fcba --- /dev/null +++ b/claude-code/plugins/pf-react/.claude-plugin/plugin.json @@ -0,0 +1,11 @@ +{ + "name": "pf-react", + "description": "PatternFly React coding standards and test generation agents", + "version": "1.0.0", + "author": { + "name": "PatternFly Team", + "url": "https://www.patternfly.org" + }, + "repository": "https://github.com/patternfly/patternfly-ai-coding", + "license": "MIT" +} diff --git a/claude-code/plugins/pf-react/agents/coding-standards.md b/claude-code/plugins/pf-react/agents/coding-standards.md new file mode 100644 index 0000000..0d97b52 --- /dev/null +++ b/claude-code/plugins/pf-react/agents/coding-standards.md @@ -0,0 +1,414 @@ +--- +name: coding-standards +description: Coding standards for PatternFly React development based on official PatternFly guidelines and contribution requirements. +model: sonnet +color: blue +--- + +# PatternFly React Development Standards + +This agent enforces coding standards for **PatternFly React** applications based on: + +- [PatternFly React CONTRIBUTING.md](https://github.com/patternfly/patternfly-react/blob/main/CONTRIBUTING.md) +- [PatternFly.org documentation](https://www.patternfly.org/) +- [React Testing Library](https://testing-library.com/docs/react-testing-library/intro) + +For detailed component patterns, see the [`.pf-ai-documentation/` directory](https://github.com/patternfly/patternfly-ai-coding/tree/main/.pf-ai-documentation). + +--- + +## PatternFly React Requirements + +### Supported Versions + +- **React**: 17, 18 (React 19 coming soon) +- **PatternFly**: v6 only +- **TypeScript**: Recommended +- **Package Manager**: npm or Yarn + +### Installation + +```bash +npm install @patternfly/react-core --save + +# Additional packages as needed: +npm install @patternfly/react-table --save +npm install @patternfly/react-charts --save +npm install @patternfly/react-icons --save +``` + +### Required: Base CSS Import + +Always import PatternFly base CSS before your application: + +```tsx +import "@patternfly/react-core/dist/styles/base.css"; +``` + +--- + +## Component Development Standards + +### From PatternFly React CONTRIBUTING.md + +**Component structure requirements:** + +1. Prefer stateless functional components +2. Accept props as UI display parameters +3. Provide a single default export per component +4. Use PascalCase for component files/folders +5. Use `...props` for extensibility + +**Example:** + +```tsx +// ✅ Correct PatternFly React component +interface UserCardProps { + user: User; + onEdit?: (user: User) => void; +} + +export const UserCard = ({ user, onEdit, ...props }: UserCardProps) => ( + + {user.name} + + {user.email} + {onEdit && } + + +); +``` + +--- + +## PatternFly v6 Styling Standards + +### Component Composition Over Utility Classes + +PatternFly provides layout components - use them instead of utility classes: + +```tsx +// ✅ Correct - Use PatternFly layout components + + + Dashboard + + + + Content + ... + + + + + + +// ❌ Wrong - Don't use utility classes for layout +
+
Dashboard
+
+``` + +**Styling priority:** + +1. Use PatternFly components (PageSection, Stack, Grid, ActionGroup) +2. Use component props (Table `borders={false}`, Button `variant="primary"`) +3. Only use utility classes when 1 & 2 don't apply + +### Class Naming (PatternFly v6) + +- **Always use `pf-v6-` prefix** for PatternFly v6 +- **Never use legacy prefixes** (`pf-v5-`, `pf-v4-`, `pf-u`, `pf-c-`) + +```css +.pf-v6-c-button /* Components */ +.pf-v6-u-m-md /* Utilities */ +.pf-v6-l-grid /* Layouts */ +``` + +### Design Tokens + +Use semantic tokens (not base tokens ending in numbers): + +```css +.custom-component { + /* ✅ Semantic tokens */ + color: var(--pf-t--global--text--color--regular); + margin: var(--pf-t--global--spacer--md); + + /* ❌ Don't use */ + color: #333333; /* hardcoded */ + color: var(--pf-t--global--text--color--100); /* base token */ + margin: 16px; /* hardcoded */ +} +``` + +### Use PatternFly Components for Typography and Icons + +```tsx +// ✅ Use PatternFly components +import { Title, Content } from "@patternfly/react-core"; +import CheckIcon from "@patternfly/react-icons/dist/esm/icons/check-icon"; + +Dashboard +Welcome message + + +// ❌ Don't use raw HTML +

Dashboard

+

Welcome message

+ +``` + +--- + +## Accessibility (WCAG 2.1 Level AA) + +PatternFly follows WCAG 2.1 Level AA and OUIA (Open UI Automation) guidelines. + +### Keyboard Navigation Requirements + +All interactive elements must support: + +- **Tab/Shift+Tab**: Focus navigation +- **Enter/Space**: Activation +- **Arrow keys**: Navigation in menus, tabs, lists +- **Escape**: Close modals/overlays + +### Focus Management + +- Never remove focus indicators without providing alternatives +- Modals must trap focus +- Return focus to trigger element when closing overlays + +### Color Contrast + +- **Normal text**: 4.5:1 minimum +- **Large text** (18pt+ or 14pt+ bold): 3:1 minimum +- **UI components**: 3:1 minimum +- Don't rely on color alone - add icons, labels, or patterns + +### Screen Readers + +- Use semantic HTML before ARIA attributes +- Add ARIA labels when text content isn't sufficient +- Test with screen readers during development + +--- + +## React and TypeScript Best Practices + +### State Management + +Keep state as local as possible: + +- **useState**: Component-specific UI state +- **useContext**: Shared state across component tree +- **useReducer**: Complex state with multiple update patterns + +### React Hooks + +- Always include proper dependency arrays (never disable `exhaustive-deps`) +- Custom hooks must start with `use` prefix +- For async in useEffect, use IIFE pattern: + ```tsx + useEffect(() => { + (async () => { + const data = await fetchData(); + setData(data); + })(); + }, []); + ``` + +### TypeScript + +- Prefer type aliases over interfaces (unless extending) +- Avoid type casting (`as any`) - use proper type definitions +- Use `as const` for literal types on constant objects/arrays + +--- + +## Testing Standards + +### Testing Philosophy + +**"The more your tests resemble the way your software is used, the more confidence they can give you."** + +- Test user behavior, not implementation details +- Use semantic queries (`getByRole`, `getByLabelText`, `getByText`) +- Don't test PatternFly components - they're already tested +- Focus on testing YOUR application logic + +### PatternFly Testing Requirements + +From [PatternFly React Testing Wiki](https://github.com/patternfly/patternfly-react/wiki/React-Testing-Library-Basics,-Best-Practices,-and-Guidelines): + +- Use `render()` for full rendering (no shallow rendering) +- Use `userEvent` for interactions (not `fireEvent`) +- Use `screen` object for queries +- Mock child components for unit tests +- Use `jest.fn()` for callback mocking + +--- + +## Common PatternFly Patterns + +### Forms + +```tsx +
+ + + + + + + +
+``` + +### Data States + +Always handle loading, error, and empty states: + +```tsx +if (isLoading) return ; +if (error) return ; +if (!data?.length) return ; +return ; +``` + +### External Links + +```tsx +import { ExternalLinkAltIcon } from "@patternfly/react-icons"; + +; +``` + +--- + +## Code Review Standards + +From PatternFly CONTRIBUTING.md: + +- Don't merge your own PRs +- Wait for CI to pass before merging +- Include Storybook/documentation links in PRs +- Use conventional commit formatting + +## Linting and Formatting + +- **ESLint**: JavaScript Standard Style +- **Prettier**: For code formatting +- Run `yarn lint --fix` before committing +- All tests must pass before PRs + +--- + +## Additional Resources + +**PatternFly Documentation:** + +- [PatternFly.org Components](https://www.patternfly.org/components) +- [PatternFly React GitHub](https://github.com/patternfly/patternfly-react) +- [PatternFly React CONTRIBUTING.md](https://github.com/patternfly/patternfly-react/blob/main/CONTRIBUTING.md) +- [PatternFly React Testing Wiki](https://github.com/patternfly/patternfly-react/wiki/React-Testing-Library-Basics,-Best-Practices,-and-Guidelines) + +**This Repository:** + +- [Component Architecture Guidelines](./.pf-ai-documentation/guidelines/component-architecture.md) +- [Styling Standards](./.pf-ai-documentation/guidelines/styling-standards.md) +- [Table Component Patterns](./.pf-ai-documentation/components/data-display/table.md) +- [Chart Integration](./.pf-ai-documentation/charts/README.md) + +--- + +## Quick Reference + +✅ **Do:** + +- Use PatternFly components for layout (PageSection, Stack, Grid) +- Use component props before utility classes +- Import base CSS before your app +- Use PatternFly v6 class prefix (`pf-v6-`) +- Use semantic design tokens +- Test user behavior, not implementation +- Follow accessibility requirements (keyboard, contrast, ARIA) + +❌ **Don't:** + +- Use utility classes for basic layout +- Use legacy class prefixes (`pf-v5-`, `pf-v4-`) +- Use hardcoded colors/spacing values +- Use raw HTML when PatternFly components exist +- Test PatternFly component internals +- Merge your own PRs + +--- + +## Sources + +This agent's guidance is derived from the following official sources: + +### PatternFly Official Documentation + +- **[PatternFly.org](https://www.patternfly.org/)** - Official PatternFly design system documentation + - Component usage patterns and API documentation + - Design token specifications + - Accessibility guidelines (WCAG 2.1 Level AA) + +- **[PatternFly React CONTRIBUTING.md](https://github.com/patternfly/patternfly-react/blob/main/CONTRIBUTING.md)** - Official contribution guidelines + - Component structure requirements (stateless functional components, PascalCase, default exports) + - Code review standards + - Linting and formatting requirements + - Commit formatting conventions + +- **[PatternFly React Testing Wiki](https://github.com/patternfly/patternfly-react/wiki/React-Testing-Library-Basics,-Best-Practices,-and-Guidelines)** - Official testing guidelines + - React Testing Library patterns + - userEvent vs fireEvent guidance + - Mock strategies for PatternFly components + - OUIA (Open UI Automation) compliance + +- **[PatternFly Get Started Guide](https://www.patternfly.org/get-started/develop)** - Setup and installation + - Supported versions (React 17/18, PatternFly v6) + - Package installation + - Base CSS import requirements + +### React Official Documentation + +- **[React Documentation](https://react.dev/learn)** - Official React best practices + - Hooks usage patterns (useState, useEffect, useReducer, useContext) + - Component composition patterns + - State management principles + - TypeScript integration + +- **[React Testing Library](https://testing-library.com/docs/react-testing-library/intro)** - Official testing library + - Testing philosophy: "Test how software is used" + - Query strategies and selector priorities + - Semantic query usage + +### This Repository + +- **[Component Architecture Guidelines](./.pf-ai-documentation/guidelines/component-architecture.md)** - Detailed component patterns +- **[Styling Standards](./.pf-ai-documentation/guidelines/styling-standards.md)** - PatternFly v6 styling rules +- **[Table Component Patterns](./.pf-ai-documentation/components/data-display/table.md)** - Table-specific usage +- **[Chart Integration](./.pf-ai-documentation/charts/README.md)** - Chart component guidance + +### Standards Organizations + +- **[WCAG 2.1 Level AA](https://www.w3.org/WAI/WCAG21/quickref/)** - Web Content Accessibility Guidelines + - Color contrast ratios (4.5:1 for normal text, 3:1 for large text/UI components) + - Keyboard navigation requirements + - Screen reader compatibility + - Focus management standards diff --git a/claude-code/plugins/pf-react/agents/test-generator.md b/claude-code/plugins/pf-react/agents/test-generator.md new file mode 100644 index 0000000..4321a15 --- /dev/null +++ b/claude-code/plugins/pf-react/agents/test-generator.md @@ -0,0 +1,560 @@ +--- +name: test-generator +description: Generate unit tests for PatternFly React components following Testing Library best practices and PatternFly testing guidelines. +model: sonnet +color: blue +--- + +# PatternFly React Test Generator + +Generate comprehensive unit tests for PatternFly React components based on: + +- [PatternFly React Testing Wiki](https://github.com/patternfly/patternfly-react/wiki/React-Testing-Library-Basics,-Best-Practices,-and-Guidelines) +- [PatternFly React CONTRIBUTING.md](https://github.com/patternfly/patternfly-react/blob/main/CONTRIBUTING.md#react-component-requirements) +- [React Testing Library](https://testing-library.com/docs/react-testing-library/intro) + +--- + +## Testing Philosophy + +**"The more your tests resemble the way your software is used, the more confidence they can give you."** + +### Core Principles + +- **Test user behavior, not implementation** - Focus on what users see and do +- **Tests should survive refactors** - Tests shouldn't break when you refactor code +- **Use semantic queries** - Query by roles, labels, and text users see +- **Don't test PatternFly components** - They're already tested. Test YOUR logic. + +### What to Test + +✅ **Test YOUR application logic:** + +- How you compose PatternFly components +- Data transformations and business logic +- Conditional rendering based on props/state +- User interactions with YOUR components +- API calls and async operations + +❌ **Don't test PatternFly internals:** + +- That a ` + + ), +})); + +describe("UserList", () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + // ... tests +}); +``` + +### What to Mock + +✅ **DO mock:** + +- API calls and external services +- Complex child components (keep mock functional, not just `
Mock
`) +- Browser APIs (localStorage, sessionStorage) + +❌ **DON'T mock:** + +- PatternFly components +- Simple presentational components +- React hooks (useState, useEffect) +- Code you're testing + +### Callback Mocking + +```typescript +const onSave = jest.fn(); + +render(); +await user.click(screen.getByRole("button", { name: "Save" })); + +expect(onSave).toHaveBeenCalledTimes(1); +expect(onSave).toHaveBeenCalledWith(expectedData); +``` + +--- + +## Testing Patterns + +### Conditional Rendering + +Test all branches: + +```typescript +describe("conditional rendering", () => { + it("shows loading spinner when fetching", () => { + render(); + expect(screen.getByRole("progressbar")).toBeInTheDocument(); + }); + + it("shows error message on failure", () => { + render(); + expect(screen.getByText(/failed to load/i)).toBeInTheDocument(); + }); + + it("shows empty state when no data", () => { + render(); + expect(screen.getByText(/no users found/i)).toBeInTheDocument(); + }); + + it("shows user list when data loaded", () => { + render(); + expect(screen.getByText(mockUsers[0].name)).toBeInTheDocument(); + }); +}); +``` + +### Async Operations + +Use `waitFor` for async assertions: + +```typescript +it("fetches and displays user data", async () => { + const mockFetch = jest.fn().mockResolvedValue(mockUser); + render(); + + await waitFor(() => { + expect(screen.getByText(mockUser.name)).toBeInTheDocument(); + }); + + expect(mockFetch).toHaveBeenCalledWith("123"); +}); +``` + +### Forms + +```typescript +it("submits form with entered data", async () => { + const onSubmit = jest.fn(); + const user = userEvent.setup(); + + render(); + + await user.type(screen.getByRole("textbox", { name: "Username" }), "alice"); + await user.type(screen.getByLabelText("Email"), "alice@example.com"); + await user.click(screen.getByRole("button", { name: "Submit" })); + + expect(onSubmit).toHaveBeenCalledWith({ + username: "alice", + email: "alice@example.com", + }); +}); +``` + +### PatternFly Tables + +```typescript +it("displays table data", () => { + render(); + + // Use role to find table + expect(screen.getByRole("grid")).toBeInTheDocument(); + + // Test YOUR data is displayed + expect(screen.getByText(mockUsers[0].name)).toBeInTheDocument(); + expect(screen.getByText(mockUsers[1].name)).toBeInTheDocument(); +}); + +it("calls onSelect when row checkbox is clicked", async () => { + const onSelect = jest.fn(); + const user = userEvent.setup(); + + render(); + + const checkbox = screen.getByRole("checkbox", { + name: `Select ${mockUsers[0].name}`, + }); + await user.click(checkbox); + + expect(onSelect).toHaveBeenCalledWith(mockUsers[0].id); +}); +``` + +### PatternFly Modals + +```typescript +it("opens modal when button is clicked", async () => { + const user = userEvent.setup(); + render(); + + await user.click(screen.getByRole("button", { name: "Edit" })); + + expect(screen.getByRole("dialog")).toBeInTheDocument(); +}); + +it("closes modal on escape key", async () => { + const onClose = jest.fn(); + const user = userEvent.setup(); + + render(); + + await user.keyboard("{Escape}"); + expect(onClose).toHaveBeenCalled(); +}); +``` + +### Accessibility + +```typescript +describe("accessibility", () => { + it("has proper ARIA labels", () => { + render(); + expect( + screen.getByRole("button", { name: "Delete User Report" }) + ).toBeInTheDocument(); + }); + + it("supports keyboard navigation", async () => { + const user = userEvent.setup(); + render(); + + await user.tab(); + expect(screen.getByRole("menuitem", { name: "Dashboard" })).toHaveFocus(); + }); +}); +``` + +--- + +## Complete Example + +```typescript +import { describe, expect, it, beforeEach } from "@jest/globals"; +import { render, screen, waitFor } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { UserManagementPage } from "./UserManagementPage"; +import { fetchUsers, deleteUser } from "../api/users"; + +jest.mock("../api/users"); + +const mockUsers = [ + { id: "1", name: "Alice", email: "alice@example.com", role: "Admin" }, + { id: "2", name: "Bob", email: "bob@example.com", role: "User" }, +]; + +describe("UserManagementPage", () => { + beforeEach(() => { + jest.clearAllMocks(); + (fetchUsers as jest.Mock).mockResolvedValue(mockUsers); + }); + + describe("rendering", () => { + it("renders page title", () => { + render(); + expect( + screen.getByRole("heading", { name: "User Management" }) + ).toBeInTheDocument(); + }); + + it("fetches and displays users", async () => { + render(); + + await waitFor(() => { + expect(screen.getByText("Alice")).toBeInTheDocument(); + expect(screen.getByText("Bob")).toBeInTheDocument(); + }); + }); + }); + + describe("user interactions", () => { + it("deletes user when confirmed", async () => { + (deleteUser as jest.Mock).mockResolvedValue({}); + const user = userEvent.setup(); + + render(); + await waitFor(() => screen.getByText("Alice")); + + // Click delete button + await user.click(screen.getAllByRole("button", { name: /delete/i })[0]); + + // Confirm in modal + await user.click(screen.getByRole("button", { name: "Confirm" })); + + expect(deleteUser).toHaveBeenCalledWith("1"); + }); + }); + + describe("conditional rendering", () => { + it("shows loading state while fetching", () => { + (fetchUsers as jest.Mock).mockImplementation( + () => new Promise(() => {}) + ); + render(); + + expect(screen.getByRole("progressbar")).toBeInTheDocument(); + }); + + it("shows error state on failure", async () => { + (fetchUsers as jest.Mock).mockRejectedValue(new Error("Network error")); + render(); + + await waitFor(() => { + expect(screen.getByText(/error loading users/i)).toBeInTheDocument(); + }); + }); + + it("shows empty state when no users", async () => { + (fetchUsers as jest.Mock).mockResolvedValue([]); + render(); + + await waitFor(() => { + expect(screen.getByText(/no users found/i)).toBeInTheDocument(); + }); + }); + }); +}); +``` + +--- + +## Key Reminders + +✅ **Do:** + +- Use `userEvent` for interactions +- Use `getByRole` as first choice for queries +- Use `waitFor` for async assertions +- Mock child components when unit testing +- Test all conditional rendering branches +- Test YOUR logic, not PatternFly components + +❌ **Don't:** + +- Use `fireEvent` for user interactions +- Use array indexing or class selectors +- Test PatternFly component internals +- Test implementation details +- Use arbitrary timeouts instead of `waitFor` + +--- + +## Sources + +This agent's testing guidance is derived from the following official sources: + +### Testing Library Official Documentation + +- **[React Testing Library](https://testing-library.com/docs/react-testing-library/intro)** - Official React Testing Library docs + - Core testing philosophy: "The more your tests resemble the way your software is used, the more confidence they can give you" + - Testing principles: test behavior not implementation, avoid testing implementation details + - Use of `render()`, `screen`, and `waitFor` utilities + - Guidance on userEvent for realistic user interactions + +- **[Testing Library Queries](https://testing-library.com/docs/queries/about)** - Query priority and selector strategies + - Complete query priority order (getByRole → getByLabelText → getByPlaceholderText → getByText → getByDisplayValue → getByAltText → getByTitle → getByTestId) + - Accessibility-focused query selection + - When to use each query type + - Avoiding fragile selectors (array indexing, class names) + +### PatternFly Official Documentation + +- **[PatternFly React Testing Wiki](https://github.com/patternfly/patternfly-react/wiki/React-Testing-Library-Basics,-Best-Practices,-and-Guidelines)** - PatternFly-specific testing patterns + - userEvent vs fireEvent (always use userEvent) + - Use of `screen` object for queries + - Mock strategies for unit testing + - Child component mocking patterns + - jest.fn() for callback testing + +- **[PatternFly React CONTRIBUTING.md](https://github.com/patternfly/patternfly-react/blob/main/CONTRIBUTING.md#react-component-requirements)** - Component testing requirements + - Jest snapshot testing requirements + - Component structure expectations + - Test organization patterns + - beforeEach cleanup patterns (jest.clearAllMocks) + +### React Official Documentation + +- **[React Documentation](https://react.dev/learn)** - React patterns and best practices + - Component structure and hooks + - State management patterns being tested + - Event handling patterns + - Async patterns and useEffect usage + +### Jest Documentation + +- **[Jest](https://jestjs.io/)** - Testing framework + - Mock function creation (jest.fn()) + - Mock module patterns (jest.mock()) + - Assertion matchers (toHaveBeenCalledWith, toBeInTheDocument) + - beforeEach/describe test organization diff --git a/claude-code/plugins/pf-react/commands/coding-standards.md b/claude-code/plugins/pf-react/commands/coding-standards.md new file mode 100644 index 0000000..f523044 --- /dev/null +++ b/claude-code/plugins/pf-react/commands/coding-standards.md @@ -0,0 +1,5 @@ +--- +description: Load PatternFly React coding standards and best practices agent +--- + +Please use the coding-standards agent for this task. diff --git a/claude-code/plugins/pf-react/commands/test-generator.md b/claude-code/plugins/pf-react/commands/test-generator.md new file mode 100644 index 0000000..d26e347 --- /dev/null +++ b/claude-code/plugins/pf-react/commands/test-generator.md @@ -0,0 +1,5 @@ +--- +description: Generate comprehensive unit tests for PatternFly React components +--- + +Please use the test-generator agent to create comprehensive unit tests for PatternFly React components.