Vydané zdroje
Stáhnout zdroje ZIP
CH-J Server Manager
Procházejte adresáře a soubory konkrétního vydání aplikace.
Zdroje jsou zveřejněny pod CH-J Proprietary Software License 1.14. Jejich dostupnost nemění licenční podmínky ani neposkytuje další oprávnění.
1
"use strict";2
// Run with Electron, not node. Uses the production renderer/preload/IPC and real local probes.3
const { app, clipboard, ipcMain, dialog } = require("electron");4
const assert = require("node:assert/strict");5
const fs = require("node:fs");6
const os = require("node:os");7
const path = require("node:path");8
const http = require("node:http");9
const zlib = require("node:zlib");10
const { once } = require("node:events");11
const { createMainWindow, hardenSession } = require("../src/main/bootstrap/createMainWindow");12
const { registerCoreIpc } = require("../src/main/ipc/registerCoreIpc");13
const { DiagnosticsService } = require("../src/main/diagnostics/diagnosticsService");14
const { ConfigStore } = require("../src/main/config/configStore");15
const root = fs.mkdtempSync(path.join(os.tmpdir(), "chj-diagnostics-ui-"));16
app.setPath("userData", root);17
let window, server, diagnostics;18
const errors = [];19
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));20
async function until(source, timeout = 15000) {21
const start = Date.now();22
while (Date.now() - start < timeout) { if (await window.webContents.executeJavaScript(source)) return; await wait(50); }23
throw new Error("UI condition timed out: " + source);24
}25
async function run() {26
await app.whenReady();27
server = http.createServer((req, res) => {28
const body = Buffer.from("Local diagnostics UI smoke ".repeat(30));29
const encoder = { gzip: zlib.gzipSync, br: zlib.brotliCompressSync, deflate: zlib.deflateSync, zstd: zlib.zstdCompressSync }[req.headers["accept-encoding"]];30
res.setHeader("content-type", "text/plain");31
if (encoder) { res.setHeader("content-encoding", req.headers["accept-encoding"]); res.end(encoder(body)); } else res.end(body);32
});33
server.on("clientError", (_error, socket) => socket.destroy());34
server.listen(0, "127.0.0.1"); await once(server, "listening");35
diagnostics = new DiagnosticsService({ storageRoot: root });36
const configStore = new ConfigStore(root); configStore.load(); configStore.update({ updates: { autoCheck: false } });37
hardenSession(); window = createMainWindow();38
window.webContents.on("console-message", (event) => { if (event.level === "error") { errors.push(event.message); console.error(event.message); } });39
// Unrelated services stay offline in this test. All diagnostics use production implementations.40
registerCoreIpc({ ipcMain, app, clipboard, dialog, configStore, diagnosticsService: diagnostics,41
pluginService: { getState: () => ({ installed: [], catalog: [], windows: [] }) }, pluginRuntime: { notifyLanguageChanged() {} },42
vaultStore: { status: () => ({ unlocked: true }) }, profileService: { list: () => [] },43
updateService: { getState: () => ({ currentVersion: "0.0.1", status: "idle", releases: [] }) }, getMainWindow: () => window });44
diagnostics.on("progress", (value) => window.webContents.send("diagnostics:progress", value));45
await until('Boolean(document.querySelector(".diag-toolbar"))');46
assert.deepEqual(await window.webContents.executeJavaScript('Array.from(document.querySelectorAll(".sidebar [data-view], #hashToolButton")).map(n => n.dataset.view || "hash").filter(n => ["plugins","diagnostics","hash"].includes(n))'), ["plugins", "diagnostics", "hash"]);47
await window.webContents.executeJavaScript(`document.querySelector('[data-view="diagnostics"]').click(); document.querySelector('.diag-toolbar input').value = 'http://127.0.0.1:${server.address().port}/'; document.querySelector('#diag-panel-http .primary').click();`);48
await until('diagnosticsView.state.report?.status === "completed"');49
const result = await window.webContents.executeJavaScript('diagnosticsView.state.report');50
assert.equal(result.results.http[0].comparisons[0].samples[0].negotiated, "1.1");51
assert.equal(result.results.http[0].comparisons[0].samples[0].downloadedBytes, 810);52
assert.equal(result.results.http[0].comparisons[2].samples[0].status, "unavailable");53
assert.equal(await window.webContents.executeJavaScript('typeof window.require'), "undefined");54
for (const language of ["de", "en", "cs"]) await window.webContents.executeJavaScript(`applyLanguage('${language}'); document.querySelector('#diag-tab-http').click();`);55
await window.webContents.executeJavaScript('document.querySelector(".diag-controls select:last-of-type"); diagnosticsView.refreshLanguage();');56
// Exercise both themes, narrow window, real compression and persistent history.57
for (const theme of ["dark", "light"]) {58
await window.webContents.executeJavaScript(`{ const themeSelect = Array.from(document.querySelectorAll('.diag-controls select')).at(-1); themeSelect.value = '${theme}'; themeSelect.dispatchEvent(new Event('change')); }`);59
await wait(100);60
assert.equal(await window.webContents.executeJavaScript('document.querySelector("#diagnosticsView").dataset.theme'), theme);61
}62
await window.webContents.executeJavaScript('Array.from(document.querySelectorAll("#diag-panel-http .primary"))[1].click()');63
await until('diagnosticsView.state.report?.results.compression && diagnosticsView.state.report.status === "completed"');64
assert.equal(await window.webContents.executeJavaScript('diagnosticsView.state.report.results.compression[0].results.find(r=>r.encoding==="br").status'), "success");65
const history = diagnostics.history.list(); assert.equal(history.length, 2);66
assert.equal(new (require("../src/main/diagnostics/historyStore").DiagnosticsHistory)(root).list().length, 2);67
window.setSize(960, 720);68
await wait(100);69
assert.equal(await window.webContents.executeJavaScript("document.documentElement.scrollWidth <= window.innerWidth"), true);70
await window.webContents.executeJavaScript('document.querySelector("#diag-tab-history").click()'); await wait(100);71
assert.equal(await window.webContents.executeJavaScript('document.querySelectorAll("#diag-panel-history tbody tr").length'), 2);72
const preferences = window.webContents.getLastWebPreferences(); assert.equal(preferences.contextIsolation, true); assert.equal(preferences.sandbox, true); assert.equal(preferences.nodeIntegration, false);73
const artifacts = process.env.CHJ_DIAGNOSTICS_SMOKE_ARTIFACT_DIR;74
if (artifacts) { fs.mkdirSync(artifacts, { recursive: true }); await window.webContents.executeJavaScript('document.querySelector("#diag-tab-http").click()'); await wait(100); fs.writeFileSync(path.join(artifacts, "diagnostics-light.png"), (await Promise.race([window.webContents.capturePage(), wait(5000).then(() => { throw new Error("Screenshot capture timed out"); })])).toPNG()); }75
assert.deepEqual(errors, []);76
console.log("CHJ_DIAGNOSTICS_UI_OK: real HTTP/1.1, protocol failures, Brotli, history, CZ/DE/EN, light/dark, sandbox");77
}78
run().then(() => finish(0), (error) => { console.error(error); finish(1); });79
let finishing = false;80
function finish(code) { if (finishing) return; finishing = true; diagnostics?.stopAll(); window?.destroy(); server?.close(); try { fs.rmSync(root, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch (error) { console.error("Temporary Chromium cache cleanup:", error.code); } app.exit(code); }81
setTimeout(() => { console.error("Diagnostics UI smoke exceeded 30s"); finish(1); }, 30000).unref();SHA-256: 4a34e1ca136fcfd6b6d9cc9256304a1c7f76a245646053ea74d724ed3420ad27
SHA-256 archivu: 5ac91caf4fa32a6fdb114f2430deed486fbe7489d5eea343d1f034169fafb5e0