import assert from 'node:assert/strict'; import { JSDOM } from 'jsdom'; // Minimal DOM matching index.html's tab contract const HTML = `
`; const dom = new JSDOM(HTML, { url: 'http://localhost/' }); global.window = dom.window; global.document = dom.window.document; global.localStorage = dom.window.localStorage; dom.window.alert = () => {}; global.alert = () => {}; const $ = sel => document.querySelector(sel); const tab = name => [...document.querySelectorAll('.tab-btn')].find(b => b.dataset.tab === name); const btnByText = (root, text) => [...root.querySelectorAll('button')].find(b => b.textContent === text); const fire = (el, type) => el.dispatchEvent(new dom.window.Event(type, { bubbles: true })); // Importing app.js runs the startup load + renderEmployees() const { state } = await import('../js/app.js'); // --- Employees tab renders its input --- assert.ok($('#emp-name-input'), 'employee name input rendered'); // --- Adding an employee updates state and the list --- const input = $('#emp-name-input'); input.value = 'Alice'; btnByText(document.getElementById('tab-employees'), 'Hinzufügen').click(); input.value = 'Bob'; btnByText(document.getElementById('tab-employees'), 'Hinzufügen').click(); assert.equal(state.employees.length, 2, 'two employees added to state'); assert.ok(document.getElementById('employee-list').textContent.includes('Alice'), 'Alice listed'); // --- Planning tab renders a calendar grid (exercises makeDayCell) --- tab('planning').click(); const dayCells = document.querySelectorAll('#calendar-wrapper .cal-day'); assert.ok(dayCells.length > 0, 'calendar grid rendered day cells'); // --- Generating a plan fills slots --- btnByText(document.getElementById('tab-planning'), 'Plan generieren').click(); const selects = [...document.querySelectorAll('#calendar-wrapper select')]; const filled = selects.filter(s => s.value !== ''); assert.ok(filled.length > 0, 'generate assigned moderators to slots'); assert.ok(state.history.length > 0, 'generated assignments stored in history'); // --- Manual slot change persists as a manual entry --- const histBefore = state.history.length; const firstFilled = filled[0]; const iso = state.history[0].date; // change first filled slot to "— Leer —" firstFilled.value = ''; fire(firstFilled, 'change'); assert.ok(state.history.length <= histBefore, 'clearing a slot removed its entry'); // --- Debounced save flushes on beforeunload and persists to localStorage --- fire(window, 'beforeunload'); const saved = JSON.parse(localStorage.getItem('morning-planner-state')); assert.equal(saved.employees.length, 2, 'employees persisted to localStorage'); assert.ok(saved.history.length > 0, 'history persisted to localStorage'); // --- Data tab renders the history table --- tab('data').click(); assert.ok(document.getElementById('tab-data').textContent.includes('Verlauf'), 'data tab rendered'); console.log('All render tests passed.');