// Run with: node --test e2e_tests/invoice-provisionperiod.cjs const { test } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const { chromium } = require('playwright'); const root = path.resolve(__dirname, '..'); const read = (file) => fs.readFileSync(path.join(root, file), 'utf8'); test('service dates and periods survive entry, editing and reopening', async () => { const browser = await chromium.launch({ headless: true, channel: process.env.PLAYWRIGHT_CHANNEL || (process.platform === 'win32' ? 'msedge' : undefined) }); try { const page = await browser.newPage({ timezoneId: 'Europe/Berlin' }); await page.setContent(''); for (const file of [ 'Fuchs/wwwroot/lib/jquery/jquery.js', 'Fuchs/js/intranet/oci_texts_basic_de.js', 'Fuchs/js/intranet/oci_basic.js', 'Fuchs/js/intranet/oci_mainbase.js', 'Fuchs/js/intranet/oci_main.js' ]) { await page.addScriptTag({ content: read(file) }); } // Use the production form builder/serializer and dialog submit handler; // only the modal shell and server transport are replaced locally. const source = read('Fuchs/js/intranet/modules/fis.inv_shared.js'); await page.addScriptTag({ content: 'var $inv = { d: { sync: function(delta) { window.lastDelta = delta; } } };\n' + source.slice(source.indexOf('$inv.provToIso ='), source.indexOf('/* Main recipient + CC')) }); const results = await page.evaluate(() => { let dialog; $ocms.dlg = (content, options) => { dialog = { content, options }; return dialog; }; function open(value) { const t = $('').text(value); const changes = []; $inv.eProvisionPeriod({ data: { t, change: (value) => changes.push(value) } }); return { t, changes, fields: dialog.content.find('input').map((i, e) => e.value).get() }; } const cases = [ ['', '2026-10-06', '', '06.10.2026'], ['', '2026-10-01', '2026-10-06', '01.10.2026 - 06.10.2026'], ['18.06.2026', '2026-10-06', '', '06.10.2026'], ['01.06.2026 - 30.06.2026', '2026-10-01', '2026-10-06', '01.10.2026 - 06.10.2026'], ['18.06.2026', '2026-10-01', '2026-10-06', '01.10.2026 - 06.10.2026'], ['01.06.2026 - 30.06.2026', '2026-10-06', '', '06.10.2026'], ['2026-06-18', '2026-10-06', '', '06.10.2026'], ['2026-06-01 - 2026-06-30', '2026-10-01', '2026-10-06', '01.10.2026 - 06.10.2026'], ['18.06.2026', '', '', ''], ['', '2026-10-06', '2026-10-06', '06.10.2026'] ]; const dates = cases.map(([initial, von, bis, expected]) => { const entry = open(initial); dialog.content.find('[name=von]').val(von); dialog.content.find('[name=bis]').val(bis); dialog.options.confirm.call(dialog.content[0]); const saved = window.lastDelta; return { initial, von, bis, expected, saved, displayed: entry.t.text(), changes: entry.changes, prefilled: entry.fields, reopened: open(saved.Value).fields }; }); const optional = $('
'); const emptyOptional = optional.serializeObject(true); const emptyOptionalTyped = optional.serializeObject(true, { typedvalues: true }); optional.find('input').prop('required', true); const emptyRequired = optional.serializeObject(true); let submitted = false; $ocms.dlgform([{ name: 'date', type: 'date', required: true }], { success: () => { submitted = true; } }); dialog.options.confirm.call(dialog.content[0]); return { dates, emptyOptional, emptyOptionalTyped, emptyRequired, submitted }; }); for (const row of results.dates) { const label = JSON.stringify([row.initial, row.von, row.bis]); assert.deepEqual(row.saved, { Target: 'provisionperiod', Value: row.expected }, label); assert.equal(row.displayed, row.expected, label); assert.deepEqual(row.changes, [row.expected], label); assert.deepEqual(row.reopened, row.von ? [row.von, row.bis === row.von ? '' : row.bis] : ['', ''], label); } assert.deepEqual(results.dates[2].prefilled, ['2026-06-18', '']); assert.deepEqual(results.dates[3].prefilled, ['2026-06-01', '2026-06-30']); assert.deepEqual(results.dates[6].prefilled, ['2026-06-18', '']); assert.deepEqual(results.dates[7].prefilled, ['2026-06-01', '2026-06-30']); assert.deepEqual(results.emptyOptional, { date: '' }); assert.deepEqual(results.emptyOptionalTyped, { date: '' }); assert.equal(results.emptyRequired, null); assert.equal(results.submitted, false, 'invalid forms must not invoke success and clear existing values'); } finally { await browser.close(); } });