Loading...
Loading...
> Comprehensive testing with Vitest for unit tests and Playwright for E2E tests.
130+ tests included. Vitest for unit tests, Playwright for E2E, and axe-core for accessibility.
DESC: Execute all Vitest unit tests
1$npm test
DESC: Execute Playwright tests
1$npm run test:e2e
DESC: Execute both unit and E2E tests
1$npm run test:all
Available test commands
1$# Unit tests (Vitest)2$npm test # Run all unit tests3$npm run test:watch # Watch mode4$npm run test:coverage # Generate coverage report5$npm run test:ui # Open Vitest UI67$# E2E tests (Playwright)8$npm run test:e2e # Run all E2E tests9$npm run test:e2e:ui # Open Playwright UI10$npm run test:e2e:headed # Run with visible browser1112$# Accessibility tests13$npm run test:a11y # Run accessibility tests1415$# All tests16$npm run test:all # Run Vitest + Playwright
Test components, hooks, and utilities
1// tests/unit/components/button.test.tsx2import { render, screen, fireEvent } from "@testing-library/react";3import { describe, it, expect, vi } from "vitest";4import { Button } from "@/components/ui/button";56describe("Button", () => {7 it("renders with correct text", () => {8 render(<Button>Click me</Button>);9 expect(screen.getByRole("button")).toHaveTextContent("Click me");10 });1112 it("calls onClick when clicked", () => {13 const onClick = vi.fn();14 render(<Button onClick={onClick}>Click me</Button>);1516 fireEvent.click(screen.getByRole("button"));17 expect(onClick).toHaveBeenCalledTimes(1);18 });1920 it("is disabled when disabled prop is true", () => {21 render(<Button disabled>Click me</Button>);22 expect(screen.getByRole("button")).toBeDisabled();23 });24});
Example hook test with timer mocking
1// tests/unit/hooks/use-debounce.test.ts2import { renderHook, act } from "@testing-library/react";3import { describe, it, expect, vi } from "vitest";4import { useDebounce } from "@/hooks/use-debounce";56describe("useDebounce", () => {7 beforeEach(() => {8 vi.useFakeTimers();9 });1011 afterEach(() => {12 vi.useRealTimers();13 });1415 it("debounces value changes", () => {16 const { result, rerender } = renderHook(17 ({ value, delay }) => useDebounce(value, delay),18 { initialProps: { value: "initial", delay: 500 } }19 );2021 rerender({ value: "updated", delay: 500 });22 expect(result.current).toBe("initial");2324 act(() => {25 vi.advanceTimersByTime(500);26 });2728 expect(result.current).toBe("updated");29 });30});
Test complete user flows
1// tests/e2e/auth.spec.ts2import { test, expect } from "@playwright/test";34test.describe("Authentication", () => {5 test("user can sign up", async ({ page }) => {6 await page.goto("/signup");78 await page.fill('input[name="email"]', "test@example.com");9 await page.fill('input[name="password"]', "SecurePass123!");10 await page.fill('input[name="name"]', "Test User");1112 await page.click('button[type="submit"]');1314 await expect(page).toHaveURL(/dashboard|verify/);15 });1617 test("user can sign in", async ({ page }) => {18 await page.goto("/signin");1920 await page.fill('input[name="email"]', "existing@example.com");21 await page.fill('input[name="password"]', "password123");2223 await page.click('button[type="submit"]');2425 await expect(page).toHaveURL("/dashboard");26 });27});
Test for a11y violations
1// tests/accessibility/home.spec.ts2import { test, expect } from "@playwright/test";3import AxeBuilder from "@axe-core/playwright";45test.describe("Accessibility", () => {6 test("home page has no a11y violations", async ({ page }) => {7 await page.goto("/");89 const results = await new AxeBuilder({ page }).analyze();1011 expect(results.violations).toEqual([]);12 });13});
GitHub Actions workflow for automated testing
1# .github/workflows/test.yml2name: Tests34on: [push, pull_request]56jobs:7 test:8 runs-on: ubuntu-latest910 steps:11 - uses: actions/checkout@v41213 - name: Setup Node.js14 uses: actions/setup-node@v415 with:16 node-version: "20"17 cache: "npm"1819 - name: Install dependencies20 run: npm ci2122 - name: Run unit tests23 run: npm test2425 - name: Install Playwright26 run: npx playwright install --with-deps2728 - name: Run E2E tests29 run: npm run test:e2e