From a4e0faaeb3498e5f0bc4e04cc5e946fcc1801a4a Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Wed, 18 Mar 2026 19:53:47 +0300 Subject: [PATCH] feat(web-test): add speech support to showTitleSlide Title slides can now have TTS narration, same as showCaption/showImage. Pass opts.speech as string for custom narration text, or true to use the title text. Includes smart wait for video timeline sync. Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/skills/web-test/scripts/browser.mjs | 24 +++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.claude/skills/web-test/scripts/browser.mjs b/.claude/skills/web-test/scripts/browser.mjs index be714a78..2afbaccc 100644 --- a/.claude/skills/web-test/scripts/browser.mjs +++ b/.claude/skills/web-test/scripts/browser.mjs @@ -4190,7 +4190,19 @@ export async function showTitleSlide(text, opts = {}) { background = 'linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%)', color = '#fff', fontSize = 36, + speech, } = opts; + + // Collect caption for TTS narration if recording + let smartWaitMs = 0; + if (recorder && speech && speech !== false) { + const captionText = typeof speech === 'string' ? speech : text.replace(/\n/g, ' '); + if (captionText) { + recorder.captions.push({ text: captionText, speech: captionText, time: Math.round(recorder.videoTimeMs) }); + smartWaitMs = Math.max(2000, captionText.length * 100); + } + } + await page.evaluate(({ text, subtitle, background, color, fontSize }) => { let div = document.getElementById('__web_test_title'); if (!div) { @@ -4211,6 +4223,18 @@ export async function showTitleSlide(text, opts = {}) { } div.innerHTML = `
${html}
`; }, { text, subtitle, background, color, fontSize }); + + // Smart TTS wait (same pattern as showCaption/showImage) + if (smartWaitMs > 0) { + let remaining = smartWaitMs; + while (remaining > 0) { + const chunk = Math.min(remaining, 1000); + await page.waitForTimeout(chunk); + remaining -= chunk; + if (recorder?._flushFrames) recorder._flushFrames(); + } + recorder.captionCredit = { waitedMs: smartWaitMs, at: Date.now() }; + } } /** Remove the title slide overlay. */