Files
deskhub/DeskHub-Webseite/tools/manual/capture_extra.js
T
2026-11-05 21:22:03 +00:00

86 lines
5.1 KiB
JavaScript

'use strict';
/**
* tools/manual/capture_extra.js: nimmt die neuen Bilder für das Handbuch auf (Passkeys, Anmeldeseite, Mitarbeiter-Menü, Anmelde-Wächter) (Demo-Installation mit erfundenen Daten, siehe seed_manual.php).
* 1. php tools/demo-video/seed_demo.php <Ordner> && php tools/manual/seed_manual.php <Ordner> && php tools/manual/install_plugins.php <Ordner> <Plugin-ZIPs>
* 2. DESKHUB_CATALOG_DEFAULTS=tests/fixtures/no-catalog.php php -S 127.0.0.1:8097 -t <Ordner>
* 3. electron tools/manual/capture_manual.js <Bilderordner>
*/
const { app, BrowserWindow } = require('electron');
const fs = require('fs');
const path = require('path');
const BASE = 'http://127.0.0.1:8097';
const OUT = path.resolve(process.argv[2] || path.join(__dirname, 'shots'));
const W = 1180; // schmaler als ein Bildschirm: Die Bilder werden auf A4 verkleinert und müssen lesbar bleiben
const SIDEBAR = 240; // Breite der Seitenleiste; sie wird aus den Bildern der Seiten herausgeschnitten (eigenes Bild vom Menü)
const H = 860;
const MAXH = 2400;
fs.mkdirSync(OUT, { recursive: true });
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
let win;
const run = (js) => win.webContents.executeJavaScript(js, true);
const report = { ok: [], fail: [] };
/** Seite laden und alles entfernen, was nur zur Demo-Installation gehört (SQLite-Hinweis, Zähler der Sitzung). */
async function load(url, wait = 700) {
await win.loadURL(BASE + url);
await sleep(wait);
await run(`(() => {
document.getElementById('session-timer-bar')?.remove();
document.querySelectorAll('div,p,section,aside').forEach((e) => { if (e.children.length < 8 && /SQLite-Modus aktiv/.test(e.textContent) && e.textContent.length < 400) e.remove(); });
})()`);
}
/** Bild der Seite speichern: höchstens MAXH hoch; mit full = false nur der sichtbare Teil. */
async function shot(name, { full = true, clip = null, keepSidebar = false } = {}) {
let h = H;
if (full) {
h = await run('Math.max(document.documentElement.scrollHeight, document.body.scrollHeight)');
h = Math.min(Math.max(h, 500), MAXH);
}
win.setContentSize(W, h);
await sleep(350);
const hasSidebar = await run(`(() => { const s = document.getElementById('sidebar'); return !!s && s.getBoundingClientRect().width > 100; })()`);
let img = await win.webContents.capturePage();
if (clip) img = img.crop(clip);
else if (hasSidebar && !keepSidebar) img = img.crop({ x: SIDEBAR, y: 0, width: W - SIDEBAR, height: h });
fs.writeFileSync(path.join(OUT, name + '.png'), img.toPNG());
win.setContentSize(W, H);
report.ok.push(name);
}
async function page(name, url, opts = {}) {
try {
await load(url, opts.wait);
if (opts.prep) { await run(opts.prep); await sleep(opts.prepWait || 400); }
await shot(name, opts);
} catch (e) {
report.fail.push(name + ': ' + e.message);
}
}
async function login(email, pass, loginUrl) {
await load(loginUrl, 600);
await run(`(() => { const f = document.querySelector('form'); f.querySelector('[name=email]').value = ${JSON.stringify(email)}; f.querySelector('[name=password]').value = ${JSON.stringify(pass)}; f.submit(); })()`);
await sleep(1500);
}
app.whenReady().then(async () => {
win = new BrowserWindow({ width: W, height: H, show: true, useContentSize: true, webPreferences: { contextIsolation: true, backgroundThrottling: false } });
try {
// Anmeldeseite mit dem Passkey-Knopf (im Electron-Fenster ohne Passkey-Unterstützung wird er von Hand eingeblendet)
await page('staff-login', '/staff/login.php', { full: false, prep: `(() => { const b = document.getElementById('passkey-login'); if (b) b.style.display = 'block'; })()` });
await login('lena@demo.example', 'Demo-Passwort-1234', '/staff/login.php');
await page('profil-sicherheit', '/staff/profile.php?tab=security', { prep: `(() => { const a = document.getElementById('passkey-add'); if (a && !a.getAttribute('data-off')) a.style.display = 'block'; const u = document.getElementById('pk_unsupported'); if (u) u.style.display = 'none'; })()` });
await page('admin-anmelde-waechter', '/staff/login_log.php');
await page('admin-mitarbeiter-passkeys', '/staff/staff_manage.php?edit=3', { prep: `(() => { const h = [...document.querySelectorAll('h3')].find((x) => x.textContent.includes('Passkeys von')); if (!h) return; const card = h.closest('.card'); let n = card.previousElementSibling; while (n) { const p = n.previousElementSibling; if (n.tagName !== 'STYLE') n.style.display = 'none'; n = p; } })()` });
await page('admin-menue-aktionen', '/staff/staff_manage.php', { full: false, prep: `(() => { const row = [...document.querySelectorAll('#sm-table tbody tr')].find((r) => r.textContent.includes('Tim')); row?.querySelector('.sm-menu summary')?.click(); })()` });
} catch (e) {
report.fail.push('FATAL ' + e.stack);
}
fs.writeFileSync(path.join(OUT, '_bericht_extra.json'), JSON.stringify(report, null, 1));
console.log(`Aufgenommen: ${report.ok.length}, Fehler: ${report.fail.length}`);
report.fail.forEach((f) => console.log(' - ' + f));
app.quit();
});