102 lines
4.9 KiB
JavaScript
102 lines
4.9 KiB
JavaScript
// Teil des UI-Testlaufs (scripts/ui-smoke.js): prüft das Tray-Menüfenster in echtem Electron, ohne das
|
|
// Tray-Symbol selbst. Zeigt das Fenster, fährt mit der Maus darüber, klickt, drückt Esc.
|
|
// Gibt „✓ …“ und „✗ …“ Zeilen aus; Aufruf durch ui-smoke.js.
|
|
|
|
const { app } = require('electron');
|
|
const path = require('path');
|
|
|
|
const ROOT = path.resolve(__dirname, '..');
|
|
const { createTrayPopup } = require(path.join(ROOT, 'src', 'features', 'trayPopup.js'));
|
|
const trayMenu = require(path.join(ROOT, 'src', 'features', 'trayMenu.js'));
|
|
|
|
let failed = 0;
|
|
function check(name, ok, detail = '') {
|
|
if (!ok) failed++;
|
|
console.log(`${ok ? '✓' : '✗'} ${name}${detail ? ` — ${detail}` : ''}`);
|
|
}
|
|
|
|
app.disableHardwareAcceleration();
|
|
app.on('window-all-closed', (e) => e.preventDefault());
|
|
|
|
app.whenReady().then(async () => {
|
|
const wait = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
const log = [];
|
|
let active = 1;
|
|
const template = () => trayMenu.buildTrayTemplate({
|
|
version: '0.0.0', active, queued: 2, paused: false, autostart: true,
|
|
onOpen: () => log.push('open'), onHistory: () => log.push('history'), onPause: () => log.push('pause'),
|
|
onCancel: () => log.push('cancel'), onAutostart: () => log.push('autostart'), onQuit: () => log.push('quit')
|
|
});
|
|
const popup = createTrayPopup({
|
|
htmlPath: path.join(ROOT, 'renderer', 'tray-menu.html'),
|
|
preloadPath: path.join(ROOT, 'tray-menu-preload.js'),
|
|
getModel: () => trayMenu.serializeTemplate(template()),
|
|
onAction: (id) => trayMenu.runAction(template(), id)
|
|
});
|
|
|
|
const js = (code) => popup.getWindow().webContents.executeJavaScript(code);
|
|
const items = async () => JSON.parse(await js(`JSON.stringify([...document.querySelectorAll('.item')].map(b => { const r = b.getBoundingClientRect(); return { text: b.innerText.trim(), disabled: b.disabled, x: r.x, y: r.y, h: r.height }; }))`));
|
|
const mid = (i) => ({ x: Math.round(i.x + 40), y: Math.round(i.y + i.h / 2) });
|
|
const bg = (label) => js(`(() => { const b = [...document.querySelectorAll('.item')].find(x => x.innerText.includes(${JSON.stringify(label)})); return getComputedStyle(b).backgroundColor; })()`);
|
|
const mouse = (type, p, extra = {}) => popup.getWindow().webContents.sendInputEvent({ type, x: p.x, y: p.y, ...extra });
|
|
|
|
try {
|
|
popup.warmUp();
|
|
await wait(6000); // erster Renderer-Start dauert mehrere Sekunden
|
|
popup.show();
|
|
await wait(800);
|
|
check('Menüfenster wird sichtbar', popup.isVisible());
|
|
|
|
let list = await items();
|
|
check('Menü zeigt Einträge mit Pausieren und Abbrechen',
|
|
['Fenster öffnen', 'Upload-Verlauf', 'Übertragung pausieren', 'Laufende Übertragung abbrechen', 'Beenden'].every((t) => list.some((i) => i.text.includes(t))));
|
|
|
|
// Hover folgt der Maus
|
|
const history = list.find((i) => i.text.includes('Upload-Verlauf'));
|
|
// Das frisch geöffnete Fenster braucht einen Moment, bis es sein erstes Bild gezeichnet hat und Hover annimmt.
|
|
let hovered = 'rgba(0, 0, 0, 0)';
|
|
for (let i = 0; i < 12 && hovered === 'rgba(0, 0, 0, 0)'; i++) {
|
|
mouse('mouseMove', { x: mid(history).x + (i % 2), y: mid(history).y });
|
|
await wait(250);
|
|
hovered = await bg('Upload-Verlauf');
|
|
}
|
|
const other = await bg('Fenster öffnen');
|
|
check('Hover markiert den Eintrag unter der Maus', hovered !== 'rgba(0, 0, 0, 0)' && other === 'rgba(0, 0, 0, 0)', `${hovered} / ${other}`);
|
|
|
|
// Gesperrter Eintrag bleibt unmarkiert und löst nichts aus
|
|
active = 0; popup.refresh(); await wait(400);
|
|
list = await items();
|
|
const cancel = list.find((i) => i.text.includes('abbrechen'));
|
|
mouse('mouseMove', mid(cancel));
|
|
await wait(300);
|
|
check('Gesperrter Eintrag wird nicht markiert', cancel.disabled && (await bg('abbrechen')) === 'rgba(0, 0, 0, 0)');
|
|
mouse('mouseDown', mid(cancel), { button: 'left', clickCount: 1 });
|
|
mouse('mouseUp', mid(cancel), { button: 'left', clickCount: 1 });
|
|
await wait(400);
|
|
check('Klick auf gesperrten Eintrag löst keine Aktion aus', log.length === 0 && popup.isVisible());
|
|
|
|
// Klick führt die Aktion aus und schließt das Fenster
|
|
const open = list.find((i) => i.text.includes('Fenster öffnen'));
|
|
mouse('mouseMove', mid(open));
|
|
mouse('mouseDown', mid(open), { button: 'left', clickCount: 1 });
|
|
mouse('mouseUp', mid(open), { button: 'left', clickCount: 1 });
|
|
await wait(600);
|
|
check('Klick führt die Aktion aus und schließt das Menü', log.join() === 'open' && !popup.isVisible());
|
|
|
|
// Esc schließt
|
|
popup.show();
|
|
await wait(900);
|
|
const reopened = popup.isVisible();
|
|
const win = popup.getWindow();
|
|
win.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Escape' });
|
|
win.webContents.sendInputEvent({ type: 'keyUp', keyCode: 'Escape' });
|
|
await wait(500);
|
|
check('Esc schließt das Menü', reopened && !popup.isVisible());
|
|
} catch (e) {
|
|
check('Menüfenster-Test ohne Ausnahme', false, e.message);
|
|
}
|
|
|
|
popup.destroy();
|
|
app.exit(failed ? 1 : 0);
|
|
});
|