This commit is contained in:
Mateusz Gruszczyński committed 2026-10-13 00:57:19 +02:00
1 parent 81ab39e70a
commit 101df02a5f
45 files changed
+1148 -2277

No files matched your search

@@ -13,14 +13,14 @@ assert(html.includes('id="panel-overview"'));
for (const id of ids) assert(html.includes(`data-dashboard-widget="${id}"`));
assert.doesNotMatch(css, /#panel-overview \.stats-grid \.stat:is\(:hover, :focus-visible, :focus-within\)/,
'Overview details must never become hover/focus popovers');
assert.match(css, /#panel-overview \.stats-grid \.stat-chart > \.stat-chart-legend/,
assert.match(css, /#panel-overview \.stats-grid \.stat-chart\s*>\s*\.stat-chart-legend/,
'in-card chart legends must be visible, including on touch devices');
assert.match(css, /#panel-overview \.stats-grid \{ grid-template-columns: repeat\(6, minmax\(0, 1fr\)\); \}/,
assert.match(css, /#panel-overview \.stats-grid\s*\{\s*grid-template-columns:\s*repeat\(6, minmax\(0, 1fr\)\);\s*\}/,
'desktop Overview must retain the original six cards per row');
assert.doesNotMatch(css, /#panel-overview \.stats-grid \{ grid-template-columns: repeat\(4, minmax\(0, 1fr\)\); \}/,
assert.doesNotMatch(css, /#panel-overview \.stats-grid\s*\{\s*grid-template-columns:\s*repeat\(4, minmax\(0, 1fr\)\);\s*\}/,
'do not replace the original six-column Overview with a four-column layout');
assert.match(css, /#panel-overview \.stats-grid > \.stat \{ min-height: 126px;/,
'cards should be tall enough for their inline metric legends');
assert.doesNotMatch(css, /#panel-overview \.stats-grid\s*>\s*\.stat\s*\{[^}]*\bmin-height\s*:/s,
'0.32.0 fixed height produced empty tiles; let inline metric legends size the row');
assert.match(html, /id="stream-dashboard-traffic-detail"/);
assert.match(html, /id="stream-dashboard-rx-rate"/);
assert.match(html, /id="stream-dashboard-tx-rate"/);
@@ -95,9 +95,38 @@ assert.equal(elements.get('stream-dashboard-overview-detail').textContent, 'stre
context.applyAdminPreferencesTest({ dashboard_widgets: cardIds, dashboard_hidden_widgets: ids });
assert(ids.every(id => cards.get(id).hidden), 'hiding cards must still work');
assert(!cards.get('requests').hidden, 'legacy widgets must retain their visibility');
assert.match(css, /dashboard-widget-setting:is\(:hover, :focus-within\) \.dashboard-widget-description/, 'description is a tooltip');
assert.match(css, /\.dashboard-widget-description \{[^}]*position: absolute/s, 'tooltip must not occupy a second row');
assert.match(prefsSource, /toggle\.setAttribute\("aria-describedby", description\.id\)/, 'description must be accessible');
// 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.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; } };
const makeElement = (tag, text, className) => ({
tag, textContent: text || '', className, dataset: {}, children: [], attributes: {},
classList: { toggle() {} }, setAttribute(name, value) { this.attributes[name] = value; },
append(...children) { this.children.push(...children); }, addEventListener() {},
});
for (const card of cards.values()) card.querySelector = () => ({ textContent: card.dataset.dashboardWidget });
elements.set('dashboard-widget-list', widgetList);
context.el = makeElement;
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');
for (const id of ids) {
const row = widgetList.children.find(item => item.dataset.dashboardWidgetSetting === id);
const button = row.children[0];
const key = ({ stream_overview: 'streamWidgetOverviewDescription',
stream_traffic: 'streamWidgetTrafficDescription', stream_sessions: 'streamWidgetSessionsDescription',
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(widgetList.children.filter(row => row.title).length, 4,
'only the four translated Stream descriptions have tooltip text');
// 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');
@@ -117,4 +146,4 @@ for (const locale of [pl, en]) {
}
assert.equal(pl.streamMetricsFromStream, 'Z ustawień Stream');
assert.equal(pl.streamMetricsDefaultOff, 'Domyślnie wyłączone');
console.log('PASS: Stream visibility, inline Overview legends, preserved Appearance tooltip and Vhost enable label.');
console.log('PASS: Stream visibility, inline Overview legends, scroll-safe native Appearance tooltips and Vhost enable label.');