test(e2e): realign mocks + assertions with the current API and OCR-era UI
The route-mocked E2E specs had drifted from the app they exercise, so
each rendered an empty/500 page and timed out on missing elements:
- Manga detail + reader loads now also fetch read-progress/{id} and
/similar; several specs never mocked them, so the load's Promise.all
rejected. Add the mocks and fill the manga fixtures out to a real
MangaDetail (status/alt_titles/authors/genres/tags/... ) so the
components stop throwing mid-render.
- back-nav + library: widen `read-progress*`/`page-tags` globs — `*`
doesn't cross `/`, so `/me/read-progress/{id}` fell through to the
proxy and 500'd; mock the library page-tags pair too.
- manga-list search: wait for the initial load to settle before
searching so the search fetch can't race the mount-time load.
- reader-chapter-select: assert the shared `chapterLabel` output.
- admin-analysis: the active OCR backend extracts text only, so the
detail modal shows OCR (no tags/NSFW) and metrics shows tiles +
trend charts (no by-model) — assert what the OCR-era UI renders.
- profile: assert the wrong-password 401 stays inline (guards the
fix in the preceding commit) and mock the guest bookmark/collection
fetches the /profile load maps to the sign-in prompt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,14 +2,23 @@ import { test, expect, type Page } from '@playwright/test';
|
||||
|
||||
const mangaId = '11111111-1111-1111-1111-111111111111';
|
||||
const chapterId = 'c1111111-1111-1111-1111-111111111111';
|
||||
// A faithful `MangaDetail` (GET /v1/mangas/:id) — the detail page reads
|
||||
// authors/genres/tags/alt_titles/content_warnings, so a minimal shape makes
|
||||
// the component throw mid-render and nothing paints.
|
||||
const mangaFixture = {
|
||||
id: mangaId,
|
||||
title: 'Berserk',
|
||||
author: 'Kentaro Miura',
|
||||
status: 'ongoing',
|
||||
alt_titles: [],
|
||||
description: 'A dark fantasy.',
|
||||
cover_image_path: 'mangas/11111111-1111-1111-1111-111111111111/cover.png',
|
||||
created_at: '2026-01-01T00:00:00Z',
|
||||
updated_at: '2026-01-01T00:00:00Z'
|
||||
updated_at: '2026-01-01T00:00:00Z',
|
||||
authors: [{ id: 'a1111111-1111-1111-1111-111111111111', name: 'Kentaro Miura' }],
|
||||
genres: [],
|
||||
tags: [],
|
||||
content_warnings: [],
|
||||
chapter_storage_bytes: 0
|
||||
};
|
||||
const chaptersFixture = [
|
||||
{
|
||||
@@ -103,6 +112,24 @@ async function mockReaderApis(page: Page) {
|
||||
body: JSON.stringify({ pages: pagesFixture })
|
||||
})
|
||||
);
|
||||
// Guest: no saved read position. The manga-detail + reader loads both
|
||||
// call this; a 401 maps to `null` in getMyReadProgressForManga, matching
|
||||
// a real unauthenticated request.
|
||||
await page.route(`**/api/v1/me/read-progress/${mangaId}`, (route) =>
|
||||
route.fulfill({
|
||||
status: 401,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify({ error: { code: 'unauthenticated', message: 'unauthenticated' } })
|
||||
})
|
||||
);
|
||||
// Recommendations: a real `{ items }` top-N (empty is a valid result).
|
||||
await page.route(`**/api/v1/mangas/${mangaId}/similar`, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify({ items: [] })
|
||||
})
|
||||
);
|
||||
// Stub image bytes so the <img> doesn't 404 (1x1 transparent PNG).
|
||||
const png = Buffer.from(
|
||||
'89504e470d0a1a0a0000000d49484452000000010000000108060000001f15c4890000000d49444154789c63000100000005000158a3b62a0000000049454e44ae426082',
|
||||
@@ -118,7 +145,7 @@ test('manga overview shows title, cover, and a chapter list', async ({ page }) =
|
||||
await page.goto(`/manga/${mangaId}`);
|
||||
|
||||
await expect(page.getByTestId('manga-title')).toHaveText('Berserk');
|
||||
await expect(page.getByTestId('manga-author')).toContainText('Kentaro Miura');
|
||||
await expect(page.getByTestId('manga-authors')).toContainText('Kentaro Miura');
|
||||
await expect(page.getByTestId('manga-cover')).toBeVisible();
|
||||
await expect(page.getByTestId('chapter-list')).toContainText('The Brand');
|
||||
await expect(page.getByTestId('bookmark-signin')).toBeVisible();
|
||||
|
||||
Reference in New Issue
Block a user