import { test, expect } from '@playwright/test'; // These E2E tests run against the dev server (vite on :5173) which proxies // /api to the backend. Set E2E_BASE_URL to point at a different deployment. // // A live backend (and Postgres) must be reachable. Routes mock the network // where possible to keep journeys deterministic. test('home page renders the Mangalord heading and search input', async ({ page }) => { // Mock the list endpoint so the test doesn't depend on DB state. await page.route('**/api/mangas*', async (route) => { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify([]) }); }); await page.goto('/'); await expect(page.getByRole('link', { name: 'Mangalord' })).toBeVisible(); await expect(page.getByTestId('search-input')).toBeVisible(); await expect(page.getByTestId('empty')).toContainText('No mangas yet'); }); test('search updates the manga list', async ({ page }) => { let lastSearch: string | null = null; await page.route('**/api/mangas*', async (route) => { const url = new URL(route.request().url()); lastSearch = url.searchParams.get('search'); const body = lastSearch === 'berserk' ? [ { id: 'b1', title: 'Berserk', author: 'Kentaro Miura', description: null, cover_image_path: null, created_at: '2026-01-01T00:00:00Z', updated_at: '2026-01-01T00:00:00Z' } ] : []; await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(body) }); }); await page.goto('/'); await page.getByTestId('search-input').fill('berserk'); await page.getByRole('button', { name: 'Search' }).click(); await expect(page.getByTestId('manga-list')).toContainText('Berserk'); expect(lastSearch).toBe('berserk'); });