test: cover constrained character dom
This commit is contained in:
parent
5219bc4588
commit
b0f475d850
@ -52,6 +52,8 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned wi
|
|||||||
prose after malformed LLM JSON, clamping caller timeouts, and bounding upstream error text.
|
prose after malformed LLM JSON, clamping caller timeouts, and bounding upstream error text.
|
||||||
- **Unified Provider Retries.** TTS and LLM provider requests now retry bounded connection, timeout, and transient HTTP
|
- **Unified Provider Retries.** TTS and LLM provider requests now retry bounded connection, timeout, and transient HTTP
|
||||||
failures with exponential backoff while closing discarded responses.
|
failures with exponential backoff while closing discarded responses.
|
||||||
|
- **Constrained DOM Coverage.** Added a 250-character browser fixture proving character-library rendering stays within
|
||||||
|
the configured 50-row page and expands only on explicit user action.
|
||||||
- **4 GiB Container Validation.** Verified the current image serves the application under a hard 4 GiB cgroup limit
|
- **4 GiB Container Validation.** Verified the current image serves the application under a hard 4 GiB cgroup limit
|
||||||
with no OOM kill; the probe recorded approximately 50.6 MiB idle memory and 0.09% CPU.
|
with no OOM kill; the probe recorded approximately 50.6 MiB idle memory and 0.09% CPU.
|
||||||
- **Profile Completeness Coverage.** Added browser regression coverage for empty, partial, and fully populated
|
- **Profile Completeness Coverage.** Added browser regression coverage for empty, partial, and fully populated
|
||||||
|
|||||||
3
TODO.md
3
TODO.md
@ -115,7 +115,8 @@ the first block before investing in architecture or polish.
|
|||||||
## P1 — Frontend performance and memory safety
|
## P1 — Frontend performance and memory safety
|
||||||
|
|
||||||
- [ ] Lazy-load Audiobook, Rehearser, Studio, and image-generation modules only when opened.
|
- [ ] Lazy-load Audiobook, Rehearser, Studio, and image-generation modules only when opened.
|
||||||
- [ ] Virtualize or paginate large character and voice tables; render approximately 30–50 visible rows.
|
- [x] Paginate large character and voice tables; render approximately 25–50 visible rows, with a constrained-device
|
||||||
|
regression covering a 250-character production.
|
||||||
- [ ] Cache `/api/voices` with explicit invalidation instead of repeated full scans.
|
- [ ] Cache `/api/voices` with explicit invalidation instead of repeated full scans.
|
||||||
- [x] Lazy-load profile images and concept art.
|
- [x] Lazy-load profile images and concept art.
|
||||||
- [ ] Update only affected table rows instead of rebuilding entire tables.
|
- [ ] Update only affected table rows instead of rebuilding entire tables.
|
||||||
|
|||||||
@ -20,3 +20,22 @@ test('4 GB browser profile caps shared batch concurrency at two', async ({ page
|
|||||||
});
|
});
|
||||||
expect(maxActive).toBeLessThanOrEqual(2);
|
expect(maxActive).toBeLessThanOrEqual(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('large character productions keep the rendered DOM paginated', async ({ page }) => {
|
||||||
|
const characters = Array.from({ length: 250 }, (_, index) => ({
|
||||||
|
id: 'large-' + index, book: 'Large Smoke Book', name: 'Character ' + index,
|
||||||
|
tags: '', voice: null, sheet: { gender: index % 2 ? 'F' : 'M' },
|
||||||
|
}));
|
||||||
|
await page.route('**/api/characters*', route => route.fulfill({ json: { characters } }));
|
||||||
|
await page.route('**/api/voices*', route => route.fulfill({ json: [] }));
|
||||||
|
await page.route('**/api/settings*', route => route.fulfill({ json: {} }));
|
||||||
|
await page.goto('/', { waitUntil: 'domcontentloaded' });
|
||||||
|
await page.waitForFunction(() => typeof window.libraryRenderCharacters === 'function', null, { timeout: 15_000 });
|
||||||
|
await page.waitForSelector('#lib-chars-list', { state: 'attached', timeout: 15_000 });
|
||||||
|
await page.waitForSelector('#app-skeleton', { state: 'detached', timeout: 15_000 });
|
||||||
|
await page.evaluate(() => window.navTo('s-library'));
|
||||||
|
await page.locator('.lib-tab[data-library-view="characters"]').click();
|
||||||
|
await expect.poll(() => page.locator('#lib-chars-list .lib-char-card').count()).toBeLessThanOrEqual(50);
|
||||||
|
await page.locator('#lib-chars-list .lib-chars-load-more').click();
|
||||||
|
await expect.poll(() => page.locator('#lib-chars-list .lib-char-card').count()).toBeLessThanOrEqual(100);
|
||||||
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user