101 lines
7.1 KiB
JavaScript
101 lines
7.1 KiB
JavaScript
// 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: "Помощник отключён." } }));
|
||
})();
|