Adds Playwright E2E and Vitest test infrastructure
Some checks failed
Lint / Lint and Check (push) Failing after 48s
Some checks failed
Lint / Lint and Check (push) Failing after 48s
Integrates Playwright for end-to-end browser testing with automated web server setup, example smoke tests, and CI-compatible configuration. Introduces Vitest, Testing Library, and related utilities for fast component and unit testing. Updates scripts, development dependencies, and lockfile to support both test suites. Establishes unified testing commands for local and CI workflows, laying groundwork for comprehensive automated UI and integration coverage.
This commit is contained in:
120
app/dashboard/page.test.tsx
Normal file
120
app/dashboard/page.test.tsx
Normal file
@@ -0,0 +1,120 @@
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import Dashboard from './page';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
|
||||
// Mock next/navigation
|
||||
vi.mock('next/navigation', () => ({
|
||||
useRouter: () => ({
|
||||
push: vi.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
// Mock ResizeObserver
|
||||
global.ResizeObserver = class ResizeObserver {
|
||||
observe() {}
|
||||
unobserve() {}
|
||||
disconnect() {}
|
||||
};
|
||||
|
||||
// Mock fetch
|
||||
global.fetch = vi.fn();
|
||||
|
||||
const createTestQueryClient = () => new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
retry: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
describe('Dashboard', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
|
||||
// Mock Auth Response
|
||||
(global.fetch as any).mockImplementation((url: string) => {
|
||||
if (url === '/api/auth') {
|
||||
return Promise.resolve({
|
||||
json: () => Promise.resolve({ authenticated: true, token: 'test-token' }),
|
||||
});
|
||||
}
|
||||
if (url === '/api/habits') {
|
||||
return Promise.resolve({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({
|
||||
habits: [
|
||||
{
|
||||
id: 1,
|
||||
name: 'Test Habit',
|
||||
type: 'neutral',
|
||||
totalLogs: 5,
|
||||
logsLastWeek: 2,
|
||||
logsLastMonth: 5,
|
||||
createdAt: new Date().toISOString(),
|
||||
lastLoggedAt: new Date().toISOString(),
|
||||
}
|
||||
]
|
||||
}),
|
||||
});
|
||||
}
|
||||
return Promise.resolve({ ok: true, json: () => Promise.resolve({}) });
|
||||
});
|
||||
});
|
||||
|
||||
it('renders habits correctly', async () => {
|
||||
render(
|
||||
<QueryClientProvider client={createTestQueryClient()}>
|
||||
<Dashboard />
|
||||
</QueryClientProvider>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Test Habit')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('opens edit dialog when edit button is clicked', async () => {
|
||||
render(
|
||||
<QueryClientProvider client={createTestQueryClient()}>
|
||||
<Dashboard />
|
||||
</QueryClientProvider>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Test Habit')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const editBtn = screen.getByTestId('edit-habit-1');
|
||||
fireEvent.click(editBtn);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
||||
expect(screen.getByText('Edit Habit')).toBeInTheDocument();
|
||||
expect(screen.getByDisplayValue('Test Habit')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('opens archive confirmation when archive button is clicked', async () => {
|
||||
render(
|
||||
<QueryClientProvider client={createTestQueryClient()}>
|
||||
<Dashboard />
|
||||
</QueryClientProvider>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Test Habit')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Open Edit Dialog
|
||||
fireEvent.click(screen.getByTestId('edit-habit-1'));
|
||||
await waitFor(() => screen.getByRole('dialog'));
|
||||
|
||||
// Click Archive
|
||||
fireEvent.click(screen.getByText('Archive Habit'));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Confirm Delete')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user