import { test, expect, type Page } from '@playwright/test'; import { SORT_FIELD_LABELS } from '../src/lib/mangaSort'; // These E2E tests run against the SvelteKit dev server, which proxies /api // to the backend. Playwright starts vite via `webServer` (see // playwright.config.ts) unless E2E_BASE_URL points at a different deployment. // // Routes are mocked at the page level so the journeys are deterministic and // don't require a live backend. const emptyPage = { items: [], page: { limit: 50, offset: 0, total: null } }; async function mockAnonymous(page: Page) { // Force public mode so the root +layout.ts doesn't bounce us to /login // (a dev backend with PRIVATE_MODE=true must not leak into E2E runs). await page.route('**/api/v1/auth/config', async (route) => { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ self_register_enabled: true, private_mode: false }) }); }); await page.route('**/api/v1/auth/me', async (route) => { await route.fulfill({ status: 401, contentType: 'application/json', body: JSON.stringify({ error: { code: 'unauthenticated', message: 'unauthenticated' } }) }); }); } test('home page renders the Mangalord heading and search input', async ({ page }) => { await mockAnonymous(page); await page.route('**/api/v1/mangas*', async (route) => { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(emptyPage) }); }); 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'); }); // Anti-drift guard: the desktop sort