-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Agent Name
pf-rtl-interact-test
Problem It Solves
This slash command - agent is used to help write unit / behavior tests.
Agent Markdown
`---
description: Generate React Testing Library tests focused on user interactions and snapshots
argument-hint: [component-file-path]
Generate comprehensive React Testing Library tests focused on user interactions and snapshots for the component at: $ARGUMENTS
Your Task
-
Read and analyze the component file to identify:
- Interactive elements (buttons, inputs, forms, toggles, etc.)
- Event handlers (onClick, onKeyDown, onChange, onSubmit, etc.)
- Props that control behavior
- State changes triggered by user actions
- Conditional rendering based on interactions
-
Generate test file in a
__tests__/directory next to the component- File naming: If component is
Button.tsx, create__tests__/Button.test.tsx - If
__tests__/doesn't exist, create it
- File naming: If component is
-
Write interaction-focused tests following these patterns:
Test Structure
import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { ComponentName } from '../ComponentName';
describe('ComponentName', () => {
test('descriptive test name', async () => {
const user = userEvent.setup();
const mockCallback = jest.fn();
render(<ComponentName onSomeEvent={mockCallback} />);
await user.click(screen.getByRole('button', { name: 'Label' }));
expect(mockCallback).toHaveBeenCalledWith(expectedArgs);
});
});Test Categories to Generate
1. Click Interactions
- Test all clickable elements (buttons, links, toggles)
- Verify callbacks are invoked with correct arguments
- Test state changes after clicks
- Test multiple click sequences
2. Keyboard Interactions
- Test Enter key on interactive elements
- Test Escape key for closing/canceling
- Test Tab navigation
- Test Arrow keys for navigation/selection
- Test Space for toggles/checkboxes
- Verify keyboard callbacks
3. Form Interactions
- Test typing in input fields
- Test form submissions
- Test field validation
- Test clearing fields
- Test select/dropdown changes
4. State-Dependent Interactions
- Test interactions when component is in different states
- Test disabled state (interactions should not work)
- Test expanded/collapsed states
- Test selected/unselected states
5. Accessibility in Interactions
- Verify ARIA attributes change correctly (aria-expanded, aria-pressed, etc.)
- Test accessible names remain correct
- Verify focus management
- Test screen reader announcements (aria-live)
6. Snapshot Tests
- Always place snapshot tests at the end of the test file (after all interaction tests)
- Snapshots serve as regression detection, not primary tests
- Use
const { asFragment } = render(...)pattern - Use
toMatchSnapshot()with external snapshot files - For simple components: Single snapshot with representative props
- For complex components: Multiple snapshots for different states (default, expanded, disabled, etc.)
- Use descriptive test names: "matches snapshot" or "renders [state] snapshot"
Code Quality Standards
Always:
- Use
userEvent.setup()at the start of each test - Use
awaitwith all user events (user.click(),user.type(), etc.) - Use
screenqueries (not destructured queries) - Use semantic queries:
getByRole,getByLabelText,getByPlaceholderText - Create mock functions with
jest.fn()for callbacks - Use descriptive test names that explain the behavior being tested
- Group related tests in
describeblocks
Avoid:
- Direct DOM manipulation
- Testing implementation details
- Testing props directly (test behavior instead)
- Synchronous user interactions (always use
await)
Example Patterns
Testing a click callback:
test('calls onClick handler when button is clicked', async () => {
const user = userEvent.setup();
const onClick = jest.fn();
render(<Button onClick={onClick}>Click me</Button>);
await user.click(screen.getByRole('button', { name: 'Click me' }));
expect(onClick).toHaveBeenCalledTimes(1);
});Testing keyboard interaction:
test('closes modal when Escape key is pressed', async () => {
const user = userEvent.setup();
const onClose = jest.fn();
render(<Modal isOpen onClose={onClose} />);
await user.keyboard('{Escape}');
expect(onClose).toHaveBeenCalled();
});Testing form input:
test('calls onChange when user types in input', async () => {
const user = userEvent.setup();
const onChange = jest.fn();
render(<Input onChange={onChange} />);
const input = screen.getByRole('textbox');
await user.type(input, 'Hello');
expect(onChange).toHaveBeenCalledTimes(5); // once per character
});Testing state changes:
test('toggles expanded state when toggle button is clicked', async () => {
const user = userEvent.setup();
render(<Accordion />);
const toggle = screen.getByRole('button', { name: 'Toggle section' });
expect(toggle).toHaveAttribute('aria-expanded', 'false');
await user.click(toggle);
expect(toggle).toHaveAttribute('aria-expanded', 'true');
});Testing with snapshots (simple component - single snapshot):
// All interaction tests above...
// Snapshot test at the very end
test('matches snapshot', () => {
const { asFragment } = render(
<Button variant="primary" onClick={jest.fn()}>
Click me
</Button>
);
expect(asFragment()).toMatchSnapshot();
});Testing with snapshots (complex component - multiple states):
// All interaction tests above...
// Multiple snapshots for different states
test('renders default state snapshot', () => {
const { asFragment } = render(<Accordion>Content</Accordion>);
expect(asFragment()).toMatchSnapshot();
});
test('renders expanded state snapshot', () => {
const { asFragment } = render(<Accordion isExpanded>Content</Accordion>);
expect(asFragment()).toMatchSnapshot();
});
test('renders disabled state snapshot', () => {
const { asFragment } = render(<Accordion isDisabled>Content</Accordion>);
expect(asFragment()).toMatchSnapshot();
});Output Requirements
- Create the test file in the appropriate location
- Include all necessary imports
- Generate 5-15 interaction tests covering the main interactive behaviors
- Add 1-3 snapshot tests at the end (simple components: 1 snapshot, complex components: 2-3 snapshots for different states)
- Include helpful comments for complex test setups
- Ensure tests are independent and can run in any order
- Follow existing code style in the project
After generating the tests, provide a summary of:
- How many tests were created (interaction tests + snapshot tests)
- What interactions are covered
- What states are captured in snapshots
- Any additional tests that might be beneficial to add manually
`
Testing Notes (Optional)
Use /pf-rtl-interact-test path/to/Component.tsx in any project on your system
Tested on: user feedback repo (patternfly/react-user-feedback#97)
What worked: Creation of unit tests for user feedback for a single component.
What needs improvement: Could add ability to work on multiple components.
Edge cases or limitations: