Compare commits

..

2 Commits

Author SHA1 Message Date
Kantine Wrapper
37afc2957b chore: update build artifacts for v1.4.18 2026-02-24 20:50:20 +01:00
Kantine Wrapper
b1763135aa test(ui): massively expand DOM testing suite to cover all Modals and Actions (v1.4.18) 2026-02-24 20:50:19 +01:00
7 changed files with 109 additions and 17 deletions

View File

@@ -1,3 +1,6 @@
## v1.4.18
- 🧪 **Testing**: Die automatische DOM-Testing Suite (`test_dom.js`) wurde massiv ausgebaut. Sie prüft nun neben der Alarmglocke und den Highlights auch systematisch alle anderen UI-Komponenten (Login-Modal, History-Modal, Versionen-Modal, Theme-Toggle, und Navigation Tabs) auf korrekte Event-Listener-Bindungen, um Regressionen (tote Buttons) endgültig auszuschließen.
## v1.4.17 ## v1.4.17
- 🐛 **Bugfix**: Regression behoben: Der "Persönliche Highlights" (Stern-Button) Dialog öffnet sich nun wieder korrekt. - 🐛 **Bugfix**: Regression behoben: Der "Persönliche Highlights" (Stern-Button) Dialog öffnet sich nun wieder korrekt.
- 🧪 **Testing**: Es wurde ein initialer UI-Testing-Hook (`test_dom.js` mit `jsdom`) in die Build-Pipeline integriert, um kritische DOM Event-Listener Regressionen (wie den Highlights-Button und die Alarmglocke) automatisch zu preventen. - 🧪 **Testing**: Es wurde ein initialer UI-Testing-Hook (`test_dom.js` mit `jsdom`) in die Build-Pipeline integriert, um kritische DOM Event-Listener Regressionen (wie den Highlights-Button und die Alarmglocke) automatisch zu preventen.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

16
dist/install.html vendored

File diff suppressed because one or more lines are too long

View File

@@ -2021,7 +2021,7 @@ body {
<div class="brand"> <div class="brand">
<span class="material-icons-round logo-icon">restaurant_menu</span> <span class="material-icons-round logo-icon">restaurant_menu</span>
<div class="header-left"> <div class="header-left">
<h1>Kantinen Übersicht <small class="version-tag" style="font-size: 0.6em; opacity: 0.7; font-weight: 400; cursor: pointer;" title="Klick für Versionsmenü">v1.4.17</small></h1> <h1>Kantinen Übersicht <small class="version-tag" style="font-size: 0.6em; opacity: 0.7; font-weight: 400; cursor: pointer;" title="Klick für Versionsmenü">v1.4.18</small></h1>
<div id="last-updated-subtitle" class="subtitle"></div> <div id="last-updated-subtitle" class="subtitle"></div>
</div> </div>
<div class="nav-group" style="margin-left: 1rem;"> <div class="nav-group" style="margin-left: 1rem;">
@@ -2163,7 +2163,7 @@ body {
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div style="margin-bottom: 1rem;"> <div style="margin-bottom: 1rem;">
<strong>Aktuell:</strong> <span id="version-current">v1.4.17</span> <strong>Aktuell:</strong> <span id="version-current">v1.4.18</span>
</div> </div>
<div class="dev-toggle"> <div class="dev-toggle">
<label style="display:flex;align-items:center;gap:8px;cursor:pointer;"> <label style="display:flex;align-items:center;gap:8px;cursor:pointer;">
@@ -4010,7 +4010,7 @@ body {
// Periodic update check (runs on init + every hour) // Periodic update check (runs on init + every hour)
async function checkForUpdates() { async function checkForUpdates() {
const currentVersion = 'v1.4.17'; const currentVersion = 'v1.4.18';
const devMode = localStorage.getItem('kantine_dev_mode') === 'true'; const devMode = localStorage.getItem('kantine_dev_mode') === 'true';
try { try {
@@ -4051,7 +4051,7 @@ body {
const modal = document.getElementById('version-modal'); const modal = document.getElementById('version-modal');
const container = document.getElementById('version-list-container'); const container = document.getElementById('version-list-container');
const devToggle = document.getElementById('dev-mode-toggle'); const devToggle = document.getElementById('dev-mode-toggle');
const currentVersion = 'v1.4.17'; const currentVersion = 'v1.4.18';
if (!modal) return; if (!modal) return;
modal.classList.remove('hidden'); modal.classList.remove('hidden');

View File

@@ -29,6 +29,43 @@ const html = `
<button id="btn-add-tag">Add</button> <button id="btn-add-tag">Add</button>
<ul id="tags-list"></ul> <ul id="tags-list"></ul>
</div> </div>
<!-- Mocks for Login Modal -->
<button id="btn-login-open">Login</button>
<div id="login-modal" class="modal hidden">
<button id="btn-login-close">Close</button>
<form id="login-form"></form>
<div id="login-error" class="hidden"></div>
</div>
<!-- Mocks for History Modal -->
<button id="btn-history">History</button>
<div id="history-modal" class="modal hidden">
<button id="btn-history-close">Close</button>
<div id="history-loading" class="hidden"></div>
<div id="history-content"></div>
</div>
<!-- Mocks for Version Modal -->
<span class="version-tag">v1.4.17</span>
<div id="version-modal" class="modal hidden">
<button id="btn-version-close">Close</button>
<button id="btn-clear-cache">Clear</button>
<span id="version-current"></span>
<div id="version-list-container"></div>
</div>
<!-- Mocks for Theme Toggle -->
<button id="theme-toggle"><span class="theme-icon">light_mode</span></button>
<!-- Mocks for Navigation Tabs -->
<button id="btn-this-week" class="active">This Week</button>
<button id="btn-next-week">Next Week</button>
<button id="btn-refresh">Refresh</button>
<button id="btn-logout">Logout</button>
<div class="order-history-header">Header</div>
<button id="btn-error-redirect">Error Redirect</button>
</body> </body>
</html> </html>
`; `;
@@ -37,7 +74,8 @@ log("Reading file jsCode...");
const jsCode = fs.readFileSync('kantine.js', 'utf8') const jsCode = fs.readFileSync('kantine.js', 'utf8')
.replace('(function () {', '') .replace('(function () {', '')
.replace('})();', '') .replace('})();', '')
.replace('if (window.__KANTINE_LOADED) return;', ''); .replace('if (window.__KANTINE_LOADED) return;', '')
.replace('window.location.reload();', 'window.__RELOAD_CALLED = true;');
log("Instantiating JSDOM..."); log("Instantiating JSDOM...");
const dom = new JSDOM(html, { runScripts: "dangerously", url: "http://localhost/" }); const dom = new JSDOM(html, { runScripts: "dangerously", url: "http://localhost/" });
@@ -74,9 +112,6 @@ const testCode = `
const hlModal = document.getElementById('highlights-modal'); const hlModal = document.getElementById('highlights-modal');
if (!hlModal.classList.contains('hidden')) throw new Error("Highlights modal should be hidden initially"); if (!hlModal.classList.contains('hidden')) throw new Error("Highlights modal should be hidden initially");
// Call bindEvents manually to attach the listeners since the IIFE is stripped
bindEvents();
// Click to open // Click to open
document.getElementById('btn-highlights').click(); document.getElementById('btn-highlights').click();
if (hlModal.classList.contains('hidden')) throw new Error("Highlights modal did not open upon clicking btn-highlights!"); if (hlModal.classList.contains('hidden')) throw new Error("Highlights modal did not open upon clicking btn-highlights!");
@@ -87,6 +122,56 @@ const testCode = `
console.log("✅ Highlights Modal Test Passed"); console.log("✅ Highlights Modal Test Passed");
console.log("--- Testing Login Modal ---");
const loginModal = document.getElementById('login-modal');
document.getElementById('btn-login-open').click();
if (loginModal.classList.contains('hidden')) throw new Error("Login modal should open");
document.getElementById('btn-login-close').click();
if (!loginModal.classList.contains('hidden')) throw new Error("Login modal should close");
console.log("✅ Login Modal Test Passed");
console.log("--- Testing History Modal ---");
// We need authToken to be truthy to open history modal
authToken = "fake_token";
const historyModal = document.getElementById('history-modal');
document.getElementById('btn-history').click();
if (historyModal.classList.contains('hidden')) throw new Error("History modal should open");
document.getElementById('btn-history-close').click();
if (!historyModal.classList.contains('hidden')) throw new Error("History modal should close");
console.log("✅ History Modal Test Passed");
console.log("--- Testing Version Modal ---");
const versionModal = document.getElementById('version-modal');
document.querySelector('.version-tag').click();
if (versionModal.classList.contains('hidden')) throw new Error("Version modal should open");
document.getElementById('btn-version-close').click();
if (!versionModal.classList.contains('hidden')) throw new Error("Version modal should close");
console.log("✅ Version Modal Test Passed");
console.log("--- Testing Theme Toggle ---");
const themeBtn = document.getElementById('theme-toggle');
const initialTheme = document.documentElement.getAttribute('data-theme');
themeBtn.click();
const newTheme = document.documentElement.getAttribute('data-theme');
if (initialTheme === newTheme) throw new Error("Theme did not toggle");
console.log("✅ Theme Toggle Test Passed");
console.log("--- Testing Navigation Tabs ---");
const btnThis = document.getElementById('btn-this-week');
const btnNext = document.getElementById('btn-next-week');
btnNext.click();
if (!btnNext.classList.contains('active') || btnThis.classList.contains('active')) throw new Error("Next week tab not active");
btnThis.click();
if (!btnThis.classList.contains('active') || btnNext.classList.contains('active')) throw new Error("This week tab not active");
console.log("✅ Navigation Tabs Test Passed");
console.log("--- Testing Clear Cache Button ---");
// Mock confirm directly inside evaluated JSDOM context
window.confirm = () => true;
document.getElementById('btn-clear-cache').click();
if (!window.__RELOAD_CALLED) throw new Error("Clear cache did not reload the page");
console.log("✅ Clear Cache Button Test Passed");
window.__TEST_PASSED = true; window.__TEST_PASSED = true;
`; `;

View File

@@ -1 +1 @@
v1.4.17 v1.4.18