WellNuo/admin/components/ui/__tests__/Button.test.tsx
Sergei 4b60a92777 Add basic UI components for web application
- Set up Tailwind CSS configuration for styling
- Create Button component with variants (primary, secondary, outline, ghost, danger)
- Create Input component with label, error, and helper text support
- Create Card component with composable subcomponents (Header, Title, Description, Content, Footer)
- Create LoadingSpinner component with size and fullscreen options
- Create ErrorMessage component with retry and dismiss actions
- Add comprehensive test suite using Jest and React Testing Library
- Configure ESLint and Jest for quality assurance

All components follow consistent design patterns from mobile app
and include proper TypeScript types and accessibility features.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-31 18:11:31 -08:00

95 lines
3.0 KiB
TypeScript

import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { Button } from '../Button';
describe('Button', () => {
it('renders children correctly', () => {
render(<Button>Click me</Button>);
expect(screen.getByText('Click me')).toBeInTheDocument();
});
it('applies primary variant by default', () => {
render(<Button>Primary</Button>);
const button = screen.getByRole('button');
expect(button).toHaveClass('bg-primary');
});
it('applies secondary variant when specified', () => {
render(<Button variant="secondary">Secondary</Button>);
const button = screen.getByRole('button');
expect(button).toHaveClass('bg-secondary');
});
it('applies outline variant when specified', () => {
render(<Button variant="outline">Outline</Button>);
const button = screen.getByRole('button');
expect(button).toHaveClass('border-2');
expect(button).toHaveClass('border-primary');
});
it('applies danger variant when specified', () => {
render(<Button variant="danger">Danger</Button>);
const button = screen.getByRole('button');
expect(button).toHaveClass('bg-error');
});
it('applies small size correctly', () => {
render(<Button size="sm">Small</Button>);
const button = screen.getByRole('button');
expect(button).toHaveClass('px-3');
expect(button).toHaveClass('py-1.5');
});
it('applies large size correctly', () => {
render(<Button size="lg">Large</Button>);
const button = screen.getByRole('button');
expect(button).toHaveClass('px-6');
expect(button).toHaveClass('py-3');
});
it('applies full width when specified', () => {
render(<Button fullWidth>Full Width</Button>);
const button = screen.getByRole('button');
expect(button).toHaveClass('w-full');
});
it('disables button when disabled prop is true', () => {
render(<Button disabled>Disabled</Button>);
const button = screen.getByRole('button');
expect(button).toBeDisabled();
});
it('shows loading spinner when loading', () => {
render(<Button loading>Loading</Button>);
const button = screen.getByRole('button');
expect(button).toBeDisabled();
expect(button.querySelector('svg')).toBeInTheDocument();
});
it('calls onClick when clicked', () => {
const handleClick = jest.fn();
render(<Button onClick={handleClick}>Click me</Button>);
const button = screen.getByRole('button');
fireEvent.click(button);
expect(handleClick).toHaveBeenCalledTimes(1);
});
it('does not call onClick when disabled', () => {
const handleClick = jest.fn();
render(
<Button disabled onClick={handleClick}>
Disabled
</Button>
);
const button = screen.getByRole('button');
fireEvent.click(button);
expect(handleClick).not.toHaveBeenCalled();
});
it('applies custom className', () => {
render(<Button className="custom-class">Custom</Button>);
const button = screen.getByRole('button');
expect(button).toHaveClass('custom-class');
});
});