// Run with: node tests/modal_frontend_0346.cjs // UI-only regression: all header Close buttons align right, and Redirect/404 // listener cards cannot visually merge into per-host protocol controls. 'use strict'; const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const read = file => fs.readFileSync(path.join(__dirname, '..', file), 'utf8'); const html = read('src/admin/web/index.html'); const css = read('src/admin/web/style.css'); const dialog = id => { const start = html.indexOf(`id="${id}"`); assert.ok(start >= 0, `Missing ${id}`); const close = html.indexOf('', start); assert.ok(close > start, `Missing dialog end for ${id}`); return html.slice(start, close); }; const rightAligned = css.match(/\.window-heading\s*>\s*button\[data-i18n="close"\]\s*\{([^}]+)\}/); assert.ok(rightAligned, 'A shared header Close rule must exist'); assert.match(rightAligned[1], /margin-inline-start:\s*auto\s*;/); assert.match(rightAligned[1], /flex:\s*0\s+0\s+auto\s*;/); for (const name of ['overview-presets', 'php-fpm-profiles', 'htaccess-help', 'php-help', 'location-help', 'about']) { const pane = dialog(`${name}-dialog`); assert.match(pane, /class="window-heading"/); assert.match(pane, new RegExp(`]*id="${name}-close")(?=[^>]*data-i18n="close")[^>]*>`)); } // The existing grouped actions use .window-tools and retain their right alignment. assert.match(css, /\.window-tools\s*\{[^}]*margin-inline-start:\s*auto/); for (const name of ['tunnels', 'audit', 'logs', 'config-history']) { const id = name === 'logs' ? 'logs-dialog' : name === 'audit' ? 'audit-dialog' : `${name}-dialog`; assert.match(dialog(id), /class="window-tools"/); } const frontendStyles = css.match(/\.frontend-protocol-controls\s*\{([^}]+)\}/); assert.ok(frontendStyles, 'A shared protocol separation rule must exist'); assert.match(frontendStyles[1], /margin-block-start:\s*16px\s*;/); assert.match(frontendStyles[1], /padding-block-start:\s*12px\s*;/); assert.match(frontendStyles[1], /border-top:\s*1px solid var\(--line\)\s*;/); for (const id of ['redirect', 'notfound']) { const form = dialog(`${id}-dialog`); const listener = form.indexOf(`id="${id}-listeners"`); const protocol = form.indexOf('class="frontend-protocol-controls"'); const label = form.indexOf('data-i18n="vhProtocols"'); const h2 = form.indexOf(`id="${id}-http2"`); const h3 = form.indexOf(`id="${id}-http3"`); assert.ok(listener > 0 && protocol > listener && label > protocol && h2 > label && h3 > h2); assert.equal(form.match(/class="frontend-protocol-controls"/g)?.length, 1); for (const field of [`${id}-listeners`, `${id}-http2`, `${id}-http3`]) assert.equal((html.match(new RegExp(`id="${field}"`, 'g')) || []).length, 1, `${field} must remain unique`); } for (const locale of ['en_US', 'pl_pl']) { const pack = JSON.parse(read(`langs/${locale}.json`)).translations; assert.ok(pack.vhProtocols); assert.equal(pack.aboutLicenseValue, 'GNU AGPL v3'); } assert.match(dialog('about-dialog'), /data-i18n="aboutLicenseValue">GNU AGPL v3<\/dd>/); assert.match(read('Cargo.toml'), /^version = "0\.34\.6"$/m); assert.equal(JSON.parse(read('src/admin/openapi.json')).info.version, '0.34.6'); console.log('0.34.6 modal Close alignment, Redirect/404 spacing, About and version: PASS');