// Deterministic browser APIs for layout and interaction tests, without touching browser accounts. (() => { const listeners = []; const contentListeners = []; const disconnectListeners = []; let sessionEnabled = false; const fixtureStorage = { preferences: {}, onboarding: { state: "complete", version: 1 } }; window.__fixtureStorage = fixtureStorage; window.__downloadRequests = []; window.__quickRequests = []; window.__emitJob = job => { fixtureStorage.jobs ||= {}; fixtureStorage.jobs[job.id] = job; listeners.forEach(listener => listener({ event: "job", job: fixtureStorage.jobs[job.id] })); }; window.__historyRequests = []; window.__uiDisconnect = () => disconnectListeners.forEach(listener => listener()); window.__contentMessage = message => contentListeners.forEach(listener => listener(message)); let autoUpdate = true; window.__updateRequests = []; const hardware = () => ({ version: window.__helperVersion || "1.3.2", bundle: { mode: "autonomous", version: window.__helperVersion || "1.3.2", updateTogether: true }, supportsComponentUpdates: true, supportsWorkFolder: true, updateSettings: { enabled: autoUpdate }, gpu: window.__amdOnly ? "AMD Radeon RX 7900 XTX" : "NVIDIA GeForce RTX 5080", nvenc: window.__dependencyMissing || window.__amdOnly ? [] : ["h264", "hevc", "av1"], amf: window.__amdOnly ? ["h264", "hevc", "av1"] : [], amf10bit: window.__amdOnly ? ["hevc", "av1"] : [], defaultFolder: "D:\\Videos", ready: !window.__dependencyMissing, dependencies: ["python", "yt_dlp", "ejs", "node", "ffmpeg"].map(id => ({ id, status: window.__dependencyMissing && id === "ffmpeg" ? "missing" : "installed", version: "test-version" })) }); const metadata = { id: "aircAruvnKk", url: "https://www.youtube.com/watch?v=aircAruvnKk", title: "But what is a neural network? | Deep learning chapter 1", channel: "3Blue1Brown", duration: 1148, videos: [ { id: "401", height: 2160, fps: 60, codec: "av01.0.13M.08", extension: "mp4", hasAudio: false, size: 350000000, hdr: "SDR" }, { id: "137", height: 1080, fps: 30, codec: "avc1.640028", extension: "mp4", hasAudio: false, size: 100000000, hdr: "SDR" }, { id: "18", height: 360, fps: 30, codec: "avc1.42001E", extension: "mp4", hasAudio: true, size: 35000000, hdr: "SDR" }, ], audios: [{ id: "251", codec: "opus", extension: "webm", bitrate: 160, language: "en", note: "English", size: 5000000 }] }; window.chrome = { runtime: { getManifest: () => ({ version: window.__extensionVersion || "1.4.5" }), getURL: file => `https://ui.ytdl.test/${file}`, sendMessage: async message => { if (message.type === "QUICK_DOWNLOAD") { window.__quickRequests.push(message.url); return { ok: true, jobId: "fixture-job" }; } if (message.type === "CLOSE_MENU") parent.postMessage({ type: "FIXTURE_CLOSE_MENU" }, "https://www.youtube.com"); return { tabId: 42, jobs: [] }; }, onMessage: { addListener: listener => contentListeners.push(listener) }, connect: () => ({ onMessage: { addListener: listener => listeners.push(listener) }, onDisconnect: { addListener: listener => disconnectListeners.push(listener) }, postMessage: message => { let result; if ((message.action === "hello" || message.action === "helper_start") && window.__helperMissing) { setTimeout(() => { listeners.forEach(listener => listener({ event: "helper", helper: { status: "missing", message: "Помощник не установлен. Скачайте установщик." } })); listeners.forEach(listener => listener({ id: message.id, ok: false, error: "Помощник не установлен." })); }, 5); return; } if (message.action === "hello" || message.action === "helper_start") result = hardware(); if (message.action === "helper_status") result = { status: "running", hardware: hardware() }; if (message.action === "update_settings") { autoUpdate = message.payload.enabled; result = { enabled: autoUpdate }; } if (message.action === "helper_update") { window.__updateRequests.push(message.payload); result = { jobId: "fixture-update" }; setTimeout(() => window.__emitJob({ id: "fixture-update", kind: "update", canCancel: false, title: "Обновление компонентов", status: "running", stage: "updating", percent: 36, message: "Скачиваю FFmpeg…" }), 10); } if (message.action === "dependency_install") { result = { jobId: "fixture-dependency" }; setTimeout(() => { window.__dependencyMissing = false; listeners.forEach(listener => listener({ event: "helper", helper: { status: "running", hardware: hardware() } })); }, 30); } if (message.action === "helper_remove") { result = { removed: true }; listeners.forEach(listener => listener({ event: "helper", helper: { status: "missing", message: "Помощник удалён." } })); } if (message.action === "session_status") result = { status: sessionEnabled ? "connected" : "disabled", message: "Вход текущего браузера" }; if (message.action === "session_enable") { sessionEnabled = message.payload.enabled; result = { status: sessionEnabled ? "connected" : "disabled" }; } if (message.action === "inspect") { if (window.__requiresLogin && !sessionEnabled) { setTimeout(() => listeners.forEach(listener => listener({id:message.id,ok:false,error:"ERROR: Sign in to confirm you’re not a bot. Use --cookies for authentication"})),5); return; } result = metadata; } if (message.action === "pick_folder") result = { folder: "D:\\Videos\\YouTube" }; if (message.action === "open_history") { window.__historyRequests.push(message.payload); result = { opened: true }; } if (message.action === "download") { window.__downloadRequests.push(message.payload); result = { jobId: "fixture-job" }; } if (message.action === "state" || message.action === "jobs") result = { jobs: Object.values(fixtureStorage.jobs || {}) }; setTimeout(() => listeners.forEach(listener => listener({ id: message.id, ok: true, result })), 5); }, }), }, storage: { local: { get: async keys => { const data = { ...fixtureStorage }; if (window.__firstRun && !window.__onboardingStored) delete data.onboarding; return Object.fromEntries((Array.isArray(keys) ? keys : [keys]).filter(key => key in data).map(key => [key, structuredClone(data[key])])); }, set: async data => { Object.assign(fixtureStorage, structuredClone(data)); if (data.onboarding) window.__onboardingStored = true; }, } }, permissions: { request: async () => window.__denySessionPermission !== true }, }; window.__helperOffline = () => listeners.forEach(listener => listener({ event: "helper", helper: { status: "offline", message: "Помощник отключён." } })); })();