CH-J Server ManagerSerververwaltung über SSH
Menü
Veröffentlichte Quellen

CH-J Server Manager

Durchsuchen Sie Verzeichnisse und Dateien einer bestimmten Anwendungsausgabe.

Quellen als ZIP herunterladen
CH-J Proprietary Software License 1.14

Die Quellen werden unter der CH-J Proprietary Software License 1.14 bereitgestellt. Ihre Verfügbarkeit ändert die Lizenzbedingungen nicht und gewährt keine zusätzlichen Rechte.

7,1 KB · 81 ZeilenDatei herunterladen
1"use strict";
2// Run with Electron, not node. Uses the production renderer/preload/IPC and real local probes.
3const { app, clipboard, ipcMain, dialog } = require("electron");
4const assert = require("node:assert/strict");
5const fs = require("node:fs");
6const os = require("node:os");
7const path = require("node:path");
8const http = require("node:http");
9const zlib = require("node:zlib");
10const { once } = require("node:events");
11const { createMainWindow, hardenSession } = require("../src/main/bootstrap/createMainWindow");
12const { registerCoreIpc } = require("../src/main/ipc/registerCoreIpc");
13const { DiagnosticsService } = require("../src/main/diagnostics/diagnosticsService");
14const { ConfigStore } = require("../src/main/config/configStore");
15const root = fs.mkdtempSync(path.join(os.tmpdir(), "chj-diagnostics-ui-"));
16app.setPath("userData", root);
17let window, server, diagnostics;
18const errors = [];
19const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
20async 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);
25async 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");
78run().then(() => finish(0), (error) => { console.error(error); finish(1); });
79let finishing = false;
80function 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); }
81setTimeout(() => { console.error("Diagnostics UI smoke exceeded 30s"); finish(1); }, 30000).unref();

SHA-256: 4a34e1ca136fcfd6b6d9cc9256304a1c7f76a245646053ea74d724ed3420ad27

SHA-256 des Archivs: 5ac91caf4fa32a6fdb114f2430deed486fbe7489d5eea343d1f034169fafb5e0