This commit is contained in:
Mateusz Gruszczyński committed 2026-11-08 06:20:03 +01:00
1 parent 5cb63f542c
commit 17e314e159
27 files changed
+1017 -291

No files matched your search

+61
View File
@@ -71,4 +71,65 @@ assert.match(shellCss, /prefers-reduced-motion: reduce[\s\S]*data-logo-effect/);
assert.equal(openapi.components.schemas.AdminPreferences.properties.logo_animation.default, false);
assert.ok(pl.translations.logoAnimation && pl.translations.logoAnimationHelp);
// Mobile/Safari regression: injected icons must never be mistaken for chart SVGs or
// stretched by descendant chart rules, and refreshes must not rebuild decorated buttons.
const runtimeJs = read("src/admin/web/app/runtime.js");
const scalesJs = read("src/admin/web/app/chart-scales.js");
const editorsCss = read("src/admin/web/css/40-editors.css");
assert.match(runtimeJs, /row\.querySelector\("svg:not\(\.ui-icon\)"\)/);
assert.doesNotMatch(runtimeJs, /row\.querySelector\("svg"\)/);
assert.match(runtimeJs, /querySelector\(":scope > svg\.ui-icon"\)/);
assert.match(scalesJs, /svg\.classList\.contains\("ui-icon"\)/);
assert.match(scalesJs, /querySelectorAll\("svg:not\(\.ui-icon\)"\)/);
for (const source of [css, overviewCss, editorsCss]) assert.doesNotMatch(source, /(^|\n)[^\n{}]*(\.network-interface-row|\.stat-chart|\.activity-card|\.system-card|\.function-live-chart|\.mini-live-chart|\.vhost-chart|\.connection-card) svg[ ,{]/, "descendant chart svg rules must exclude .ui-icon");
assert.match(css, /html\[data-interface-icons="true"\] :is\(button, a, summary\)>svg\.ui-icon/);
assert.match(icons, /\.mobile-menu-toggle"\) return null|draft-dock-toggle, \.mobile-menu-toggle/);
assert.match(editorsCss, /Spacing review \(0\.36\.2\)/);
assert.match(editorsCss, /\.vhost-backend-protocol-badge \{[^}]*letter-spacing: 1px;[^}]*\}/);
assert.match(editorsCss, /\.tls-pqc-control>a/);
console.log("Panel SVG icon preference contract: OK");
// CSS cleanup (0.36.3): the legacy body[data-density] mechanism must not come back.
{
const cssDir = path.join(__dirname, "..", "src", "admin", "web", "css");
for (const name of fs.readdirSync(cssDir).filter((file) => file.endsWith(".css"))) {
assert.doesNotMatch(fs.readFileSync(path.join(cssDir, name), "utf8"), /body\[data-density/, `${name} still has legacy body[data-density] rules`);
}
}
// Cache outcomes bar shows percentages inside its segments and hides labels that do not fit.
{
const rt = fs.readFileSync(path.join(__dirname, "..", "src", "admin", "web", "app", "runtime.js"), "utf8");
assert.match(rt, /function fitCacheMixLabels/);
assert.match(rt, /segment\.textContent = mix && pct > 0/);
}
// Settings layout (0.36.3): rows pattern for Appearance and horizontal sub-tabs.
{
const css = fs.readFileSync(path.join(__dirname, "..", "src", "admin", "web", "css", "50-settings.css"), "utf8");
assert.match(css, /#settings-page-appearance \.appearance-settings-grid>label \{/);
assert.match(css, /#panel-settings \.settings-tabs\.sub-tabs \{\s*display: flex;\s*flex-direction: row;/);
}
// Chart styles (0.36.3): every style id must be wired through Rust validation, OpenAPI, JS, CSS tokens, the selector and the language pack.
{
const root = path.join(__dirname, "..");
const read = (file) => fs.readFileSync(path.join(root, file), "utf8");
const styles = ["default", "soft", "technical", "high_contrast", "neon", "monochrome", "warm", "cool", "sunset", "aurora", "ocean", "forest", "pastel", "terminal", "blueprint", "colorblind"];
const rust = read("src/admin/preferences.rs"), js = read("src/admin/web/app/preferences.js"), tokens = read("src/admin/web/css/00-tokens.css"), html = read("src/admin/web/index.html");
const openapi = JSON.parse(read("src/admin/openapi.json")).components.schemas;
const enumValues = JSON.stringify(openapi).match(/"chart_style":\{"type":"string","enum":(\[[^\]]*\])/);
assert.ok(enumValues, "chart_style enum must be present in OpenAPI");
const documented = JSON.parse(enumValues[1]);
for (const style of styles) {
assert.ok(documented.includes(style), `OpenAPI chart_style missing ${style}`);
assert.ok(rust.includes(`"${style}"`), `Rust validation missing ${style}`);
assert.ok(js.includes(`"${style}"`), `preferences.js missing ${style}`);
assert.ok(tokens.includes(`html[data-chart-style=${style}]`), `tokens missing ${style}`);
assert.ok(tokens.includes(`.chart-style-choice[data-chart-preset=${style}]`), `swatches missing ${style}`);
assert.ok(html.includes(`value="${style}"`), `selector missing ${style}`);
}
assert.equal(documented.length, styles.length, "OpenAPI chart_style enum must list exactly the supported styles");
}
+1 -1
View File
@@ -51,5 +51,5 @@ const events = openapi.paths["/api/events"].get;
const logsFlag = (events.parameters || []).find(parameter => parameter.name === "logs");
assert.equal(logsFlag?.schema?.type, "boolean");
assert.equal(logsFlag?.schema?.default, true);
assert.equal(openapi.info.version, "0.36.2");
assert.equal(openapi.info.version, "0.36.3");
console.log("Panel refresh/API contract checks: OK");