test: validate throttled desktop navigation

This commit is contained in:
mARTin-B78 2026-09-04 09:49:57 +02:00
parent 690673625d
commit e18bc6a8cc
4 changed files with 29 additions and 3 deletions

View File

@ -8,6 +8,8 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned wi
## [Unreleased] ## [Unreleased]
### Added ### Added
- **Throttled Desktop Smoke Coverage.** Chromium CDP now exercises app navigation at 4× CPU throttling and
asserts bounded DOM/audio counts while capturing the browser heap metric when available.
- **Background Job History Panel.** The Benchmark section now shows sanitized, restart-safe background-job status, - **Background Job History Panel.** The Benchmark section now shows sanitized, restart-safe background-job status,
progress, elapsed time, errors, and cancellation controls. Replay is deliberately limited to reopening the source progress, elapsed time, errors, and cancellation controls. Replay is deliberately limited to reopening the source
workflow because prompts, text, audio, and image inputs are never retained for implicit retries. Completed voice-design workflow because prompts, text, audio, and image inputs are never retained for implicit retries. Completed voice-design

View File

@ -62,7 +62,8 @@ the first block before investing in architecture or polish.
- [ ] **M — Add constrained-device validation.** Test with Chrome CPU/memory throttling, - [ ] **M — Add constrained-device validation.** Test with Chrome CPU/memory throttling,
a 4 GB VM/container, and measure browser, Docker and temporary-disk usage. Automated browser emulation proves a 4 GB VM/container, and measure browser, Docker and temporary-disk usage. Automated browser emulation proves
the 4 GB shared-pool cap, and the current `1.23.3` image served successfully under a hard 4 GiB cgroup limit the 4 GB shared-pool cap, and the current `1.23.3` image served successfully under a hard 4 GiB cgroup limit
without OOM; browser heap/DOM/audio and workload resource measurements remain. without OOM; desktop Chromium now has a 4× CPU-throttled navigation regression with DOM/audio/heap probes,
while full workload resource measurements remain.
- [ ] **L — Add background jobs and bounded queues.** Image generation already has the full interactive job path, - [ ] **L — Add background jobs and bounded queues.** Image generation already has the full interactive job path,
and transcription, voice design, and casting now have optional ID/status/cancel/timeout paths while preserving and transcription, voice design, and casting now have optional ID/status/cancel/timeout paths while preserving
synchronous callers. Job metadata now persists in SQLite and marks interrupted work after restart; durable binary synchronous callers. Job metadata now persists in SQLite and marks interrupted work after restart; durable binary
@ -201,7 +202,8 @@ the first block before investing in architecture or polish.
- [x] Add explicit Docker memory limits; the web container defaults to `mem_limit: 8g` and `mem_reservation: 2g`, configurable per host. - [x] Add explicit Docker memory limits; the web container defaults to `mem_limit: 8g` and `mem_reservation: 2g`, configurable per host.
- [x] Limit upload sizes and clean converted upload intermediates; continue expanding endpoint-specific temporary-file and job limits. - [x] Limit upload sizes and clean converted upload intermediates; continue expanding endpoint-specific temporary-file and job limits.
- [ ] Test with Chrome DevTools CPU/memory throttling. - [x] Test with Chrome DevTools-equivalent CPU throttling; desktop Playwright uses Chromium CDP at 4× CPU and
asserts navigation plus bounded DOM/audio counts, with JS heap captured when Chromium exposes it.
- [x] Test the current image in a container limited to 4 GB RAM; the app served `/` with a 4 GiB cgroup limit, - [x] Test the current image in a container limited to 4 GB RAM; the app served `/` with a 4 GiB cgroup limit,
~50.6 MiB idle memory, 0.09% CPU, and no OOM kill. ~50.6 MiB idle memory, 0.09% CPU, and no OOM kill.
- [ ] Monitor browser-tab memory, JavaScript heap, DOM-node count, active audio blobs, Docker memory, and temporary disk usage. - [ ] Monitor browser-tab memory, JavaScript heap, DOM-node count, active audio blobs, Docker memory, and temporary disk usage.

View File

@ -1 +1 @@
1.24.4 1.24.5

View File

@ -39,3 +39,25 @@ test('large character productions keep the rendered DOM paginated', async ({ pag
await page.locator('#lib-chars-list .lib-chars-load-more').click(); 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); await expect.poll(() => page.locator('#lib-chars-list .lib-char-card').count()).toBeLessThanOrEqual(100);
}); });
test('desktop navigation remains usable under Chrome CPU throttling', async ({ page }, testInfo) => {
test.skip(testInfo.project.name !== 'desktop', 'Chromium CDP throttling is a desktop measurement');
const cdp = await page.context().newCDPSession(page);
await cdp.send('Emulation.setCPUThrottlingRate', { rate: 4 });
try {
await page.goto('/', { waitUntil: 'domcontentloaded' });
await page.waitForSelector('#app-skeleton', { state: 'detached', timeout: 20_000 });
await page.evaluate(() => window.navTo('s-performance'));
await expect(page.locator('#background-jobs-card')).toBeVisible({ timeout: 15_000 });
const metrics = await page.evaluate(() => ({
domNodes: document.getElementsByTagName('*').length,
audioElements: document.querySelectorAll('audio').length,
jsHeapBytes: performance.memory?.usedJSHeapSize || null,
}));
expect(metrics.domNodes).toBeLessThan(20_000);
expect(metrics.audioElements).toBeLessThan(64);
} finally {
await cdp.send('Emulation.setCPUThrottlingRate', { rate: 1 }).catch(() => {});
await cdp.detach().catch(() => {});
}
});