fix(stream-test): hide Chrome toolbar in fullscreen so the address bar stays off the broadcast

On the streamed VNC desktop (xfwm4), Chrome did not hide its toolbar when a
video entered HTML5 fullscreen via 'f' - the window was full-screen (outerHeight
1080) but the tab/address bar stayed, leaving only 988px of content, so the
address bar bled into the Go-Live broadcast.

Toggle Chrome-initiated browser fullscreen via CDP (Browser.setWindowBounds
windowState fullscreen) around the 'f' step. That reliably hides the toolbar
(innerHeight 1080 vs 988); the toolbar is restored on exit, so normal browsing
still shows it. Verified live: clean full-screen video, no toolbar.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
javis-bot
2026-06-10 15:39:08 +09:00
parent 4176a68873
commit c6a0ca4572

View File

@@ -8,6 +8,13 @@
// and entering 나무위키. The CDP/DOM API is used ONLY to read state for
// verification (paused/quality/fullscreen) and as a rare click fallback when an
// element has no on-screen box.
//
// One environment workaround: on the streamed VNC desktop (xfwm4) Chrome does
// NOT hide its toolbar when a video enters HTML5 fullscreen ('f'), so the
// address bar bleeds into the broadcast. We therefore toggle the BROWSER window
// into Chrome-initiated fullscreen via CDP (Browser.setWindowBounds) around the
// 'f' step - that reliably hides the toolbar (innerHeight 1080 vs 988) - then
// restore it. This is a window-chrome action, not a page interaction.
import { chromium } from 'playwright';
import { humanClick, humanType, humanKey, humanHover, navigateOmnibox, humanScroll, sleep } from './human.mjs';
@@ -23,6 +30,19 @@ page.setDefaultTimeout(25000);
const read = (fn) => page.evaluate(fn);
const playerLoc = () => page.locator('#movie_player');
// Toggle Chrome-initiated browser fullscreen (hides the toolbar on this WM,
// which HTML5 'f' fullscreen alone does not). on=true -> fullscreen.
async function browserFullscreen(on) {
try {
const sess = await b.newBrowserCDPSession();
const { targetInfos } = await sess.send('Target.getTargets');
const t = targetInfos.find((x) => x.type === 'page' && x.url.startsWith('http'));
if (!t) return;
const { windowId } = await sess.send('Browser.getWindowForTarget', { targetId: t.targetId });
await sess.send('Browser.setWindowBounds', { windowId, bounds: { windowState: on ? 'fullscreen' : 'normal' } });
} catch { /* best-effort */ }
}
// 1) open YouTube by typing the URL in the address bar
await navigateOmnibox('https://www.youtube.com'); await sleep(3000);
@@ -73,14 +93,17 @@ if ((await auto.count().catch(() => 0)) && (await auto.getAttribute('aria-checke
}
console.log('STEP watch-1080-windowed'); await sleep(20000);
// 7) fullscreen with the real 'f' key (hover the player to focus it), 20s
// 7) fullscreen: hide the browser toolbar (CDP), then the real 'f' key makes the
// video fill the now toolbar-free screen (innerHeight 1080). 20s.
await browserFullscreen(true); await sleep(800);
await humanHover(page, playerLoc());
await humanKey('f'); await sleep(1500);
if (!(await read(() => !!document.fullscreenElement))) { await humanHover(page, playerLoc()); await humanKey('f'); await sleep(1200); }
console.log('STEP fullscreen', await read(() => ({ full: !!document.fullscreenElement, h: window.innerHeight }))); await sleep(20000);
// 8) exit fullscreen with real 'f'
// 8) exit video fullscreen ('f'), then restore the browser toolbar
await humanKey('f'); await sleep(1500);
await browserFullscreen(false); await sleep(500);
// 9) Naver via the address bar, then really type the query
await navigateOmnibox('https://www.naver.com'); await sleep(2800);