This commit is contained in:
Mateusz Gruszczyński committed 2026-10-13 21:29:57 +02:00
1 parent bb025dcf44
commit b0f211555a
74 files changed
+6089 -556

No files matched your search

@@ -24,11 +24,12 @@ assert.doesNotMatch(css, /#panel-overview \.stats-grid\s*>\s*\.stat\s*\{[^}]*\bm
assert.match(html, /id="stream-dashboard-traffic-detail"/);
assert.match(html, /id="stream-dashboard-rx-rate"/);
assert.match(html, /id="stream-dashboard-tx-rate"/);
assert.doesNotMatch(html.slice(html.indexOf('id="panel-overview"'), html.indexOf('class="overview-grid"')), /<article[^>]*tabindex="0"/,
assert.doesNotMatch(html.slice(html.indexOf('id="panel-overview"'), html.indexOf('id="panel-vhosts"')), /<article[^>]*tabindex="0"/,
'metric cards must not introduce redundant keyboard stops');
const cardIds = [...html.matchAll(/<article class="stat[^"]*" data-dashboard-widget="([^"]+)"/g)].map(m => m[1]);
assert.equal(cardIds.length, 16, 'existing Overview cards must be retained');
assert.equal(cardIds.filter(id => !id.startsWith('backend_') && !id.startsWith('extra_')).length, 16, 'original Overview cards must be retained');
assert.equal(cardIds.length, 48, '30 existing metric/Stream/backend tiles and 18 optional small charts must be registered');
const cards = new Map(cardIds.map(id => [id, { dataset: { dashboardWidget: id }, hidden: id.startsWith('stream_') }]));
const grid = { querySelectorAll: () => [...cards.values()], append(node) { assert(cards.has(node.dataset.dashboardWidget)); } };
const elements = new Map();
@@ -53,15 +54,16 @@ const context = {
normalizeRefreshPreferences: v => v || {}, renderRefreshPreferences() {},
applyAdminTheme: v => v, applyAdminLanguage: v => v, applyAdminUiScale: v => v,
applyAdminTimeFormat: v => v, applyAdminChartStyle: v => v,
applyAdminButtonStyle: v => v, applyAdminTableDensity: v => v,
applyAdminButtonStyle: v => v, applyAdminCornerStyle: v => v, applyAdminTableDensity: v => v,
applyAdminDashboardDensity: v => v, refreshAppearanceUi() {},
};
vm.createContext(context);
const registryPrelude = `const ADMIN_DASHBOARD_WIDGET_REGISTRY = Object.freeze(${fs.readFileSync("src/admin/web/dashboard-widgets.json", "utf8")});`;
const constants = prefsSource.slice(prefsSource.indexOf('const ADMIN_DASHBOARD_WIDGETS'), prefsSource.indexOf('const CHART_STYLE_KEYS'));
const normalize = prefsSource.slice(prefsSource.indexOf('function normalizeDashboardWidgets'), prefsSource.indexOf('function browserLanguage'));
const applyLayout = prefsSource.slice(prefsSource.indexOf('function applyDashboardLayout'), prefsSource.indexOf('function dashboardWidgetLabel'));
const applyPreferences = prefsSource.slice(prefsSource.indexOf('function applyAdminPreferences'), prefsSource.indexOf('try { applyAdminTheme('));
vm.runInContext(`${constants}\n${normalize}\nlet adminPreferences = null;\n${applyLayout}\n${applyPreferences}\nthis.getPrefs = () => adminPreferences;\nthis.applyAdminPreferencesTest = applyAdminPreferences;`, context);
vm.runInContext(`${registryPrelude}\n${constants}\n${normalize}\nlet adminPreferences = null;\n${applyLayout}\n${applyPreferences}\nthis.getPrefs = () => adminPreferences;\nthis.applyAdminPreferencesTest = applyAdminPreferences;`, context);
window.rustProxyPreferences = { current: () => context.getPrefs() };
vm.runInContext(streamSource, context);
@@ -97,8 +99,8 @@ assert(ids.every(id => cards.get(id).hidden), 'hiding cards must still work');
assert(!cards.get('requests').hidden, 'legacy widgets must retain their visibility');
// Native title tooltips do not participate in layout or create horizontal scroll.
assert.doesNotMatch(css, /dashboard-widget-(?:description|setting-label-block)/, 'obsolete custom tooltip styles must be removed');
assert.match(css, /grid-template-columns: repeat\(auto-fit, minmax\(min\(180px, 100%\), 1fr\)\)/,
'settings card columns must fit even a narrower mobile container');
assert.match(css, /grid-template-columns: repeat\(auto-fit, minmax\(min\(260px, 100%\), 1fr\)\)/,
'effective Appearance card columns must preserve a readable name and right-aligned arrows');
assert.doesNotMatch(prefsSource, /role", "tooltip"|aria-describedby|dashboard-widget-description/,
'old popover DOM and associations must be removed');
const widgetList = { children: [], replaceChildren(...children) { this.children = children; } };
@@ -114,7 +116,7 @@ context.CSS = { escape: value => value };
vm.runInContext(prefsSource.slice(prefsSource.indexOf('function dashboardWidgetLabel'),
prefsSource.indexOf('function refreshChartStylePalette')), context);
context.renderDashboardWidgetSettings();
assert.equal(widgetList.children.length, cardIds.length, 'all cards retain settings controls');
assert.equal(widgetList.children.length, 62, 'all cards and full-width panels retain settings controls');
for (const id of ids) {
const row = widgetList.children.find(item => item.dataset.dashboardWidgetSetting === id);
const button = row.children[0];
@@ -123,10 +125,12 @@ for (const id of ids) {
stream_backend_health: 'streamWidgetHealthDescription' })[id];
assert.equal(row.title, key, `${id} must have a localized browser tooltip`);
assert.equal(button.attributes['aria-description'], key, 'the tooltip must remain accessible');
assert.equal(button.children.length, 2, 'label must not contain an injected custom tooltip');
assert.equal(button.children.length, 2, 'Appearance shows only the visibility indicator and label');
assert.equal(row.children.length, 2, 'Appearance keeps badge metadata in the visual editor, not in each setting');
assert.equal(row.children[1].className, 'dashboard-widget-setting-actions', 'move actions remain on the right');
}
assert.equal(widgetList.children.filter(row => row.title).length, 4,
'only the four translated Stream descriptions have tooltip text');
assert.equal(widgetList.children.filter(row => row.title).length, 50,
'Stream, backend, performance and full-panel entries have translated descriptions');
// Editor-specific regressions: avoid the redundant enable hint and label the
// two distinct inheritance layers instead of saying "Inherit" everywhere.
const editor = fs.readFileSync('src/admin/web/streams.js', 'utf8');