test: preserve dialogue-only recast merges
This commit is contained in:
parent
b6f4a9518b
commit
29f5243f6b
@ -8,6 +8,8 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned wi
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
- **Dialogue-only merge regression coverage.** Recast/verify normalization now has explicit browser coverage proving that
|
||||
only adjacent known-speaker dialogue merges; narration and unknown-speaker lines remain separate.
|
||||
- **Visual identity regression coverage.** Portrait and concept-sheet prompt tests now verify shared identity anchors;
|
||||
completed pairs centralize prompt-version, identity-fingerprint, and asset-digest metadata.
|
||||
- **Frontend namespace migration completed.** The remaining utility, library, cast-compatibility, i18n, and settings/log
|
||||
|
||||
2
TODO.md
2
TODO.md
@ -268,7 +268,7 @@ codebase; benefit is relative user/reliability impact.
|
||||
|
||||
- [x] **P1 / M — High benefit — Identity-anchor regression tests.** Add automated coverage proving avatar and concept-sheet
|
||||
requests share canonical identity anchors and persist the prompt version used for each generated asset.
|
||||
- [ ] **P1 / S–M — Medium benefit — Preserve dialogue-only merging.** Keep the dialogue-only merge for recast/verify
|
||||
- [x] **P1 / S–M — Medium benefit — Preserve dialogue-only merging.** Keep the dialogue-only merge for recast/verify
|
||||
outputs where adjacent pairs still occur, with regression coverage for the non-dialogue boundaries.
|
||||
- [ ] **P1 / L–XL — Very high benefit — Rework segmentation from Run 3.** Inspect the earlier dialogue split/fusion
|
||||
stages and correct the dominant unmatched-segment class using the measured Run 3 artifacts.
|
||||
|
||||
@ -88,6 +88,7 @@ Done incrementally as global-scope ordered files (no ES-module change needed)
|
||||
- ✅ All remaining application frontend modules are either privately scoped or intentionally stateless bootstrap/cache IIFEs;
|
||||
legacy globals are explicit compatibility exports and new integrations use `window.TTVC` namespaces.
|
||||
- ✅ Visual pair generation centralizes prompt-version, identity-fingerprint, and asset-digest metadata with regression coverage for shared anchors.
|
||||
- ✅ Recast/verify dialogue merging has regression coverage for known-speaker-only behavior and non-dialogue boundaries.
|
||||
- ✅ `static/css/resource-diagnostics.css` — isolated Performance/resource diagnostic panel styles.
|
||||
- ✅ `static/css/background-jobs.css` — isolated background-job history and retry-panel styles.
|
||||
- ✅ `static/css/voice-design.css` — isolated Voice Design form, samples, and preview-match styles.
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="color-scheme" content="light dark">
|
||||
<meta name="theme-color" content="#2563EB">
|
||||
<meta name="app-version" content="1.24.99">
|
||||
<meta name="app-version" content="1.25.0">
|
||||
<link rel="manifest" href="/manifest.webmanifest">
|
||||
<link rel="icon" href="/static/icon.svg" type="image/svg+xml">
|
||||
<link rel="apple-touch-icon" href="/static/icon.svg">
|
||||
@ -27,12 +27,12 @@
|
||||
|
||||
<!-- ── Core styles (local — no CDN dependency for first paint) ────────── -->
|
||||
<link rel="stylesheet" href="/static/vendor/mdi/materialdesignicons.min.css">
|
||||
<link rel="stylesheet" href="/static/style.css?v=1.24.99">
|
||||
<link rel="stylesheet" href="/static/css/resource-diagnostics.css?v=1.24.99">
|
||||
<link rel="stylesheet" href="/static/css/background-jobs.css?v=1.24.99">
|
||||
<link rel="stylesheet" href="/static/css/voice-design.css?v=1.24.99">
|
||||
<link rel="stylesheet" href="/static/css/rehearser.css?v=1.24.99">
|
||||
<link rel="stylesheet" href="/static/css/audiobook.css?v=1.24.99">
|
||||
<link rel="stylesheet" href="/static/style.css?v=1.25.0">
|
||||
<link rel="stylesheet" href="/static/css/resource-diagnostics.css?v=1.25.0">
|
||||
<link rel="stylesheet" href="/static/css/background-jobs.css?v=1.25.0">
|
||||
<link rel="stylesheet" href="/static/css/voice-design.css?v=1.25.0">
|
||||
<link rel="stylesheet" href="/static/css/rehearser.css?v=1.25.0">
|
||||
<link rel="stylesheet" href="/static/css/audiobook.css?v=1.25.0">
|
||||
|
||||
|
||||
<!-- ── Flag icons — non-blocking (loaded async, icons appear after JS) ── -->
|
||||
@ -397,7 +397,7 @@ window.toggleNavTree = function(treeId, chevronId) {
|
||||
</script>
|
||||
|
||||
<!-- loader.js: fetches sections → loads JS modules → removes skeleton -->
|
||||
<script src="/static/loader.js?v=1.24.99"></script>
|
||||
<script src="/static/loader.js?v=1.25.0"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -41,6 +41,34 @@ test('Audiobook lazy modules publish their namespace APIs after loading', async
|
||||
}))).toEqual({ castView: 'function', stream: 'function', startCast: 'function', pipelineCast: 'function', core: 'function', preview: 'function', exportAudio: 'function' });
|
||||
});
|
||||
|
||||
test('Audiobook recast merge preserves narration and merges only known dialogue pairs', async ({ page }) => {
|
||||
await page.goto('/', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForFunction(() => typeof window.navTo === 'function', null, { timeout: 15_000 });
|
||||
await page.waitForSelector('#app-skeleton', { state: 'detached', timeout: 15_000 });
|
||||
await page.evaluate(() => window.navTo('s-reader'));
|
||||
await page.waitForFunction(() => typeof window.TTVC?.audiobook?.cast?.mergeAdjacentDialogue === 'function', null, { timeout: 15_000 });
|
||||
await expect.poll(() => page.evaluate(() => {
|
||||
const merge = window.TTVC.audiobook.cast.mergeAdjacentDialogue;
|
||||
return merge([
|
||||
{ type: 'narration', speaker: 'Narrator', text: 'A.' },
|
||||
{ type: 'narration', speaker: 'Narrator', text: 'B.' },
|
||||
{ type: 'dialogue', speaker: 'Mira', text: 'C.' },
|
||||
{ type: 'dialogue', speaker: 'Mira', text: 'D.' },
|
||||
{ type: 'dialogue', speaker: 'Unknown', text: 'E.' },
|
||||
{ type: 'dialogue', speaker: 'Unknown', text: 'F.' },
|
||||
]);
|
||||
})).toEqual({
|
||||
segments: [
|
||||
{ type: 'narration', speaker: 'Narrator', text: 'A.' },
|
||||
{ type: 'narration', speaker: 'Narrator', text: 'B.' },
|
||||
{ type: 'dialogue', speaker: 'Mira', text: 'C.\n\nD.' },
|
||||
{ type: 'dialogue', speaker: 'Unknown', text: 'E.' },
|
||||
{ type: 'dialogue', speaker: 'Unknown', text: 'F.' },
|
||||
],
|
||||
merged: 1,
|
||||
});
|
||||
});
|
||||
|
||||
test('Rehearser playback module publishes transport APIs after loading', async ({ page }) => {
|
||||
await page.goto('/', { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForFunction(() => typeof window.navTo === 'function', null, { timeout: 15_000 });
|
||||
|
||||
Loading…
Reference in New Issue
Block a user