Hacky demo changes

This commit is contained in:
Andras Schmelczer 2026-05-06 19:36:04 +01:00
parent 7cba369308
commit ea7afd618c
39 changed files with 2041 additions and 745 deletions

123
video/src/browser.ts Normal file
View file

@ -0,0 +1,123 @@
import { chromium, type Browser, type BrowserContext } from 'playwright';
import { AUTH_STATE_PATH, CAPTURE_SCALE, OUTPUT_DIR, VIDEO_SIZE, VIEWPORT } from './config.js';
export interface RecordingBrowser {
browser: Browser;
context: BrowserContext;
}
export async function launchRecordingBrowser(): Promise<RecordingBrowser> {
const browser = await chromium.launch({
headless: true,
args: [
'--disable-blink-features=AutomationControlled',
'--use-gl=angle',
'--use-angle=swiftshader',
'--enable-unsafe-swiftshader',
'--ignore-gpu-blocklist',
'--disable-frame-rate-limit',
'--disable-gpu-vsync',
'--disable-features=CalculateNativeWinOcclusion,IntensiveWakeUpThrottling',
'--disable-renderer-backgrounding',
'--disable-background-timer-throttling',
'--disable-backgrounding-occluded-windows',
],
});
const context = await browser.newContext({
storageState: AUTH_STATE_PATH,
viewport: VIEWPORT,
deviceScaleFactor: CAPTURE_SCALE,
recordVideo: { dir: OUTPUT_DIR, size: VIDEO_SIZE },
});
await suppressDevServerNoise(context);
return { browser, context };
}
async function suppressDevServerNoise(context: BrowserContext) {
await context.addInitScript(() => {
(window as typeof window & { __demoRecording?: boolean }).__demoRecording = true;
const RealWS = window.WebSocket;
window.WebSocket = new Proxy(RealWS, {
construct(target, args) {
const url = String(args[0] ?? '');
const proto = (args[1] as string | string[] | undefined) ?? '';
const protoStr = Array.isArray(proto) ? proto.join(',') : proto;
if (
protoStr.includes('vite-hmr') ||
protoStr.includes('webpack') ||
url.includes('/ws') ||
url.includes('sockjs-node')
) {
const fake = new EventTarget() as WebSocket;
Object.defineProperties(fake, {
readyState: { value: RealWS.CLOSED },
url: { value: url },
protocol: { value: '' },
extensions: { value: '' },
bufferedAmount: { value: 0 },
binaryType: { value: 'blob', writable: true },
});
fake.send = () => {};
fake.close = () => fake.dispatchEvent(new Event('close'));
queueMicrotask(() => fake.dispatchEvent(new Event('close')));
return fake;
}
return Reflect.construct(target, args);
},
});
Object.defineProperty(window.location, 'reload', {
value: () => {},
configurable: true,
});
window.addEventListener('error', (e) => e.stopImmediatePropagation(), true);
window.addEventListener('unhandledrejection', (e) => e.stopImmediatePropagation(), true);
const styleEl = document.createElement('style');
styleEl.textContent = `
vite-error-overlay,
wds-overlay,
#webpack-dev-server-client-overlay,
#webpack-dev-server-client-overlay-div,
iframe[src*="webpack-dev-server"],
iframe[id*="webpack"],
[id*="webpack-dev-server-client"],
[class*="error-overlay"],
[class*="webpack-error"] {
display: none !important;
visibility: hidden !important;
opacity: 0 !important;
pointer-events: none !important;
}
`;
(document.head ?? document.documentElement).appendChild(styleEl);
const killOverlay = (node: Element) => {
const tag = node.tagName?.toLowerCase();
const id = (node as HTMLElement).id?.toLowerCase() ?? '';
if (
tag === 'vite-error-overlay' ||
tag === 'wds-overlay' ||
id.includes('webpack-dev-server-client') ||
id.includes('webpack-error')
) {
(node as HTMLElement).remove();
}
};
const obs = new MutationObserver((muts) => {
for (const m of muts) {
m.addedNodes.forEach((n) => {
if (n.nodeType === 1) killOverlay(n as Element);
});
}
});
if (document.body) obs.observe(document.body, { childList: true, subtree: true });
else {
document.addEventListener('DOMContentLoaded', () =>
obs.observe(document.body, { childList: true, subtree: true })
);
}
});
}