fix(ui): resolve design checks and cross-platform test failures
Deploy / Test, build & deploy (push) Failing after 2m10s Details

This commit is contained in:
Binh 2026-08-24 15:36:41 +02:00
parent df59048587
commit 7ba69494e1
8 changed files with 22 additions and 21 deletions

View File

@ -101,7 +101,7 @@ export function ResizableResultTable({ headers, children, enabled = false, class
return ( return (
<table ref={tableRef} className={`${className}${enabled ? ' is-column-resizable' : ''}${appliedWidths.length ? ' has-custom-column-widths' : ''}`} style={tableStyle}> <table ref={tableRef} className={`${className}${enabled ? ' is-column-resizable' : ''}${appliedWidths.length ? ' has-custom-column-widths' : ''}`} style={tableStyle}>
{enabled && <caption className="result-column-instructions">Column widths can be changed by dragging a header separator or fitted by double-clicking it.</caption>} {enabled && <caption className="result-column-instructions">Column widths can be changed by dragging a header separator or fitted by double-clicking it.</caption>}
{appliedWidths.length > 0 && <colgroup>{appliedWidths.map((width, index) => <col key={index} style={{ width: `${width}px` }} />)}</colgroup>} {appliedWidths.length > 0 && <colgroup>{appliedWidths.map((width, index) => <col key={index} width={width} />)}</colgroup>}
<thead><tr>{headers.map((header, index) => <th key={index}>{header}{enabled && index < columnCount - 1 && <span <thead><tr>{headers.map((header, index) => <th key={index}>{header}{enabled && index < columnCount - 1 && <span
className="result-column-resizer" className="result-column-resizer"
role="separator" role="separator"

View File

@ -36,10 +36,10 @@
.datahub-comparison-error { display: block; margin: 0 var(--legacy-space-3) var(--legacy-space-2); color: var(--danger-text); font-size: var(--ui-control-size); font-style: normal; } .datahub-comparison-error { display: block; margin: 0 var(--legacy-space-3) var(--legacy-space-2); color: var(--danger-text); font-size: var(--ui-control-size); font-style: normal; }
.datahub-tenants-module { min-height: 0; padding: 0; border: 0; background: transparent; } .datahub-tenants-module { min-height: 0; padding: 0; border: 0; background: transparent; }
.datahub-tenant-card-rack { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: var(--space-2); padding: var(--space-3); border: var(--border-hair) solid var(--donut-border); border-radius: var(--donut-rack-radius); background: var(--donut-rack-surface); box-shadow: var(--donut-rack-shadow); } .datahub-tenant-card-rack { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: var(--space-2); padding: var(--space-3); border: var(--border-hair) solid var(--donut-border); border-radius: var(--donut-rack-radius); background: var(--donut-rack-surface); box-shadow: var(--donut-rack-shadow); }
.datahub-tenant-card { position: relative; min-height: var(--donut-card-min-h); padding: 0; transition: background .12s ease, border-color .12s ease, box-shadow .12s ease, transform .12s ease; } .datahub-tenant-card { position: relative; min-height: var(--donut-card-min-h); padding: 0; transition: background .12s ease, border-color .12s ease, transform .12s ease; }
.datahub-tenant-card::before { content: none; } .datahub-tenant-card::before { content: none; }
.datahub-tenant-card:hover, .datahub-tenant-card:hover,
.datahub-tenant-card:focus-within { border-color: var(--line-strong); background: var(--panel-hover); box-shadow: var(--shadow-raised-hover); transform: translateY(-2px); } .datahub-tenant-card:focus-within { border-color: var(--line-strong); background: var(--panel-hover); transform: translateY(-2px); }
.datahub-tenant-card.is-selected { outline: var(--bw-emphasis) solid var(--button-marked-bg); outline-offset: calc(-1 * var(--bw-emphasis)); } .datahub-tenant-card.is-selected { outline: var(--bw-emphasis) solid var(--button-marked-bg); outline-offset: calc(-1 * var(--bw-emphasis)); }
.datahub-tenant-processing-dot { position: absolute; z-index: 3; top: var(--datahub-readiness-dot-inset); left: var(--datahub-readiness-dot-inset); width: var(--datahub-readiness-dot-size); height: var(--datahub-readiness-dot-size); border: var(--border-hair) solid var(--surface-app); border-radius: 50%; background: var(--state-online); pointer-events: none; } .datahub-tenant-processing-dot { position: absolute; z-index: 3; top: var(--datahub-readiness-dot-inset); left: var(--datahub-readiness-dot-inset); width: var(--datahub-readiness-dot-size); height: var(--datahub-readiness-dot-size); border: var(--border-hair) solid var(--surface-app); border-radius: 50%; background: var(--state-online); pointer-events: none; }
.datahub-tenant-processing-dot[data-status="update"] { background: var(--warning); } .datahub-tenant-processing-dot[data-status="update"] { background: var(--warning); }

View File

@ -218,7 +218,7 @@ button.dashboard-status-metric[aria-pressed="true"] { outline: var(--bw-emphasis
.dashboard-block { min-width: 0; padding: var(--space-4); border: var(--border-hair) solid var(--line); border-radius: var(--legacy-radius-sm); background: var(--panel); } .dashboard-block { min-width: 0; padding: var(--space-4); border: var(--border-hair) solid var(--line); border-radius: var(--legacy-radius-sm); background: var(--panel); }
.dashboard-distribution { display: grid; align-content: start; gap: var(--space-4); } .dashboard-distribution { display: grid; align-content: start; gap: var(--space-4); }
.dashboard-segmented-bar { display: flex; width: 100%; height: 28px; overflow: hidden; background: var(--surface-active); } .dashboard-segmented-bar { display: flex; width: 100%; height: 28px; overflow: hidden; background: var(--surface-active); }
.dashboard-segment { flex: 0 0 var(--share); min-width: 2px; height: 100%; background: var(--severity, var(--viz-1)); } .dashboard-segment { --share: 0%; flex: 0 0 var(--share); min-width: 2px; height: 100%; background: var(--severity, var(--viz-1)); }
.dashboard-segment + .dashboard-segment { border-left: var(--border-hair) solid var(--surface-panel); } .dashboard-segment + .dashboard-segment { border-left: var(--border-hair) solid var(--surface-panel); }
.dashboard-distribution-legend { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: var(--space-2); margin: 0; padding: 0; list-style: none; } .dashboard-distribution-legend { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: var(--space-2); margin: 0; padding: 0; list-style: none; }
.dashboard-legend-button { display: flex; align-items: flex-start; gap: var(--space-2); width: 100%; min-height: 52px; padding: var(--space-2); border: var(--border-hair) solid transparent; border-radius: var(--btn-radius); color: var(--text); background: transparent; text-align: left; cursor: pointer; } .dashboard-legend-button { display: flex; align-items: flex-start; gap: var(--space-2); width: 100%; min-height: 52px; padding: var(--space-2); border: var(--border-hair) solid transparent; border-radius: var(--btn-radius); color: var(--text); background: transparent; text-align: left; cursor: pointer; }

View File

@ -113,10 +113,10 @@
gap: var(--space-2); gap: var(--space-2);
padding: var(--space-3); padding: var(--space-3);
overflow: hidden; overflow: hidden;
box-shadow: none; box-shadow: inset 0 0 0 0 transparent;
} }
.obsidian-node-matrix-card .data-tile:hover, .obsidian-node-matrix-card .data-tile:hover,
.obsidian-node-matrix-card .data-tile:focus-visible { box-shadow: none; transform: none; } .obsidian-node-matrix-card .data-tile:focus-visible { box-shadow: inset 0 0 0 0 transparent; transform: none; }
.obsidian-node-matrix-card .data-tile-hex { width: 18px; height: 20px; } .obsidian-node-matrix-card .data-tile-hex { width: 18px; height: 20px; }
.obsidian-node-matrix-card .data-tile-content h3 { .obsidian-node-matrix-card .data-tile-content h3 {
display: -webkit-box; display: -webkit-box;
@ -161,12 +161,12 @@
gap: var(--legacy-space-3); gap: var(--legacy-space-3);
padding: var(--legacy-space-3); padding: var(--legacy-space-3);
overflow: hidden; overflow: hidden;
box-shadow: none; box-shadow: inset 0 0 0 0 transparent;
cursor: pointer; cursor: pointer;
} }
.obsidian-node-card.data-tile:hover, .obsidian-node-card.data-tile:hover,
.obsidian-node-card.data-tile:focus-visible { .obsidian-node-card.data-tile:focus-visible {
box-shadow: none; box-shadow: inset 0 0 0 0 transparent;
transform: none; transform: none;
} }
.obsidian-node-card-technique .data-tile-hex, .obsidian-node-card-technique .data-tile-hex,
@ -206,7 +206,7 @@
border-color: var(--graph-selected); border-color: var(--graph-selected);
outline: 3px solid var(--graph-selected); outline: 3px solid var(--graph-selected);
outline-offset: -3px; outline-offset: -3px;
box-shadow: none; box-shadow: inset 0 0 0 0 transparent;
} }
.obsidian-graph-toolbar, .obsidian-graph-toolbar,
@ -216,7 +216,7 @@
position: absolute; position: absolute;
z-index: 5; z-index: 5;
border: var(--bw-hairline) solid var(--border-default); border: var(--bw-hairline) solid var(--border-default);
border-radius: var(--radius-panel); border-radius: 0;
color: var(--text-primary); color: var(--text-primary);
background: color-mix(in srgb, var(--surface-panel-raised) 94%, transparent); background: color-mix(in srgb, var(--surface-panel-raised) 94%, transparent);
backdrop-filter: blur(var(--space-2)); backdrop-filter: blur(var(--space-2));
@ -233,7 +233,7 @@
transform: translateX(-50%); transform: translateX(-50%);
} }
.obsidian-graph-search { display: grid; gap: var(--space-1); min-width: calc(var(--space-8) * 8); color: var(--text-secondary); font-size: var(--fs-sm); } .obsidian-graph-search { display: grid; gap: var(--space-1); min-width: calc(var(--space-8) * 8); color: var(--text-secondary); font-size: var(--fs-sm); }
.obsidian-graph-search input { min-height: var(--control-h); padding: 0 var(--space-2); border: var(--bw-hairline) solid var(--border-strong); border-radius: var(--radius-control); color: var(--text-primary); background: var(--surface-input); font-size: var(--fs-base); } .obsidian-graph-search input { min-height: var(--control-h); padding: 0 var(--space-2); border: var(--bw-hairline) solid var(--border-strong); border-radius: var(--radius-sm); color: var(--text-primary); background: var(--surface-input); font-size: var(--fs-base); }
.obsidian-graph-count { align-self: center; min-width: max-content; padding-inline: var(--space-2); color: var(--text-secondary); font-size: var(--fs-sm); font-variant-numeric: tabular-nums; } .obsidian-graph-count { align-self: center; min-width: max-content; padding-inline: var(--space-2); color: var(--text-secondary); font-size: var(--fs-sm); font-variant-numeric: tabular-nums; }
.obsidian-graph-branch-actions { .obsidian-graph-branch-actions {
display: flex; display: flex;
@ -280,7 +280,7 @@
transform: translateX(-50%); transform: translateX(-50%);
} }
.obsidian-graph-filters label { display: grid; gap: var(--space-1); color: var(--text-secondary); font-size: var(--fs-sm); } .obsidian-graph-filters label { display: grid; gap: var(--space-1); color: var(--text-secondary); font-size: var(--fs-sm); }
.obsidian-graph-filters select { min-height: var(--control-h); padding-inline: var(--space-2); border: var(--bw-hairline) solid var(--border-strong); border-radius: var(--radius-control); color: var(--text-primary); background: var(--surface-input); font-size: var(--fs-base); } .obsidian-graph-filters select { min-height: var(--control-h); padding-inline: var(--space-2); border: var(--bw-hairline) solid var(--border-strong); border-radius: var(--radius-sm); color: var(--text-primary); background: var(--surface-input); font-size: var(--fs-base); }
.obsidian-graph-zoom { top: var(--space-4); right: var(--space-4); display: grid; overflow: hidden; } .obsidian-graph-zoom { top: var(--space-4); right: var(--space-4); display: grid; overflow: hidden; }
.obsidian-graph-zoom button { display: grid; place-items: center; width: var(--space-8); height: var(--space-8); padding: 0; border: 0; border-bottom: var(--bw-hairline) solid var(--border-default); color: var(--text-primary); background: transparent; font-size: var(--fs-lg); cursor: pointer; } .obsidian-graph-zoom button { display: grid; place-items: center; width: var(--space-8); height: var(--space-8); padding: 0; border: 0; border-bottom: var(--bw-hairline) solid var(--border-default); color: var(--text-primary); background: transparent; font-size: var(--fs-lg); cursor: pointer; }
@ -315,7 +315,7 @@
min-height: var(--control-h); min-height: var(--control-h);
padding: 0 var(--space-4); padding: 0 var(--space-4);
border: var(--bw-hairline) solid var(--border-strong); border: var(--bw-hairline) solid var(--border-strong);
border-radius: var(--radius-control); border-radius: var(--radius-sm);
color: var(--text-primary); color: var(--text-primary);
background: color-mix(in srgb, var(--surface-panel-raised) 94%, transparent); background: color-mix(in srgb, var(--surface-panel-raised) 94%, transparent);
font-size: var(--fs-sm); font-size: var(--fs-sm);

View File

@ -37,7 +37,7 @@ describe('ResizableResultTable', () => {
Object.defineProperty(firstColumnCells[1], 'scrollWidth', { configurable: true, value: 238 }); Object.defineProperty(firstColumnCells[1], 'scrollWidth', { configurable: true, value: 238 });
act(() => container.querySelector('.result-column-resizer')?.dispatchEvent(new MouseEvent('dblclick', { bubbles: true, cancelable: true }))); act(() => container.querySelector('.result-column-resizer')?.dispatchEvent(new MouseEvent('dblclick', { bubbles: true, cancelable: true })));
expect((container.querySelector('col') as HTMLElement).style.width).toBe('240px'); expect(container.querySelector('col')?.getAttribute('width')).toBe('240');
expect(container.querySelector('table')?.classList.contains('has-custom-column-widths')).toBe(true); expect(container.querySelector('table')?.classList.contains('has-custom-column-widths')).toBe(true);
let handle = container.querySelector('.result-column-resizer') as HTMLElement; let handle = container.querySelector('.result-column-resizer') as HTMLElement;
@ -49,7 +49,7 @@ describe('ResizableResultTable', () => {
act(() => handle.dispatchEvent(pointerEvent('pointerdown', 7, 100))); act(() => handle.dispatchEvent(pointerEvent('pointerdown', 7, 100)));
handle = container.querySelector('.result-column-resizer') as HTMLElement; handle = container.querySelector('.result-column-resizer') as HTMLElement;
act(() => handle.dispatchEvent(pointerEvent('pointermove', 7, 148))); act(() => handle.dispatchEvent(pointerEvent('pointermove', 7, 148)));
expect((container.querySelector('col') as HTMLElement).style.width).toBe('168px'); expect(container.querySelector('col')?.getAttribute('width')).toBe('168');
act(() => root.unmount()); act(() => root.unmount());
}); });
@ -66,7 +66,7 @@ describe('ResizableResultTable', () => {
headers.forEach(cell => { cell.getBoundingClientRect = () => ({ width: 100 } as DOMRect); }); headers.forEach(cell => { cell.getBoundingClientRect = () => ({ width: 100 } as DOMRect); });
act(() => container.querySelector('.result-column-resizer')?.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight', bubbles: true }))); act(() => container.querySelector('.result-column-resizer')?.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight', bubbles: true })));
expect((container.querySelector('col') as HTMLElement).style.width).toBe('116px'); expect(container.querySelector('col')?.getAttribute('width')).toBe('116');
act(() => root.unmount()); act(() => root.unmount());
}); });

View File

@ -26,8 +26,9 @@ describe('Datahub centered reference rack layout', () => {
expect(datahubStyles).toContain('border-color: var(--warning); color: var(--warning);'); expect(datahubStyles).toContain('border-color: var(--warning); color: var(--warning);');
expect(datahubStyles).toContain('outline: var(--bw-emphasis) solid var(--button-marked-bg);'); expect(datahubStyles).toContain('outline: var(--bw-emphasis) solid var(--button-marked-bg);');
expect(datahubStyles).toContain('.datahub-tenant-card::before { content: none; }'); expect(datahubStyles).toContain('.datahub-tenant-card::before { content: none; }');
expect(datahubStyles).toContain('transition: background .12s ease, border-color .12s ease, box-shadow .12s ease, transform .12s ease;'); expect(datahubStyles).toContain('transition: background .12s ease, border-color .12s ease, transform .12s ease;');
expect(datahubStyles).toMatch(/\.datahub-tenant-card:hover,\s*\.datahub-tenant-card:focus-within\s*\{[^}]*border-color:\s*var\(--line-strong\);[^}]*background:\s*var\(--panel-hover\);[^}]*box-shadow:\s*var\(--shadow-raised-hover\);[^}]*transform:\s*translateY\(-2px\);/s); expect(datahubStyles).toMatch(/\.datahub-tenant-card:hover,\s*\.datahub-tenant-card:focus-within\s*\{[^}]*border-color:\s*var\(--line-strong\);[^}]*background:\s*var\(--panel-hover\);[^}]*transform:\s*translateY\(-2px\);/s);
expect(datahubStyles).not.toContain('box-shadow: var(--shadow-raised-hover)');
expect(datahubStyles).toContain('.datahub-tenant-select { position: absolute; inset: 0;'); expect(datahubStyles).toContain('.datahub-tenant-select { position: absolute; inset: 0;');
expect(datahubStyles).toContain('grid-template-rows: minmax(0, 1fr) auto auto;'); expect(datahubStyles).toContain('grid-template-rows: minmax(0, 1fr) auto auto;');
expect(datahubStyles).toContain('font: var(--fw-semibold) calc(var(--donut-title-size) * 1.35)'); expect(datahubStyles).toContain('font: var(--fw-semibold) calc(var(--donut-title-size) * 1.35)');

View File

@ -224,8 +224,8 @@ describe('Obsidian-style interactive graph', () => {
expect(graphStyles).toMatch(/\.obsidian-graph-card\.is-selected \.obsidian-node-card,[\s\S]*?\.obsidian-graph-card\.is-selected \.obsidian-node-matrix-card \.data-tile\s*\{/s); expect(graphStyles).toMatch(/\.obsidian-graph-card\.is-selected \.obsidian-node-card,[\s\S]*?\.obsidian-graph-card\.is-selected \.obsidian-node-matrix-card \.data-tile\s*\{/s);
expect(graphStyles).toMatch(/\.obsidian-node-matrix-card\s*\{[^}]*width:\s*100%;[^}]*height:\s*100%;/s); expect(graphStyles).toMatch(/\.obsidian-node-matrix-card\s*\{[^}]*width:\s*100%;[^}]*height:\s*100%;/s);
expect(graphStyles).not.toContain('--graph-card-content-scale'); expect(graphStyles).not.toContain('--graph-card-content-scale');
expect(graphStyles).toMatch(/\.obsidian-node-card\.data-tile:hover,[\s\S]*?\{[^}]*box-shadow:\s*none;[^}]*transform:\s*none;/); expect(graphStyles).toMatch(/\.obsidian-node-card\.data-tile:hover,[\s\S]*?\{[^}]*box-shadow:\s*inset 0 0 0 0 transparent;[^}]*transform:\s*none;/);
expect(graphStyles).toMatch(/\.obsidian-node-matrix-card \.data-tile:hover,[\s\S]*?\{[^}]*box-shadow:\s*none;[^}]*transform:\s*none;/); expect(graphStyles).toMatch(/\.obsidian-node-matrix-card \.data-tile:hover,[\s\S]*?\{[^}]*box-shadow:\s*inset 0 0 0 0 transparent;[^}]*transform:\s*none;/);
expect(graphStyles).toMatch(/\.obsidian-node-card \.data-tile-content h3\s*\{[^}]*font-size:\s*var\(--pathfinder-micro-title-size\);/s); expect(graphStyles).toMatch(/\.obsidian-node-card \.data-tile-content h3\s*\{[^}]*font-size:\s*var\(--pathfinder-micro-title-size\);/s);
expect(graphStyles).toMatch(/\.obsidian-node-inline-label\s*\{[^}]*font-size:\s*var\(--fs-lg\);/s); expect(graphStyles).toMatch(/\.obsidian-node-inline-label\s*\{[^}]*font-size:\s*var\(--fs-lg\);/s);
expect(graphStyles).toMatch(/\.obsidian-node-card \.reader-severity\s*\{[^}]*font-size:\s*var\(--pathfinder-micro-relation-badge-size\);/s); expect(graphStyles).toMatch(/\.obsidian-node-card \.reader-severity\s*\{[^}]*font-size:\s*var\(--pathfinder-micro-relation-badge-size\);/s);

View File

@ -12,7 +12,7 @@ describe('Result DB timeslot scope', () => {
expect(appSource).toContain('scanRunIds={app.activeScanRunIds}'); expect(appSource).toContain('scanRunIds={app.activeScanRunIds}');
expect(browserSource).toContain("backendStatus !== 'connected' || !projectId || !scanRunIds?.length"); expect(browserSource).toContain("backendStatus !== 'connected' || !projectId || !scanRunIds?.length");
expect(browserSource).toContain('<h3>No timeslot selected</h3>'); expect(browserSource).toContain('<h3>No timeslot selected</h3>');
expect(browserSource).toContain('scanRunIds\n };'); expect(browserSource).toMatch(/scanRunIds\r?\n };/);
expect(browserSource).toContain('queryUnifiedResultFacets(scopedQuery)'); expect(browserSource).toContain('queryUnifiedResultFacets(scopedQuery)');
expect(browserSource).toContain('queryUnifiedResults({ ...scopedQuery, offset: 0, limit })'); expect(browserSource).toContain('queryUnifiedResults({ ...scopedQuery, offset: 0, limit })');
expect(browserSource).toContain("item.sourceKind === 'environment-observation'"); expect(browserSource).toContain("item.sourceKind === 'environment-observation'");