Synchronize Electron test assertions with completed input and queue events
CI / verify (push) Waiting to run
CI / verify (push) Waiting to run
This commit is contained in:
@@ -98,6 +98,7 @@ npm audit --omit=dev
|
||||
|
||||
## Zuletzt verifiziert
|
||||
|
||||
- CI-Timingkorrektur nach `2.1.50`: Checkbox-Test wartet begrenzt auf native Klick-, Tab- und Leertastenverarbeitung und meldet bei Zeitüberschreitung Aktion und letzten Zustand; Hintergrunddrosselung im isolierten Testfenster deaktiviert. Start-/Reload-Test akzeptiert einen leeren, noch nicht belieferten Renderer nicht mehr als abgeschlossen, sondern wartet auf den Dateikandidaten und die abgearbeitete Ereigniswarteschlange. Bestehende Zustands-, Fokus-, Stil-, Duplikat- und Generationenprüfungen unverändert. Beide betroffenen Tests zehnmal hintereinander erfolgreich; Lint und 18 Servertests erfolgreich. Reine Teständerung, kein App-Release erforderlich.
|
||||
- Release `2.1.50`: englischer GitHub- und inhaltlich gleichwertiger deutscher Forgejo-Changelog mit allen Änderungen seit `2.1.49`, Titel, Tag, jeweils vier Assets und Update-Metadaten verifiziert. Alle acht veröffentlichten Assets erneut heruntergeladen und per Größe/SHA-512 mit lokalen Dateien verglichen. Echter Updater mit Version `2.1.49` erkennt `2.1.50`, akzeptiert englische Release Notes, gültigen Veröffentlichungszeitpunkt und Forgejo-Manifest. Installer 98.034.441 Bytes, Portable 97.809.731 Bytes; beide Produktversion `2.1.50`. Öffentlicher Quellcheck einschließlich Screenshots erfolgreich (164 Dateien). Release-Commit `e51a4c5`, annotierter Tag `0c32d9a` auf beiden Remotes identisch. Lokaler Update-Anzeigetest vollständig entfernt; keine produktive Serveränderung.
|
||||
- Releasevorbereitung `2.1.50`: 845 Haupttests und 18 Backup-API-Tests erfolgreich, Lint erfolgreich, Produktionsaudit ohne Schwachstellen. Ausführliche englische/deutsche Release-Texte decken Änderungen seit `2.1.49` ab. Lokale Update-Simulation deaktiviert; Entwicklungslauncher verwendet wieder den echten Updater. Keine produktive Serveränderung erforderlich.
|
||||
- Update-Dialog nach `2.1.49`: Versionsmeldung von 12 auf 14 px erhöht. Updater reicht `published_at` als `publishedAt` weiter; Anzeige ergänzt lokale Veröffentlichungszeit als `TT.MM.JJJJ - HH:mm`, fehlende/ungültige Werte bleiben ausgeblendet. Deutsche und englische Übersetzung mit Datum geprüft. 40 Übersetzungs-/Updater-Tests, zwei gezielte Renderer-Tests und Lint ohne Warnungen erfolgreich. Laufende Entwicklung zeigt im lokalen Test `Update v2.1.50 verfügbar (22.09.2026 - 19:30)`; kein Release veröffentlicht.
|
||||
|
||||
@@ -44,15 +44,25 @@ const fs = require('node:fs');
|
||||
const assert = require('node:assert/strict');
|
||||
app.whenReady().then(async () => {
|
||||
const css = fs.readFileSync(process.env.MHU_CHECKBOX_CSS, 'utf8');
|
||||
const win = new BrowserWindow({ show: false, width: 500, height: 400 });
|
||||
const win = new BrowserWindow({ show: false, width: 500, height: 400, webPreferences: { backgroundThrottling: false } });
|
||||
const wc = win.webContents;
|
||||
async function waitForState(expression, accepts, action) {
|
||||
const deadline = Date.now() + 3000;
|
||||
let state;
|
||||
do {
|
||||
state = await wc.executeJavaScript(expression);
|
||||
if (accepts(state)) return state;
|
||||
await new Promise(resolve => setTimeout(resolve, 20));
|
||||
} while (Date.now() < deadline);
|
||||
throw new Error(action + ' did not complete: ' + JSON.stringify(state));
|
||||
}
|
||||
await win.loadURL('data:text/html;charset=utf-8,' + encodeURIComponent('<style>' + css + '</style><button id="before">Before</button><input id="check" class="hs-input" type="checkbox"><input id="number" class="hs-input" type="number" value="5">'));
|
||||
wc.focus();
|
||||
const point = await wc.executeJavaScript('(() => { const r = document.getElementById("check").getBoundingClientRect(); return { x: Math.round(r.x + r.width / 2), y: Math.round(r.y + r.height / 2) }; })()');
|
||||
for (const expected of [true, false]) {
|
||||
wc.sendInputEvent({ type: 'mouseDown', button: 'left', clickCount: 1, ...point });
|
||||
wc.sendInputEvent({ type: 'mouseUp', button: 'left', clickCount: 1, ...point });
|
||||
const state = await wc.executeJavaScript('(() => { const c = document.getElementById("check"); const s = getComputedStyle(c); return { checked: c.checked, shadow: s.boxShadow, outline: s.outlineStyle }; })()');
|
||||
const state = await waitForState('(() => { const c = document.getElementById("check"); const s = getComputedStyle(c); return { checked: c.checked, shadow: s.boxShadow, outline: s.outlineStyle }; })()', state => state.checked === expected, 'Checkbox mouse click');
|
||||
assert.equal(state.checked, expected);
|
||||
assert.equal(state.shadow, 'none');
|
||||
assert.equal(state.outline, 'none');
|
||||
@@ -60,13 +70,13 @@ app.whenReady().then(async () => {
|
||||
await wc.executeJavaScript('document.getElementById("before").focus()');
|
||||
wc.sendInputEvent({ type: 'keyDown', keyCode: 'Tab' });
|
||||
wc.sendInputEvent({ type: 'keyUp', keyCode: 'Tab' });
|
||||
const keyboard = await wc.executeJavaScript('(() => { const c = document.getElementById("check"); return { active: document.activeElement === c, visible: c.matches(":focus-visible"), outline: getComputedStyle(c).outlineStyle }; })()');
|
||||
const keyboard = await waitForState('(() => { const c = document.getElementById("check"); return { active: document.activeElement === c, visible: c.matches(":focus-visible"), outline: getComputedStyle(c).outlineStyle }; })()', state => state.active, 'Checkbox Tab focus');
|
||||
assert.equal(keyboard.active, true);
|
||||
assert.equal(keyboard.visible, true);
|
||||
assert.notEqual(keyboard.outline, 'none');
|
||||
wc.sendInputEvent({ type: 'keyDown', keyCode: 'Space' });
|
||||
wc.sendInputEvent({ type: 'keyUp', keyCode: 'Space' });
|
||||
assert.equal(await wc.executeJavaScript('document.getElementById("check").checked'), true);
|
||||
assert.equal(await waitForState('document.getElementById("check").checked', checked => checked, 'Checkbox Space toggle'), true);
|
||||
assert.notEqual(await wc.executeJavaScript('document.getElementById("number").focus(); getComputedStyle(document.getElementById("number")).boxShadow'), 'none');
|
||||
win.destroy();
|
||||
fs.writeFileSync(process.env.MHU_CHECKBOX_RESULT, JSON.stringify({ ok: true }));
|
||||
@@ -4889,7 +4899,7 @@ async function waitFor(read, timeoutMs = 20000) {
|
||||
rendererState = await waitFor(async () => {
|
||||
try {
|
||||
const state = await window.webContents.executeJavaScript("(() => { if (typeof queueJobs === 'undefined' || typeof automationEventQueue === 'undefined') return null; return { candidateNames: queueJobs.filter(job => job.fileName === 'scenario-ready.mkv').map(job => job.fileName), draining: Boolean(automationEventDrainPromise), pendingCandidates: automationEventQueue.size }; })()");
|
||||
return state && !state.draining && state.pendingCandidates === 0 ? state : null;
|
||||
return state && state.candidateNames.length > 0 && !state.draining && state.pendingCandidates === 0 ? state : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user