diff --git a/package.json b/package.json index 89d9182..68ee688 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,10 @@ }, "devDependencies": { "@eslint/js": "^10.0.1", + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.2", + "@testing-library/user-event": "^14.6.1", + "@types/jsdom": "^28.0.3", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", "eslint": "^10.2.1", @@ -40,6 +44,7 @@ "eslint-plugin-react-refresh": "^0.5.2", "globals": "^17.5.0", "husky": "^9.1.7", + "jsdom": "^29.1.1", "lint-staged": "^16.4.0", "prettier": "^3.8.3", "typescript-eslint": "^8.58.2", diff --git a/src/components/ui/Button.test.tsx b/src/components/ui/Button.test.tsx new file mode 100644 index 0000000..f536318 --- /dev/null +++ b/src/components/ui/Button.test.tsx @@ -0,0 +1,16 @@ +import { render, screen } from '@testing-library/react'; +import { Button } from './Button'; +import { describe, it, expect } from 'vitest'; + +describe('Button component', () => { + it('renders children correctly', () => { + render(); + expect(screen.getByText('Click Me')).toBeInTheDocument(); + }); + + it('shows loading state when loading prop is true', () => { + render(); + expect(screen.getByText('⏳')).toBeInTheDocument(); + expect(screen.getByRole('button')).toBeDisabled(); + }); +}); diff --git a/src/test/setup.ts b/src/test/setup.ts new file mode 100644 index 0000000..7b0828b --- /dev/null +++ b/src/test/setup.ts @@ -0,0 +1 @@ +import '@testing-library/jest-dom'; diff --git a/vite.config.ts b/vite.config.ts index 0e77097..80a6bac 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,4 +1,4 @@ -import { defineConfig } from 'vite'; +import { defineConfig } from 'vitest/config'; import react from '@vitejs/plugin-react'; import tailwindcss from '@tailwindcss/vite'; import path from 'path'; @@ -14,4 +14,9 @@ export default defineConfig({ port: 5173, open: true, }, + test: { + environment: 'jsdom', + setupFiles: ['./src/test/setup.ts'], + globals: true, + }, });